Browse Source

Merge branch 'hbchen_sale_manage'

hbchen 11 months ago
parent
commit
b8fb3bdb02

+ 153 - 0
src/router/modules/sellerRoutes.js

@@ -0,0 +1,153 @@
+//出差管理路由模块
+import Home from '@/layouts/index.vue'
+
+export default [
+    /* 销售管理 */
+	{
+		path: '/',
+		component: Home,
+		name: 'dataReport_manage',
+		icon_path: require('@/assets/img/home/saller_ico.png'),
+		meta: {
+			title: "销售管理",
+		},
+		children: [
+			// {
+			// 	path: "sellerStatisticSeller",
+			// 	name: "销售路演统计",
+			// 	component: () => import('@/views/roadshow_manage/statistics/seller.vue')
+			// },
+			// {
+			// 	path: "sellerSpecialSeller",
+			// 	name: "专项路演统计",
+			// 	component: () => import('@/views/roadshow_manage/statistics/specialSeller.vue')
+			// },
+			{
+				path: 'sellerStatisticNewcustom',
+				component: () => import('@/views/dataReport_manage/statistic/newCustom.vue'),
+				name: 'sellerStatisticNewcustom',
+				meta: {
+					title: "新增客户统计",
+				},
+			},
+			// {
+			// 	path: 'sellerStatisticStockcustom',
+			// 	component: () => import('@/views/dataReport_manage/statistic/stockCustom.vue'),
+			// 	name: '存量客户统计',
+			// 	hidden: false
+			// },
+			// {
+			// 	path: 'sellerStatisticContractcustom',
+			// 	component: () => import('@/views/dataReport_manage/statistic/contractCustom.vue'),
+			// 	name: '续约客户统计',
+			// 	hidden: false
+			// },
+			{
+				path: 'newCustomlist',
+				component: () => import('@/views/dataReport_manage/statistic/newCustomlist.vue'),
+				name: 'newCustomlist',
+				meta: {
+					pathFrom: 'sellerStatisticNewcustom',
+					pathName: '新增客户统计',
+					title:'新增客户列表'
+				},
+				hidden: true
+			},
+			// {
+			// 	path: 'contractCustomlist',
+			// 	component: () => import('@/views/dataReport_manage/statistic/newCustomlist.vue'),
+			// 	name: '续约客户列表',
+			// 	meta: {
+			// 		pathFrom: 'sellerStatisticContractcustom',
+			// 		pathName: '续约客户统计'
+			// 	},
+			// 	hidden: true
+			// },
+			// {
+			// 	path: 'sellerTodoTask',
+			// 	component: () => import('@/views/dataReport_manage/statistic/todoTask.vue'),
+			// 	name: '销售To Do统计',
+			// 	hidden: false
+			// },
+			// {
+			// 	path: 'todoTaskList',
+			// 	component: () => import('@/views/dataReport_manage/statistic/todoTaskList.vue'),
+			// 	name: '客户任务列表',
+			// 	meta: {
+			// 		pathFrom: 'sellerTodoTask',
+			// 		pathName: '销售To Do统计'
+			// 	},
+			// 	hidden: true
+			// },
+			// {
+			// 	path: 'undoneTaskList',
+			// 	/* component: () => import('@/views/dataReport_manage/statistic/undoneTaskList.vue'), */
+			// 	component: () => import('@/views/dataReport_manage/statistic/todoTaskList.vue'),
+			// 	name: '未完成任务列表',
+			// 	meta: {
+			// 		pathFrom: 'sellerTodoTask',
+			// 		pathName: '销售To Do统计'
+			// 	},
+			// 	hidden: true
+			// },
+			// {
+			// 	path: 'doingTaskList',
+			// 	component: () => import('@/views/dataReport_manage/statistic/todoTaskList.vue'),
+			// 	name: '进行中任务列表',
+			// 	meta: {
+			// 		pathFrom: 'sellerTodoTask',
+			// 		pathName: '销售To Do统计'
+			// 	},
+			// 	hidden: true
+			// },
+			// {
+			// 	path: 'tryList',
+			// 	component: () => import('@/views/dataReport_manage/statistic/newCustomlist.vue'),
+			// 	name: '试用客户列表',
+			// 	meta: {
+			// 		pathFrom: 'sellerTodoTask',
+			// 		pathName: '销售To Do统计'
+			// 	},
+			// 	hidden: true
+			// },
+			// {
+			// 	path:"ficcProductStatistic",
+			// 	component: () => import('@/views/dataReport_manage/statistic/ficcProduct.vue'),
+			// 	name: '分产品阅读统计',
+			// 	hidden: false
+			// },
+			// {
+			// 	path: 'ficcProductlist',
+			// 	component: () => import('@/views/dataReport_manage/statistic/ficcProductList.vue'),
+			// 	name: '分产品阅读客户列表',
+			// 	meta: {
+			// 		pathFrom: 'ficcProductStatistic',
+			// 		pathName: '分产品阅读统计'
+			// 	},
+			// 	hidden: true
+			// },
+			// {
+			// 	path:"receiveCompanyPermission",
+			// 	name: '添加客户权限',
+			// 	component: () => import('@/views/custom_manage/saleAuthManage.vue'),
+			// 	hidden: false,
+			// },
+			// {
+			// 	path:"abnormalRenewal",
+			// 	name: '续约异常统计',
+			// 	component: () => import('@/views/dataReport_manage/statistic/abnormalRenewal.vue'),
+			// 	hidden: false,
+			// },
+			// {
+			// 	path: 'abnormalRenewalCustomlist',
+			// 	component: () => import('@/views/dataReport_manage/statistic/newCustomlist.vue'),
+			// 	name: '续约异常客户列表',
+			// 	meta: {
+			// 		pathFrom: 'abnormalRenewal',
+			// 		pathName: '续约异常统计' 
+			// 	},
+			// 	hidden: true
+			// },
+		]
+	},
+]

+ 217 - 0
src/views/custom_manage/custom/components/shareListDialog.vue

@@ -0,0 +1,217 @@
+<script setup>
+import { ref,watch } from "vue";
+import {ElMessage,ElMessageBox} from "element-plus"
+import { useRoute} from 'vue-router';
+
+import { customInterence } from '@/api/api.js'
+
+const $route = useRoute()
+
+const props = defineProps({
+    isShareRecodeDialogShow:{
+        type:Boolean,
+        default:false
+    },
+    allowEdit:{ //是否允许编辑历史记录
+        type:Boolean,
+        default:true
+    },
+    customInfo:{ //客户信息
+        type:Object,
+        default:()=>{return {}}
+    }
+});
+const emits=defineEmits(['close'])
+
+const tableColumns=[{
+    label:'沟通描述',
+    key:'Content',
+    minWidth:350
+},{
+    label:'创建人',
+    key:'SysAdminName'
+},{
+    label:'创建时间',
+    key:'CreateTime',
+    minWidth:150
+}]
+
+const recordContent=ref('')
+const recordList=ref([])
+const tableLoading=ref(false)
+
+watch(()=>props.isShareRecodeDialogShow,(val)=>{
+    if(val){
+        recordContent.value=''
+        getRecordList()
+    }
+})
+
+const getRecordList=()=>{
+    tableLoading.value = true
+    console.log(props.customInfo)
+
+    let CompanyType = $route.path==='/overseasCustomList' ? props.customInfo.Source : 2;
+    customInterence.getRecordList({
+        CompanyId:props.customInfo.CompanyId,
+        CompanyType
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        recordList.value = res.Data
+        tableLoading.value = false
+    })
+}
+const tableRowClassName=({row})=>{
+    if(row.Mark){
+        return 'mark-row'
+    }
+    return ''
+}
+const addNewRecord=()=>{
+    if(!recordContent.value.length){
+        ElMessage.warning('请输入沟通描述')
+        return
+    }
+    let CompanyType = $route.path==='/overseasCustomList' ? props.customInfo.Source : 2;
+    customInterence.addRecord({
+        CompanyId:props.customInfo.CompanyId,
+        Content:recordContent.value,
+        CompanyType
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        ElMessage.success('添加成功')
+        recordContent.value = ''
+        getRecordList()
+    })
+}
+const deleteRecord=(data)=>{
+    ElMessageBox.confirm('沟通记录删除后不可恢复,确认删除吗?','提示',{
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type:'warning',
+        appendToBody:false
+    }).then(()=>{
+        //删除
+        customInterence.deleteRecord({
+            CompanyServiceRecordId:data.CompanyServiceRecordId
+        }).then(res=>{
+            if(res.Ret!==200) return 
+            ElMessage.success('删除成功')
+            getRecordList()
+        })
+    }).catch(()=>{})
+}
+const markRecord=(data,index)=>{
+    customInterence.markRecord({
+        CompanyServiceRecordId:data.CompanyServiceRecordId,
+        Status:data.Mark?0:1
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        ElMessage.success(`${data.Mark?'取消标记':'标记'}成功`)
+        getRecordList()
+    })
+
+}
+const closeDia=()=>{
+    emits('close')
+}
+
+</script>
+
+<template>
+    <el-dialog
+        :model-value="props.isShareRecodeDialogShow"
+        :close-on-click-modal="false"
+        :modal-append-to-body="true"
+        :append-to-body="true"
+        :title="`${props.customInfo.CompanyName}——沟通记录`"
+        class="share-list-dialog"
+        @close="closeDia"
+    >
+        <div class="dialog-cotainer">
+            <div class="add-box" v-if="props.allowEdit">
+                <p class="label">沟通描述</p>
+                <el-input
+                    type="textarea"
+                    placeholder="请输入沟通描述"
+                    v-model="recordContent"
+                    :rows="3"
+                />
+                <div v-if="props.allowEdit" style="margin-top:10px">
+                    <el-button type="primary" @click="addNewRecord">保存</el-button>
+                </div>
+            </div>
+            <div class="table-box">
+                <p class="label" >历史沟通</p>
+                <el-table 
+                    border 
+                    :data="recordList"
+                    :row-class-name="tableRowClassName"
+                    v-loading="tableLoading">
+                    <el-table-column v-for="column in tableColumns" :key="column.key"
+                        :prop="column.key"
+                        :label="column.label"
+                        :min-width="column.minWidth"
+                        align="center"
+                    >
+                    </el-table-column>
+                    <el-table-column 
+                        v-if="props.allowEdit"
+                        label="操作"
+                        align="center"
+                        width="120"
+                    >
+                    <template #default="{row,$index}">
+                        <el-button link size="small" style="color:#409eff;"
+                            @click="markRecord(row,$index)"
+                        >{{row.Mark?'取消标记':'标记'}}</el-button>
+                        <el-button link size="small" style="color:red;"
+                            @click="deleteRecord(row)"
+                        >删除</el-button>
+                    </template>
+                    </el-table-column>
+                </el-table>
+            </div>
+        </div>
+        <div class="foot-container" v-if="!props.allowEdit">
+            <el-button type="primary" @click="closeDia">知道了</el-button>
+        </div>
+    </el-dialog>
+</template>
+
+<style  lang="scss">
+.share-list-dialog{
+    .dialog-cotainer{
+        padding:10px 40px;
+        .label{
+            margin-bottom: 10px;
+        }
+        .add-box{
+            margin-bottom: 30px;
+        }
+        .table-box{
+            .el-table{
+                max-height:300px;
+                overflow-y: auto !important;
+                /* border-bottom: 1px solid #EBEEF5; */
+                &::before{
+                    height: 0;
+                }
+                .el-table__empty-block{
+                    border-bottom: 1px solid #EBEEF5;
+                }
+                .mark-row{
+                    background: #FEF0F0;
+                    &:hover>td{
+                        background-color: #FEF0F0 !important;
+                    }
+                }
+            }
+        }
+    }
+    .foot-container{
+        text-align: center;
+        padding: 40px 0;
+    }
+}
+</style>

+ 128 - 0
src/views/custom_manage/custom/hooks/customlistHook.js

@@ -0,0 +1,128 @@
+/* 拓展客户列表额外需求 原页面太长 逻辑不好找 */
+import { ref,reactive } from "vue";
+import {ElMessage,ElMessageBox} from "element-plus"
+
+import { customInterence } from '@/api/api.js'
+
+const act_trialTag=ref(0)//默认的标签状态
+const trialTagArr=ref([])
+const trialTags=reactive([ 
+	{
+		label: '推进',
+		value: 2
+	},
+	{
+		label: '跟踪',
+		value: 3
+	},
+	{
+		label: '预备',
+		value: 4
+	},
+	{
+		label: '未分类',
+		value: 1
+	},
+])// 试用的标签状态
+const isTotalDayDialogShow=ref(false)//控制累计试用天数弹窗
+const customInfo=ref({})
+const isShareRecodeDialogShow=ref(false)//控制服务记录弹窗
+const allowEdit=ref(true)//是否允许编辑服务记录
+const isCloseCustomDialogShow=ref(false)
+const closeReason=ref('')
+const fromArea=ref('')
+const areaArr=reactive([{name:'国内'},{name:'海外'}])
+
+//打开服务记录弹窗
+const handleShowShareRecode=(data,type='')=>{
+	if(data.ServiceTimes===0&&type==='list') return
+	allowEdit.value = type==='list'?false:true
+	isShareRecodeDialogShow.value = true
+	customInfo.value = data
+}
+
+/* 切换标签状态 */
+// const changeTagStatus=({ TryStage })=>{
+// 	act_trialTag.value = TryStage;
+// 	this.$refs.userTable.clearSort();
+// 	this.sort_type =  '';
+// 	this.sort_param = '';
+// 	this.SortByTodo = false;
+// 	this.page_no = 1;
+// 	this.getTableData()
+// }
+
+/* 改变客户的试用标签 */
+// changeTrialHandle({ CompanyId },trialItem) {
+// 	const { ProductId,TryStage } = trialItem;
+
+// 	customInterence.setTrialTag({
+// 		CompanyId,
+// 		ProductId,
+// 		TryStage
+// 	}).then(res => {
+// 		if(res.Ret !== 200) return
+// 		this.$message.success('设置成功');
+
+// 		this.getTableData()
+// 	})
+// },
+
+/* 打开 累计试用天数弹窗 */
+// handleTotalDayClick(data){
+// 	this.isTotalDayDialogShow = true
+// 	this.customInfo = data
+// },
+/* 打开关闭理由弹窗 */
+// openCloseReasonDialog(data){
+// 	this.customInfo = data
+// 	this.closeReason=''
+// 	this.isCloseCustomDialogShow = true
+// },
+/* 关闭客户 */
+// closeCustom(){
+// 	if(!this.closeReason){
+// 		this.$message.warning('请填写关闭理由')
+// 		return
+// 	}
+// 	customInterence.closeCustom({
+// 		CompanyId:this.customInfo.CompanyId,
+// 		Remark:this.closeReason
+// 	}).then(res=>{
+// 		if(res.Ret!==200) return 
+// 		this.getTableData()
+// 		this.$message.success('关闭客户成功')
+// 		this.isCloseCustomDialogShow = false
+// 	})
+	
+// },
+/* 确认将客户转流失 */
+// turnLose(data){
+// 	this.$confirm(`是否确认将【${data.CompanyName}】转为流失客户?`,'提示',{
+// 		confirmButtonText:'确认',
+// 		cancelButtonText:'取消',
+// 		type: 'warning'
+// 	}).then(()=>{
+// 		customInterence.turnLose({
+// 			CompanyId:data.CompanyId
+// 		}).then(res=>{
+// 			if(res.Ret!==200) return 
+// 			this.getTableData()
+// 			this.$message.success('转流失成功')
+// 		})
+		
+// 	}).catch(()=>{})
+// },
+/* 筛选所属区域 */
+// changeFromArea(){
+// 	this.page_no = 1;
+// 	this.getTableData()
+// },
+
+export function customListHook(){
+	return {
+		isShareRecodeDialogShow,
+		customInfo,
+		handleShowShareRecode
+	}
+}

+ 271 - 0
src/views/dataReport_manage/statistic/hook.js

@@ -0,0 +1,271 @@
+import moment from 'moment';
+import {computed,ref} from "vue"
+import $ from 'jquery'
+
+/* 	获取几周前 周一周日日期 或前几月月份*/
+const getWeekOrMonthDate=(weeknum,type='week')=>{
+	if(type === 'week') {
+		const weekStart = moment().subtract(weeknum, 'week').startOf('isoWeek').format('YYYY.MM.DD'); //周一
+		const weekEnd = moment().subtract(weeknum, 'week').endOf('isoWeek').format('YYYY.MM.DD'); //周日
+
+		// console.log(weekStart,weekEnd)
+		return `${weekStart}~${weekEnd}`;
+	} else {
+		const month = moment().subtract(weeknum,'M').format('YYYY.MM');
+		return month;
+	}
+}
+
+const dataLoading=ref(false)
+const default_tab=ref('周度统计表')
+const select_date=ref('')
+const totalGroupArr=ref([])//总合计列表
+const datalist=ref([])//表格数据
+
+const tableTheadColumns=ref([
+	`本周(${getWeekOrMonthDate(0)})`,
+	`上一周(${getWeekOrMonthDate(1)})`,
+	`上两周(${getWeekOrMonthDate(2)})`,
+	`上三周(${getWeekOrMonthDate(3)})`,
+	`上四周(${getWeekOrMonthDate(4)})`,
+	`上五周(${getWeekOrMonthDate(5)})`])//动态表头配置
+const staticTabs=ref([ '周度统计表','月度统计表','近1个月','近3个月','近6个月' ])
+
+const Role=computed(()=>{
+	return localStorage.getItem('Role');
+})
+
+const activeTab=computed(()=>{
+	let tabName = sessionStorage.getItem('renewalTab')?sessionStorage.getItem('renewalTab'):'FICC'
+	return {
+		tabName, // FICC QY
+		tabSummationName:tabName == 'FICC'?'ficc总合计':'权益总合计',
+		productionId:tabName == 'FICC'?1:2, // 1 FICC 2 权益
+	}
+})
+
+/* 处理数据结构 便于页面渲染 */
+const filterTableData=(data,other_param={},type='new')=>{
+	let list=[]
+	if(type=='new'){
+		list = data.map(item => ([
+			{
+				key: '试用',
+				value: item.TryOutNum,
+				ids: item.TryOutIds,
+				...other_param
+			},
+			{
+				key: '活跃',
+				value: activeTab.value.tabName=='FICC'?[item.AllActiveNum,item.NoIncrementalActiveNum]:item.AllActiveNum,
+				ids: activeTab.value.tabName=='FICC'?[item.AllActiveIds,item.NoIncrementalActiveIds]:item.AllActiveIds,
+				...other_param
+			},
+			{
+				key: '正式',
+				value: item.FormalNum,
+				ids: item.FormalIds,
+				...other_param
+			}
+		]))
+	}else if(type == 'renew'){
+		list=data.map(item=>{
+			if(activeTab.value.tabName !== 'QY'){
+				return [
+					{
+						key: '到期',
+						value: item.ExpireNum,
+						ids: item.ExpireIds,
+						...other_param
+					},
+					{
+						key: '续约',
+						value:item.RenewNum,
+						ids: item.RenewIds,
+						...other_param
+					},
+					{
+						key: '续约异常',
+						value:item.UnusualRenewNum,
+						ids: item.UnusualRenewIds,
+						...other_param
+					}
+				]
+			}else{
+				return [
+					{
+						key: '到期',
+						value: item.ExpireNum,
+						ids: item.ExpireIds,
+						...other_param
+					},
+					{
+						key: '续约',
+						value:item.RenewNum,
+						ids: item.RenewIds,
+						...other_param
+					},
+				]
+			}
+		})
+		// list = data.map(item => ([
+		// 	{
+		// 		key: '到期',
+		// 		value: item.ExpireNum,
+		// 		ids: item.ExpireIds,
+		// 		...other_param
+		// 	},
+		// 	{
+		// 		key: '续约',
+		// 		value:item.RenewNum,
+		// 		ids: item.RenewIds,
+		// 		...other_param
+		// 	}
+		// ]))
+	}else if(type==='ficcproduct'){
+		list = data.map(item => ([
+			{
+				key: '正式',
+				value: item.FormalNum,
+				ids: item.FormalIds,
+				...other_param
+			},
+			{
+				key: '试用',
+				value: item.TryOutNum,
+				ids: item.TryOutIds,
+				...other_param
+			},
+			{
+				key: '合计',
+				value: item.AllNum,
+				ids: item.AllIds,
+				...other_param
+			},
+		]))
+		
+
+	}
+
+	return list.flat(Infinity);
+}
+
+// 切换 FICC 和 权益 TAB
+const switchTab=(tabName,callback)=>{
+	activeTab.value.tabName = tabName
+	activeTab.value.tabSummationName = tabName == 'FICC'?"ficc总合计":"权益总合计"
+	activeTab.value.productionId = tabName == 'FICC'?1:2
+	callback()
+}
+
+/* 选择日期改变清空高亮按钮 */
+const dateChange=(callback)=>{
+	default_tab.value = '';
+	tableTheadColumns.value = ['试用','活跃','正式'];
+
+	callback();
+}
+
+/* 切换顶部tab */
+const changeTabHandle=(tab,callback)=>{
+	$('.table-body-wrapper')[0].scrollTop = 0;
+	default_tab.value = tab;
+
+	switch(tab) {
+		case '周度统计表':
+			tableTheadColumns.value = [
+				`本周(${getWeekOrMonthDate(0)})`,
+				`上一周(${getWeekOrMonthDate(1)})`,
+				`上两周(${getWeekOrMonthDate(2)})`,
+				`上三周(${getWeekOrMonthDate(3)})`,
+				`上四周(${getWeekOrMonthDate(4)})`,
+				`上五周(${getWeekOrMonthDate(5)})`];
+			break;
+		case '月度统计表':
+			tableTheadColumns.value = [
+				getWeekOrMonthDate(0,'month'),
+				getWeekOrMonthDate(1,'month'),
+				getWeekOrMonthDate(2,'month'),
+				getWeekOrMonthDate(3,'month'),
+				getWeekOrMonthDate(4,'month'),
+				getWeekOrMonthDate(5,'month')];
+
+			break;
+		default:
+			tableTheadColumns.value = ['试用','活跃','正式'];
+
+			break;
+	}
+
+	let typeObj = {
+		'近1个月': 1,
+		'近3个月': 3,
+		'近6个月': 6
+	};
+	typeObj[tab] ? filterDate(typeObj[tab]) : filterDate(0);
+
+	callback();
+
+}
+
+/* 获取近几个月的日期范围 */
+const filterDate=(month)=>{
+	if(month) {
+		let date_before = moment().subtract(month,'M').format("YYYY-MM-DD");
+		let date_now = moment().format("YYYY-MM-DD");
+		let date = [date_before,date_now]
+		select_date.value = date;
+	}else {
+		select_date.value = '';
+	}
+}
+
+export const createdHook=()=>{
+	if(Role.value.indexOf('rai')!=-1){
+		activeTab.value.tabName = 'QY'
+		activeTab.value.tabSummationName = '权益总合计'
+		activeTab.value.productionId = 2
+	}
+}
+export function dataHook(){
+	return {
+		dataLoading,
+		default_tab,
+		select_date,
+		totalGroupArr,
+		datalist,
+		tableTheadColumns,
+		staticTabs
+	}
+}
+export function computedHook(){
+	return {
+		Role,
+		activeTab,
+	}
+}
+
+export function functionHook(){
+	return {
+		filterTableData,
+		switchTab,
+		dateChange,
+		changeTabHandle
+	}
+}
+
+	// data() {
+	// 	return {
+	// 		filterDaysOptions: [
+	// 			{ label:'+60D',value: 1,msg:'合同到期后两个月内未签约' },
+	// 			{ label:'+30D',value: 4,msg:'合同到期后一个月内未签约' },
+	// 			{ label:'到期',value: 5,msg:'合同到期未签约' },
+	// 			{ label:'-30D',value: 6,msg:'合同到期前一个月' },
+	// 			{ label:'-60D',value: 7,msg:'合同到期前两个月' },
+	// 			{ label:'-90D',value: 8,msg:'合同到期前三个月' },
+	// 			{ label:'-120D',value: 9,msg:'合同到期前四个月' },
+	// 		],
+	// 		actFilterDay: 1
+	// 	}
+	// },
+

+ 113 - 0
src/views/dataReport_manage/statistic/index.scss

@@ -0,0 +1,113 @@
+.statistic-container {
+	height: calc(100vh - 120px);
+	background-color: #fff;
+	box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+	border-radius: 4px;
+	padding: 30px 20px;
+	.custom-tab-box{
+		display: flex;
+		align-items: center;
+		margin-bottom: 24px;
+	 .custom-tab{
+		font-size: 18px;
+		border-bottom: 2px transparent solid;
+		padding: 2px 0;
+		color: #999999;
+		margin-right: 60px;
+		cursor: pointer;
+	 }
+	 .activeTab{
+		border-bottom: 2px #409EFF solid;
+		color: #409EFF;
+	 }
+	}
+	.frequency-cont {
+		display: flex;
+		align-items: center;
+		margin-bottom: 30px;
+		.frequency-ul {
+			display: flex;
+			align-items: center;
+			li {
+				width: 110px;
+				height: 40px;
+				text-align: center;
+				line-height: 40px;
+				border: 1px solid #B3D8FF;
+				background: #ECF5FF;
+				color: #409EFF;
+				border-radius: 4px;
+				cursor: pointer;
+				margin-right: 20px;
+				&.act {
+					background: #409EFF;
+					color: #fff;
+				}
+			}
+		}
+	}
+
+	.table-cont {
+		.table-body-wrapper {
+			max-height: calc(100vh - 370px);
+			// margin-right: -5px;
+			// overflow: hidden;
+			overflow-y: scroll;
+			overflow-x: auto;
+			border-bottom: 1px solid #dcdfe6;
+			border-top: 1px solid #dcdfe6;
+		}
+
+		table {
+			width: 100%;
+			font-size: 14px;
+			color: #666;
+			thead{
+				position: sticky;
+				top: 0;
+				left: 0;
+				border-left: 1px solid #dcdfe6;
+				border-right: 1px solid #dcdfe6;
+				td{
+					border: none;
+					outline-color: #dcdfe6;
+					outline-style: solid;
+					outline-width: 0.5px;
+				}
+			}
+			td,
+			th {
+				min-width: 35px;
+				// word-break: break-all;
+				border: 1px solid #dcdfe6;
+				height: 45px;
+				text-align: center;
+				background-color: #fff;
+			}
+	
+			.head-column {
+				background-color: #F0F2F5;
+				word-break: break-word;
+			}
+	
+			.data-cell{
+				// color: #409EFF;
+			}
+			.link {
+				color: #409EFF;
+				span{
+					
+					cursor: pointer;
+				}
+			}
+
+			.thead-sticky {
+				position: sticky;
+				top: 0;
+			}
+			// .td-hj{
+			// 	width: 10% !important; 
+			// }
+		}
+	}
+}

+ 373 - 0
src/views/dataReport_manage/statistic/newCustom.vue

@@ -0,0 +1,373 @@
+<script>
+import { defineComponent } from "vue";
+
+export default defineComponent({
+  beforeRouteEnter(to, from, next) {
+		// 从续约客户列表进来才使用 renewalTab
+		if(from.path != '/newCustomlist'){
+			sessionStorage.removeItem('renewalTab')
+		}
+		next()
+  },
+});
+</script>
+
+<script setup>
+import _ from "lodash"
+import { useRouter} from 'vue-router';
+import DatePicker from 'vue-datepicker-next';
+import { InfoFilled,ArrowDown,ArrowUp } from '@element-plus/icons-vue'
+
+import { dataMainInterface } from '@/api/api.js';
+import {createdHook,dataHook,computedHook,functionHook} from './hook'
+
+const $router = useRouter()
+const {dataLoading,default_tab,select_date,totalGroupArr,datalist,tableTheadColumns,staticTabs}=dataHook()
+const {Role,activeTab}=computedHook()
+const {filterTableData,switchTab,dateChange,changeTabHandle}=functionHook()
+
+//1 ficc 2权益
+const tipMap=new Map([
+	['试用','在所选时间段内,新建的或转为试用状态的客户数量(正式转试用的除外)'],
+	['活跃1','在所选时间段内,累计报告阅读次数由<50次,转变为≥50次的试用客户数量<br/>在所选时间段内,累计报告阅读次数由<50次,转变为≥50次的非新增试用客户数量'],
+	['活跃2','在所选时间段内,互动量由<50次,转变为≥50次的试用客户数量'],
+	['正式1','首次申请转正的审批通过时间,在所选时间段内的客户数'],
+	['正式2','新签合同的开始日期在统计时间段内的客户'],
+])
+
+/* 获取表格数据 */
+const getTableData=()=>{
+	dataLoading.value = false;
+	dataMainInterface.newcustomStatistic({
+		DataType: default_tab.value === '周度统计表' ? 'week' : default_tab.value === '月度统计表' ? 'month' : 'time_interval',
+		StartDate: select_date.value ? select_date.value[0] : '',
+		EndDate: select_date.value ? select_date.value[1] : '',
+		ProductId:activeTab.value.productionId
+	}).then(res => {
+		const { Data,Ret } = res;
+		if(Ret !== 200) return
+
+		//总合计数据处理
+		totalGroupArr.value = filterTableData(Data.CompanyReportRecordNumList);
+
+		//处理数据结构
+		let data = _.cloneDeep(Data.List).sort((a,b) => b.Item.length - a.Item.length);
+		if(!['admin','ficc_admin'].includes(Role.value)) data = data.sort((a,b) => b.Item.length - a.Item.length);
+
+		data.forEach(item => {
+			item.showDetail=false
+			
+			let groupDataArr = filterTableData(item.CompanyReportRecordNumList,{
+				rs_name: item.Name + '合计'
+			});
+			item.subGroupArr=groupDataArr
+			// $set(item,'subGroupArr',groupDataArr)
+
+			item.Item && item.Item.forEach(sub_item => {
+				
+				let dataArr = filterTableData(sub_item.CompanyReportRecordNumList,{
+					rs_name : sub_item.Name,
+
+				})
+				sub_item.dataArr=dataArr
+				// $set(sub_item,'dataArr',dataArr)
+			})
+		})
+
+		datalist.value = data;
+		dataLoading.value = true;
+		// console.log(data);
+		/**
+		 * 前一版每页显示前4周和前4个月的数据时  为7%
+		 * 现在每页显示前6周和前6个月的数据
+		 */
+		// const dynamic_width = {
+		// 	'周度统计表': '5%',
+		// 	'月度统计表': '5%',
+		// }
+		// console.log(this.default_tab);
+		// this.$nextTick(() => {
+		// 	this.dataLoading = true;
+			// $('table').find('td').css({ width: dynamic_width[this.default_tab]&&dynamic_width[this.default_tab]})
+			// $('table').find('.thead-rs').css({ width: dynamic_width[this.default_tab] ? dynamic_width[this.default_tab] : '120px' })
+			// $('table').find('.head-column').css({ width: dynamic_width[this.default_tab] ? dynamic_width[this.default_tab] : '25%' })
+		// })
+	})
+}
+/* 进入列表 */
+const goList=({ ids, key, rs_name, value },index, parent,sub_index= "")=>{
+	if(!parent.length || !value) return
+	if(sub_index && (!value[sub_index] || !parent.length)) return
+
+	let column_title = getColumnTitle(index);
+
+	let title =  encodeURIComponent(`${column_title}/${rs_name}/${key}`);
+	sessionStorage.setItem('renewalTab',activeTab.value.tabName)	
+	const {href}=$router.resolve({
+		name: 'newCustomlist',
+		query: {
+			ids: sub_index !== '' ? encodeURIComponent(ids[sub_index]) : encodeURIComponent(ids),
+			title
+		}
+	})
+	window.open(href,'_blank')
+}
+
+/* 获取数据对应表头 */
+const getColumnTitle=(index)=>{
+	let title = '';
+
+	if(['周度统计表','月度统计表'].includes(default_tab.value)) {
+		title = [0,1,2].includes(index) 
+		? tableTheadColumns.value[0]
+		: [3,4,5].includes(index) 
+		? tableTheadColumns.value[1]
+		: [6,7,8].includes(index) 
+		? tableTheadColumns.value[2]
+		: [9,10,11].includes(index) 
+		? tableTheadColumns.value[3]
+		: [12,13,14].includes(index) 
+		? tableTheadColumns.value[4]
+		: [15,16,17].includes(index) 
+		? tableTheadColumns.value[5]
+		: '';
+	} else {
+		title = default_tab.value || `${select_date.value[0]}~${select_date.value[1]}`;
+	}
+	
+	return title
+}
+
+createdHook()
+getTableData()
+
+</script>
+
+<template>
+	<div class="statistic-container">
+		<div class="custom-tab-box" v-if="Role==='admin'">
+			<div class="custom-tab" :class="activeTab.tabName =='FICC' && 'activeTab'" @click="switchTab('FICC',getTableData)">
+				FICC
+			</div>
+			<div class="custom-tab" :class="activeTab.tabName =='QY' && 'activeTab'" @click="switchTab('QY',getTableData)">
+				权益
+			</div>
+		</div>
+		<div class="frequency-cont">
+			<ul class="frequency-ul">
+				<li v-for="tab in staticTabs" :key="tab" :class="{act: tab=== default_tab}" @click="changeTabHandle(tab,getTableData)">{{ tab }}</li>
+			</ul>
+			<date-picker
+			v-model:value="select_date"
+			type="date" 
+			range
+			value-type="format"
+			:clearable="false"
+			@change="dateChange(getTableData)"
+			placeholder="请选择统计时间"/>
+		</div>
+		<div class="table-cont" v-show="dataLoading">
+			<div class="table-body-wrapper">
+				<table>
+					<thead>
+						<tr>
+							<td rowspan="2" class="thead-rs">组别</td>
+							<td rowspan="2" class="thead-rs">销售</td>
+							<td
+								:colspan="['周度统计表','月度统计表'].includes(default_tab) ? 3 : 1"
+								v-for="item in tableTheadColumns"
+								:key="item" 
+								class="head-column"
+							>
+								{{item}}
+								<el-tooltip 
+									effect="dark" 
+									placement="top-start"
+									v-if="!['周度统计表','月度统计表'].includes(default_tab)"
+								>
+									<el-icon :size="14" style="vertical-align: text-top;"><InfoFilled /></el-icon>
+									<template #content>
+										<div v-html="tipMap.get(item==='试用'?item:`${item}${activeTab.productionId}`)"></div>
+									</template>
+								</el-tooltip>
+							</td>	
+						</tr>
+						<tr v-if="['月度统计表'].includes(default_tab)">
+							<template v-for="(item,index) in new Array(6).fill('')" :key="index" >
+								<td>
+									试用
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('试用')"
+									>
+										<el-icon :size="14" style="vertical-align: text-top;"><InfoFilled /></el-icon>
+									</el-tooltip>
+								</td>
+								<td>
+									活跃
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('活跃'+activeTab.productionId)"
+									>
+										<el-icon :size="14" style="vertical-align: text-top;"><InfoFilled /></el-icon>
+										<template #content>
+											<div v-html="tipMap.get('活跃'+activeTab.productionId)"></div>
+										</template>
+									</el-tooltip>
+								</td>
+								<td>
+									正式
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('正式'+activeTab.productionId)"
+									>
+										<el-icon :size="14" style="vertical-align: text-top;"><InfoFilled /></el-icon>
+									</el-tooltip>
+								</td>
+							</template>
+						</tr>
+						<tr v-else-if="['周度统计表'].includes(default_tab)" >
+							<template v-for="(item,index) in new Array(6).fill('')" :key="index" style="display: table;">
+								<td>
+									试用
+								<el-tooltip 
+									effect="dark" 
+									placement="top-start" 
+									v-if="index === 0"
+									:content="tipMap.get('试用')"
+								>
+									<el-icon :size="14" style="vertical-align: text-top;"><InfoFilled /></el-icon>
+								</el-tooltip>
+								</td>
+								<td>
+									活跃
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('活跃'+activeTab.productionId)"
+									>
+										<el-icon :size="14" style="vertical-align: text-top;"><InfoFilled /></el-icon>
+										<template #content>
+											<div v-html="tipMap.get('活跃'+activeTab.productionId)"></div>
+										</template>
+									</el-tooltip>
+								</td>
+								<td>
+									正式
+									<el-tooltip 
+										effect="dark" 
+										placement="top-start" 
+										v-if="index === 0"
+										:content="tipMap.get('正式'+activeTab.productionId)"
+									>
+										<el-icon :size="14" style="vertical-align: text-top;"><InfoFilled /></el-icon>
+									</el-tooltip>
+								</td>
+							</template>
+						</tr>
+					</thead>
+					<tbody v-for="item in datalist" :key="item.Name">
+							<tr>
+								<td colspan="2" 
+									@click="item.showDetail=!item.showDetail" 
+								>{{item.Name}}合计
+									<el-icon :size="14" style="vertical-align: text-top;" v-if="item.Item.length">
+										<ArrowUp v-show="item.showDetail" />
+										<ArrowDown v-show="!item.showDetail" />
+									</el-icon>
+								</td>
+								<td 
+									v-for="(group_data,group_data_key) in item.subGroupArr" 
+									:key="group_data_key"
+									:class="{link: item.Item.length}"
+								>
+
+									<span 
+										@click="goList(group_data,group_data_key,item.Item)" 
+										v-if="Object.prototype.toString.call(group_data.value) === '[object Number]'"
+									>
+										{{ group_data.value !== 0 ? group_data.value : '' }}
+									</span>
+
+									<span 
+										v-else 
+										v-for="(sub_data_value,sub_index) in group_data.value" 
+										@click="goList(group_data,group_data_key,item.Item,sub_index)" 
+										:key="sub_index" 
+										:style=" sub_data_value ? '' : 'color:#666'"
+									>
+										{{sub_data_value}} 
+										<span style="color:#666">{{ sub_index === group_data.value.length - 1 ? '' : '/' }}</span>
+									</span>
+								</td>
+							</tr>
+							<template v-if="item.Item.length" >
+								<tr :style="{display:item.showDetail?'table-row':'none'}">
+									<td :rowspan="item.Item.length+1" class="thead-rs">{{item.Name}}</td>
+								</tr>
+
+								<tr v-for="rs in item.Item" :key="rs.AdminId" :style="{display:item.showDetail?'table-row':'none'}">
+									<td class="thead-rs">{{rs.Name}}</td>
+
+									<td 
+										:class="['data-cell',{link: item.Item.length}]" 
+										v-for="(data,data_key) in rs.dataArr" 
+										:key="data_key"
+									>
+										
+										<span 
+											@click="goList(data,data_key,item.Item)" 
+											v-if="Object.prototype.toString.call(data.value) === '[object Number]'"
+										>
+											{{ data.value !== 0 ? data.value : '' }}
+										</span>
+
+										<span 
+											v-else 
+											v-for="(sub_data_value,sub_index) in data.value" 
+											:key="sub_index" 
+											:style=" sub_data_value ? '' : 'color:#666'" 
+											@click="goList(data,data_key,item.Item,sub_index)"
+										>
+											{{sub_data_value}} 	
+											<span style="color:#666">{{ sub_index === data.value.length - 1 ? '' : '/' }}</span>
+										</span>
+									</td>
+									
+								</tr>
+							</template>	
+					</tbody>
+
+					<tfoot>
+						<tr>
+							<td colspan="2">{{activeTab.tabSummationName}}</td>
+							<td v-for="(total_data,total_data_key) in totalGroupArr" :key="total_data_key">
+
+								<span v-if="Object.prototype.toString.call(total_data.value) === '[object Number]'">
+									{{ total_data.value !== 0 ? total_data.value : '' }}
+								</span>
+
+								<span v-else v-for="(sub_data_value,sub_index) in total_data.value" :key="sub_index">
+									{{sub_data_value}} 
+									<span>{{ sub_index === total_data.value.length - 1 ? '' : '/' }}</span>
+								</span>
+							</td>
+						</tr>
+					</tfoot>
+				</table>
+			</div>	
+		</div>
+	</div>
+</template>
+
+<style lang='scss' scoped>
+*{ box-sizing: border-box;}
+@import './index.scss';
+</style>

+ 366 - 0
src/views/dataReport_manage/statistic/newCustomlist.vue

@@ -0,0 +1,366 @@
+<script>
+import { defineComponent } from "vue";
+
+export default defineComponent({
+  beforeRouteEnter(to, from, next) {
+		/* 页面进入前是否清除参数 */
+		if(from.path!='/customDetail') {
+			sessionStorage.removeItem('newCustomBack')
+		}
+		next()
+  },
+});
+</script>
+
+<script setup>
+import { ref,reactive,computed } from "vue";
+import { useRouter,useRoute} from 'vue-router';
+import _ from 'lodash'
+import {onBeforeRouteLeave} from "vue-router"
+
+import { dataMainInterface } from '@/api/api.js';
+import mPage from '@/components/mPage.vue';
+import ShareListDialog from '@/views/custom_manage/custom/components/shareListDialog.vue';
+import {customListHook} from '@/views/custom_manage/custom/hooks/customlistHook.js';
+import {formatTime} from '@/hooks/mixins/index.js'
+
+const $route = useRoute()
+const $router = useRouter()
+const {isShareRecodeDialogShow,customInfo,handleShowShareRecode} = customListHook()
+
+const title=ref('')
+const ids=ref('')//公司id
+const tableData=ref([])
+const tableColumns=[
+	{
+		label: '客户名称',
+		key: 'CompanyName',
+		minwidthsty: '180px',
+	},
+	{
+		label: '客户类型',
+		key: 'CompanyType',
+		widthsty: '80px',
+	},
+	{
+		label: '所属行业',
+		key: 'IndustryName',
+	},
+	{
+		label: '客户地址',
+		key: 'City',
+		widthsty: '110px',
+	},
+	{
+		label: '所属销售',
+		key: 'SellerName',
+	},
+	{
+		label: '分配销售',
+		key: 'ShareSeller',
+	},
+	{
+		label: '客户状态',
+		key: 'Status',
+		// widthsty: '180px',
+	},
+	{
+		label: '累计阅读次数',
+		key: 'viewTotal',
+	},
+	{
+		label: '累计路演次数',
+		key: 'RoadShowTotal',
+	},
+	{
+		label: '最近一次阅读时间',
+		key: 'LastViewTime',
+		widthsty: '200px',
+	},
+	{
+		label: '服务期限',
+		key: 'EndDate',
+		minwidthsty: '180px',
+	},
+	{
+		label: '到期天数',
+		key: 'ExpireDay',
+		widthsty: '110px'
+	}
+]
+let sort_obj=reactive({
+	param: '',
+	type: ''
+})//排序字段
+const total=ref(0)
+const page_no=ref(1)
+const pageSize=ref(10)
+
+const Role = computed(()=>{
+	return localStorage.getItem('Role');
+})
+
+const tableColumnsComputed = computed(()=>{
+	// 分配销售 续约统计和续约异常统计需要显示
+	let hasDistributionSales = Role.value.indexOf('rai')==-1 && 
+													['/contractCustomlist','/abnormalRenewalCustomlist'].includes($route.path)
+	if(hasDistributionSales){
+		return tableColumns
+	}else{
+		return tableColumns.filter(item => item.label!='分配销售')
+	}
+})
+
+/* 获取数据	 */
+const getTableData=()=>{
+
+	const { param, type } = sort_obj;
+
+	dataMainInterface.newcustomList({
+		PageSize: pageSize.value,
+		CurrentIndex: page_no.value,
+		SortParam: param,
+		SortType: type,
+		CompanyIds: ids.value
+	}).then(res => {
+		const { Ret,Data } = res;
+		if(Ret !== 200) return
+
+		total.value = res.Data.Paging.Totals;
+		tableData.value = Data.List || [];
+	})
+}
+
+/* 切换页码 */
+const handleCurrentChange=(page)=>{
+	page_no.value = page;
+	getTableData();
+}
+
+/* 排序变化时 */
+const sortChangeHandle=({ prop,order })=>{
+	console.log(prop,order)
+	page_no.value = 1;
+
+	const typeMap = {
+		'RoadShowTotal': 'roadShowTotal',
+		'LastViewTime': 'viewTime',
+		'ExpireDay': 'expireDay',
+	}
+
+	sort_obj = {
+		type: order === 'ascending' ? 'asc' : order === 'descending' ? 'desc' : '',
+		param: typeMap[prop] || prop
+	}
+	getTableData();
+}
+
+/* 前往详情页 */
+const goDetail=({CompanyId})=>{
+	$router.push({
+		path:'/customDetail',
+		query:{
+			id: CompanyId,
+		}
+	})
+}
+
+const init=()=>{
+	if($route.query.ids) {
+		ids.value = decodeURIComponent($route.query.ids);	
+	}
+	title.value = decodeURIComponent($route.query.title);
+	if($route.query.sort_obj){
+		sort_obj = $route.query.sort_obj
+	}
+	if($route.query.ids||$route.query.title||$route.query.sort_obj){
+		let backData = {
+					page_no: page_no.value,
+					ids: ids.value,
+					title: title.value,
+			sort_obj:sort_obj
+			};
+		localStorage.setItem("newCustomBack", JSON.stringify(backData));
+	}
+	if(sessionStorage.getItem('newCustomBack')) {
+		let newCustomBack= JSON.parse(sessionStorage.getItem('newCustomBack'));
+		page_no.value = newCustomBack.page_no;
+		ids.value = newCustomBack.ids;
+		title.value = newCustomBack.title;
+		sort_obj = newCustomBack.sort_obj
+	}else if(localStorage.getItem("newCustomBack")){
+				let newCustomBack = JSON.parse(localStorage.getItem("newCustomBack"));
+				page_no.value = newCustomBack.page_no;
+				ids.value = newCustomBack.ids;
+				title.value = newCustomBack.title;
+		sort_obj = newCustomBack.sort_obj
+		}
+
+	ids.value && getTableData();
+}
+
+/* 页面跳转前记录参数 */
+onBeforeRouteLeave((to, form, next) =>{
+	let backData = {
+		page_no: page_no.value,
+		ids: ids.value,
+		title: title.value,
+		sort_obj:sort_obj
+	}
+	sessionStorage.setItem('newCustomBack',JSON.stringify(backData))
+	localStorage.removeItem("newCustomBack");
+	next()
+})
+
+init()
+
+</script>
+
+<template>
+	<div class="list-container">
+		<span class="tag">{{title}}</span>
+		<el-table
+			:data="tableData"
+			@sort-change="sortChangeHandle"
+			border
+			class="table-cont"
+			size="default"
+		>
+			<el-table-column
+				v-for="item in tableColumnsComputed"
+				:key="item.label"
+				:label="item.label"
+				:width="item.widthsty"
+				:min-width="item.minwidthsty"
+				:prop="item.key"
+				align="center"
+				:sortable="['viewTotal','RoadShowTotal','LastViewTime','ExpireDay','createTime'].includes(item.key) ? 'custom' : false"
+			>
+				<template #default="{row}">
+
+					<span v-if="item.key === 'CompanyName'" @click="goDetail(row)" class="customName editsty">
+						{{row.CompanyName}}
+					</span>
+
+					<span v-else-if="item.key === 'CompanyType'">
+						<span :style="row.IsSuspend===1?'color:#bbb':''">{{row.CompanyType}}</span> 
+						<span v-if="row.FiccPackageType"  class="ficc-package">{{row.FiccPackageType == 1 ? '大套餐': '小套餐'}}</span>
+					</span>
+
+					<span v-else-if="item.key === 'City'">
+						{{`${row.Province}/${row.City}`}}
+					</span>
+
+					<span v-else-if="item.key === 'Status'">
+						{{row.Status}}
+					</span>
+
+					<span v-else-if="item.key === 'viewTotal'">
+						{{row.AllViewTotal}}
+					</span>
+
+					<span v-else-if="item.key === 'LastViewTime'">
+						{{
+							row.FiccLastViewTime 
+							? `ficc: ${row.FiccLastViewTime}` 
+							:row.RaiLastViewTime?
+							 `权益: ${row.RaiLastViewTime}`:'--'
+						}}
+					</span>
+
+					<span v-else-if="item.key === 'EndDate'">
+						<!-- 正常的时间显示 -->
+						<template v-if="row.StartDate.indexOf('/')==-1">
+							<template v-if="row.Status=='流失'">
+								创建时间:{{formatTime(row.CreatedTime)}}
+							</template>
+							<template v-else-if="row.Status == '永续'">
+								永久
+							</template>
+							<template v-else-if="row.Status == '冻结'">
+								{{row.FreezeStartDate}}~{{row.FreezeEndDate}}
+							</template>
+							<template v-else>
+								{{row.StartDate}}~{{row.EndDate}}
+							</template>
+						</template>
+						<!-- 公用客户的时间显示 -->
+						<template v-else>
+							{{row.StartDate.substr(0,10)}}~{{row.EndDate.substr(0,10)}}/{{row.StartDate.substr(11)}}~{{row.EndDate.substr(11)}}
+						</template>
+					</span>
+
+					<span v-else>{{ row[item.key]}}</span>
+				</template>
+			</el-table-column>
+			<el-table-column
+				:prop="title.includes('正式') ? 'formalTime' : 'createTime'"
+				:label="title.includes('正式') ? '转正时间' : '创建时间'"
+				sortable="custom"
+				align="center" 
+				min-width="120"
+			>
+				<template #default="scope">
+					<span>
+						<template v-if="title.includes('正式')">
+							{{formatTime(scope.row.FormalTime)}}
+						</template>
+						<template v-else>
+							{{formatTime(scope.row.CreatedTime)}}
+						</template>
+					</span> 
+				</template>
+			</el-table-column>
+			<el-table-column label="操作" align="center" width="85px">
+				<template #default="scope">
+					<el-button link type="primary" @click="handleShowShareRecode(scope.row,'list')" style="padding:12px 0;">沟通记录</el-button>
+				</template>
+			</el-table-column>
+			<div slot="empty" style="line-height:44px;margin:60px 0;color:#999;">
+				<img src="~@/assets/img/cus_m/nodata.png" alt="" style="display:block;width:160px;height:128px;margin: auto;">
+				<span>暂无数据</span>
+			</div>
+		</el-table>
+		<div class="bottom">
+			<m-page
+				:total="total"
+				:page_no="page_no"
+				@handleCurrentChange="handleCurrentChange"
+			/>
+		</div>
+
+		<!-- 服务记录弹窗 -->
+		<ShareListDialog
+			:isShareRecodeDialogShow="isShareRecodeDialogShow"
+			:customInfo="customInfo"
+			:allowEdit="false"
+			@close="()=>{isShareRecodeDialogShow=false;}"
+		/>
+	</div>
+</template>
+
+<style lang="scss" scoped>
+*{ box-sizing: border-box; }
+.list-container {
+	min-height: calc(100vh - 120px);
+	background-color: #fff;
+	box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+	border-radius: 4px;
+	padding: 30px 20px;
+	.tag {
+		padding: 10px 24px;
+		display: inline-block;
+		background: #E8F3FF;
+		color: #2D8CF0;
+		font-size: 14px;
+		border-radius: 4px;
+	}
+	.table-cont {
+		margin-top: 20px;
+		margin-bottom: 20px;
+	}
+	.bottom {
+		height: 40px;
+	}
+}
+</style>