Browse Source

no message

master
xpz2018 9 months ago
parent
commit
1ec4ccd36e
8 changed files with 115 additions and 75 deletions
  1. 9
      src/enums/customerEnum.ts
  2. 18
      src/views/clue/clueList/index.vue
  3. 53
      src/views/clue/components/data.ts
  4. 46
      src/views/clue/components/modal.vue
  5. 8
      src/views/clue/customer/data.ts
  6. 19
      src/views/components/Profile.vue
  7. 15
      src/views/components/Timeline.vue
  8. 22
      src/views/sys/workbench/components/WorkbenchHeader.vue

9
src/enums/customerEnum.ts

@ -60,6 +60,7 @@ export const validStatusList = [
export const followStageList = [
{ label: '联系不上', value: -2, color: 'green' },
{ label: '放弃线索', value: -1, color: 'red' },
{ label: '新线索', value: 0, color: 'red' },
{ label: '未接通,待跟进', value: 1, color: 'red' },
{ label: '已接通,未详细沟通', value: 2, color: 'green' },
{ label: '已接通,已详细沟通', value: 3, color: 'gray' },
@ -74,7 +75,9 @@ export const incomeList = [
{ label: '3001~5000', value: 1 },
{ label: '5001~8000', value: 2 },
{ label: '8001~12000', value: 3 },
{ label: '12001~20000', value: 4 },
{ label: '20001~50000', value: 5 },
{ label: '50000以上', value: 5 },
{ label: '12001~15000', value: 4 },
{ label: '15001~20000', value: 5 },
{ label: '20001~25000', value: 6 },
{ label: '25001~30000', value: 7 },
{ label: '30000以上', value: 8 },
]

18
src/views/clue/clueList/index.vue

@ -16,23 +16,7 @@
</div>
</template> -->
<template #userinfo="{ text, record }">
<div class="flex-row-center-start" style="padding-left: 12px;">
<Avatar :src="record.profilePhoto || 'https://dating-agency-prod.oss-cn-shenzhen.aliyuncs.com/827036501B11.png'" :size="64" />
<div class="flex-col" style="margin-left: 12px;">
<div class="flex-row">
<span class="single-line" style="font-size: 14px;color: #333;font-weight: bold;max-width: 160px;">{{record.nickName}}</span>
<!-- <span class="single-line" style="font-size: 13px;color: #666;margin: 0 12px;">(ID{{record.id}})</span> -->
<span style="font-size: 13px;color: #666;margin-left: 12px;">{{genderList.find((find) => find.value === record.genderCode)?.label}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;" v-if="record.phone">{{record.phone}}</span>
</div>
<div class="flex-row">
<span style="font-size: 13px;color: #666;">{{record.age}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;">{{educationList.find((find) => find.value === record.educationCode)?.label}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;">{{maritalList.find((find) => find.value === record.maritalStatusCode)?.label}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;" v-if="record.occupation">{{record.occupation}}</span>
</div>
</div>
</div>
<Profile :info="record" />
</template>
<template #allocateInfo="{ text, record }">
<Timeline :list="record.datingClueFollowRecordList"/>

53
src/views/clue/components/data.ts

@ -60,7 +60,16 @@ export const modalFormSchema: FormSchema[] = [
}
},
},
{ field: 'age', label: '年龄', component: 'InputNumber', colProps: { span: 8 },},
{
field: 'birthYear',
label: '出生年份',
component: 'InputNumber',
colProps: { span: 8 },
componentProps: {
min: 1920,
max: 2007
}
},
{ field: 'nickName', label: '昵称', component: 'Input', colProps: { span: 8 },},
{ field: 'phone', label: '电话号码', component: 'Input', colProps: { span: 8 },},
{ field: 'weChatId', label: '微信号', component: 'Input', colProps: { span: 8 }, },
@ -75,7 +84,6 @@ export const modalFormSchema: FormSchema[] = [
// componentProps: ({ formModel }) => {
// return {
// style: { width: '100%' },
// disabled: !!formModel.name && formModel.name !== -1,
// disabledDate: (current: Dayjs) => {
// const date: Dayjs = dayjs().subtract(18, 'year')
// return current && current > date.endOf('year')
@ -83,6 +91,17 @@ export const modalFormSchema: FormSchema[] = [
// }
// },
// },
{
label: '线索时间',
colProps: { span: 8 },
component: 'DatePicker',
field: 'clueTime',
componentProps: {
// showTime: true,
style: { width: '100%' },
// mode: 'year'
},
},
{
field: 'educationCode',
@ -186,20 +205,20 @@ export const modalFormSchema: FormSchema[] = [
},
},
},
{
field: 'bodilyFormCode',
label: '体型',
colProps: { span: 8 },
component: 'ApiSelect',
componentProps: {
labelField: 'desc',
api: getBodilyFormList,
getPopupContainer: () => document.body,
onChange: (_: any, v: any) => {
basicInfoData.value.bodilyForm = v?.label
},
},
},
// {
// field: 'bodilyFormCode',
// label: '体型',
// colProps: { span: 8 },
// component: 'ApiSelect',
// componentProps: {
// labelField: 'desc',
// api: getBodilyFormList,
// getPopupContainer: () => document.body,
// onChange: (_: any, v: any) => {
// basicInfoData.value.bodilyForm = v?.label
// },
// },
// },
// {
// field: 'accountTypeCode',
// label: '户口',
@ -307,7 +326,7 @@ export const modalFormSchema: FormSchema[] = [
slot: 'profilePhoto',
},
{
field: 'describeInfo',
field: 'remark',
label: '个人描述',
component: 'InputTextArea',
colProps: { span: 16 },

46
src/views/clue/components/modal.vue

@ -14,6 +14,7 @@
<ImpExcel @success="loadDataSuccess" dateFormat="YYYY-MM-DD">
<Button>导入Excel</Button>
</ImpExcel>
<Button type="link" style="margin-top: 16px;" @click="exportExcel">下载线索导入模板</Button>
</template>
</Result>
<BasicTable v-for="(table, index) in tableListRef"
@ -29,6 +30,9 @@
<Tabs tab-position="left" v-model:activeKey="activeKey2" :animated="false" @change="onInfoChange">
<TabPane key="1" tab="个人资料">
<BasicForm @register="registerForm" style="padding: 16px 48px 0px 0px;" >
<!-- <template #birthYear="{ model, field }">
<DatePicker v-model:value="model[field]" mode="year" :open="open" format="YYYY" @openChange="openChange" @panelChange="panelChange"/>
</template> -->
<template #profilePhoto="{ model, field }">
<CropperAvatar :value="model[field]" @change="uploadAvatarAfter"/>
</template>
@ -78,8 +82,11 @@
<script setup lang="ts">
import { ref, unref, nextTick } from 'vue'
import { Tabs, TabPane, Button, Result, InputNumber } from 'ant-design-vue'
import moment from 'moment/moment'
import dayjs, { Dayjs } from 'dayjs'
import { Tabs, TabPane, Button, Result, InputNumber, DatePicker } from 'ant-design-vue'
import Icon from '/@/components/Icon'
import { downloadByUrl } from '/@/utils/file/download'
import { modalFormSchema, basicInfoData, demandMarriageSchema, demandMarriageMoreData } from './data'
import { ImpExcel, ExcelData } from '/@/components/Excel';
import { BasicTable, BasicColumn } from '/@/components/Table'
@ -88,6 +95,7 @@
import { BasicModal, useModalInner } from '/@/components/Modal'
import { CropperAvatar } from '/@/components/Cropper';
import { createClueRecord, importClueRecord, getClueInfo, editClueRecord } from '/@/api/clue'
import { formatToDate } from '/@/utils/dateUtil'
const activeKey2 = ref<string>('1')
@ -100,6 +108,7 @@
})
const ifUpdate = ref<boolean>(false)
const open = ref<boolean>(false)
const details = ref<any>()
const [registerModal, { closeModal, setModalProps }] = useModalInner(async (data) => {
ifUpdate.value = !!data.ifUpdate
@ -143,11 +152,28 @@
closeModal()
}
function openChange(status) {
if (status) {
open.value = true;
} else {
open.value = false;
}
}
function disabledDate (current: any) {
const date: Dayjs = dayjs().subtract(18, 'year')
return current && current > date.endOf('year')
}
function panelChange(value) {
// widgetVal
setFieldsValue({ birthYear: String(value.year()) });
open.value = false;
}
function uploadAvatarAfter(value) {
//
setFieldsValue({
profilePhoto: value,
});
setFieldsValue({ profilePhoto: value });
}
async function onInfoChange(){
@ -174,8 +200,9 @@
await validate()
const values: any = getFieldsValue()
// console.log({...values, ...basicInfoData.value})
const { clueTime } = values
setModalProps({ confirmLoading: true })
values.clueTime = formatToDate(clueTime)
const { domicilePlace, address } = values || {}
const demandInfo: any = getFieldsValue3()
@ -196,9 +223,14 @@
channelType: 1,
datingClueDemand,
cityCode: address?.[1],
cityName: basicInfoData.value.cityName,
provinceCode: address?.[0],
provinceName: basicInfoData.value.provinceName,
districtCode: address?.[2],
districtName: basicInfoData.value.districtName,
domicilePlaceCityCode: domicilePlace?.[1],
domicilePlaceCityName: basicInfoData.value.domicilePlaceCityName,
domicilePlaceProvinceName: basicInfoData.value.domicilePlaceProvinceName,
domicilePlaceProvinceCode: domicilePlace?.[0]
}
if(details.value && details.value.id){
@ -229,6 +261,10 @@
tableListRef.value.push({ title: sheetName, dataSource: results, columns, header });
}
}
function exportExcel() {
downloadByUrl({url: `https://dating-agency-prod.oss-cn-shenzhen.aliyuncs.com/template/线索导入模板.xlsx`});
}
</script>
<style scoped lang="less">

8
src/views/clue/customer/data.ts

@ -291,9 +291,8 @@ export const basicSchema: FormSchema[] = [
},
},
},
{
field: 'describeInfo',
field: 'remark',
label: '个人描述',
component: 'InputTextArea',
colProps: { span: 24 },
@ -309,11 +308,6 @@ export const basicSchema: FormSchema[] = [
{ field: 'empty1', label: '', slot: 'empty1', component: 'Input' },
]
const dateComProps = {
showTime: true,
style: { width: '100%' },
}
export const modalFormSchema: FormSchema[] = [
{
field: 'datingClueFollowType',

19
src/views/components/Profile.vue

@ -1,17 +1,24 @@
<template>
<div class="flex-row-center-start" style="padding-left: 12px;">
<Avatar :src="info.profilePhoto || 'https://dating-agency-prod.oss-cn-shenzhen.aliyuncs.com/827036501B11.png'" :size="64" />
<div class="flex-col-center-center" style="min-width: 100px;">
<Avatar :src="info.profilePhoto || 'https://dating-agency-prod.oss-cn-shenzhen.aliyuncs.com/827036501B11.png'" :size="64" />
<div style="background-color: #FAA19D;border-radius: 24px;padding: 2px 12px;margin-top: 8px;" v-if="info.cityName">
<span style="font-size: 12px;color: #fff;">{{info.provinceName}}-{{info.cityName}}</span>
</div>
</div>
<div class="flex-col" style="margin-left: 12px;">
<div class="flex-row">
<span class="single-line" style="font-size: 14px;color: #333;font-weight: bold;max-width: 160px;">{{info.nickName}}</span>
<!-- <span class="single-line" style="font-size: 13px;color: #666;margin: 0 12px;">(ID{{info.id}})</span> -->
<span class="single-line" style="font-size: 13px;color: #333;margin-left: 12px;">{{info.genderCode == 1 ? '女' : '男'}}</span>
<span class="single-line" style="font-size: 13px;color: #333;margin-left: 12px;" v-if="info.phone">{{info.phone}}</span>
<span class="single-line" style="font-size: 13px;color: #666;margin-left: 12px;">({{info.orgName}})</span>
</div>
<div class="flex-row">
<span style="font-size: 13px;color: #666;" v-if="info.age">{{info.age}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;">{{educationList.find((find) => find.value === info.educationCode)?.label}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;">{{maritalList.find((find) => find.value === info.maritalStatusCode)?.label}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;" v-if="info.occupation">{{info.occupation}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;" v-if="info.incomeCode">月收入{{incomeList.find((find) => find.value === info.incomeCode)?.label}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;" v-if="info.educationCode !== null">{{educationList.find((find) => find.value === info.educationCode)?.label}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;" v-if="info.maritalStatusCode !== null">{{maritalList.find((find) => find.value === info.maritalStatusCode)?.label}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;" v-if="info.occupation !== null">{{info.occupation}}</span>
<span style="font-size: 13px;color: #666;margin-left: 12px;" v-if="info.incomeCode !== null">月收入{{incomeList.find((find) => find.value === info.incomeCode)?.label}}</span>
</div>
</div>
</div>

15
src/views/components/Timeline.vue

@ -4,32 +4,35 @@
<div class="ant-timeline-item-tail" v-if="list.length > 1"></div>
<div class="ant-timeline-item-head ant-timeline-item-head-blue"><!----></div>
<div class="ant-timeline-item-content">
<div class="flex-row-center-start">
<div class="flex-row-center-start">
<span style="color: rgb(153, 153, 153);">{{list[0].createTime}}</span>
<span style="color: rgb(51, 51, 51);margin-left: 10px;">{{list[0].operatorName}}</span>
<span style="color: #333;" v-if="list[0].datingClueFollowStage">-{{followStageList.find((find) => find.value === list[0].datingClueFollowStage)?.label}}</span>
</div>
<span style="color: #faa19d;margin-left: 16px;" v-if="list[0].remark">{{list[0].remark}}</span>
</div>
</div>
</li>
<li class="ant-timeline-item" :style="{padding: list.length > 2 ? '0 0 10px' : '0px'}" v-if="list.length >= 2">
<div class="ant-timeline-item-tail" v-if="list.length > 2"></div>
<div class="ant-timeline-item-head ant-timeline-item-head-blue"><!----></div>
<div class="ant-timeline-item-content">
<div class="flex-row-center-start">
<div class="flex-row-center-start">
<span style="color: rgb(153, 153, 153);">{{list[1].createTime}}</span>
<span style="color: rgb(51, 51, 51);margin-left: 10px;">{{list[1].operatorName}}</span>
<span style="color: #333;" v-if="list[1].datingClueFollowStage">-{{followStageList.find((find) => find.value === list[1].datingClueFollowStage)?.label}}</span>
</div>
<span style="color: #faa19d;margin-left: 16px;" v-if="list[1].remark">{{list[1].remark}}</span>
</div>
</div>
</li>
<li class="ant-timeline-item" style="padding: 0px;" v-if="list.length >= 3">
<div class="ant-timeline-item-head ant-timeline-item-head-blue"><!----></div>
<div class="ant-timeline-item-content">
<div class="flex-row-center-start">
<div class="flex-row-center-start">
<span style="color: rgb(153, 153, 153);">{{list[2].createTime}}</span>
<span style="color: rgb(51, 51, 51);margin-left: 10px;">{{list[2].operatorName}}</span>
<span style="color: #333;" v-if="list[2].datingClueFollowStage">-{{followStageList.find((find) => find.value === list[2].datingClueFollowStage)?.label}}</span>
</div>
<span style="color: #faa19d;margin-left: 16px;" v-if="list[2].remark">{{list[2].remark}}</span>
</div>
</div>
</li>
</ul>

22
src/views/sys/workbench/components/WorkbenchHeader.vue

@ -6,19 +6,7 @@
<span class="text-secondary"> 今日晴20 - 32 </span>
</div>
<div class="flex flex-1 justify-end md:mt-0 mt-4">
<div class="flex flex-col justify-center text-right">
<span class="text-secondary"> 待办 </span>
<span class="text-2xl">2/10</span>
</div>
<div class="flex flex-col justify-center text-right md:mx-16 mx-12">
<span class="text-secondary"> 项目 </span>
<span class="text-2xl">8</span>
</div>
<div class="flex flex-col justify-center text-right md:mr-10 mr-4">
<span class="text-secondary"> 团队 </span>
<span class="text-2xl">300</span>
</div>
<Button type="link" @click="exportExcel"><template #icon><Icon icon="ant-design:edit-twotone" size="16px" style="margin-right: -4px;"/></template>下载线索导入模板</Button>
</div>
</div>
</template>
@ -26,9 +14,15 @@
import { computed } from 'vue';
import { Avatar } from 'ant-design-vue';
import { useUserStore } from '/@/store/modules/user'
import { Button } from 'ant-design-vue'
import { Icon } from '/@/components/Icon'
import headerImg from '/@/assets/images/header.jpg'
import { downloadByUrl } from '/@/utils/file/download'
const userStore = useUserStore();
const userinfo = computed(() => userStore.getUserInfo);
function exportExcel() {
downloadByUrl({url: `https://dating-agency-prod.oss-cn-shenzhen.aliyuncs.com/template/线索导入模板.xlsx`});
}
</script>
Loading…
Cancel
Save