初始化

This commit is contained in:
qsh
2024-04-28 16:20:45 +08:00
parent 3f2749b6c4
commit 58929c05ef
687 changed files with 90151 additions and 13 deletions

View File

@@ -0,0 +1,79 @@
<template>
<div>
<!-- 搜索工作栏 -->
<Search
:schema="allSchemas.searchSchema"
labelWidth="0"
@search="setSearchParams"
@reset="setSearchParams"
/>
<!-- 列表 -->
<SSTable
class="mt-20px"
v-model:tableObject="tableObject"
:tableColumns="allSchemas.tableColumns"
@get-list="getTableList"
>
<el-table-column
v-for="item in allSchemas.tableColumns"
:key="item.field"
:prop="item.field"
:label="item.label"
min-width="120px"
/>
<el-table-column label="操作" width="140px" fixed="right">
<template #default="scope">
<el-button
type="primary"
class="mr-10px"
link
style="padding: 0; margin-left: 0"
@click="sellAfter(scope.row)"
>售后</el-button
>
<el-button type="primary" class="mr-10px" link style="padding: 0; margin-left: 0"
>售后审核</el-button
>
<el-button
type="primary"
class="mr-10px"
link
style="padding: 0; margin-left: 0"
@click="feeBack(scope.row)"
>回款</el-button
>
<el-button type="primary" class="mr-10px" link style="padding: 0; margin-left: 0"
>回款确认</el-button
>
</template>
</el-table-column>
</SSTable>
</div>
</template>
<script setup name="ClueOrder">
import { allSchemas } from './order.data'
const tableObject = ref({
tableList: [{ name: '测试', contact: '18888888888' }],
loading: false,
total: 1,
pageSize: 20,
currentPage: 1
})
function setSearchParams() {
// 方法体
}
// 查询
function getTableList() {
// 方法体
}
// 售后
function sellAfter() {
// 方法体
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,98 @@
// import { CrudSchema } from '@/hooks/web/useCrudSchemas'
import { dateFormatter } from '@/utils/formatTime'
// import * as MailAccountApi from '@/api/system/mail/account'
// const userList = await MailAccountApi.getSimpleMailAccountList()
const userList = []
const crudSchemas = reactive([
{
label: '订单号',
field: 'orderNo',
isSearch: true,
isTable: true
},
{
label: '线索名称',
field: 'name',
isSearch: true,
isTable: true
},
{
label: '联系方式',
field: 'contact',
isSearch: true,
isTable: true
},
{
label: '线索来源',
field: 'resource',
isSearch: true,
isTable: true,
search: {
component: 'Select',
api: () => userList,
componentProps: {
optionsAlias: {
labelField: 'name',
valueField: 'id'
}
}
}
},
{
label: '跟进人员',
field: 'userId',
isSearch: true,
isTable: true,
search: {
component: 'Select',
api: () => userList,
componentProps: {
optionsAlias: {
labelField: 'name',
valueField: 'id'
}
}
}
},
{
label: '成交时间',
field: 'createTime',
isSearch: true,
isTable: true,
table: {
fixed: 'left'
},
formatter: dateFormatter,
detail: {
dateFormat: 'YYYY-MM-DD'
},
search: {
component: 'DatePicker',
componentProps: {
type: 'daterange',
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
startPlaceholder: '创建时间',
endPlaceholder: '创建时间'
}
}
},
{
label: '是否全款',
field: 'isFull',
isSearch: true,
isTable: true,
search: {
component: 'Radio',
componentProps: {
options: [
{ label: '全款', value: 1 },
{ label: '非全款', value: 0 }
]
}
}
}
])
export const { allSchemas } = useCrudSchemas(crudSchemas)

View File

@@ -0,0 +1,246 @@
<template>
<el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px">
<el-tabs v-model="tabName">
<el-tab-pane label="线索信息" name="info">
<Form
ref="formRef"
v-loading="formLoading"
:rules="rules"
isCol
:schema="allSchemas.formSchema"
/>
</el-tab-pane>
<el-tab-pane label="跟进信息" name="follow">
<el-button type="primary" @click="handleAppendFollow">新增跟进人</el-button>
<el-table :data="followList">
<el-table-column label="跟进人">
<template #default="{ row }">
<el-select v-model="row.followUser" placeholder="选择跟进人" filterable>
<el-option
v-for="item in userOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="nextFollowTime" label="下次跟进时间">
<template #default="{ row }">
<el-date-picker v-model="row.nextFollowTime" type="date" placeholder="选择日期时间" />
</template>
</el-table-column>
<el-table-column label="操作" width="80">
<template #default="{ $index }">
<Icon icon="ep:remove-filled" class="text-red-500" @click="handleRemove($index)" />
<!-- <el-button @click="handleRemove(row, $index)">
</el-button> -->
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="位置信息" name="map">
<div class="flex justify-between">
<el-select
v-model="areaValue"
filterable
clearable
remote
style="width: 350px"
reserve-keyword
placeholder="请输入关键词"
:remote-method="remoteMethod"
@change="currentSelect"
>
<el-option
v-for="item in areaList"
:key="item.id"
:label="item.name"
:value="item.name"
class="one-text"
>
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.district }}</span>
</el-option>
</el-select>
<el-checkbox v-model="showSchool" :label="true" @change="handleShowSchool"
>展示场地</el-checkbox
>
</div>
<div id="dialogMap" class="mt-20px" style="height: 400px; width: 100%"></div>
</el-tab-pane>
</el-tabs>
<template #footer>
<span>
<el-button @click="dialogVisible = false"> </el-button>
<el-button :disabled="formLoading" type="primary" @click="handleSave"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { allSchemas, rules } from '../cluePool.data'
import { formatDate } from '@/utils/formatTime'
import AMapLoader from '@amap/amap-jsapi-loader'
import ImgPostion from '@/assets/imgs/flag/flag_red.png'
import ImgFlag from '@/assets/imgs/flag/position_blue.png'
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formType = ref('') // 表单的类型create - 新增update - 修改
const formRef = ref() // 表单 Ref
const tabName = ref('info')
const followList = ref([])
const userOptions = ref([])
const areaValue = ref('新天地国际')
const areaList = ref([])
const open = async (type, info) => {
dialogVisible.value = true
dialogTitle.value = type == 'create' ? '新增线索' : '修改线索'
formType.value = type
// 修改时,设置数据
if (info) {
formLoading.value = true
try {
const data = { ...info }
nextTick(() => {
formRef.value.setValues(data)
})
} finally {
formLoading.value = false
}
}
if (!dialogMap.value) {
nextTick(() => {
initMap()
remoteMethod('新天地国际')
})
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
function handleSave() {
console.log('保存')
}
function handleAppendFollow() {
followList.value.push({
followUser: undefined,
nextFollowTime: formatDate(new Date())
})
}
function handleRemove(index) {
followList.value.splice(index, 1)
}
// 地图相关
const dialogMap = ref(null)
const aMap = ref(null)
let AutoComplete = ref(null)
let geoCoder = ref(null)
function initMap() {
AMapLoader.load({
key: '2ffb0e2ea90b1df0b8be48ed66e18fc8', //设置您的key
version: '2.0',
plugins: ['AMap.Geocoder', 'AMap.AutoComplete']
}).then((AMap) => {
aMap.value = AMap
dialogMap.value = new AMap.Map('dialogMap', {
zoom: 12,
zooms: [2, 22],
center: [117.283042, 31.86119]
})
AutoComplete.value = new AMap.AutoComplete({
city: '全国'
})
geoCoder.value = new AMap.Geocoder()
dialogMap.value.on('click', (e) => {
addmark(e.lnglat.getLng(), e.lnglat.getLat(), AMap)
})
})
}
let marker = ref(null)
function addmark(lat, lng, AMap) {
marker.value && removeMarker()
marker.value = new AMap.Marker({
position: new AMap.LngLat(lat, lng),
zoom: 13,
icon: ImgPostion
})
dialogMap.value.add(marker.value)
dialogMap.value.setCenter([lat, lng], '', 500)
}
function removeMarker() {
dialogMap.value.remove(marker.value)
}
const showSchool = ref(false)
const schoolMarkers = ref([])
function handleShowSchool() {
if (showSchool.value) {
let marker1 = new aMap.value.Marker({
map: dialogMap.value,
position: [117.258001, 31.895216],
label: {
content: '慧安驾校桃花社区训练基地',
direction: 'left'
},
icon: ImgFlag,
// extData: element,
clickable: true
})
let marker2 = new aMap.value.Marker({
map: dialogMap.value,
position: [117.286731, 31.902396],
label: {
content: '皖西瑞星驾校总校D',
direction: 'left'
},
icon: ImgFlag,
// extData: element,
clickable: true
})
schoolMarkers.value = [marker1, marker2]
} else {
dialogMap.value.remove(schoolMarkers.value)
}
}
function remoteMethod(searchValue) {
if (searchValue !== '') {
setTimeout(() => {
AutoComplete.value.search(searchValue, (status, result) => {
if (result.tips?.length) {
areaList.value = result?.tips
}
})
}, 200)
}
}
function currentSelect(val) {
const area = areaList.value.find((it) => it.name == val)
if (area) {
addmark(area.location?.lng, area.location?.lat, aMap.value)
dialogMap.value.setCenter([area.location?.lng, area.location?.lat], '', 500)
}
}
</script>
<style scoped>
:deep() .amap-logo {
display: none !important;
}
:deep() .amap-copyright {
display: none !important;
}
</style>

View File

@@ -0,0 +1,261 @@
<template>
<el-dialog :title="dialogTitle" v-model="dialogVisible" width="1000px">
<div class="flex">
<Form
style="flex: 1"
ref="formRef"
v-loading="formLoading"
isCol
:rules="rules"
:schema="allSchemas.formSchema"
/>
<div class="ml-20px" style="width: 300px">
<el-input
v-model="keyword"
placeholder="请输入关键字查询关键话术"
clearable
@keyup.enter="filterList"
/>
<el-collapse v-model="activeQues" :accordion="false">
<el-collapse-item
v-for="item in showList"
:key="item.skillId"
:title="item.question"
:name="item.skillId"
>
<div v-dompurify-html="item.content"></div>
</el-collapse-item>
</el-collapse>
</div>
</div>
</el-dialog>
</template>
<script setup>
import { allSchemas, rules } from './follow.data'
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formType = ref('') // 表单的类型create - 新增update - 修改
const formRef = ref() // 表单 Ref
const open = async (type, info) => {
dialogVisible.value = true
dialogTitle.value = type == 'create' ? '新增跟进记录' : '修改跟进记录'
formType.value = type
// 修改时,设置数据
if (info) {
formLoading.value = true
try {
const data = { ...info }
formRef.value.setValues(data)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
const resultList = [
{
searchValue: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null,
params: {},
orderName: null,
orderType: null,
skillId: 1,
deptId: 167,
question: '暂时先看题的',
skillKey: '先看科目一',
keyList: ['先看科目一'],
content:
'<p>科目一的题目不难的,等会可以加个微信给您发一些做题技巧,我们驾校离你也很近,后面您计划找驾校报名了可以接您来我们驾校实地看看的</p>',
status: 2
},
{
searchValue: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null,
params: {},
orderName: null,
orderType: null,
skillId: 2,
deptId: 167,
question: '你们怎么练车的',
skillKey: '练车人数',
keyList: ['练车人数'],
content:
'<p>我们驾校这边练车是自己提前在微信上跟教练约时间来练车的,科二练车的时候到你练车了是你一个人一辆车,教练一对一教学的,也可以一对二,不用排队等的</p>',
status: 2
},
{
searchValue: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null,
params: {},
orderName: null,
orderType: null,
skillId: 3,
deptId: 167,
question: '教练怎么样 凶嘛',
skillKey: '教练凶',
keyList: ['教练凶'],
content:
'<p>我们驾校教练都是驾校本部教练,也都是经过正规培训上岗的,脾气比较温和幽默的,不存在凶学员的情况,学车氛围也比较好;学员也不需要给教练送礼的</p>',
status: 2
},
{
searchValue: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null,
params: {},
orderName: null,
orderType: null,
skillId: 4,
deptId: 167,
question: '驾校通过率咋样',
skillKey: '通过率',
keyList: ['通过率'],
content:
'<p>我们驾校在合肥也是老牌驾校的了,在合肥干了十几年了,并且拥有自家考场,科二科三考试都在我们自家考场考试,所以通过率一直非常高</p>',
status: 2
},
{
searchValue: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null,
params: {},
orderName: null,
orderType: null,
skillId: 5,
deptId: 167,
question: '可以晚上练车吗?',
skillKey: '晚上练车',
keyList: ['晚上练车'],
content:
'<p>我们驾校练车时间是根据学员的时间来安排的,但是晚上练车视线不太好,因为考试的时候也是白天嘛,建议最好是白天过来练车,然后等熟练了后期可以让教练加加班晚上</p>',
status: 2
},
{
searchValue: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null,
params: {},
orderName: null,
orderType: null,
skillId: 6,
deptId: 167,
question: '大学生有优惠嘛',
skillKey: '学生优惠',
keyList: ['学生优惠'],
content: '<p>学生我们驾校是有优惠的,而且我们驾校有专设学生班,练车不用排队,随到随练的</p>',
status: 2
},
{
searchValue: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null,
params: {},
orderName: null,
orderType: null,
skillId: 7,
deptId: 167,
question: '拿证时间多久',
skillKey: '拿证时间',
keyList: ['拿证时间'],
content: '<p>C1手动挡正常拿证时间45天左右拿证C2自动挡正常35天左右拿证</p>',
status: 2
},
{
searchValue: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null,
params: {},
orderName: null,
orderType: null,
skillId: 8,
deptId: 167,
question: '驾校有熟人',
skillKey: '熟人',
keyList: ['熟人'],
content:
'<p>你朋友认识的人是教练还是驾校里面工作人员呢,驾校场地在哪呢 学车肯定是要对比的 要个近的合适的,我们驾校离你很近,而且学费目前也在做活动比较优惠,您可以对比一下的,找驾校也是可以自己来现场看过后再决定的</p>',
status: 2
},
{
searchValue: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null,
params: {},
orderName: null,
orderType: null,
skillId: 9,
deptId: 167,
question: '考试地点在哪',
skillKey: '考试地点',
keyList: ['考试地点'],
content:
'<p>科一和科四是统一要去滨湖车管所考试的,科二科三合肥市总共六个考场,科二和科三考试是就近安排考场考试的,这样考试也方便些</p>',
status: 2
},
{
searchValue: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null,
params: {},
orderName: null,
orderType: null,
skillId: 10,
deptId: 167,
question: '没时间练车',
skillKey: '没时间学车',
keyList: ['没时间学车'],
content:
'<p>我们驾校练车时间根据学员时间来安排,并且也不用每天都来的,一周抽时间来练个三四次就可以的,每次来一个小时这样,科二来个十来次 科三来个十来次就行,耽误不了你太多时间的</p>',
status: 2
}
]
const showList = ref(resultList)
const keyword = ref('')
const activeQues = ref('')
function filterList() {
showList.value = resultList.filter((it) => it.question.includes(keyword.value))
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,92 @@
<template>
<el-dialog title="成交登记" v-model="show" width="800px">
<Descriptions :data="info" :schema="schema" :columns="2" />
<el-form :model="form" ref="formRef" :rules="rules" label-width="80px" class="mt-20px">
<el-row :gutter="20">
<el-col :span="12" :offset="0">
<el-form-item label="成交日期">
<el-date-picker
v-model="form.date"
type="date"
placeholder="选择日期时间"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="12" :offset="0">
<el-form-item label="是否全款">
<el-radio-group v-model="form.isFull">
<el-radio :label="1"> 全款 </el-radio>
<el-radio :label="2"> 非全款 </el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" :offset="0">
<el-form-item label="支付金额">
<el-input-number v-model="form.pay" :min="1" :step="1" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="24" :offset="0">
<el-form-item label="备注">
<Editor v-model:modelValue="form.remark" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span>
<el-button @click="show = false"> </el-button>
<el-button type="primary" @click="handleSave"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
const show = ref(false)
const form = ref({})
const rules = ref({})
const info = ref({})
const schema = ref([
{
field: 'name',
label: '线索名称'
},
{
field: 'specsName',
label: '联系方式'
},
{
field: 'supplier',
label: '意向状态'
},
{
field: 'supplier',
label: '创建时间'
},
{
field: 'purchaseCount',
label: '诉求',
span: 2
},
{
field: 'remark',
label: '备注',
isEditor: true,
span: 2
}
])
function open(val) {
show.value = true
info.value = { ...val }
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
function handleSave() {
console.log('保存成功')
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,234 @@
<template>
<el-drawer
v-model="show"
direction="rtl"
size="60%"
style="min-width: 700px"
:with-header="false"
:destroy-on-close="true"
:show-close="true"
:wrapperClosable="true"
>
<!-- header -->
<el-skeleton :loading="loading" animated>
<div class="flex justify-between" style="height: 32px">
<div class="flex" style="align-items: center">
<b class="mr-5px text-24px">{{ info.name }}</b>
<div class="mr-5px text-16px">1888888888</div>
<el-tag type="success">A高意向</el-tag>
</div>
<div>
<el-button type="primary" plain>修改</el-button>
<el-button type="danger" plain>删除</el-button>
</div>
</div>
</el-skeleton>
<!-- 基础信息 -->
<el-skeleton :loading="loading" animated>
<el-table :data="followList" size="small" border class="mt-10px">
<el-table-column prop="name" label="跟进人" />
<el-table-column prop="latestFollowTime" label="最新跟进时间" />
<el-table-column prop="nextFollowTime" label="下次跟进时间" />
<el-table-column prop="saleStatus" label="成交状态" />
</el-table>
</el-skeleton>
<el-divider direction="horizontal" />
<!-- 详细信息 -->
<el-tabs v-model="infoIndex" type="border-card">
<el-tab-pane label="跟进记录" name="followRecord">
<el-button class="mb-10px" type="primary" @click="addFollow">添加跟进记录</el-button>
<el-timeline>
<el-timeline-item timestamp="2024-04-01" placement="top">
<el-card shadow="always" :body-style="{ padding: '10px' }">
<div>
<div class="flex justify-between" style="align-items: center">
<div class="flex align-baseline">
<b class="text-18px">张三</b>
<span class="text-14 ml-10px">2024-04-01 09:00:00</span>
</div>
<div>
<el-button type="primary" plain @click="updateFollow()">修改</el-button>
<el-button type="danger" plain>删除</el-button>
</div>
</div>
<div v-dompurify-html="followContent"></div>
<div class="flex mt-10px" style="align-items: center">
<div class="flex" style="color: #666; align-items: center">
<Icon icon="ep:clock" class="mr-5px" />
<span>本次跟进时间2024-04-05 10:57</span>
</div>
<div class="flex ml-50px" style="color: #666; align-items: center">
<Icon icon="ep:clock" class="mr-5px" />
<span>下次跟进时间2024-04-10 10:00</span>
</div>
</div>
</div>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="2024-02-01" placement="top">
<el-card shadow="always" :body-style="{ padding: '10px' }">
<div>
<div class="flex justify-between" style="align-items: center">
<div class="flex align-baseline">
<b class="text-18px">李四</b>
<span class="text-14 ml-10px">2024-02-01 09:00:00</span>
</div>
<div>
<el-button type="primary" plain>修改</el-button>
<el-button type="danger" plain>删除</el-button>
</div>
</div>
<div key="followContent" v-dompurify-html="followContent2"></div>
<div class="flex mt-10px" style="align-items: center">
<div class="flex" style="color: #666; align-items: center">
<Icon icon="ep:clock" class="mr-5px" />
<span>本次跟进时间2024-02-05 10:57</span>
</div>
<div class="flex ml-50px" style="color: #666; align-items: center">
<Icon icon="ep:clock" class="mr-5px" />
<span>下次跟进时间2024-02-10 10:00</span>
</div>
</div>
</div>
</el-card>
</el-timeline-item>
</el-timeline>
</el-tab-pane>
<el-tab-pane label="详细信息" name="infoDetail">
<el-descriptions :column="2" border>
<el-descriptions-item min-width="150px" label="线索名称">{{
info.name
}}</el-descriptions-item>
<el-descriptions-item min-width="150px" label="联系方式"
>18888888888</el-descriptions-item
>
<el-descriptions-item min-width="150px" label="线索来源">驾考宝典</el-descriptions-item>
<el-descriptions-item min-width="150px" label="意向状态">高意向</el-descriptions-item>
<el-descriptions-item min-width="150px" :span="2" label="诉求"
>这是诉求内容这是诉求内容这是诉求内容这是诉求内容这是诉求内容这是诉求内容这是诉求内容</el-descriptions-item
>
<el-descriptions-item min-width="150px" :span="2" label="备注"
>这是备注内容</el-descriptions-item
>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="操作记录" name="operateRecord">
<el-timeline>
<el-timeline-item timestamp="2024-04-01" placement="top">
<el-card shadow="always" :body-style="{ padding: '10px' }">
<div style="color: #666">
<div class="pt-5px">
<span>操作人机器人1号</span>
</div>
<div class="pt-5px pb-5px">
<span>成交线索</span>
</div>
<div class="flex" style="align-items: center">
<Icon icon="ep:clock" class="mr-5px" />
<span>操作时间2024-04-05 10:57</span>
</div>
</div>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="2024-02-01" placement="top">
<el-card shadow="always" :body-style="{ padding: '10px' }">
<div style="color: #666">
<div class="pt-5px">
<span>操作人机器人2号</span>
</div>
<div class="pt-5px pb-5px">
<span>修改意向状态为高意向</span>
</div>
<div class="flex" style="align-items: center">
<Icon icon="ep:clock" class="mr-5px" />
<span>操作时间2024-04-1 10:57</span>
</div>
</div>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="2024-02-01" placement="top">
<el-card shadow="always" :body-style="{ padding: '10px' }">
<div style="color: #666">
<div class="pt-5px">
<span>操作人机器人1号</span>
</div>
<div class="pt-5px pb-5px">
<span>跟进线索</span>
</div>
<div class="flex" style="align-items: center">
<Icon icon="ep:clock" class="mr-5px" />
<span>操作时间2024-04-1 10:57</span>
</div>
</div>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="2024-02-01" placement="top">
<el-card shadow="always" :body-style="{ padding: '10px' }">
<div style="color: #666">
<div class="pt-5px">
<span>操作人机器人2号</span>
</div>
<div class="pt-5px pb-5px">
<span>创建线索</span>
</div>
<div class="flex" style="align-items: center">
<Icon icon="ep:clock" class="mr-5px" />
<span>操作时间2024-04-1 10:57</span>
</div>
</div>
</el-card>
</el-timeline-item>
</el-timeline>
</el-tab-pane>
</el-tabs>
<!-- 新建编辑跟进信息 -->
<DialogFollow ref="followRef" />
</el-drawer>
</template>
<script setup>
import DialogFollow from './DialogFollow.vue'
const show = ref(false)
const info = ref(null)
const loading = ref(false)
const followContent = `<p style="color: red;">这是本次跟进的内容。</p><br/><p>我还能放图片,但需要你自己排版:</p><br/><img style="width: 200px;" src="https://q6.itc.cn/images01/20240407/0e6be21aebc847648109304f20370790.jpeg">`
const followContent2 = `<p style="color: red;">这是本次跟进的内容。</p>`
const followList = ref([
{
name: '李四',
latestFollowTime: '2024-02-01',
nextFollowTime: '2024-04-01',
saleStatus: '未成交'
},
{
name: '王二',
latestFollowTime: '2024-03-01',
nextFollowTime: '2024-04-11',
saleStatus: '已成交'
}
])
function open(row) {
info.value = row
show.value = true
}
const infoIndex = ref('followRecord')
defineExpose({
open
})
const followRef = ref()
function addFollow() {
followRef.value.open('create', null)
}
function updateFollow() {
followRef.value.open('update', { nextFollowTime: '2024-04-01 12:12' })
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,55 @@
import { dateFormatter } from '@/utils/formatTime'
// 表单校验
export const rules = reactive({
username: [required],
password: [required]
})
// CrudSchemahttps://doc.iocoder.cn/vue3/crud-schema/
const crudSchemas = reactive([
{
label: '本次跟进时间',
field: 'createTime',
formatter: dateFormatter,
form: {
component: 'DatePicker',
componentProps: {
type: 'datetime',
format: 'YYYY-MM-DD HH:mm',
valueFormat: 'YYYY-MM-DD HH:mm',
placeholder: '创建时间'
}
}
},
{
label: '下次跟进时间',
field: 'nextTime',
isForm: true,
formatter: dateFormatter,
detail: {
dateFormat: 'YYYY-MM-DD HH:mm'
},
form: {
component: 'DatePicker',
componentProps: {
type: 'datetime',
format: 'YYYY-MM-DD HH:mm',
valueFormat: 'YYYY-MM-DD HH:mm',
placeholder: '下次跟进时间'
}
}
},
{
label: '跟进内容',
field: 'remark',
isTable: true,
form: {
component: 'Editor',
colProps: {
span: 24
}
}
}
])
export const { allSchemas } = useCrudSchemas(crudSchemas)

View File

@@ -0,0 +1,188 @@
// import { CrudSchema } from '@/hooks/web/useCrudSchemas'
import { dateFormatter } from '@/utils/formatTime'
// import * as MailAccountApi from '@/api/system/mail/account'
// 表单校验
export const rules = reactive({
username: [required],
password: [required],
host: [required],
port: [required],
sslEnable: [required]
})
// const userList = await MailAccountApi.getSimpleMailAccountList()
const userList = []
// CrudSchemahttps://doc.iocoder.cn/vue3/crud-schema/
const crudSchemas = reactive([
{
label: '线索名称',
field: 'name',
isSearch: true,
isTable: true
},
{
label: '联系方式',
field: 'contact',
isSearch: true,
isTable: true
},
{
label: '线索来源',
field: 'resource',
isSearch: true,
isTable: true,
search: {
component: 'Select',
api: () => userList,
componentProps: {
optionsAlias: {
labelField: 'name',
valueField: 'id'
}
}
},
form: {
component: 'Select',
api: () => userList,
componentProps: {
optionsAlias: {
labelField: 'name',
valueField: 'id'
}
}
}
},
{
label: '意向状态',
field: 'intention',
isSearch: true,
isTable: true,
table: {
fixed: 'left'
},
search: {
component: 'Select',
api: () => userList,
componentProps: {
optionsAlias: {
labelField: 'name',
valueField: 'id'
}
}
},
form: {
component: 'Select',
api: () => userList,
componentProps: {
optionsAlias: {
labelField: 'name',
valueField: 'id'
}
}
}
},
{
label: '跟进人员',
field: 'userId',
isSearch: true,
isTable: true,
isForm: false,
search: {
component: 'Select',
api: () => userList,
componentProps: {
optionsAlias: {
labelField: 'name',
valueField: 'id'
}
}
}
},
{
label: '下次跟进时间',
field: 'nextTime',
isSearch: true,
isTable: true,
isForm: false,
formatter: dateFormatter,
detail: {
dateFormat: 'YYYY-MM-DD'
},
search: {
component: 'DatePicker',
componentProps: {
type: 'daterange',
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
startPlaceholder: '下次跟进时间',
endPlaceholder: '下次跟进时间'
}
}
},
{
label: '诉求',
field: 'need',
isTable: true,
form: {
component: 'Input',
componentProps: {
type: 'textarea'
},
colProps: {
span: 24
}
}
},
{
label: '最新跟进时间',
field: 'latestFollowTime',
isTable: true,
isForm: false
},
{
label: '备注',
field: 'remark',
isTable: true,
form: {
component: 'Editor',
colProps: {
span: 24
}
}
},
{
label: '创建时间',
field: 'createTime',
isSearch: true,
isTable: true,
table: {
fixed: 'left'
},
formatter: dateFormatter,
detail: {
dateFormat: 'YYYY-MM-DD'
},
search: {
component: 'DatePicker',
componentProps: {
type: 'daterange',
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
startPlaceholder: '创建时间',
endPlaceholder: '创建时间'
}
},
form: {
component: 'DatePicker',
componentProps: {
type: 'date',
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
placeholder: '创建时间'
}
}
}
])
export const { allSchemas } = useCrudSchemas(crudSchemas)

View File

@@ -0,0 +1,126 @@
<template>
<div>
<div class="relative">
<el-tabs v-model="searchForm.mode" size="small">
<el-tab-pane label="全部" name="0" />
<el-tab-pane name="1">
<template #label>
<Tooltip message="除了无效线索和已成交的线索" />
<el-badge :value="123" :max="9999">
<span class="ml-3px">未成交</span>
</el-badge>
</template>
</el-tab-pane>
<el-tab-pane name="2">
<template #label>
<Tooltip message="下次跟进时间在今日之前的未成交线索" />
<el-badge :value="234" :max="9999">
<span class="ml-3px">待跟进</span>
</el-badge>
</template>
</el-tab-pane>
<el-tab-pane name="3">
<template #label>
<Tooltip message="只有创建时间,无下次跟进时间的未成交线索" />
<el-badge :value="423" :max="9999">
<span class="ml-3px">新线索</span>
</el-badge>
</template>
</el-tab-pane>
<el-tab-pane label="公海" name="4" />
</el-tabs>
<div class="absolute" style="right: 10px; top: 0">
<el-button plain>导入</el-button>
<el-button type="primary" @click="handleInsert">新增</el-button>
</div>
</div>
<!-- 搜索工作栏 -->
<Search
:schema="allSchemas.searchSchema"
labelWidth="0"
@search="setSearchParams"
@reset="setSearchParams"
/>
<!-- 列表 -->
<SSTable
class="mt-20px"
v-model:tableObject="tableObject"
:tableColumns="allSchemas.tableColumns"
@get-list="getTableList"
>
<el-table-column
v-for="item in allSchemas.tableColumns"
:key="item.field"
:prop="item.field"
:label="item.label"
min-width="120px"
/>
<el-table-column label="操作" width="200px" fixed="right">
<template #default="scope">
<el-button type="primary" link @click="handleDetail(scope.row)">详情</el-button>
<el-button type="primary" link @click="handleEdit(scope.row)">修改</el-button>
<el-button type="primary" link @click="handleSuccess(scope.row)">登记</el-button>
<el-button type="primary" link>释放</el-button>
</template>
</el-table-column>
</SSTable>
<DialogClue ref="formRef" />
<DrawerClue ref="drawerRef" />
<DialogSuccess ref="successRef" />
</div>
</template>
<script setup name="CluePool">
import { allSchemas } from './cluePool.data'
import DialogClue from './Comp/DialogClue.vue'
import DrawerClue from './Comp/DrawerClue.vue'
import DialogSuccess from './Comp/DialogSuccess.vue'
const searchForm = ref({
mode: '2'
})
const formRef = ref()
const drawerRef = ref()
const successRef = ref()
// const { tableObject, tableMethods } = useTable({
// getListApi: MailTemplateApi.getMailTemplatePage, // 分页接口
// delListApi: MailTemplateApi.deleteMailTemplate // 删除接口
// })
const tableObject = ref({
tableList: [{ name: '测试', contact: '18888888888' }],
loading: false,
total: 1,
pageSize: 20,
currentPage: 1
})
const setSearchParams = function () {
// 方法体
}
function getTableList() {
// 查询
}
// 新增
function handleInsert() {
formRef.value.open('create', null)
}
// 编辑
function handleEdit(row) {
formRef.value.open('update', row)
}
// 详情
function handleDetail(row) {
drawerRef.value.open(row)
}
// 登记
function handleSuccess(row) {
successRef.value.open(row)
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,52 @@
<template>
<div>
<el-table :data="list" border stripe>
<el-table-column type="index" width="50" />
<el-table-column label="来源名称">
<template #default="{ row }">
<el-input v-model="row.name" placeholder="请输入" :clearable="false" />
</template>
</el-table-column>
<el-table-column label="获取连接">
<template #default="{ row }">
<el-input v-model="row.link" placeholder="请输入" :clearable="false" />
</template>
</el-table-column>
<el-table-column label="操作" width="100px">
<template #default="{ $index }">
<el-button type="primary" style="padding: 0px" text @click="handleRemove($index)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div class="mt-20px flex justify-center">
<el-button type="primary" @click="handleInsert">新增规则</el-button>
<el-button type="primary" @click="onSubmit">保存</el-button>
<el-button>重置</el-button>
</div>
</div>
</template>
<script setup>
const list = ref([
{ name: '一点通账号1', link: 'http://baidu.com' },
{ name: '一点通账号2', link: 'http://baidu.com' },
{ name: '宝典账号', link: 'http://baidu.com' },
{ name: '抖音', link: 'http://baidu.com' }
])
function handleInsert() {
list.value.push({ name: '', link: '' })
}
function onSubmit() {
console.log('保存成功')
}
function handleRemove(idx) {
list.value.splice(idx, 1)
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,138 @@
<template>
<el-form :model="form" ref="sendForm" :rules="rules" label-width="100px" :inline="false">
<el-form-item label="是否自动分配">
<el-radio-group v-model="form.isAuto">
<el-radio :label="1"> 自动分配 </el-radio>
<el-radio :label="0"> 手动分配 </el-radio>
</el-radio-group>
</el-form-item>
<div v-if="form.isAuto">
<el-form-item label="分配对象">
<div>
<el-checkbox
v-model="checkUserAll"
:indeterminate="userIndeterminate"
@change="userCheckAllChange"
>
全选
</el-checkbox>
<el-checkbox-group v-model="form.users" @change="userCheckedChange">
<el-checkbox
v-for="(item, index) in userOptions"
:key="index"
:label="item.value"
:value="item.value"
>
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
</div>
</el-form-item>
<el-form-item label="线索来源">
<div>
<el-checkbox
v-model="checkResourceAll"
:indeterminate="resourceIndeterminate"
@change="resourceCheckAllChange"
>
全选
</el-checkbox>
<el-checkbox-group v-model="form.resource" @change="resourceCheckedChange">
<el-checkbox
v-for="(item, index) in resourceOptions"
:key="index"
:label="item.value"
:value="item.value"
>
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
</div>
</el-form-item>
<el-form-item label="权重配置">
<div>
<div v-for="(item, index) in intentionOptions" :key="index" class="flex mb-10px">
<div class="mr-15px" style="width: 100px">{{ item.label }}</div>
<el-input v-model="item.value" type="number" placeholder="请输入权重">
<template #suffix> % </template>
</el-input>
</div>
</div>
</el-form-item>
<el-form-item label="分配时间">
<el-time-picker
v-model="form.sendTime"
placeholder="任意时间点"
format="HH:mm"
value-format="HH:mm"
:clearable="false"
/>
</el-form-item>
</div>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存</el-button>
<el-button>重置</el-button>
</el-form-item>
</el-form>
</template>
<script setup>
const form = ref({
isAuto: 1,
users: [1, 2],
resource: [3],
sendTime: '00:00'
})
const rules = ref({})
const checkUserAll = ref(false)
const userIndeterminate = ref(true)
const userOptions = ref([
{ label: '张三', value: 1 },
{ label: '李四', value: 2 },
{ label: '王二', value: 3 }
])
function userCheckAllChange(val) {
form.value.users = val ? userOptions.value.map((it) => it.value) : []
userIndeterminate.value = false
}
function userCheckedChange(val) {
const checkedCount = val.length
checkUserAll.value = checkedCount == userOptions.value.length
userIndeterminate.value = checkedCount > 0 && checkedCount < userOptions.value.length
}
function onSubmit() {
console.log('hhahah')
}
const checkResourceAll = ref(false)
const resourceIndeterminate = ref(true)
const resourceOptions = ref([
{ label: '抖音', value: 1 },
{ label: '一点通', value: 2 },
{ label: '驾考宝典', value: 3 }
])
function resourceCheckAllChange(val) {
form.value.resource = val ? resourceOptions.value.map((it) => it.value) : []
resourceIndeterminate.value = false
}
function resourceCheckedChange(val) {
const checkedCount = val.length
checkResourceAll.value = checkedCount == resourceOptions.value.length
resourceIndeterminate.value = checkedCount > 0 && checkedCount < resourceOptions.value.length
}
const intentionOptions = ref([
{ label: '高意向', value: 20 },
{ label: '中意向', value: 20 },
{ label: '低意向', value: 20 },
{ label: '未知意向', value: 40 }
])
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,122 @@
<template>
<el-row :gutter="80">
<el-col :span="10" :offset="0">
<el-button class="mb-10px" type="primary" @click="handleInsert">新增属性</el-button>
<el-table :data="tableList">
<el-table-column prop="name" label="名称" />
<el-table-column label="启用状态">
<template #default="{ row }">
<el-switch
v-model="row.status"
:active-value="1"
:inactive-value="0"
:disabled="!row.canUpdate"
@change="changeStatus(row)"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="80px">
<template #default="{ row }">
<el-button
type="primary"
text
:disabled="!row.canUpdate"
style="padding: 0"
@click="remove(row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</el-col>
<el-col :span="14" :offset="0">
<el-form :model="form" ref="fieldForm" :rules="rules" label-width="80px" :inline="false">
<el-form-item label="属性名称" prop="name">
<el-input v-model="form.name" placeholder="请输入属性名称" />
</el-form-item>
<el-form-item label="属性类型" prop="type">
<el-select
v-model="form.type"
placeholder="请选择属性类型"
clearable
filterable
style="width: 100%"
>
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item
v-if="['Checkbox', 'Radio', 'Select'].includes(form.type)"
label="选项"
prop="option"
key="option"
>
<div>
<el-button type="primary" @click="optionList.push([])"> 新增选项 </el-button>
<div
class="flex justify-between mt-10px"
v-for="(item, index) in optionList"
:key="index"
>
<el-input v-model="item.label" placeholder="请输入选项内容" clearable />
<el-button type="primary" text @click="optionList.splice(index, 1)">删除</el-button>
</div>
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</template>
<script setup>
const tableList = ref([{ name: '咨询车型', status: 0, canUpdate: false }])
const form = ref({
name: undefined,
type: undefined,
option: undefined
})
const typeOptions = ref([
{ label: '输入框', value: 'Input' },
{ label: '多选', value: 'Checkbox' },
{ label: '单选', value: 'Radio' },
{ label: '下拉选', value: 'Select' },
{ label: '开关', value: 'Switch' },
{ label: '日期选择', value: 'DatePicker' },
{ label: '时间选择', value: 'TimePicker' },
{ label: '富文本', value: 'Editor' },
{ label: '图片', value: 'UploadImg' },
{ label: '文件', value: 'UploadFile' }
])
const rules = {}
const optionList = ref([])
function handleInsert() {
console.log('新增')
}
function changeStatus(row) {
console.log(row.status)
}
function remove(row) {
console.log(row.status)
}
function onSubmit() {
console.log('保存')
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,122 @@
<template>
<el-row :gutter="80">
<el-col :span="10" :offset="0">
<el-button class="mb-10px" type="primary" @click="handleInsert">新增属性</el-button>
<el-table :data="tableList">
<el-table-column prop="name" label="名称" />
<el-table-column label="启用状态">
<template #default="{ row }">
<el-switch
v-model="row.status"
:active-value="1"
:inactive-value="0"
:disabled="!row.canUpdate"
@change="changeStatus(row)"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="80px">
<template #default="{ row }">
<el-button
type="primary"
text
:disabled="!row.canUpdate"
style="padding: 0"
@click="remove(row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</el-col>
<el-col :span="14" :offset="0">
<el-form :model="form" ref="fieldForm" :rules="rules" label-width="80px" :inline="false">
<el-form-item label="属性名称" prop="name">
<el-input v-model="form.name" placeholder="请输入属性名称" />
</el-form-item>
<el-form-item label="属性类型" prop="type">
<el-select
v-model="form.type"
placeholder="请选择属性类型"
clearable
filterable
style="width: 100%"
>
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item
v-if="['Checkbox', 'Radio', 'Select'].includes(form.type)"
label="选项"
prop="option"
key="option"
>
<div>
<el-button type="primary" @click="optionList.push([])"> 新增选项 </el-button>
<div
class="flex justify-between mt-10px"
v-for="(item, index) in optionList"
:key="index"
>
<el-input v-model="item.label" placeholder="请输入选项内容" clearable />
<el-button type="primary" text @click="optionList.splice(index, 1)">删除</el-button>
</div>
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</template>
<script setup>
const tableList = ref([{ name: '额外支出费用', status: 1, canUpdate: true }])
const form = ref({
name: undefined,
type: undefined,
option: undefined
})
const typeOptions = ref([
{ label: '输入框', value: 'Input' },
{ label: '多选', value: 'Checkbox' },
{ label: '单选', value: 'Radio' },
{ label: '下拉选', value: 'Select' },
{ label: '开关', value: 'Switch' },
{ label: '日期选择', value: 'DatePicker' },
{ label: '时间选择', value: 'TimePicker' },
{ label: '富文本', value: 'Editor' },
{ label: '图片', value: 'UploadImg' },
{ label: '文件', value: 'UploadFile' }
])
const rules = {}
const optionList = ref([])
function handleInsert() {
console.log('新增')
}
function changeStatus(row) {
console.log(row.status)
}
function remove(row) {
console.log(row.status)
}
function onSubmit() {
console.log('保存')
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,198 @@
<template>
<div class="flex">
<el-card shadow="always" :body-style="{ padding: '10px' }">
<div
class="flex text-14px cursor-pointer"
v-for="(item, index) in list"
:key="index"
style="height: 48px; line-height: 48px; width: 240px"
@click="handleChoose(item.value)"
:class="{ actived: item.value == msgType }"
>
<div class="font-bold pl-20px">{{ item.name }}</div>
</div>
</el-card>
<el-card shadow="always" :body-style="{ padding: '10px' }" class="ml-20px flex-1">
<el-form :model="form" ref="msgForm" :rules="rules" label-width="100px" :inline="false">
<el-form-item prop="isEnable">
<template #label>
<div class="flex justify-center" style="align-items: center">
<Tooltip message="是否发送对应消息通知" />
<span>是否启用</span>
</div>
</template>
<el-radio-group v-model="form.isEnable">
<el-radio :label="1"> 启用 </el-radio>
<el-radio :label="0"> 禁用 </el-radio>
</el-radio-group>
</el-form-item>
<div v-if="form.isEnable">
<el-form-item label="微信通知" prop="wxMsg">
<el-radio-group v-model="form.wxMsg">
<el-radio :label="1"> 启用 </el-radio>
<el-radio :label="0"> 禁用 </el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="发送对象" prop="msgTo">
<div>
<el-checkbox-group v-model="form.msgTo">
<el-checkbox :label="1"> 创建人 </el-checkbox>
<el-checkbox :label="2"> 跟进人 </el-checkbox>
<el-checkbox :label="3"> 指定用户 </el-checkbox>
<el-checkbox v-if="form.wxMsg" :label="4"> 微信群 </el-checkbox>
</el-checkbox-group>
<div class="flex">
<div v-if="form.msgTo.includes(3)" class="flex mr-20px" style="align-items: center">
<div class="mr-15px" style="width: 80px">指定用户</div>
<el-select
v-model="form.msgToUsers"
placeholder="选择用户,可多选"
filterable
multiple
style="width: 300px"
>
<el-option
v-for="item in userOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div v-if="form.msgTo.includes(4)" class="flex mr-20px" style="align-items: center">
<div
class="mr-15px flex"
style="align-items: center; width: 180px; text-align: right"
>
<Tooltip message="已添加微信机器人的群" />
<span>微信群名称</span>
</div>
<el-input v-model="form.wxGroup" placeholder="请输入群名称" />
</div>
</div>
</div>
</el-form-item>
<el-form-item label="发送时间" prop="sendTime">
<div>
<el-radio-group v-model="form.sendTime">
<el-radio :label="1"> 立即发送 </el-radio>
<el-radio :label="2"> 指定时间 </el-radio>
</el-radio-group>
<div v-if="form.sendTime == 2">
<span class="mr-15px">指定时间</span>
<el-radio-group v-model="form.msgTimeType" @change="form.days = []">
<el-radio :label="1"> 每日 </el-radio>
<el-radio :label="2"> 次日 </el-radio>
<el-radio :label="3"> 每周 </el-radio>
<el-radio :label="4"> 每月 </el-radio>
</el-radio-group>
<div v-if="[3, 4].includes(form.msgTimeType)" class="mt-15px">
<span class="mr-15px">日期</span>
<el-select v-model="form.days" placeholder="选择日期,可多选" multiple filterable>
<el-option
v-for="item in dayOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div class="mt-15px">
<span class="mr-15px">具体时间</span>
<el-time-picker
v-model="form.msgTime"
placeholder="具体时间"
:clearable="false"
format="HH:mm"
value-format="HH:mm"
class="ml-20px"
/>
</div>
</div>
</div>
</el-form-item>
<el-form-item label="消息模板" prop="msgTemplate">
<el-input
v-model="form.msgTemplate"
type="textarea"
:autosize="{ minRows: 4, maxRows: 6 }"
placeholder="请输入模板内容"
/>
</el-form-item>
</div>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存</el-button>
<el-button>重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script setup>
const list = [
{ name: '成交通知', value: 'CJTZ' },
{ name: '释放预警通知', value: 'SFYJTZ' },
{ name: '待跟进通知', value: 'DGJTZ' },
{ name: '撞单通知', value: 'ZDTZ' },
{ name: '待审核通知', value: 'DSHTZ' },
{ name: '审核结果通知', value: 'SHJGTZ' }
]
const msgType = ref('CJTZ')
const form = ref({
isEnable: true,
wxMsg: false,
msgTo: [],
msgToUsers: [],
wxGroup: '',
sendTime: 1,
msgTimeType: 1,
msgTime: '00:00',
days: []
})
const rules = ref({})
const userOptions = ref([
{ label: '张张', value: '1' },
{ label: '李李', value: '2' },
{ label: '王王', value: '3' },
{ label: '赵赵', value: '4' }
])
const dayOptions = computed(() => {
const weekList = [
{ label: '周一', value: 1 },
{ label: '周二', value: 2 },
{ label: '周三', value: 3 },
{ label: '周四', value: 4 },
{ label: '周五', value: 5 },
{ label: '周六', value: 6 },
{ label: '周日', value: 7 }
]
let monthList = []
for (let i = 0; i < 28; i++) {
monthList.push({ label: `${i + 1}`, value: i + 1 })
}
let obj = {
3: weekList,
4: monthList
}
return obj[form.value.msgTimeType] || []
})
function handleChoose(type) {
msgType.value = type
}
function onSubmit() {
console.log('保存成功')
}
</script>
<style lang="scss" scoped>
.actived {
background-color: #f0f7ff;
}
</style>

View File

@@ -0,0 +1,33 @@
<template>
<div>
<el-tabs v-model="tabIndex" type="border-card">
<el-tab-pane label="线索属性" :name="0">
<FieldClue />
</el-tab-pane>
<el-tab-pane label="成交属性" :name="1">
<FieldOrder />
</el-tab-pane>
<el-tab-pane label="线索获取规则" :name="2">
<ClueGet />
</el-tab-pane>
<el-tab-pane label="线索分配规则" :name="3">
<ClueSend />
</el-tab-pane>
<el-tab-pane label="消息通知" :name="4">
<MsgSend />
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup name="ClueSetting">
import FieldClue from './Comp/FieldClue.vue'
import FieldOrder from './Comp/FieldOrder.vue'
import ClueGet from './Comp/ClueGet.vue'
import ClueSend from './Comp/ClueSend.vue'
import MsgSend from './Comp/MsgSend.vue'
const tabIndex = ref(0)
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,7 @@
<template>
<div> 关键话术 </div>
</template>
<script setup></script>
<style lang="scss" scoped></style>