瀏覽代碼

续约审批;转正审批;申请转正;补充协议;审批列表

Karsa 7 月之前
父節點
當前提交
fca357520c

+ 57 - 68
src/router/modules/customRoutes.js

@@ -51,15 +51,15 @@ export default [
           pathName: '正式客户共享'
         }
       },
-      {
-        path: "customAllList",
-        component: () => import("@/views/custom_manage/custom/customAllList.vue"),
-        name: "customAllList",
-        hidden: false,
-        meta: {
-          title: '全量客户列表'
-        }
-      },
+      // {
+      //   path: "customAllList",
+      //   component: () => import("@/views/custom_manage/custom/customAllList.vue"),
+      //   name: "customAllList",
+      //   hidden: false,
+      //   meta: {
+      //     title: '全量客户列表'
+      //   }
+      // },
       {
         path: "customListEn",
         component: () => import("@/views/custom_manage/customEn/customListEn.vue"),
@@ -199,59 +199,54 @@ export default [
           keepAlive: false,
         },
       },
-      // {
-      //   path: "addAgreement",
-      //   name: "补充协议",
-      //   component: () => import("@/views/custom_manage/customList/updateServe.vue"),
-      //   hidden: true,
-      //   meta: {
-      //     pathFrom: "customList",
-      //     pathName: "客户列表",
-      //     keepAlive: false,
-      //   },
-      // },
-      // {
-      //   path: "turnCustom",
-      //   name: "申请转正",
-      //   component: () => import("@/views/custom_manage/customList/applyTurn.vue"),
-      //   hidden: true,
-      //   meta: {
-      //     pathFrom: "customList",
-      //     pathName: "客户列表",
-      //     keepAlive: false,
-      //   },
-      // },
-      // {
-      //   path: "approvalUpdate",
-      //   name: "续约审批",
-      //   component: () => import("@/views/custom_manage/approvalUpdate.vue"),
-      //   hidden: true,
-      //   meta: {
-      //     pathFrom: "approvalList",
-      //     pathName: "审批列表",
-      //     keepAlive: false,
-      //   },
-      // },
-      // {
-      //   path: "approvalTurn",
-      //   name: "转正审批",
-      //   component: () => import("@/views/custom_manage/approvalTurn.vue"),
-      //   hidden: true,
-      //   meta: {
-      //     pathFrom: "approvalList",
-      //     pathName: "审批列表",
-      //     keepAlive: false,
-      //   },
-      // },
-      // {
-      //   path: "potentialList",
-      //   component: () => import("@/views/custom_manage/potentialList.vue"),
-      //   name: "潜在用户",
-      //   hidden: false,
-      //   meta: {
-      //     keepAlive: false,
-      //   },
-      // },
+      {
+        path: "addAgreement",
+        name: "addAgreement",
+        component: () => import("@/views/custom_manage/custom/updateServe.vue"),
+        hidden: true,
+        meta: {
+          title: '补充协议',
+          pathFrom: "customList",
+          pathName: "客户列表",
+          keepAlive: false,
+        },
+      },
+      {
+        path: "turnCustom",
+        name: "turnCustom",
+        component: () => import("@/views/custom_manage/custom/applyTurn.vue"),
+        hidden: true,
+        meta: {
+          title: '申请转正',
+          pathFrom: "customList",
+          pathName: "客户列表",
+          keepAlive: false,
+        },
+      },
+      {
+        path: "approvalUpdate",
+        name: "approvalUpdate",
+        component: () => import("@/views/custom_manage/custom/approvalUpdate.vue"),
+        hidden: true,
+        meta: {
+          title: '续约审批',
+          pathFrom: "approvalList",
+          pathName: "审批列表",
+          keepAlive: false,
+        },
+      },
+      {
+        path: "approvalTurn",
+        name: "approvalTurn",
+        component: () => import("@/views/custom_manage/custom/approvalTurn.vue"),
+        hidden: true,
+        meta: {
+          title: '转正审批',
+          pathFrom: "approvalList",
+          pathName: "审批列表",
+          keepAlive: false,
+        },
+      },
       {
         path: "trialApplication",
         component: () => import("@/views/custom_manage/officalTrial/trialApplication.vue"),
@@ -424,12 +419,6 @@ export default [
           title: '开票到款统计'
         }
       },
-      // {
-			// 	path: "ficcApplyList",
-			// 	name: 'ficc申请记录',
-			// 	component: () => import('@/views/ficc_manage/apply/applyList.vue'),
-			// 	hidden: false,
-			// },
       {
         path:'businessETAList',
         name:"businessETAList",

+ 797 - 0
src/views/custom_manage/custom/applyTurn.vue

@@ -0,0 +1,797 @@
+<script setup>
+import { computed, onMounted, ref, watch,nextTick } from 'vue'
+import { ElMessage,ElMessageBox } from 'element-plus'
+import { useRoute,useRouter } from 'vue-router'
+import { customInterence } from '@/api/api.js'
+import $ from 'jquery'
+import imgPreview from '@/components/imgPreview.vue'
+// import pdf from 'vue-pdf'
+import {CalculationDate} from '@/utils/CalculationDate'
+import raiPermissionbox from './components/raiPermissionbox.vue'
+
+const $route = useRoute();
+const $router = useRouter();
+
+const	formRule = {
+  amount:[
+    { required: true, message: '合同金额不能为空', trigger: 'blur' },
+    { type: 'number', message: '合同金额必须为数字'}
+  ],
+  payway:[
+    { required: true, message: '付款方式不能为空', trigger: 'blur' },
+  ],
+  payfrom:[
+    { required: true, message: '付款渠道不能为空', trigger: 'blur' },
+  ],
+  imglist:[
+    { required: true, message: '合同附件不能为空', trigger: 'blur' },
+  ]
+}
+
+const isXClassCustom = computed(() =>{
+  return companyInfo.value.Status.includes('永续') || companyInfo.value.Status.includes('X类试用')
+})
+const isRoleType = computed(() => {
+  return localStorage.getItem('RoleType') || ''
+})
+
+
+const companyInfo = ref(JSON.parse(sessionStorage.getItem('companyInfo')) || {})//客户基本信息
+const selectedQuarters = ref([])
+const hasNoChild = ref(false) // 医药、消费、科技、智造是否没有主客观
+const authList = ref([])
+const formData = ref({
+  contract_type:'',
+  term:'',
+  amount:'',
+  payway:'',
+  payfrom:'',
+  imglist:[],//合同列表图片
+  setmeal:'',
+  qyBigServeCheck:0,
+})
+/* 重新申请获取上次申请的合同信息并回显 */
+function getLastContract() {
+  customInterence.reapplyDetail({
+    CompanyApprovalId:parseInt(companyInfo.value.CompanyApprovalId)
+  }).then(res => {
+    if(res.Ret === 200) {
+      /* 处理日期 */
+      let date_arr = [];
+      date_arr.push(res.Data.Item.StartDate);
+      date_arr.push(res.Data.Item.EndDate);
+      formData.value = {
+        contract_type:res.Data.Item.ContractType,
+        term:date_arr,
+        amount:res.Data.Item.Money,
+        payway:res.Data.Item.PayMethod,
+        payfrom:res.Data.Item.PayChannel,
+        imglist:res.Data.Item.ImgUrl.split('#'),//合同列表图片
+        setmeal:res.Data.Item.PackageType,
+        qyBigServeCheck:res.Data.Item.RaiPackageType
+      }
+      selectedQuarters.value = res.Data.Item.Quarter.split(',')
+      let newArr = [];
+
+      /* 处理权限列表 */
+      if((companyInfo.value.CompanyType == '权益' || isRoleType.value== '权益') && !isXClassCustom.value ) {
+        res.Data.Item.PermissionList[0].Items.map(item => {
+          item.disabled=item.isIndeterminate=false								
+          if(item.ChartPermissionId==22 && (!item.Child)) hasNoChild.value=true
+        })
+        /* 处理数据把复选框 拆分成三个*/
+        res.Data.Item.PermissionList.length&&res.Data.Item.PermissionList.forEach(item => {
+        let arr = item.Items.filter(key=> [22,21,20,19,23,30].includes(key.ChartPermissionId))
+        let ItemsPrivate = item.Items.filter(key=> [29,31,20031,20032,52,53,54,138,62].includes(key.ChartPermissionId))
+        let ItemsUp = item.Items.filter(key=> key.PermissionName.includes('升级'))
+        let ItemsBig = item.Items.filter(key=> key.ChartPermissionId==0)
+          let obj = {
+            ...item,
+            Items:arr,
+            ItemsPrivate,
+            ItemsUp,
+            ItemsBig
+          }
+          newArr.push(obj)
+        })
+      } else {
+        res.Data.Item.PermissionList.forEach(item => {
+          item.CheckList=item.CheckList||[]
+          item.Items=item.Items||[]
+          let obj = {
+            checkAll:item.CheckList&&item.CheckList.length===item.Items.length?true:false,
+            isIndeterminate:item.CheckList&&item.CheckList.length>0 && item.CheckList.length<item.Items.length,
+            ...item,
+          }
+          newArr.push(obj)
+        })
+      }
+      authList.value = newArr;
+      formData.value.setmeal == '1' && setmealChange()
+    }
+  })
+}
+//套餐的选择
+function setmealChange(){
+  if(formData.value.setmeal == '1'){
+    authList.value.forEach(item => {
+      if(item.ClassifyName != '市场策略') {
+        item.Items.forEach(key => {
+          item.CheckList.push(key.ChartPermissionId)
+          key.Checked = true
+          key.disabled = true
+        })
+        item.isIndeterminate = false
+        item.checkAll = true
+        item.disabled = true	
+      }
+    })
+  } else {
+      authList.value.forEach(item => {
+      if(item.Items.some(_e=>_e.IsPublic==1)){
+        item.CheckList = []
+        item.Items.forEach(_e=>{
+          if(_e.IsPublic==1){
+            item.CheckList.push(_e.ChartPermissionId)
+          }
+          _e.disabled=false
+        })
+        item.isIndeterminate = true
+        }else {
+          item.Items.forEach(key => {		
+          key.Checked = false
+          key.disabled = false
+        })
+        item.CheckList = []
+        item.isIndeterminate = false
+        item.checkAll = false
+        item.disabled = false	
+        }
+        
+    })
+    ElMessage.warning('请勾选品种')
+  }
+}
+
+/* 获取基本权限信息 */
+function getAuthBasic() {
+  customInterence.authList({
+    IsShowYanXuanKouDian:true,
+    CompanyStatus:companyInfo.value.Status 
+  }).then(res => {
+    let newArr = [];
+    if(res.Ret === 200) {
+      if((companyInfo.value.CompanyType == '权益' || isRoleType.value== '权益') && !isXClassCustom.value) {
+        res.Data.List[0].Items.map(item => {
+          item.disabled=item.isIndeterminate=false								
+          if(item.ChartPermissionId==22 && (!item.Child)) hasNoChild.value=true
+        })
+        /* 处理数据把复选框 拆分成三个*/
+        res.Data.List.length&&res.Data.List.forEach(item => {
+        let arr = item.Items.filter(key=> [22,21,20,19,23,30].includes(key.ChartPermissionId))
+        let ItemsPrivate = item.Items.filter(key=> [29,31,20031,20032,52,53,54,138,62].includes(key.ChartPermissionId))
+        let ItemsUp = item.Items.filter(key=> key.PermissionName.includes('升级'))
+        let ItemsBig = item.Items.filter(key=> key.ChartPermissionId==0)
+          let obj = {
+            ...item,
+            Items:arr,
+            ItemsPrivate,
+            ItemsUp,
+            ItemsBig
+          }
+          newArr.push(obj)
+        })
+      }else {
+        res.Data.List.length&&res.Data.List.forEach(item => {
+          item.CheckList=item.CheckList||[]
+          item.Items=item.Items||[]
+            let obj = {
+              checkAll:item.CheckList&&item.CheckList.length===item.Items.length?true:false,
+              isIndeterminate:item.CheckList&&item.CheckList.length>0 && item.CheckList.length<item.Items.length,
+              ...item,
+            }
+            newArr.push(obj)
+        })
+      }
+      authList.value = newArr;
+    }
+  })
+}
+
+//获取客户申请转正的合同类型接口
+function getConstractType(){
+  customInterence.applyTurnContractType({CompanyId:Number(companyInfo.value.CompanyId)}).then(res=>{
+    if(res.Ret===200){
+      formData.value.contract_type=res.Data.ContractType
+    }
+  })
+}
+
+
+onMounted(() => {
+  if($route.query.isReapply) {
+			getLastContract();
+		}else {
+			getAuthBasic();	
+
+			//修改为直接获取接口中数据
+			getConstractType()
+		}
+})
+
+
+const formDataRef = ref(null)
+const raiPermissionboxRef = ref(null)
+/* 提交 */
+function saveHandle() {
+  formDataRef.value.validate((valid) => {
+    if (valid) {
+      /* 处理权限列表 */
+      let checkArr = [];
+      let checkArrName = [];
+      let hasMinusSignVal = 0
+      if((companyInfo.value.CompanyType==='权益' || isRoleType.value== '权益') && !isXClassCustom.value){
+        hasMinusSignVal = raiPermissionboxRef.value[0].minus_sign_val;		
+        authList.value.forEach(item => {
+            if(item.CheckList.length) {
+              checkArr.push(item.CheckList)
+              item.ItemsUp.forEach(key=>{
+                if(item.CheckList.includes(key.ChartPermissionId)) {
+                  checkArrName.push(key.PermissionName)
+                }
+              })
+            }
+          })
+        }else {
+          authList.value.forEach(item => {
+            if(item.CheckList.length) {
+              checkArr.push(item.CheckList)
+            }
+          })
+      }
+      const hasFiftyTwo = checkArr.flat(2).includes(52);
+      if(hasFiftyTwo && !hasMinusSignVal) return ElMessage.error('请输入研选扣点数')
+
+      if(!checkArr.length && companyInfo.value.CompanyType === '权益') {
+        ElMessage.warning('请选择权限!');
+        return
+      }else {
+        
+        let PermissionIds = [... new Set(checkArr.flat(2))].join(',');
+        let params = {
+          CompanyId:Number(companyInfo.value.CompanyId),
+          CompanyApprovalId:companyInfo.value.CompanyApprovalId?parseInt(companyInfo.value.CompanyApprovalId):0,
+          ContractType:formData.value.contract_type,
+          StartDate:formData.value.term[0],
+          EndDate:formData.value.term[1],
+          ImgUrl:formData.value.imglist.join('#'),
+          Money:Number(formData.value.amount),
+          PayChannel:formData.value.payfrom,
+          PayMethod:formData.value.payway,
+          PermissionIds,
+          PackageType:formData.value.setmeal ? formData.value.setmeal : 0,
+          PermissionNames:checkArrName.length? checkArrName.join(','):'',
+          RaiPackageType:formData.value.qyBigServeCheck||0,
+          Points:hasMinusSignVal||0
+        }
+
+        customInterence.applyTurn(params).then(res => {
+          if(res.Ret === 200) {
+            ElMessage.success(res.Msg);
+
+            $router.push({path:`/${$route.meta.pathFrom}`})
+          }
+        })
+      }
+    }
+  })
+}
+/* 取消 */
+function cancelHandle() {
+
+  $router.push({path:`/${$route.meta.pathFrom}`})
+}
+
+
+
+/* 选择全选或取消全选 */
+function handleCheckAll(item) {
+  // 取到所有的子菜单id
+  let ids = item.Items.map(item =>{
+    return item.ChartPermissionId
+  })
+  item.CheckList = item.checkAll ? ids : [];
+      item.isIndeterminate = false;
+}
+/* 复选框組选中时 */
+function handleChecked(item) {
+  let len = item.CheckList.length;
+  item.checkAll = len === item.Items.length;
+  item.isIndeterminate = len > 0 && len < item.Items.length;	
+}
+
+
+function dateChange(e){
+  if(!formData.value) return
+  if(parseInt((new Date() - new Date(formData.value.term[1]))/(1000*3600*24)) > 0) {
+    ElMessage.error('结束日期不能小于今天!')
+    formData.value.term = []
+    return
+  }
+  if(e){
+    
+    ElMessageBox.alert(`你选择的合同期限是 ${CalculationDate(formData.value.term[0],formData.value.term[1])}`, '', {
+      confirmButtonText: '确定'
+    });
+  }
+}
+
+
+function setSelectVarietyDisabled(item){
+  return item.Items.some(_e=>_e.IsPublic==1)||item.disabled
+}
+
+
+
+const img_replace = ref('')//重新上传的img
+const	isPreviewimg = ref(false)
+const	preAct = ref(0)
+const	isShowToggle = ref(false)//是否显示切换
+const uploadloading = ref(false)
+/* 预览 */
+function preview(id,index,img) {
+  if(img.indexOf('.pdf') == -1) {
+    preAct.value = index;
+    /* 是否显示左右切换 */
+    let bol = formData.value.imglist.some(item => {
+      return item.indexOf('.pdf') != -1
+    })
+    // 有pdf或图片只有一张
+    if(bol || formData.value.imglist.length<=1) {
+      isShowToggle.value = false
+    }else {
+      isShowToggle.value = true
+    }
+    isPreviewimg.value = true;
+  }else {
+    window.open(img)
+  }
+}
+function clickinput(index){  //上传模拟点击
+  img_replace.value = '';
+  if(index) {
+    img_replace.value = index;
+  }
+  $("#file").click();
+}
+function fileSelected(){  //选择文件上传
+  if( document.getElementById('file').files[0] ){
+    let hostfile = document.getElementById('file').files[0];
+  
+    let size = Math.floor(hostfile.size / 1024 / 1024);
+    if( size>200 ){
+        ElMessage.error('上传文件大小不能大于200M!');
+        hostfile = {};
+        return false
+    }
+
+    if( hostfile.name.toLowerCase().includes('.png') || hostfile.name.toLowerCase().includes('.jpg') || hostfile.name.toLowerCase().includes('.jpeg') || hostfile.name.toLowerCase().includes('.pdf') ){
+        let form = new FormData();
+        form.append('file',hostfile);  //hostfile.name
+        uploadloading.value=true;
+        customInterence.upload(form).then((res) => {
+          if( res.Ret === 200 ){
+                  /* 是替换还是新增 */
+                  if(img_replace.value) {
+                    formData.value.imglist.splice(img_replace.value-1,1,res.Data.ResourceUrl)
+                  }else {
+                    if(formData.value.imglist.length >= 4) {
+                      ElMessage.warning('最多上传4张')
+                    }else {
+                      formData.value.imglist.push(res.Data.ResourceUrl)
+                    }
+                  }
+          }
+          uploadloading.value=false;
+          $("#file").val('');
+          hostfile = {};
+        });
+    }else{
+      ElMessage.error('上传文件格式不正确!');
+    }
+  } 
+}
+function closePreview() {
+  isPreviewimg.value = false;
+}
+function togglePre(type) {
+  if(type==1) {
+    preAct.value--;
+    if(preAct.value < 0) {
+      preAct.value = formData.value.imglist.length-1;
+    }
+  }else {
+    preAct.value++;
+    if(preAct.value > formData.value.imglist.length-1) {
+      preAct.value = 0;
+    }
+  }
+}
+
+
+const selectedDateRange = computed(()=> {
+  if (selectedQuarters.value.length) {
+    const sortedQuarters = [...selectedQuarters.value].sort();
+    const startDate = quarterToDateRange(sortedQuarters[0]).split(" ~ ")[0];
+    const endDate = quarterToDateRange(sortedQuarters[selectedQuarters.value.length - 1]).split(" ~ ")[1];
+    return `${startDate} ~ ${endDate}`;
+  }
+  return "";
+})
+function quarterToDateRange(quarterLabel) {
+  const [year, q] = quarterLabel.split("Q");
+
+  switch (parseInt(q)) {
+    case 1:
+      return `${year}-01-01 ~ ${year}-03-31`;
+    case 2:
+      return `${year}-04-01 ~ ${year}-06-30`;
+    case 3:
+      return `${year}-07-01 ~ ${year}-09-30`;
+    case 4:
+      return `${year}-10-01 ~ ${year}-12-31`;
+  }
+}
+
+const quarters = ref(generateQuarters())
+function generateQuarters() {
+  const currentDate = new Date();
+  const currentYear = currentDate.getFullYear();
+  let currentQuarter = Math.floor(currentDate.getMonth() / 3) + 1;
+
+  let quarters = [];
+
+  for (let i = 3; i >= 0; i--) {
+    // 包括当前季度和前三个季度
+    let year = currentYear;
+    let quarter = currentQuarter - i;
+
+    while (quarter <= 0) {
+      year--; // 上一年
+      quarter += 4; // 季度数增加
+    }
+
+    quarters.push({
+      label: `${year}Q${quarter}`,
+      value: `${year}Q${quarter}`,
+    });
+  }
+
+  return quarters;
+}
+
+
+function checkboxInputHandler(){
+  formData.value.term = selectedQuarters.value ? [selectedDateRange.value.split(" ~ ")[0],selectedDateRange.value.split(" ~ ")[1]]:[]
+}
+
+function isDisabled(quarter) {
+  if (selectedQuarters.value.length === 0) return false;
+  const sortedSelected = [...selectedQuarters.value].sort();
+  const firstIndex = quarters.value.findIndex((q) => q.value === sortedSelected[0]);
+  const lastIndex = quarters.value.findIndex((q) => q.value === sortedSelected[sortedSelected.length - 1]);
+
+  const currentIndex = quarters.value.findIndex((q) => q.value === quarter.value);
+
+  return currentIndex < firstIndex - 1 || currentIndex > lastIndex + 1;
+}
+
+
+const showAlert = ref(true)
+watch(() => selectedQuarters.value,
+  (newValue) => {
+
+      if (!newValue.length) return;
+      if (!isConsecutiveSelection() && showAlert.value && isXClassCustom.value) {
+        showAlert.value = false;
+        selectedQuarters.value.pop();
+        ElMessage.error("只能选择相邻的季度");
+        nextTick(() => {
+          selectedQuarters.value.pop();
+          showAlert.value = true;
+        });
+      }
+  }
+)
+function isConsecutiveSelection() {
+  const sortedSelectedIndexes = selectedQuarters.value.map((sq) => quarters.value.findIndex((aq) => aq.value === sq)).sort((a, b) => a - b);
+  for (let i = 0; i < sortedSelectedIndexes.length - 1; i++) {
+    if (sortedSelectedIndexes[i + 1] - sortedSelectedIndexes[i] !== 1) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+</script>
+<template>
+  <div class="applyTurn_container">
+		<div class="card_cont">
+			<div class="info">
+				<h3 class="tit">客户信息</h3>
+				<ul class="info_list">
+					<li>
+						客户名称:{{companyInfo.CompanyName}}
+					</li>
+					<li>
+						社会信用码:{{companyInfo.CreditCode}}
+					</li>
+					<li>
+						地址:{{companyInfo.Address}}
+					</li>
+					<li>
+						客户类型:{{companyInfo.CompanyType}}
+					</li>
+					<li>
+						客户状态:{{companyInfo.Status}}
+					</li>
+					<li>
+						客户来源:{{companyInfo.Source}}
+					</li>
+					<li>
+						行业:{{companyInfo.IndustryName}}
+					</li>
+					<li>
+						所属销售:{{companyInfo.SellerName}}
+					</li>
+					<li>
+						备注:{{companyInfo.Reasons}}
+					</li>
+				</ul>
+			</div>
+		</div>
+		<!-- 合同列表 -->
+		<div class="card_cont">
+			<div class="apply_info">
+				<h3 style="fontSize:16px;">申请信息</h3>
+				<div class="info_cont">
+					<span style="display:block;marginBottom:30px;color:#333;paddingLeft:10px;">申请内容:试用转正式</span>
+					<el-form 
+            @submit.prevent 
+            inline 
+            :model="formData"
+            :rules="formRule"
+            hide-required-asterisk
+            ref="formDatRef" 
+            label-width="100px"
+            class="demo-ruleForm"
+          >
+						<el-form-item label="合同类型" prop="contract_type" style="width:100%" v-if="formData.contract_type">
+							<el-radio style="margin-right:5px" v-model="formData.contract_type" :label="formData.contract_type"/>
+							<el-tooltip
+								style="cursor: pointer;"
+								effect="dark"
+								placement="top-start"
+								v-if="formData.contract_type=='续约合同'||formData.contract_type=='新签合同'">
+                <template #content>
+									<div v-if="formData.contract_type=='续约合同'">
+										1、有正式转试用记录的客户,在申请转正时提交的合同<br>
+										2、所有客户在续约申请时提交的合同
+									</div>
+									<div v-if="formData.contract_type=='新签合同'">
+										没有正式转试用记录的客户,在申请转正时提交的合同
+									</div>
+                </template>
+									<i class="el-icon-info"></i>
+							</el-tooltip>
+						</el-form-item>
+						<el-form-item label="合同期限" prop="term" style="marginRight:60px;" :rules="{ required: true, message: '合同期限不能为空', trigger: 'blur' }" v-if="!isXClassCustom">
+							<i style="color:#f00;fontSize:20px;position:absolute;left:-90px;top:10%;">*</i>
+							<el-date-picker
+							v-model="formData.term"
+							type="daterange"
+							range-separator="至"
+							start-placeholder="开始日期"
+							end-placeholder="结束日期"
+							@change="dateChange"
+							value-format="yyyy-MM-dd"
+							style="width:400px;">
+							</el-date-picker>
+						</el-form-item>
+						<el-form-item label="合同期限" prop="term" :rules="{ required: true, message: '合同期限不能为空', trigger: 'change' }" style="marginRight:60px;" v-if="isXClassCustom">
+							<i style="color:#f00;fontSize:20px;position:absolute;left:-90px;top:10%;">*</i>
+							<div class="quarters-content">
+								<el-checkbox-group v-model="selectedQuarters" @input="checkboxInputHandler">
+									<el-checkbox v-for="quarter in quarters" :key="quarter.value" :label="quarter.label" :disabled="isDisabled(quarter)" >
+										{{ quarter.label }}
+									</el-checkbox>
+								</el-checkbox-group>
+								<div v-if="selectedQuarters.length > 0" class="quarters-text">
+										{{ selectedDateRange }}
+								</div>
+							</div>
+						</el-form-item>
+						<el-form-item label="合同金额" prop="amount" style="marginRight:60px;">
+							<i style="color:#f00;fontSize:20px;position:absolute;left:-90px;top:10%;">*</i>
+							<el-input 
+							v-model.number="formData.amount"
+							placeholder="请输入金额"
+							style="width:400px"
+							clearable></el-input>
+							<span style="color:#666;">元</span>
+						</el-form-item>
+						<el-form-item label="付款方式" prop="payway" style="marginRight:60px;">
+							<i style="color:#f00;fontSize:20px;position:absolute;left:-90px;top:10%;">*</i>
+							<el-select v-model="formData.payway" placeholder="请选择付款方式" style="width:400px;" clearable>
+								<el-option
+								v-for="item in ['月付','季付','半年付','年付','两年付','三年付']"
+								:key="item"
+								:label="item"
+								:value="item">
+								</el-option>
+							</el-select>
+						</el-form-item>
+						<el-form-item label="付款渠道" prop="payfrom">
+							<i style="color:#f00;fontSize:20px;position:absolute;left:-90px;top:10%;">*</i>
+							<el-input 
+							v-model="formData.payfrom"
+							placeholder="填写代支付的渠道名称,没有可以填无"
+							style="width:400px"
+							clearable></el-input>
+						</el-form-item>
+						<el-form-item label="套餐类型" prop="setmeal" style="display:block;"  :rules="{ required: true, message: '请选择套餐',trigger: 'change' }" v-if="companyInfo.CompanyType=='ficc' || isRoleType== 'ficc'">
+							<i style="color:#f00;fontSize:20px;position:absolute;left:-90px;top:10%;">*</i>
+							 <el-radio-group v-model="formData.setmeal" @change="setmealChange">
+								<el-radio :label="1">大套餐</el-radio>
+								<el-radio :label="2">小套餐</el-radio>
+							</el-radio-group>
+						</el-form-item>
+						<el-form-item class="textarea_item" style="width:97%;paddingLeft:26px;" prop="CheckList">
+							<label style="display:block;marginBottom:10px;fontSize:16px;position:relative;color:#666;">
+								<i style="color:#f00;fontSize:20px;position:absolute;left:-15px;top:10%;">*</i>
+								权限设置
+							</label>
+							<template  v-if="(companyInfo.CompanyType=='权益' || isRoleType== '权益') && !isXClassCustom" >
+								<raiPermissionbox ref="raiPermissionboxRef" v-for="item in authList" :key="item.ClassifyName" :data="item" :formData="formData"
+								:hasNoChild="hasNoChild"></raiPermissionbox>
+							</template>
+							<ul class="menu_lists" style="width:100%" v-else>
+								<li v-for="item in authList" :key="item.ClassifyName" class="menu_item">
+									<el-checkbox  :indeterminate="item.isIndeterminate" v-model="item.checkAll" :disabled="setSelectVarietyDisabled(item)" @change="handleCheckAll(item)" style="marginRight:30px;fontWeight:bold;minWidth:90px;">{{item.ClassifyName+':'}}</el-checkbox>
+									<el-checkbox-group v-model="item.CheckList" @change="handleChecked(item)">
+										<el-checkbox v-for="list in item.Items" :label="list.ChartPermissionId" :key="list.ChartPermissionId" class="list_item" :disabled="list.IsPublic==1  || list.disabled">{{list.PermissionName}}</el-checkbox>
+									</el-checkbox-group>
+								</li>
+							</ul>
+						</el-form-item>
+						<el-form-item prop="imglist" style="width:97%;paddingLeft:26px;" class="textarea_item">
+							<label style="display:block;marginBottom:10px;fontSize:16px;position:relative;color:#666;">
+								<i style="color:#f00;fontSize:20px;position:absolute;left:-15px;top:10%;">*</i>
+								上传合同附件<span style="fontSize:12px;color:#f00;">(建议上传盖章后的合同,支持png、jpg、pdf格式)</span>
+								<input type="file" name="file" @change="fileSelected()" id="file" class="true-file" style="display:none;">	
+								<el-button type="primary" size="default" @click="clickinput('')" style="marginLeft:20px;" :loading="uploadloading">点击上传</el-button>
+							</label>
+							<ul class="img_cont">
+								<li v-for="(img,index) in formData.imglist" :key="img" class="img_item">
+									<!-- <el-image :src="img" alt="" style="background:#aaa;width:240px;height:180px;" :preview-src-list="formData.imglist" :id="'img'+index"/> -->
+									<pdf ref="pdf" :src="img" style="width:240px;height:180px;overflow:hidden" v-if="img.indexOf('.pdf')!=-1" @click="preview('img'+index,index,img)"></pdf>
+									<el-image :src="img" alt="" style="background:#aaa;width:240px;height:180px;" :id="'img'+index" v-else @click="preview('img'+index,index,img)"/>
+									<i class="el-icon-zoom-in" style="position:absolute;right:12px;top:12px;color:#fff;" @click="preview('img'+index,index,img)"></i>
+									<span style="position:absolute;right:12px;bottom:12px;color:#409EFF;fontSize:16px;cursor:pointer;" @click.stop="clickinput(index+1)">重新上传</span>
+								</li>
+							</ul>
+						</el-form-item>
+					</el-form>
+				</div>
+			</div>
+			<div class="bot_cont">
+        
+				<div style="display:flex;justify-content:center;margin:80px 0 30px;">
+					<el-button type="primary" style="width:80px;marginRight:24px;" @click="saveHandle">提交</el-button>
+					<el-button type="primary" plain style="width:80px;" @click="cancelHandle">取消</el-button>
+				</div>
+			</div>
+			<!-- 图片预览 -->
+			<imgPreview
+        :isShowToggle="isShowToggle"
+        :isPreview="isPreviewimg" 
+        :arr="formData.imglist" 
+        :actIndex="preAct"
+        @close="closePreview"
+        @togglePre="togglePre"
+      ></imgPreview>
+		</div>
+
+	</div>
+</template>
+<style scoped lang="scss">
+.applyTurn_container {
+	/* min-width: 1570px; */
+	*{box-sizing: border-box;}
+	/* reset */
+	:deep(.el-form-item .el-checkbox-group) {
+		height: 40px;
+	}
+	:deep(.textarea_item .el-form-item__content) {
+		width: 100%;
+	}
+	/*  */
+	.card_cont {
+		margin-bottom: 20px;
+		border: 1px solid #ECECEC;
+		padding: 30px;
+		background: #fff;
+		border-radius: 4px;
+		box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+		.info {
+			margin-top: 10px;
+			font-size: 16px;
+			color: #666;
+			.tit {
+				color: #333;
+				font-size: 16px;
+				margin-bottom: 30px;
+			}
+			.info_list {
+				display: flex;
+				flex-wrap: wrap;
+				padding-left: 50px;
+				padding-bottom: 20px;
+				li {
+					margin-right: 113px;
+					margin-bottom: 20px;
+					min-width: 250px;
+				}
+			}
+		}
+		.apply_info {
+			font-size: 16px;
+			.info_cont {
+				padding-left: 30px;
+				margin-top: 30px;
+			}
+		}
+		.menu_lists {
+			padding: 40px 18px;
+			border: 1px dashed #AAB4CC;
+			border-radius: 4px;
+			.menu_item {
+				display: flex;
+				// align-items: center;
+				margin-bottom: 40px;
+				&:last-child {
+					margin-bottom: 0;
+				}
+				.list_item {
+					margin-right: 30px;
+					&:last-child {
+						margin-right: 0;
+					}
+				}
+			}
+		}
+		.img_cont {
+			width: 100%;
+			display: flex;
+			flex-wrap: wrap;
+			.img_item {
+				position: relative;
+				margin-right: 23px;
+				&:last-child {
+					margin-right: 0;
+				}
+			}
+		}
+	}
+	.quarters-content {
+		position: relative;
+		.quarters-text {
+			position: absolute;
+			left: 0;
+			top: 20px;
+			color: #f00;
+		}
+	}
+}
+</style>

+ 264 - 0
src/views/custom_manage/custom/approvalTurn.vue

@@ -0,0 +1,264 @@
+<script setup>
+import { computed, onMounted, ref } from 'vue'
+import { customInterence } from '@/api/api.js'
+import { useRoute,useRouter } from 'vue-router'
+import { ElMessage } from 'element-plus'
+import { filterMoney } from '@/common/js/util'
+import Ctimeline from './compontents/Ctimeline.vue'
+import imgPreview from '@/components/imgPreview.vue'
+import CustomDtlDialog from './compontents/CustomDtlDialog.vue'
+import {CalculationDate} from '@/utils/CalculationDate'
+// import pdf from 'vue-pdf'
+
+const $route = useRoute();
+const $router = useRouter()
+
+const companyId = ref($route.query.id)
+const contractId = ref($route.query.contractId)
+const isLook = ref($route.query.isLook || false)
+const companyInfo = ref(JSON.parse(sessionStorage.getItem('companyInfo')) || {})//客户基本信息
+const ProductId = ref(0)
+const status = ref('')
+const reason = ref('')
+const contractInfo = ref({})//合同信息
+const imglist = []//合同列表图片
+const authList = ref([])//权限列表
+const diff_time = ref('')
+/* 客户信息弹窗 */
+const isOpenCustomDtl = ref(false)
+
+/* 获取详情 */
+function getCompanyInfo() {
+  customInterence.approvalDetail({
+    CompanyId:companyId.value,
+    CompanyContractId:Number(contractId.value)
+  }).then(res => {
+    if(res.Ret === 200) {
+      ProductId.value=res.Data.Item.ProductId
+      /* 处理合同期限 截取一位小数剔除.0 */
+      diff_time.value = Number(
+        Number((
+        (new Date(res.Data.Item.EndDate).getTime())
+        -(new Date(res.Data.Item.StartDate).getTime())
+        )/(1000*60*60*24*365))
+        .toFixed(1).replace(/.0/,''));
+      res.Data.Item.StartDate = res.Data.Item.StartDate.replace(/-/g,'.');
+      res.Data.Item.EndDate = res.Data.Item.EndDate.replace(/-/g,'.');
+      res.Data.Item.Money = filterMoney(res.Data.Item.Money);
+      contractInfo.value = res.Data.Item;
+      imglist.value = res.Data.Item.ImgUrl.split('#');//合同图片
+      /* 权限 */
+      let auth = [];
+      res.Data.Item.PermissionList.forEach(item=> {
+        let obj = {
+          checkAll:item.CheckList&&item.CheckList.length===item.Items.length?true:false,
+          isIndeterminate:item.CheckList&&item.CheckList.length>0 && item.CheckList.length<item.Items.length,
+          ...item,
+        }
+        auth.push(obj)
+      })
+      authList.value = auth;
+    }
+  })
+}
+getCompanyInfo()
+
+onMounted(() => {
+   /* 查看审批 */
+  if(isLook.value) {
+    status.value = companyInfo.value.ApproveStatus=='已审批'?'通过':companyInfo.value.ApproveStatus;
+    reason.value = companyInfo.value.ApproveRemark;
+  }
+})
+
+
+/* 确定 */
+function ensureHandle() {
+  if(status.value == '驳回' && !reason.value) {
+    ElMessage.warning('请填写驳回理由!');
+  }else {
+    customInterence.Approval({
+      CompanyId:parseInt(companyId.value),
+      Remark:reason.value,
+      Status:status.value=='通过'?1:2,
+      ProductId:ProductId.value,
+    }).then(res => {
+      if(res.Ret === 200) {
+        ElMessage.success(res.Msg);
+        $router.go(-1);
+      }
+    })
+  }
+}
+/* 取消 */
+function cancelHandle() {
+  $router.go(-1);
+}
+
+
+const isPreviewimg = ref(false)
+const preAct = ref(0)
+const isShowToggle = ref(false)//是否显示切换
+/* 预览 */
+function preview(id,index,img) {
+  // $('#'+id).click()
+  if(img.indexOf('.pdf')!=-1){
+    window.open(img);
+  }else if(img.indexOf('.doc')!=-1||img.indexOf('.docx')!=-1){
+      window.open('https://view.officeapps.live.com/op/view.aspx?src='+img,'_blank');
+  }else{
+    let bol = imglist.value.some(item => {
+      return item.indexOf('.pdf') != -1
+    })
+    // 有pdf或图片只有一张
+    if(bol || imglist.value.length<=1) {
+      isShowToggle.value = false
+    }else {
+      isShowToggle.value = true
+    }
+    isPreviewimg.value = true;
+  }
+}
+function closePreview() {
+  isPreviewimg.value = false;
+}
+function togglePre(type) {
+  if(type==1) {
+    preAct.value--;
+    if(preAct.value < 0) {
+      preAct.value = imglist.value.length-1;
+    }
+  }else {
+    preAct.value++;
+    if(preAct.value > imglist.value.length-1) {
+      preAct.value = 0;
+    }
+  }
+}
+
+
+/* 选择全选或取消全选 */
+function handleCheckAll(item) {
+  // 取到所有的子菜单id
+  let ids = item.Items.map(item =>{
+    return item.ChartPermissionId
+  })
+  item.CheckList = item.checkAll ? ids : [];	
+  item.isIndeterminate = false;
+}
+/* 复选框組选中时 */
+function handleChecked(item) {
+  let len = item.CheckList.length;
+  item.checkAll = len === item.Items.length;
+  item.isIndeterminate = len > 0 && len < item.Items.length;
+}
+
+
+const ContractTermTxt = computed(() => {
+  let date = `${contractInfo.value.StartDate}-${contractInfo.value.EndDate}`;
+  let calculation = CalculationDate(contractInfo.value.StartDate,contractInfo.value.EndDate);
+  let str = contractInfo.value.Quarter ? contractInfo.value.Quarter + `(${date})` : date + `(${calculation})`;
+  return str
+})
+
+
+</script>
+<template>
+  <div class="approvalTurn_box">
+		<div class="approvalTurn_container">
+			<!-- 转正申请 -->
+			<div class="card_cont">
+				<h3 style="marginRight:18px;fontSize:16px;">
+					申请信息 
+					<el-button size="mini" type="primary" @click="isOpenCustomDtl=true" style="marginLeft:10px;">客户信息</el-button>
+				</h3>
+				<div class="history_item">
+					<span>待审批内容:试用转正式</span> <span class="contract_type_hint">{{contractInfo.SourceTag}}</span>
+					<ul class="detail_item">
+						<li>
+							<span>合同类型: {{contractInfo.ContractType}}</span>
+						</li>
+						<li>
+							<span style="min-width:450px;marginRight:260px;display:inline-block;">合同期限:{{ContractTermTxt}}</span>
+							<span>合同金额:{{contractInfo.Money}}元</span>
+						</li>
+						<li>
+							<span style="min-width:450px;marginRight:260px;display:inline-block;">付款方式:{{contractInfo.PayMethod}}</span>
+							<span>付款渠道:{{contractInfo.PayChannel}}</span>
+						</li>
+						<li v-if="contractInfo.PackageType">
+							<p style="min-width:320px;marginRight:260px;display:inline-block;">套餐类型:<span class="setmeal-bg">{{contractInfo.PackageType==1 ?'大套餐':'小套餐'}}</span></p>
+						</li>
+						<li class="textarea_item" style="width:97%;">
+							<label style="display:block;marginBottom:20px;fontSize:16px;position:relative;">
+								权限设置
+							</label>	
+							<ul class="menu_lists">
+								<template v-for="item in authList" >
+									<li class="menu_item" v-if="item.CheckList.length" :key="item.ClassifyName">
+										<el-checkbox :indeterminate="item.isIndeterminate" v-model="item.checkAll" disabled style="marginRight:30px;fontWeight:bold;">{{item.ClassifyName+':'}}</el-checkbox>
+										<el-checkbox-group v-model="item.CheckList" disabled>
+											<el-checkbox v-for="list in item.Items" :label="list.ChartPermissionId" :key="list.ChartPermissionId" class="list_item">{{list.PermissionName}}</el-checkbox>
+										</el-checkbox-group>
+									</li>
+								</template>
+							</ul>	
+						</li>
+						<li class="textarea_item" style="width:97%;display:flex">
+							<label style="marginRight:17px;fontSize:16px;position:relative;width:112px;">
+								查看合同附件
+							</label>
+							<ul class="img_cont">
+								<li v-for="(img,index) in imglist" :key="img" class="img_item">
+									<el-image :src="require('@/assets/img/constract/word-icon.png')" style="width:240px;height:180px;" v-if="img.indexOf('.doc')!=-1||img.indexOf('.docx')!=-1" @click="preview('img'+index,index,img)"></el-image>
+									<pdf ref="pdf" :src="img" style="width:240px;height:180px;overflow:hidden" v-else-if="img.indexOf('.pdf')!=-1" @click="preview('img'+index,index,img)"></pdf>
+									<el-image :src="img" alt="" style="background:#aaa;width:240px;height:180px;" :id="'img'+index" v-else @click="preview('img'+index,index,img)"/>
+									<i class="el-icon-zoom-in" style="position:absolute;right:12px;top:12px;color:#fff;" @click="preview('img'+index,index,img)"></i>
+								</li>
+							</ul>
+						</li>
+						<li style="marginBottom:20px;">
+							<label style="marginRight:40px;fontSize:16px;position:relative;padding-left:18px;">
+								<i style="color:#f00;fontSize:20px;position:absolute;left:0;top:2px;">*</i>
+								审批状态
+							</label>
+							<el-radio-group v-model="status" size="medium" :disabled="isLook">
+								<el-radio label="通过"></el-radio>
+								<el-radio label="驳回" style="marginLeft:0;"></el-radio>
+							</el-radio-group>
+						</li>
+						<li v-if="status=='驳回'">
+							<label style="display:block;marginBottom:10px;fontSize:16px;position:relative;padding-left:18px;">
+								<i style="color:#f00;fontSize:20px;position:absolute;left:0;top:2px;">*</i>
+								驳回理由
+							</label>
+							<el-input type="textarea" v-model="reason" rows="4" style="width:97%;" placeholder="输入理由" :disabled="isLook"></el-input>
+						</li>
+						<li style="display:flex;justify-content:center;margin:60px 0 0;" v-if="!isLook">
+							<el-button type="primary" style="width:80px;marginRight:24px;" @click="ensureHandle">确定</el-button>
+							<el-button  type="primary" plain style="width:80px;" @click="cancelHandle">取消</el-button>
+						</li>
+					</ul>
+				</div>
+			</div>
+		</div>
+		<Ctimeline :id="companyId"></Ctimeline>
+		<!-- 图片预览 -->
+		<imgPreview
+		:isShowToggle="isShowToggle"
+		:isPreview="isPreviewimg" 
+		:arr="imglist" 
+		:actIndex="preAct"
+		@close="closePreview"
+		@togglePre="togglePre"></imgPreview>
+		<!-- 客户基本信息弹窗 -->
+		<CustomDtlDialog 
+		 :isOpenCustomDtl="isOpenCustomDtl"
+		 :companyInfo="companyInfo"
+		 @cancelHandle="isOpenCustomDtl=false"
+		/>
+	</div>
+</template>
+<style scoped lang="scss">
+
+</style>

+ 258 - 0
src/views/custom_manage/custom/approvalUpdate.vue

@@ -0,0 +1,258 @@
+<script setup>
+import { onMounted, ref } from 'vue'
+import { useRoute,useRouter } from 'vue-router'
+import { ElMessage } from 'element-plus'
+import { customInterence } from '@/api/api.js'
+import { filterMoney } from '@/common/js/util'
+import Ctimeline from './compontents/Ctimeline.vue'
+import imgPreview from '@/components/imgPreview.vue'
+import CustomDtlDialog from './components/CustomDtlDialog.vue'
+// import pdf from 'vue-pdf'
+
+const $route = useRoute();
+const $router = useRouter()
+
+const companyId = ref($route.query.id)
+const contractId = ref($route.query.contractId)
+const ApplyMethod = ref($route.query.ApplyMethod)
+const isLook = ref($route.query.isLook || false)
+const companyInfo = ref(JSON.parse(sessionStorage.getItem('companyInfo')) || {})//客户基本信息
+const act = ref(['1'])//默认展开
+const ProductId = ref(0)
+const status = ref('')
+const reason = ref('')
+const contractInfo = ref({})//合同信息
+const imglist = []//合同列表图片
+const authList = ref([])//权限列表
+const diff_time = ref('')
+/* 客户信息弹窗 */
+const isOpenCustomDtl = ref(false)
+/* 获取详情 */
+function getCompanyInfo() {
+  customInterence.approvalDetail({
+    CompanyId:companyId.value,
+    CompanyContractId:Number(contractId.value)
+  }).then(res => {
+    if(res.Ret === 200) {
+      /* 处理合同期限 截取一位小数剔除.0 */
+      ProductId.value=res.Data.Item.ProductId
+      diff_time.value = Number(
+        Number((
+        (new Date(res.Data.Item.EndDate).getTime())
+        -(new Date(res.Data.Item.StartDate).getTime())
+        )/(1000*60*60*24*365))
+        .toFixed(1).replace(/.0/,''));
+      res.Data.Item.StartDate = res.Data.Item.StartDate.replace(/-/g,'.');
+      res.Data.Item.EndDate = res.Data.Item.EndDate.replace(/-/g,'.');
+      res.Data.Item.Money = filterMoney(res.Data.Item.Money);
+      contractInfo.value = res.Data.Item;
+      imglist.value = res.Data.Item.ImgUrl.split('#');//合同图片
+      /* 权限 */
+      let auth = [];
+      res.Data.Item.PermissionList.forEach(item=> {
+        let obj = {
+          checkAll:item.CheckList&&item.CheckList.length===item.Items.length?true:false,
+          isIndeterminate:item.CheckList&&item.CheckList.length>0 && item.CheckList.length<item.Items.length,
+          ...item,
+        }
+        auth.push(obj)
+      })
+      authList.value = auth;
+    }
+  })
+}
+getCompanyInfo()
+
+onMounted(() => {
+  /* 查看审批 */
+  if(isLook.value) {
+    status.value = companyInfo.value.ApproveStatus=='已审批'?'通过':companyInfo.value.ApproveStatus;
+    reason.value = companyInfo.value.ApproveRemark;
+  }
+})
+
+
+/* 确定 */
+function ensureHandle() {
+  if(status.value == '驳回' && !reason.value) {
+    ElMessage.warning('请填写驳回理由!');
+  }else {
+    customInterence.Approval({
+      CompanyId:parseInt(companyId.value),
+      Remark:reason.value,
+      Status:status.value==='通过'?1:2,
+      ProductId:ProductId.value
+    }).then(res => {
+      if(res.Ret === 200) {
+        ElMessage.success(res.Msg);
+        $router.go(-1);
+      }
+    })
+  }
+}
+/* 取消 */
+function cancelHandle() {
+  $router.go(-1);
+}
+
+
+/* 选择全选或取消全选 */
+function handleCheckAll(item) {
+  // 取到所有的子菜单id
+  let ids = item.Items.map(item =>{
+    return item.ChartPermissionId
+  })
+  item.CheckList = item.checkAll ? ids : [];	
+      item.isIndeterminate = false;
+}
+/* 复选框組选中时 */
+function handleChecked(item) {
+  let len = item.CheckList.length;
+  item.checkAll = len === item.Items.length;
+  item.isIndeterminate = len > 0 && len < item.Items.length;
+}
+
+
+
+const isPreviewimg = ref(false)
+const preAct = ref(0)
+const isShowToggle = ref(false)//是否显示切换
+/* 预览 */
+function preview(id,index,img) {
+  if(img.indexOf('.pdf')!=-1){
+    window.open(img);
+  }else if(img.indexOf('.doc')!=-1||img.indexOf('.docx')!=-1){
+      window.open('https://view.officeapps.live.com/op/view.aspx?src='+img,'_blank');
+  }else{
+    let bol = imglist.value.some(item => {
+      return item.indexOf('.pdf') != -1
+    })
+    // 有pdf或图片只有一张
+    if(bol || imglist.value.length<=1) {
+      isShowToggle.value = false
+    }else {
+      isShowToggle.value = true
+    }
+    isPreviewimg.value = true;
+  }
+
+}
+function closePreview() {
+  isPreviewimg.value = false;
+}
+function togglePre(type) {
+  if(type==1) {
+    preAct.value--;
+    if(preAct.value < 0) {
+      preAct.value = imglist.value.length-1;
+    }
+  }else {
+    preAct.value++;
+    if(preAct.value > imglist.value.length-1) {
+      preAct.value = 0;
+    }
+  }
+}
+
+
+
+</script>
+<template>
+  	<div class="approvalUp_box">
+		<div class="approvalUp_container">
+			<!-- 续约申请 -->
+			<div class="card_cont">
+				<div style="marginBottom:30px;">
+					<span style="marginRight:10px;fontSize:16px;fontWeight:bold;">{{ApplyMethod==6?'补充协议':'续约申请'}}</span>
+					<el-button size="mini" type="primary" @click="isOpenCustomDtl=true">客户信息</el-button>
+				</div>
+				<ul class="detail_item">
+					<li>
+						<span>合同类型:{{contractInfo.ContractType}}</span><span class="contract_type_hint">{{contractInfo.SourceTag}}</span>
+					</li>
+					<li>
+						<span style="min-width:320px;marginRight:260px;display:inline-block;">合同期限:{{contractInfo.Quarter}}{{contractInfo.StartDate}}-{{contractInfo.EndDate}}({{diff_time}}年期)</span>
+						<span>合同金额:{{contractInfo.Money}}元</span>
+					</li>
+					<li>
+						<span style="min-width:320px;marginRight:260px;display:inline-block;">付款方式:{{contractInfo.PayMethod}}</span>
+						<span>付款渠道:{{contractInfo.PayChannel}}</span>
+					</li>
+					<li v-if="contractInfo.PackageType">
+						<p style="min-width:320px;marginRight:260px;display:inline-block;">套餐类型:<span class="setmeal-bg">{{contractInfo.PackageType==1 ?'大套餐':'小套餐'}}</span></p>
+					</li>
+					<li class="textarea_item" style="width:97%;">
+						<label style="display:block;marginBottom:20px;fontSize:16px;position:relative;">
+							权限设置
+						</label>	
+						<ul class="menu_lists">
+						
+							<template v-for="item in authList" >
+								<li class="menu_item" v-if="item.CheckList.length" :key="item.ClassifyName">
+									<el-checkbox :indeterminate="item.isIndeterminate" v-model="item.checkAll" disabled style="marginRight:30px;fontWeight:bold;">{{item.ClassifyName+':'}}</el-checkbox>
+									<el-checkbox-group v-model="item.CheckList" disabled>
+										<el-checkbox v-for="list in item.Items" :label="list.ChartPermissionId" :key="list.ChartPermissionId" class="list_item">{{list.PermissionName}}</el-checkbox>
+									</el-checkbox-group>
+								</li>
+							</template>
+						</ul>	
+					</li>
+					<li class="textarea_item" style="width:97%;display:flex">
+						<label style="marginRight:17px;fontSize:16px;position:relative;width:112px;">
+							查看合同附件
+						</label>
+						<ul class="img_cont">
+							<li v-for="(img,index) in imglist" :key="img" class="img_item">
+								<el-image :src="require('@/assets/img/constract/word-icon.png')" style="width:240px;height:180px;" v-if="img.indexOf('.doc')!=-1||img.indexOf('.docx')!=-1" @click="preview('img'+index,index,img)"></el-image>
+								<pdf ref="pdf" :src="img" style="width:240px;height:180px;overflow:hidden" v-else-if="img.indexOf('.pdf')!=-1" @click="preview('img'+index,index,img)"></pdf>
+								<el-image :src="img" alt="" style="background:#aaa;width:240px;height:180px;" :id="'img'+index" v-else @click="preview('img'+index,index,img)"/>
+								<i class="el-icon-zoom-in" style="position:absolute;right:12px;top:12px;color:#fff;" @click="preview('img'+index,index,img)"></i>
+							</li>
+						</ul>
+					</li>
+					<li style="marginBottom:20px;">
+						<label style="marginRight:40px;fontSize:16px;position:relative;padding-left:18px;">
+							<i style="color:#f00;fontSize:20px;position:absolute;left:0;top:2px;">*</i>
+							审批状态
+						</label>
+						<el-radio-group v-model="status" size="medium" :disabled="isLook">
+							<el-radio label="通过"></el-radio>
+							<el-radio label="驳回" style="marginLeft:0;"></el-radio>
+						</el-radio-group>
+					</li>
+					<li v-if="status=='驳回'">
+						<label style="display:block;marginBottom:10px;fontSize:16px;position:relative;padding-left:18px;">
+							<i style="color:#f00;fontSize:20px;position:absolute;left:0;top:4px;">*</i>
+							驳回理由
+						</label>
+						<el-input type="textarea" v-model="reason" rows="4" style="width:97%;" placeholder="输入理由" :disabled="isLook"></el-input>
+					</li>
+					<li style="display:flex;justify-content:center;margin:60px 0 0;" v-if="!isLook">
+						<el-button type="primary" style="width:80px;marginRight:24px;" @click="ensureHandle">确定</el-button>
+						<el-button  type="primary" plain style="width:80px;" @click="cancelHandle">取消</el-button>
+					</li>
+				</ul>
+			</div>
+		</div>
+		<Ctimeline :id="companyId"></Ctimeline>
+
+		<!-- 图片预览 -->
+		<imgPreview
+		:isShowToggle="isShowToggle"
+		:isPreview="isPreviewimg" 
+		:arr="imglist" 
+		:actIndex="preAct"
+		@close="closePreview"
+		@togglePre="togglePre"></imgPreview>
+
+		<!-- 客户基本信息弹窗 -->
+		<CustomDtlDialog 
+		 :isOpenCustomDtl="isOpenCustomDtl"
+		 :companyInfo="companyInfo"
+		 @cancelHandle="isOpenCustomDtl=false"
+		/>
+	</div>
+</template>
+<style scoped lang="scss">
+
+</style>

+ 219 - 0
src/views/custom_manage/custom/components/CpessionTable.vue

@@ -0,0 +1,219 @@
+<script setup>
+import { reactive, ref } from 'vue'
+
+const props = defineProps({
+  	authList: {
+			type: Array,
+		},
+		/* 页面来源 */
+		fromType: {
+			type: String,
+		},
+		/* 表单位置 */
+		form: {
+			type: Number,
+		},
+})
+const emit = defineEmits(['selectAuthHandle','selectAuthHandle2'])
+
+
+
+const authTableRef = ref(null)
+const filterAuth = ref([])
+const rowSpanArr = ref([])
+const position = ref(0)
+const isRaiMerge = ref(0)// 权益的主客观是否合并 0不管 1合并 2拆分
+/* 处理合并数组 */
+function getRowSpan() {
+  rowSpanArr.value = [];
+  /* [2,0,1] */
+  filterAuth.value.forEach((item, index) => {
+    if (index === 0) {
+      rowSpanArr.value.push(1);
+      position.value = 0;
+    } else {
+      if (
+        filterAuth.value[index].ClassifyName ===
+        filterAuth.value[index - 1].ClassifyName
+      ) {
+        rowSpanArr.value[position.value] += 1; //项目名称相同,合并到同一个数组中
+        rowSpanArr.value.push(0);
+        filterAuth.value[index].ClassifyName = filterAuth.value[
+          index - 1
+        ].ClassifyName;
+      } else {
+        rowSpanArr.value.push(1);
+        position.value = index;
+      }
+    }
+  });
+}
+
+
+/* 合并行规则 */
+function objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+  if (columnIndex === 0) {
+    const _row = rowSpanArr.value[rowIndex];
+    return {
+      rowspan: _row,
+      colspan: 1,
+    };
+  }
+}
+
+/* 勾选权限 */
+function handleSelectionChange(val) {
+  let selectArr=[]
+  if(isRaiMerge.value==1){
+    // 由于合并时客观的那一行隐藏掉了,复选框只会影响主观的选择状态 
+    // 但是选择的时候需要主客观的ID都传
+    let completeAuth = props.authList.map((item) => {
+      return item.Items;
+    }).flat(Infinity);
+    val.map(item=>{
+      // 主观有勾选
+      if(item.PermissionType==1){
+        // 主观有勾选代表是全选
+        let idArr = completeAuth.filter(it => {
+          return it.PermissionName == item.PermissionName
+        })
+        idArr.map(it => {
+          selectArr.push(it.ChartPermissionId)
+        })
+      }else if(item.PermissionType==0){
+        // 没有区分主客观的行业
+        selectArr.push(item.ChartPermissionId)
+      }
+    })
+  }else{
+    selectArr = val.map((item, index) => {
+      return item.ChartPermissionId;
+    });
+  }
+  // console.log(selectArr);
+  props.form === 1
+    ? emit('selectAuthHandle', selectArr)
+    : emit('selectAuthHandle2', selectArr);
+}
+
+// 是否可选择
+function canSelect(row) {
+  return row.IsPublic == 1 ? false : true;
+}
+
+
+function init() {
+  	isRaiMerge.value = props.authList[0].RaiMerge
+		/* 处理表格数据格式 */
+		let tempArr=props.authList.map((item) => {
+			return item.Items;
+		});
+		tempArr = tempArr.flat(Infinity);
+		// console.log(tempArr);
+		if(!isRaiMerge.value){
+			filterAuth.value = tempArr
+		}else if(isRaiMerge.value==1){
+			// 主客观合并 只取主观的
+			filterAuth.value = tempArr.filter(it => {
+				return it.PermissionType==1 || it.PermissionType==0
+			})
+		}else if(isRaiMerge.value==2){
+			// 主客观拆分 只取主观的
+			tempArr.map(item =>{
+				// 排下序 
+				if(item.PermissionType==1){
+					//主观 找客观
+					filterAuth.value.push(item)
+					let ob = tempArr.find(it => it.PermissionName == item.PermissionName && it.PermissionType!=1)
+					ob && filterAuth.value.push(ob)
+				}else if(item.PermissionType==0){
+					filterAuth.value.push(item)
+				}else{
+					// 客观
+					if(!filterAuth.value.find(t => t.ChartPermissionId == item.ChartPermissionId)){
+						filterAuth.value.push(item)
+					}
+				}
+			})
+		}
+		/* 选中的id数组 */
+		//查看是否领取但无权限
+		let bol_have = props.authList.some((item) => item.CheckList.length);
+		let select = props.authList.map((item) => {
+			return item.CheckList;
+		});
+		select = bol_have ? select.flat(Infinity) : [];
+
+		/* 默认勾选中的表格项 */
+		let check_Auth = filterAuth.value.filter((item) => {
+			return select.includes(item.ChartPermissionId);
+		});
+		console.log(check_Auth,'check_Auth');
+		if (props.fromType === 'edit') {
+			/* 展示表格选中的key */
+			nextTick(() => {
+				if (check_Auth.length > 0) {
+					check_Auth.forEach((item) => {
+						authTableRef.value.toggleRowSelection(item, true);
+					});
+				}
+			});
+		}else {
+			/* 显示只有权限的数组 */
+			filterAuth.value = [];
+			filterAuth.value = check_Auth.filter((item) => {
+				return item.Status === '正式' || item.Status === '试用' || item.Status === '永续'||item.Status=='关闭'
+			});
+		}
+		
+		getRowSpan();
+}
+init()
+</script>
+<template>
+  <el-table
+		:data="filterAuth"
+		:span-method="objectSpanMethod"
+		@selection-change="handleSelectionChange"
+		ref="authTableRef"
+		border
+		style="margin-top: 20px"
+	>
+		<el-table-column label="所属类目" align="center" >
+			<template #default="scope">{{ scope.row.ClassifyName }}</template>
+		</el-table-column>
+		<el-table-column label="品种" align="center" >
+			<template #default="scope">
+				<!-- 权益在拆分的情况下区分主客观 -->
+				{{ isRaiMerge ==2&&scope.row.PermissionTypeName?`${scope.row.PermissionName}(${scope.row.PermissionTypeName})`:scope.row.PermissionName }}
+			</template>
+		</el-table-column>
+		<el-table-column label="状态" align="center" >
+			<template #default="scope">{{ scope.row.Status }}</template>
+		</el-table-column>
+		<el-table-column label="服务期限" align="center">
+			<template #default="scope">{{
+				scope.row.StartDate + '—' + scope.row.EndDate
+			}}</template>
+		</el-table-column>
+		<el-table-column label="剩余天数" align="center">
+			<template #default="scope">{{ scope.row.ExpireDay }}</template>
+		</el-table-column>
+		<el-table-column 
+		v-if="fromType == 'edit'" 
+		type="selection" 
+		width="70"
+		align="center"
+		label-class-name="DisabledSelection"
+		:selectable="canSelect">
+		</el-table-column>
+	</el-table>
+</template>
+<style scoped lang="scss">
+/*表格表头全选*/
+.DisabledSelection .cell::after{
+	content:"全选";
+	font-size: 12px;
+	margin-left: 2px;
+}
+</style>

+ 1 - 0
src/views/custom_manage/custom/components/CpessionTableEquity.vue

@@ -88,6 +88,7 @@ function init() {
   
   getRowSpan();
 }
+init()
 
 
 /* 处理合并数组 */

+ 285 - 0
src/views/custom_manage/custom/components/Ctimeline.vue

@@ -0,0 +1,285 @@
+<script setup>
+import { ref, watch } from 'vue'
+import { customInterence } from '@/api/api.js'
+import { ElMessage, ElMessageBox } from 'element-plus';
+
+const props = defineProps({
+  id: {
+    type:Number,
+    default:0
+  }
+})
+
+watch(
+  () => props.id,
+  () => {
+    getCustomProcess();
+  }
+)
+
+
+const activities=ref([])
+const show=ref(false)
+// 显示未续约说明按钮类型
+const specialOperationList=ref(['edit_renewal_reason','add_renewal_reason','add_try_out_reason'])
+const isShowBtn=ref(false)	// 是否显示添加未续约说明按钮
+const ficcProcess=ref([])
+const raiProcess=ref([])
+/* 获取客户进度流程*/
+function getCustomProcess() {
+  customInterence.processList({
+    CompanyId:props.id
+  }).then(res => {
+    if(res.Ret === 200) {
+      isShowBtn.value=res.Data.ShowButton
+      activities.value = res.Data.List&&res.Data.List.map(item=>{
+        return {
+          ...item,
+          CreateTime:item.CreateTime.replace(/-/g,'.')
+        }
+      }) || [];
+      //将进度流程拆分为FICC和权益
+      ficcProcess.value = activities.value.filter(item=>item.ProductName==='ficc')
+      raiProcess.value = activities.value.filter(item=>item.ProductName!=='ficc')
+      changeTimeLineData('ficc')
+      if(!ficcProcess.value.length&&raiProcess.value.length){
+        changeTimeLineData('rai')
+      }
+    }
+  })
+}
+getCustomProcess()
+
+const timeLineType=ref('')
+const timeLineData=ref([])
+//改变时间线展示的内容
+function changeTimeLineData(type){
+  if(type===timeLineType.value) return 
+  timeLineType.value = type
+  type==='ficc'&&(timeLineData.value = ficcProcess.value)
+  type==='rai'&&(timeLineData.value = raiProcess.value)
+  document.querySelector('.timeline-wrap')&&(document.querySelector('.timeline-wrap').scrollTop = 0)
+}
+
+
+
+//显示冻结理由
+function showFreeze(e){
+  ElMessageBox.confirm(e.ApproveContent, '冻结理由', {
+    confirmButtonText: '知道了',
+    showCancelButton:false,
+    type: 'info '
+  })
+}
+//展示关闭理由
+function showCloseRemark(data){
+  ElMessageBox.confirm(`${data.ApproveContent}`,'关闭理由',{
+    confirmButtonText: '知道了',
+    showCancelButton:false
+  }).then(()=>{}).catch(()=>{})
+}
+
+
+const isShowDia=ref(false)	// 是否显示弹窗
+const activeActivity=ref({})	// 当前流程内容
+//显示续约说明
+function showRemark(e){
+  activeActivity.value=e
+  isShowDia.value=true
+}
+//关闭续约说明
+function closeDia(){
+  activeActivity.value={}
+  isShowDia.value=false
+}
+
+
+const isShowAddDia=ref(false)	// 是否显示添加说明弹窗
+const remark=ref('')	// 填写的备注
+const toDoRemark=ref('')//to do 事项
+const isGiveUp=ref(false)	// 是否不再跟进
+// 显示添加说明弹窗
+function showAddRemark(e){
+  console.log(e);
+  activeActivity.value=e
+  isShowAddDia.value=true
+}
+//添加未续约说明
+async function addRemark(){
+  if(!remark.value&&!isGiveUp.value) return ElMessage.warning('请输入最新情况')
+  if(!toDoRemark.value&&!isGiveUp.value) return ElMessage.warning('请填写To Do事项')
+  // 如果选中不再跟进,需要在备注中添加额外内容
+  const addRemark = isGiveUp.value?remark.value?'。客户无续约意向,不再跟进(转为冻结客户)':'客户无续约意向,不再跟进(转为冻结客户)':''
+  // 参数
+  const params = {
+    CompanyId:activeActivity.value.CompanyId,
+    ProductId:activeActivity.value.ProductId,
+    Remark:remark.value+addRemark,
+    RenewalTodo:toDoRemark.value,
+    Renew:isGiveUp.value?1:0
+  }
+  let res = null
+  if(activeActivity.value.Operation==='try_out'){
+    params.OperationId=activeActivity.value.Id
+    // 是正式转试用添加说明
+    res = await customInterence.addTryOutRenewalReason(params)
+  }else{
+    // 添加说明
+    res = await customInterence.sellerAddListRemark(params)
+    
+  }
+  if(res.Ret===200){
+    // 关闭添加弹窗和未续约说明弹窗
+    getCustomProcess()
+    cancelAddRemark()
+    closeDia()
+    ElMessage.success('添加成功')
+  }
+}
+//取消添加未续约说明
+function cancelAddRemark(){
+  remark.value=''
+  toDoRemark.value=''
+  isGiveUp.value=false
+  isShowAddDia.value=false
+}
+
+
+
+</script>
+<template>
+  <div class="Ctimeline_container" v-if="activities.length">
+		<div class="timeline-tab" v-if="ficcProcess.length&&raiProcess.length">
+			<span :class="{'active':timeLineType==='ficc'}" @click="changeTimeLineData('ficc')">FICC</span>
+			<span :class="{'active':timeLineType==='rai'}" @click="changeTimeLineData('rai')">权益</span>
+		</div>
+		<div class="timeline-wrap" :style="{maxHeight:`${(ficcProcess.length&&raiProcess.length)?'430px':'490px'}`}">
+			<el-timeline>
+				<el-timeline-item
+					v-for="(activity, index) in timeLineData"
+					:key="index"
+					:timestamp="activity.CreateTime"
+					color="#409EFF"
+					placement="top">
+					{{activity.SysRealName+(specialOperationList.includes(activity.Operation)?'添加未续约说明':activity.Remark)}}
+					<span v-if="activity.Operation=='freeze'&&activity.ApproveContent" class="freeze-text" @click="showFreeze(activity)">冻结理由</span>
+					<span v-if="(specialOperationList.includes(activity.Operation))&&activity.ApproveContent" @click="showRemark(activity)" class="freeze-text">未续约说明</span>
+
+					<span v-if="activity.Remark=='正式转试用'" class="freeze-text" @click="showAddRemark(activity)">添加未续约说明</span>
+					<span v-if="activity.Operation==='close'&&activity.ApproveContent" @click="showCloseRemark(activity)" class="freeze-text">关闭理由</span>
+				</el-timeline-item>
+			</el-timeline>
+		</div>
+		
+		<!-- 未续约说明弹窗 -->
+		<el-dialog
+      draggable
+      v-model="isShowDia"
+      :modal-append-to-body='false'
+      center
+      width="670px"
+      @close="closeDia"
+    >
+      <template #header>
+        <div style="display:flex;alignItems:center;">
+          <span style="fontSize:16px;color:#fff;fontWeight:bold;">未续约说明</span>
+        </div>
+      </template>
+			<div style="min-height:300px">
+			<div style="font-size:14px;line-height:2">
+				<span>最新情况:</span>
+				<span>{{activeActivity.ApproveContent}}</span>
+			</div>
+			<div style="font-size:14px;line-height:2">
+				<span>To Do事项:</span>
+				<span>{{activeActivity.ApproveContentExtra}}</span>
+			</div>
+			</div>
+			<div style="text-align:center;margin:30px 0">
+				<el-button  type="primary" plain style="width:80px;" @click="closeDia">关闭</el-button>
+				<el-button type="primary" style="marginRight:24px;" @click="isShowAddDia=true">添加说明</el-button>
+			</div>
+		</el-dialog>
+
+		<!-- 添加说明弹窗 -->
+		<el-dialog
+      v-model="isShowAddDia"
+			:modal-append-to-body='false'
+			width="670px"
+      @close="cancelAddRemark"
+      draggable
+    >
+      <template #header>
+        <div>
+          <img width="15" :src="require('@/assets/img/icons/warn.png')" alt="" style="position:relative;top:2px">
+          <span>添加说明</span>
+        </div>
+      </template>
+			<div>
+				<div style="margin-bottom:5px">最新情况</div>
+				<el-input type="textarea" v-model.trim="remark" :autosize="{ minRows: 8, maxRows: 12}" placeholder="请填写最新情况" resize="none"></el-input>
+				<div style="margin-bottom:5px;margin-top:15px">To Do事项</div>
+        		<el-input type="textarea" v-model.trim="toDoRemark" :autosize="{ minRows: 8, maxRows: 12}" placeholder="请填写To Do事项" resize="none"></el-input>
+				<el-checkbox v-model="isGiveUp" style="margin:20px 10px 0;">客户无续约意向,不再跟进(转为冻结客户)</el-checkbox>
+				<div style="text-align:center;margin:30px 0">
+				<el-button type="primary" style="width:152px;margin-right:30px" @click="addRemark">确定</el-button>
+				<el-button type="primary" style="width:152px" plain @click="cancelAddRemark">取消</el-button>
+				</div>
+			</div>
+		</el-dialog>
+	</div>
+</template>
+<style scoped lang="scss">
+.Ctimeline_container {
+	box-sizing: border-box;
+	min-width: 428px;
+	max-height: 550px;
+	padding: 30px;
+	border: 1px solid #AAB4CC;
+	background: #fff;
+	border-radius: 4px;
+	*{
+		box-sizing: border-box;
+	}
+	:deep(.el-timeline-item__tail) {
+		border-color: #409EFF;
+	}
+	:deep(.el-timeline-item__timestamp.is-top) {
+		color: #999;
+		margin-bottom: 4px;
+	}
+	:deep(.el-timeline-item__content) {
+		color: #999;
+	}
+	.freeze-text{
+		color: #409EFF;
+		font-size: 12px;
+		display: inline-block;
+		cursor: pointer;
+		margin:0 5px;
+	}
+	.el-timeline{
+		margin:5px;
+	}
+	.timeline-tab{
+		display: flex;
+		margin-bottom: 30px;
+		span{
+			flex: 1;
+			text-align: center;
+			display: inline-block;
+			height: 30px;
+			line-height: 30px;
+			cursor: pointer;
+			&.active{
+				background-color: #EDF4FF;
+				color:#3385FF;
+			}
+		}
+	}
+	.timeline-wrap{
+		//max-height: calc(550px - 120px);
+		overflow-y: auto;
+	}
+}
+</style>

+ 94 - 0
src/views/custom_manage/custom/components/CustomDtlDialog.vue

@@ -0,0 +1,94 @@
+<script setup>
+import { ref } from 'vue'
+
+const props = defineProps({
+  isOpenCustomDtl: {
+    type: Boolean,
+    default: false
+  },
+  title: {
+    type: String,
+    default: '客户信息'
+  },
+  companyInfo: {
+    type: Object,
+  }
+})
+
+const emit = defineEmits(['cancelHandle'])
+
+
+function cancelHandle() {
+  emit('cancelHandle');
+}
+</script>
+<template>
+  <el-dialog
+    :model-value="isOpenCustomDtl"
+    :close-on-click-modal="false"
+    :modal-append-to-body='false'
+    @close="cancelHandle"
+    custom-class="customDtl_Dia"
+    center
+    width="50%"
+  >
+    <template #header>
+      <div style="display:flex;align-items:center;">
+        <span style="font-size:16px;">{{title}}</span>
+      </div>
+    </template>
+		<ul class="custom_dtl">
+			<li>
+				客户名称:{{companyInfo.CompanyName}}
+			</li>
+			<li>
+				社会信用码:{{companyInfo.CreditCode}}
+			</li>
+			<li>
+				地址:{{companyInfo.Address}}
+			</li>
+			<li>
+				客户类型:{{companyInfo.CompanyType}}
+			</li>
+			<li>
+				客户状态:{{companyInfo.Status}}
+			</li>
+			<li>
+				客户来源:{{companyInfo.Source}}
+			</li>
+			<li>
+				行业:{{companyInfo.IndustryName}}
+			</li>
+			<li>
+				所属销售:{{companyInfo.SellerName}}
+			</li>
+			<li>
+				申请理由:{{companyInfo.ApplyReasons||'无'}}
+			</li>
+		</ul>
+		<div style="display:flex;justify-content:center;margin:60px 0 40px;">
+			<el-button type="primary" style="width:80px;marginRight:24px;" @click="cancelHandle">知道了</el-button>
+		</div>
+	</el-dialog>
+</template>
+<style scoped lang="scss">
+.customDtl_Dia { 
+	:deep(.el-dialog__header ,.el-dialog__close.el-icon.el-icon-close) {
+	 background: #fff;
+	 color: #000;
+	}
+	.custom_dtl {
+		padding: 20px 20px 10px;
+		border: 1px solid #DCDFE6;
+		font-size: 16px;
+		display: flex;
+		flex-wrap: wrap;
+		justify-content: space-between;
+		li {
+			margin-right: 100px;
+			margin-bottom: 20px;
+			min-width: 250px;
+		}
+	}
+}
+</style>

+ 303 - 0
src/views/custom_manage/custom/components/ProductReadInfo.vue

@@ -0,0 +1,303 @@
+<script setup>
+import { ref, watch } from 'vue'
+import {customInterence} from '@/api/api.js'
+
+
+const props = defineProps({
+    productReadInfoShow:{//弹窗显示
+      type:Boolean
+    },
+    productReadId:{//联系人ID
+      type:Number
+    },
+    productReadTitle:{//弹窗标题
+      type:String
+    },
+    subProductId: { //分产品类型+id
+      type: String
+    },
+    subProductName: {
+      type: String
+    },
+    clickToal: {
+      type: Number
+    }
+})
+const emit = defineEmits(['close'])
+
+//表格的column
+//分产品阅读统计
+const totalColumn = [
+  {
+    label:'产品名称',
+    propName:'ProductName',
+  },{
+    label:'标题',
+    propName:'Title',
+  },{
+    label:'点击量',
+    propName:'VisitCount',
+    widthsty:100
+  },{
+    label:'来源',
+    propName:'Source',
+    widthsty:100
+  },{
+    label:'最近一次点击时间',
+    propName:'RecentTime'
+  }
+]
+//视频社区
+const videoColumn = [
+  {
+    label:'视频列表',
+    propName:'Title',
+  },{
+    label:'点击量',
+    propName:'VisitCount',
+    widthsty:100
+  },{
+    label:'来源',
+    propName:'Source',
+    widthsty:100
+  },{
+    label:'最近一次点击时间',
+    propName:'RecentTime'
+  }
+]
+//语音播报
+const voicePlayColumn=[
+  {
+    label:'语音播报列表',
+    propName:'Title',
+  },{
+    label:'点击量',
+    propName:'VisitCount',
+    widthsty:100
+  },{
+    label:'来源',
+    propName:'Source',
+    widthsty:100
+  },
+  {
+    label:'最近一次点击时间',
+    propName:'RecentTime'
+  }
+]
+//问答社区
+const questionColumn = [
+  {
+    label:'问答列表',
+    propName:'Title',
+  },{
+    label:'点击量',
+    propName:'VisitCount',
+    widthsty:100
+  },{
+    label:'来源',
+    propName:'Source',
+    widthsty:100
+  },
+  {
+    label:'最近一次点击时间',
+    propName:'RecentTime'
+  }
+]
+const columnMap = {
+  'Total':totalColumn,
+  'Video':videoColumn,
+  'VoicePlay':voicePlayColumn,
+  'Question':questionColumn
+}
+
+
+
+const tableName = ref('total')//当前显示表格的名称
+const tableColumn = ref([])//当前显示表格的column
+const tableData = ref([])//表格数据
+const total = ref(0)//表格数据总数
+const pageNo = ref(1)//当前页
+const pageSize = ref(10)//一页显示多少条数据
+const typeName = ref('')//分产品小标题
+const isClickSort = ref(false)//
+const choosedItem = ref({})//当前点击的数据
+//初始化表格数据
+function initTable(tableName){
+  tableName.value = tableName
+  tableColumn.value = columnMap[tableName]
+  pageNo.value= 1
+  getReadInfoDetail()
+}
+
+//关闭弹窗
+function cancelHandle(){
+  emit('close')
+}
+
+//切换表格数据
+function changeTable(item){
+  choosedItem.value = item
+  //在分列表点击数据,不做任何操作
+  if(!item.ProductType&&!item.type) return
+  //在总列表点击数据
+  if(item.ProductType){
+    const typeMap = {
+      1:'VoicePlay',
+      2:'Video',
+      3:'Question'
+    }
+    initTable(typeMap[item.ProductType])
+  }
+  //点击返回
+  if(item.type){
+    initTable(item.type)
+  }
+}
+
+//点击页码
+function handleCurrentChange(pageNo){
+  pageNo.value = pageNo
+  getReadInfoDetail()
+}
+
+//获取总的阅读统计
+async function getTotalReadInfo(orderType){
+  typeName.value = ''
+  let order = {}
+  if(orderType){
+    order.ClickSort = orderType
+  }
+  const res = await customInterence.getYbProductReadInfo({
+    UserId:props.productReadId,
+    PageSize:pageSize.value,
+    CurrentIndex:pageNo.value,
+    ...order
+  })
+  if(res.Ret===200){
+    const {List,Paging} = res.Data
+    tableData.value = List
+    total.value = Paging.Totals
+  }
+}
+
+//获取某产品的阅读详情
+async function getReadInfoDetail(orderType){
+  const {ProductType,ProductId,ProductName} = choosedItem.value
+  let params = {
+    UserId:props.productReadId,
+    ProductType,
+    PageSize:pageSize.value,
+    CurrentIndex:pageNo.value,
+  }
+  typeName.value = ProductName
+  // if(ProductType===1){
+    params.ProductId = ProductId
+  // }
+  if(orderType){
+    params.ClickSort = orderType
+  }
+  const res = await customInterence.getYbProductReadDetail(params)
+  if(res.Ret===200){
+    const {List,Paging} = res.Data
+    tableData.value = List
+    total.value = Paging.Totals
+  }
+}
+
+//点击量排序
+function sortChangeHandle({ prop,order }){
+  const orderType = order==='ascending'?1:order==='descending'?2:0
+  pageNo.value = 1
+  getReadInfoDetail(orderType)
+}
+
+
+
+watch(
+  () => props.productReadInfoShow,
+  (newVal) => {
+    if(newVal){
+        let subProductArr = props.subProductId.split('-');
+        const typeMap = {
+          1:'VoicePlay',
+          2:'Video',
+          3:'Question',
+          99:'Total',
+        }
+        choosedItem.value = {
+          ProductType: Number(subProductArr[0]),
+          ProductId: Number(subProductArr[1]),
+          ProductName: props.subProductName
+        }
+        initTable(typeMap[Number(subProductArr[0])])
+      }
+  }
+)
+
+</script>
+<template>
+  <el-dialog
+    :model-value="productReadInfoShow" 
+    :close-on-click-modal="false" 
+    :modal-append-to-body="false"
+    @close="cancelHandle" width="689px" draggable center
+  >
+    <template #header>
+      <div style="display: flex; align-items: center">
+        <span style="fontsize: 16px">{{productReadTitle}}</span>
+      </div>
+    </template>
+    <div class="dialog-container">
+      <div class="table-info-wrap">
+        <div class="table-info">
+          <p>{{typeName}}</p>
+          <p>共{{clickToal}}个点击量</p>
+        </div>
+      </div>
+      <el-table
+        :data="tableData"
+        border
+        @sort-change="sortChangeHandle"
+        max-height="400"
+        style="width: 100%; margin-bottom: 20px">
+        <el-table-column align="center"
+            v-for="item in tableColumn" :key="item.propName"
+            :label="item.label"
+            :prop="item.propName"
+            :width="item.widthsty" 
+            :min-width="item.minwidthsty"
+            :sortable="item.propName==='VisitCount'"
+        >
+        <template #default="{row}">
+          <span v-if="item.propName==='VisitCount'" class="editsty">{{row[item.propName]||'0'}}</span>
+          <span v-else-if="item.propName==='Source'">{{row[item.propName]===1?'小程序':'PC端'}}</span>
+          <span v-else>{{row[item.propName]||'--'}}</span>
+        </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination
+          layout="total,prev,pager,next"
+          small
+          :current-page="pageNo"
+          @current-change="handleCurrentChange"
+          :page-size="pageSize"
+          :total="total"
+          style="text-align: end; margin: 20px 0"
+        >
+      </el-pagination>
+    </div>
+  </el-dialog>
+</template>
+<style scoped lang="scss">
+.dialog-container{
+  margin-top: -10px;
+  :deep(.el-icon-arrow-right:before){
+    color: inherit;
+  }
+  .table-info-wrap{
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 10px;
+  }
+}
+</style>

+ 134 - 0
src/views/custom_manage/custom/components/chartAuthDialog.vue

@@ -0,0 +1,134 @@
+<script setup>
+import { computed, ref } from 'vue'
+import moment from 'moment'
+import { ElMessage } from 'element-plus'
+import { useRouter } from 'vue-router'
+
+const $router = useRouter()
+
+const props = defineProps({
+   showChartAuthPop:{
+        type:Boolean
+    },
+    chartAuthClassifyList:[],
+    chartAuthUserInfo:{}
+})
+const emit = defineEmits(['chartAuthClose','chartAuthSave'])
+
+const timePickerOptions = computed(() => {
+    let obj={
+        disabledDate(time) {
+            if(props.chartAuthUserInfo){
+                return time.getTime()<new Date(props.chartAuthUserInfo.StartTime).getTime()||time.getTime()>new Date(props.chartAuthUserInfo.ExpireDay).getTime()
+            }else{
+                return false
+            }
+        }
+    }
+
+    return obj
+})
+
+function handleClose(){
+    emit('chartAuthClose')
+}
+
+function handleSave(){
+    if(!props.chartAuthUserInfo.EndTime){
+        ElMessage.warning('请选择结束日期')
+        return
+    }
+    emit('chartAuthSave')
+}
+
+function getTimeCount(){
+    return moment(props.chartAuthUserInfo.EndTime).diff(props.chartAuthUserInfo.StartTime,'days')+1||0
+}
+
+function clickClassifyItem(item){
+    sessionStorage.setItem('myChartOpt',item.MyChartClassifyId)
+    sessionStorage.setItem('myChartIspublic',item.IsPublic)
+    let routeData = $router.resolve({ path: '/mychart', })
+    window.open(routeData.href, '_blank');
+}
+</script>
+<template>
+  <div class="chart-auth-wrap">
+    <el-dialog
+        :model-value="showChartAuthPop"
+        :close-on-click-modal="false"
+        :modal-append-to-body='false'
+        @close="handleClose"
+        center
+        top="30vh"
+        draggable
+        width="800px"
+        title="图表权限"
+    >
+
+        <div class="chart-auth-content">
+            <div class="flex type-box">
+                <div style="margin-right:10px">可见ETA图表分类: </div>
+                <div v-if="chartAuthClassifyList.length==0">暂无分类,请提醒研究员设置ETA图表权限</div>
+                <div v-else>
+                    <span v-for="item in chartAuthClassifyList" :key="item.MyChartClassifyId" @click="clickClassifyItem(item)">{{item.MyChartClassifyName}}</span>
+                </div>
+            </div>
+            <div class="flex" style="margin-bottom: 20px;">
+                <div style="margin-right:10px">图表阅读时长: </div>
+                <div><span style="color:#409EFF">{{getTimeCount()}}</span> 天</div>
+            </div>
+            <div class="flex" style="margin-bottom: 20px;align-items: center;">
+                <div style="margin-right:10px">起止时间: </div>
+                <div>
+                    <span>{{chartAuthUserInfo.StartTime}} --</span>
+                    <el-date-picker
+                        v-model="chartAuthUserInfo.EndTime"
+                        type="date"
+                        :picker-options="timePickerOptions"
+                        value-format="yyyy-MM-dd"
+                        placeholder="选择日期">
+                    </el-date-picker>
+                    <span style="color:#999">(结束日期不可晚于客户权限到期日期)</span>
+                </div>
+            </div>
+            <div class="flex" style="margin-bottom: 20px;">
+                <div style="margin-right:10px">阅读权限: </div>
+                <div>
+                    <el-switch
+                        v-model="chartAuthUserInfo.auth"
+                        active-color="#13ce66"
+                        inactive-color="#DCDFE6">
+                    </el-switch>
+                    <span style="position: relative;top:3px">{{chartAuthUserInfo.auth?'开':'关'}}</span>
+                </div>
+            </div>
+            <div style="text-align:center;margin:30px 0">
+                <el-button type="primary" @click="handleSave">保存</el-button>
+                <el-button type="primary" plain @click="handleClose">取消</el-button>
+            </div>
+        </div>
+      
+    </el-dialog>
+  </div>
+</template>
+<style scoped lang="scss">
+.chart-auth-wrap{
+    .flex{
+        display: flex;
+    }
+    .chart-auth-content{
+        font-size: 14px;
+        .type-box{
+            margin-bottom: 20px;
+            
+            span{
+                display: inline-block;
+                margin-right: 10px;
+                cursor: pointer;
+                color: #409EFF;
+            }
+        }
+    }
+}
+</style>

+ 76 - 0
src/views/custom_manage/custom/components/deductDetailDlg.vue

@@ -0,0 +1,76 @@
+<script setup>
+import { ref, watch } from 'vue'
+import { raiInterface } from "@/api/api.js";
+
+const props = defineProps({
+  isShowResearchNumber: {
+    type: Boolean,
+    default: false,
+  },
+  dataForm: {
+    type: Object,
+    default: {},
+  },
+  isShowDlgType: {
+    type: String,
+    default: "",
+  },
+})
+const emit = defineEmits(['close'])
+
+
+// 关闭弹框
+function handleClose() {
+  emit('close')
+  emit("update:isShowResearchNumber", false);
+  emit("update:isShowDlgType", "");
+}
+
+const tableList = ref([])
+// 获取表格数据
+async function getDataList() {
+  const res =
+    props.isShowDlgType == "专项调研" ? await raiInterface.specialPointsBill({ CompanyId: props.dataForm.CompanyId }) : await raiInterface.activityPointsBill({ CompanyId: props.dataForm.CompanyId });
+  if (res.Ret === 200) {
+    tableList.value = res.Data.List || [];
+  }
+}
+
+
+watch(
+  () => props.isShowResearchNumber,
+  (val) => {
+     val ? getDataList() : (tableList.value = []);
+  }
+)
+
+</script>
+<template>
+  <!-- banner 详情的弹框 -->
+  <el-dialog
+    :title="isShowDlgType == '专项调研' ? '专项调研次数明细' : '研选服务点数明细'"
+    :model-value="isShowResearchNumber"
+    width="1200px"
+    draggable
+    :close-on-click-modal="false"
+    :modal-append-to-body="false"
+    center
+    @close="handleClose"
+  >
+    <el-table style="margin-bottom: 30px" :data="tableList" border height="500">
+      <el-table-column align="center" prop="Content" label="事项"></el-table-column>
+      <el-table-column align="center" prop="CreateTime" label="时间" width="180"></el-table-column>
+      <el-table-column align="center" prop="ChartPermissionName" label="行业" width="100" v-if="isShowDlgType == '专项调研'"></el-table-column>
+      <el-table-column align="center" prop="RealName" label="参会人" width="100"></el-table-column>
+      <el-table-column align="center" prop="minNumber" label="小计" width="80">
+        <template #default="{ row }">
+          <span :style="{ color: row.BillDetailed > 0 ? '#31c640' : '#ec808d' }"> {{ row.BillDetailed > 0 ? "+" + row.BillDetailed : row.BillDetailed }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" :prop="isShowDlgType == '专项调研' ? 'Total' : 'Points'" label="合计" :width="isShowDlgType == '专项调研' ? '300' : '100'"></el-table-column>
+    </el-table>
+  </el-dialog>
+</template>
+<style scoped lang="scss">
+
+</style>

+ 96 - 0
src/views/custom_manage/custom/components/exportData.vue

@@ -0,0 +1,96 @@
+<script setup>
+import { ref, watch } from 'vue'
+import { customInterence } from "@/api/api.js";
+import { ElMessage } from 'element-plus';
+
+
+const props = defineProps({
+  exportDataIsShow: {
+    type: Boolean,
+    default: false,
+  },
+  companyId: {
+    type: Number,
+  },
+})
+const emit = defineEmits(['close'])
+
+
+watch(
+  () => props.exportDataIsShow,
+  (newval) => {
+     if (newval) companyExportList();
+  }
+)
+
+
+const exportValue = ref("")
+const options = ref([])
+const exportUrl = ref("")
+async function companyExportList() {
+  const res = await customInterence.companyExportList();
+  if (res.Ret === 200) {
+    options.value = res.Data.List || [];
+  }
+  console.log(res);
+}
+
+function exportChange() {
+  let url = "";
+  options.value.forEach((item) => {
+    if (item.Name == exportValue.value) {
+      url = item.Url;
+    }
+  });
+  exportUrl.value = process.env.API_ROOT + url  + "&CompanyId=" + Number(props.companyId)+'&' + (localStorage.getItem("auth") || "");
+}
+
+function cancelHandle() {
+  exportUrl.value = "";
+  exportValue.value = "";
+  emit("close");
+}
+
+function saveHandle() {
+  if (!exportValue.value) return ElMessage.error("请选择导出内容");
+  let link = document.createElement("a");
+  link.href = exportUrl.value;
+  link.setAttribute("download", "导出数据");
+  link.style.display = "none"; //a标签隐藏
+  document.body.appendChild(link);
+  link.click();
+  setTimeout(() => {
+    cancelHandle();
+  });
+}
+
+</script>
+<template>
+  <div class="container-export">
+    <el-dialog
+      draggable
+      :model-value="exportDataIsShow"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      title="导出数据"
+      :show-close="false"
+      @close="cancelHandle"
+      center
+      width="450px"
+    >
+      <div>
+        <p style="margin-bottom: 20px">请选择导出内容:</p>
+        <el-select style="width: 100%" v-model="exportValue" @change="exportChange" placeholder="请选择导出内容" clearable>
+          <el-option v-for="item in options" :key="item.Name" :label="item.Name" :value="item.Name"> </el-option>
+        </el-select>
+      </div>
+      <div style="display: flex; justify-content: center; margin: 40px 0">
+        <el-button type="primary" style="width: 80px; marginright: 24px" @click="saveHandle">确定</el-button>
+        <el-button type="primary" plain style="width: 80px" @click="cancelHandle">取消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<style scoped lang="scss">
+
+</style>

+ 186 - 0
src/views/custom_manage/custom/components/historyContract.vue

@@ -0,0 +1,186 @@
+<script setup>
+import { reactive, ref, toRefs } from 'vue'
+import { ElImageViewer } from 'element-plus'
+import { useRouter } from 'vue-router'
+
+const props = defineProps({
+  isPreview:{
+      type:Boolean,
+      default:false
+  },
+  dealList:{
+      type:Array,
+      default:()=>{return []}
+  }
+})
+const emit = defineEmits(['close'])
+
+
+const $router = useRouter()
+
+const state = reactive({
+  ficcContractList:[],
+  raiContractList:[],
+  contractList:[],
+  contractType:'',
+  showViewer:false,
+  constractFileImgList:[]
+})
+
+function getContractList(){
+    state.ficcContractList = props.dealList.filter(i=>i.ProductId===1)
+    state.raiContractList = props.dealList.filter(i=>i.ProductId===2)
+    changeContractType('ficc')
+    if(!state.ficcContractList.length&&state.raiContractList.length){
+        changeContractType('rai')
+    }
+}
+
+function changeContractType(type){
+    if(state.contractType===type) return 
+    state.contractType = type
+    type==='ficc'&&(state.contractList=state.ficcContractList)
+    type==='rai'&&(state.contractList=state.raiContractList)
+}
+
+function showContractFiles(data){
+    state.constractFileImgList = []
+    const {constractFiles} = data
+    const imageList = constractFiles.filter(i=>i.type==='img')
+    const wordList = constractFiles.filter(i=>i.type==='word')
+    const pdfList = constractFiles.filter(i=>i.type==='pdf')
+    imageList.forEach(i=>{
+        state.constractFileImgList.push(i.url)
+    })
+    
+    if(state.constractFileImgList.length){
+        state.showViewer = true
+    }
+}
+
+function preViewConstractFile(data,list=[]){
+    state.constractFileImgList = []
+    if(data.type==='word'){
+        window.open('https://view.officeapps.live.com/op/view.aspx?src='+data.url,'_blank');
+    }
+    if(data.type==='pdf'){
+        window.open(data.url);
+    }
+    if(data.type==='img'){
+        //改变list的顺序,当前点击的为第一个
+        list.filter(i=>i.type==='img').map(i=>{state.constractFileImgList.push(i.url)})
+        const index = state.constractFileImgList.findIndex(url=>url===data.url)
+        state.constractFileImgList = [...state.constractFileImgList.slice(index),...state.constractFileImgList.slice(0,index)]
+        if(state.constractFileImgList.length){
+            state.showViewer = true
+        }
+    }
+}
+
+function showExpand(index,type='root'){
+    type==='root'&&(state.contractList[index].extend = !state.contractList[index].extend)
+    type==='files'&&(state.contractList[index].filesExtend = !state.contractList[index].filesExtend)
+    state.contractList.splice(index,1,state.contractList[index])
+}
+
+function toContractDetail(item){
+    if(!item.ContractId) return 
+    const { href } = $router.resolve({path:'/contractdetail',query:{contractId:item.ContractId}})||{href:''}
+    href&&window.open(href, '_blank');
+}
+
+const {
+  contractList,
+  contractType,
+  showViewer,
+  constractFileImgList
+} = toRefs(state)
+</script>
+<template>
+  <!-- 历史签约弹窗 -->
+  <div class="history-contract-wrap">
+      <el-dialog
+      :model-value="isPreview"
+      :modal-append-to-body='false'
+      @close="emit('close')"
+      title="历史签约"
+      center
+      top="7vh"
+      draggable
+      width="1200px">
+          <div class="dialog-wrap">
+              <div class="contract-tab">
+                  <span :class="{'active':contractType==='ficc'}" @click="changeContractType('ficc')">FICC</span>
+                  <span :class="{'active':contractType==='rai'}" @click="changeContractType('rai')">权益</span>
+              </div>
+              <div class="contract-list">
+                  <div class="contract-item" v-for="(item,index) in contractList" :key="item.ContractCode">
+                      <div class="contract-tag">
+                          <el-tag>
+                              {{item.ContractType}}
+                              <el-tooltip
+                              class="item" 
+                              effect="dark"
+                              v-if="item.ContractType!='补充协议'"
+                              placement="top-start">
+                                <template #content>
+                                  <div v-if="item.ContractType=='新签合同'">没有正式转试用记录的客户,在申请转正时提交的合同</div>
+                                  <div v-if="item.ContractType=='续约合同'">
+                                      1、有正式转试用记录的客户,在申请转正时提交的合同<br>
+                                      2、所有客户在续约申请时提交的合同
+                                  </div>
+                                </template>
+                                <i class="el-icon-info"></i>
+                              </el-tooltip>
+                          </el-tag>
+                          <span :style="{'text-decoration-line':item.ContractId?'underline':'none'}" @click="toContractDetail(item)">合同编号:{{item.ContractCode}}</span>
+                      </div>
+                      <div class="line"></div>
+                      <!-- 合同基本信息 -->
+                      <div class="contract-base">
+                          <ul class="base-lise">
+                              <li><p>合同期限:{{item.StartDate+'~'+item.EndDate}}</p><p>合同金额:{{item.Money}}</p></li>
+                              <li><p>付款方式:{{item.PayMethod}}</p><p>付款渠道:{{item.PayChannel}}</p></li>
+                              <li><p>审批时间:{{item.ModifyTimeStr}}</p><p></p></li>
+                          </ul>
+                      </div>
+                      <!-- 权限设置和查看附件 -->
+                      <div class="contract-info">
+                          <div @click="showExpand(index,'root')">权限设置 <span><i :class="item.extend?'el-icon-arrow-down':'el-icon-arrow-right'"></i></span></div>
+                      </div>
+                      <div class="contract-root" v-show="item.extend">
+                          <ul class="menu_lists">
+                              <li v-for="auth in item.PermissionList" :key="auth.ClassifyName" class="menu_item">
+                                  <el-checkbox :indeterminate="auth.CheckList.length>0&&auth.CheckList.length<auth.Items.length" v-model="auth.CheckAll" disabled style="marginRight:30px;fontWeight:bold;">{{auth.ClassifyName+':'}}</el-checkbox>
+                                  <el-checkbox-group v-model="auth.CheckList" disabled>
+                                      <el-checkbox v-for="list in auth.Items" :label="list.ChartPermissionId" :key="list.ChartPermissionId" class="list_item">{{list.PermissionName}}</el-checkbox>
+                                  </el-checkbox-group>
+                              </li>
+                          </ul>
+                      </div>
+                      <div class="contract-info">
+                          <div @click="showExpand(index,'files')">合同附件 <span><i :class="item.filesExtend?'el-icon-arrow-down':'el-icon-arrow-right'"></i></span></div>
+                      </div>
+                      <div class="contract-files" v-show="item.filesExtend">
+                          <ul class="file-list">
+                              <li v-for="img in item.constractFiles" :key="img">
+                                  <img :src="require('@/assets/img/constract/word-icon.png')" v-if="img.type=='word'" @click="preViewConstractFile(img)"/>
+                                  <img :src="require('@/assets/img/constract/pdf.png')" v-else-if="img.type=='pdf'" @click="preViewConstractFile(img)"/>
+                                  <img :src="img.url" v-else-if="img.type=='img'" @click="preViewConstractFile(img,item.constractFiles)"/>
+                              </li>
+                          </ul>
+                      </div>
+                  </div>
+                  <span v-if="!contractList.length" style="font-size:16px;color:#999;">暂无历史合同</span>
+              </div>
+          </div>
+          <el-image-viewer 
+              v-if="showViewer" 
+              @close="()=>{this.showViewer = false}" 
+              :url-list="constractFileImgList" />
+      </el-dialog>
+  </div>
+</template>
+<style scoped lang="scss">
+
+</style>

文件差異過大導致無法顯示
+ 910 - 35
src/views/custom_manage/custom/customDetail.vue


+ 1143 - 2
src/views/custom_manage/custom/customList.vue

@@ -1,10 +1,1151 @@
+<script>
+import { defineComponent } from 'vue'
+export default defineComponent({
+  //进入前是否清除参数
+  beforeRouteEnter(to, from, next) {
+    if(!['/editCustom','/turnCustom','/updateCustom','/customDetail'].includes(from.path)) {
+      sessionStorage.removeItem('customListBack')
+    }
+    
+		next()
+  }
+})
+</script>
+
 <script setup>
 import { ref } from 'vue'
+import { useRoute,useRouter } from 'vue-router'
+import { Search,MoreFilled } from '@element-plus/icons-vue'
+import { ElMessageBox,ElMessage } from 'element-plus'
+import { customInterence } from '@/api/api.js'
+import { useViewPermissionDia,useLookTrialDia,useCommunicaRecordDia,useChooseContractDia,useList,useAddTrialDia,useViewRemarkCustomDia,useCompleteInfoDia,useFreezeReasonDia } from "./hooks/customlistHook";
+import mPage from '@/components/mPage.vue'
+
+// import Capplydia from '../compontents/Capplydialog.vue'
+// import Contactdia from '../compontents/Contactdialog'
+// import Cauthlist from '../compontents/CauthList.vue'
+// import CompleteInfo from '../compontents/CompleteInfo.vue'
+// import ContractInfo from '../compontents/ContractInfo.vue'
+// import {locationOptions} from "./location"
+// import AccumulativeFrequencyDlg from '../compontents/accumulativeFrequencyDlg.vue'
+// import ModifyToDoDialog from '../compontents/ModifyToDoDialog.vue'
+// import CheckToDoDialog from '../compontents/CheckToDoDialog.vue'
+// import HistoryToDoDialog from '../compontents/HistoryToDoDialog.vue'
+// import permissionView from './components/permissionView.vue'
+// import TotalDayDialog from '../compontents/TotalDayDialog.vue'
+// import ShareListDialog from './components/shareListDialog.vue'
+
+const $router = useRouter()
+const $route = useRoute()
+
+
+const { 
+  suspendHandle,
+  editHandle,
+  Role,
+  RaiSellerRole,
+  RoleType,
+  RoleIdentity,
+  SellerAdminId,
+} = useList();
+
 
+function initData() {
+		if(sessionStorage.getItem('customListBack')) {
+			let backData = JSON.parse(sessionStorage.getItem('customListBack'));
+			this.search_txt = backData.keyword;
+			this.page_no = backData.page_no,
+			this.act_status = backData.act_status,
+			this.type = backData.type,
+			this.trade = backData.trade,
+			this.sales = backData.sales,
+			this.variety = backData.variety,
+			this.date = backData.date,
+			this.start_date = backData.start_date,
+			this.end_date = backData.end_date,
+			this.createdate = backData.createdate,
+			this.search_txt = backData.keyword,
+			this.setmealSelect =backData.setmealSelect,
+			this.valueLocation=JSON.parse(backData.valueLocation)
+			this.todoType = backData.todoStatus  
+			// const arr =[]
+			// this.valueLocation.forEach(item=>{
+			// 		arr.push(item.join(''))
+			// })
+			// this.locationValue=arr.join(',')
+			handleChangeLocation()
+		}
+		getSale();
+	
+		// 从客户区域统计列表过来的参数
+		this.act_status=this.$route.params.Status ? this.$route.params.Status : this.act_status
+		this.type = this.$route.params.CompanyType ? this.$route.params.CompanyType : this.type
+		this.act_trialTag = this.$route.params.TryStage ? this.$route.params.TryStage : this.act_trialTag
+		this.valueLocation = this.$route.params.valueLocation ? 
+		JSON.parse(sessionStorage.getItem('regionData')) || [] :[]
+
+		if($route.query.adminId){
+			this.isShowloadding = true
+			this.getSaleByAdminId();
+		}else if(this.valueLocation.length>0){
+			this.handleChangeLocation()
+			sessionStorage.removeItem('regionData')
+		}else{
+			this.getTableData();
+		}
+		this.getmodifySale();
+}
 </script>
 <template>
-  <div></div>
+  <div class="customList_container" ref="cusContainer">
+		<div class="customList_bot_top">
+			<div>
+				<div v-if="Role!='finance'">
+				<el-button type="primary" @click="addCustom" style="marginRight:10px;width:80px;" v-if="AddCompanyBtn">新增</el-button>
+				<!-- <a :href="exportUrlDl" download>
+					<el-button type="primary" plain style="width:100px;marginRight:10px;">导出客户</el-button>
+				</a>
+				<a :href="exportUserDl" download>
+					<el-button type="primary" plain style="width:110px;">导出联系人</el-button>
+				</a> -->
+				</div>
+			</div>
+			<el-input
+			placeholder="客户名称/社会信用码/手机号码/邮箱"
+			v-model="search_txt"
+			style="max-width:520px"
+			@input="searchHandle"
+			clearable>
+        <template #prefix>
+          <el-icon><Search/></el-icon>
+        </template>
+			</el-input>
+		</div>
+		<div class="customList_bot">
+			<div class="customList_top">
+				<el-row :span="24">
+					<el-select v-model="fromArea" placeholder="请选择所属区域" style="width:200px;marginRight:10px;marginBottom:8px;" clearable @change="changeFromArea">
+						<el-option
+							v-for="item in areaArr"
+							:key="item"
+							:label="item.name"
+							:value="item.name">
+						</el-option>
+					</el-select>
+					<el-select v-model="type" placeholder="请选择客户类型" style="width:200px;marginRight:10px;marginBottom:8px;" clearable v-if="Role=='finance'||Role=='admin'" @change="changeType">
+						<el-option
+							v-for="item in typeArr"
+							:key="item"
+							:label="item.name"
+							:value="item.name">
+						</el-option>
+					</el-select>
+					<el-select v-model="trade" placeholder="请选择行业" style="width:200px;marginRight:10px;marginBottom:8px;" clearable @change="changeTrade">
+						<el-option
+							v-for="item in tradeArr"
+							:key="item.IndustryId"
+							:label="item.IndustryName"
+							:value="item.IndustryId">
+						</el-option>
+					</el-select>
+					<el-cascader
+						v-if="this.act_status=='流失' ||(Role=='finance'||Role=='admin'||Role=='ficc_admin'||Role=='rai_admin'||ManageType!=0)"
+						v-model="sales"
+						placeholder="请选择销售"
+						style="width:200px;marginRight:10px;marginBottom:8px;"
+						:options="salesArr"
+						:props="defaultSalesProps"
+						:show-all-levels="false"
+						:key="modifySales"
+						collapse-tags
+						clearable
+						filterable
+						@change="changeSales">
+					</el-cascader>
+					<el-select v-model="setmealSelect" placeholder="请选择套餐类型" style="width:200px;marginRight:10px;marginBottom:8px;" clearable @change="changeTrade">
+						<el-option
+							v-for="item in setmealArr"
+							:key="item.id"
+							:label="item.name"
+							:value="item.id">
+						</el-option>
+					</el-select>
+					<el-cascader
+						v-model="variety"
+						placeholder="请选择已购品种"
+						style="width:200px;marginRight:10px;marginBottom:8px;"
+						:options="varietyArr"
+						:props="defaultprops"
+						:show-all-levels="false"
+						collapse-tags
+						clearable
+						filterable
+						@change="changeVariety">
+					</el-cascader>
+                    <el-cascader
+						v-model="variety_red"
+						placeholder="请选择阅读权限"
+						style="width:200px;marginRight:10px;marginBottom:8px;"
+						:options="varietyArr"
+						:props="defaultprops"
+						:show-all-levels="false"
+						collapse-tags
+						clearable
+						filterable
+						@change="changeVariety">
+					</el-cascader>
+					<el-cascader v-model="valueLocation" collapse-tags :props="locationProps" clearable :options="locationOptions"  @change="handleChangeLocation" 
+            placeholder="请选择客户地址" style="width:200px;marginRight:10px;marginBottom:8px;">
+          </el-cascader>
+					<date-picker 
+						v-model="date" 
+						type="date" 
+						range
+						value-type="format"
+						placeholder="服务日期" 
+						@change="dateChange" 
+						style="width:200px;marginRight:10px;marginBottom:8px;">
+					</date-picker>
+					<date-picker 
+					v-model="createdate" 
+					type="date" 
+					range
+					value-type="format"
+					placeholder="创建时间" 
+
+					@change="dateChange2" style="width:200px;marginRight:10px;marginBottom:8px;">
+					</date-picker>
+					<el-select v-model="todoType" placeholder="请选择任务状态" clearable @change="changeTodoType" style="width:200px;marginRight:10px;marginBottom:8px;">
+						<el-option
+							v-for="item in todoTypeArr"
+							:key="item.id"
+							:label="item.name"
+							:value="item.name">
+						</el-option>
+					</el-select>
+				</el-row>
+			</div>
+			<ul class="tabs_cont">
+				<li :class="['tab',{'act':act_status === item.Status}]" v-for="(item,index) in tabs" :key="index" @click="changeStatus(item,index)">
+					{{item.Status+'('+item.Count+')'}}
+				</li>
+			</ul>
+			<ul class="tabs_cont trial-ul" v-if="act_status === '试用'">
+				<li :class="['trial-item',{'act':act_trialTag === item.TryStage}]" v-for="item in trialTagArr" :key="item.TryStage" @click="changeTagStatus(item)">
+					{{item.TryStageStr+'('+item.Count+')'}}
+				</li>
+			</ul>
+			<div class="bot_cont">
+				<el-table
+				ref="userTable"
+				:data="tableData"
+				v-loading="isShowloadding"
+				element-loading-text="数据加载中..."
+				@sort-change="sortChangeHandle"
+				border>
+					<el-table-column
+					prop="CompanyName"
+					label="客户名称"
+					align="center"
+					min-width="7.14%"
+					>
+						<template #default="scope"> 
+              <div :class="{'isShared':scope.row.IsShared}">
+                <span 
+                  v-if="scope.row.IsSuspend ===1 || scope.row.Status=='潜在'"
+                  @click="goDetail(scope.row)"
+                  class="mouse-enter"
+                  :class="{'color-red':act_status==='正式'&&scope.row.Status.includes('正式')&&scope.row.WeekViewActive===0}"
+                  :style="scope.row.Status=='潜在'?'':'color:#bbb;cursor:pointer'"
+                >
+                  {{scope.row.CompanyName}}
+                </span>
+                <span 
+                  v-else 
+                  style="color:#409EFF;cursor:pointer;" 
+                  @click="goDetail(scope.row)" 
+                  class="customName"
+                  :class="{'isShared':scope.row.IsShared,'color-red':act_status==='正式'&&scope.row.Status.includes('正式')&&scope.row.WeekViewActive===0}"
+                >{{scope.row.CompanyName}}</span>
+                <img width="15" src="../../../assets/img/icons/remark.png" alt="" v-if="scope.row.RenewalReason||(scope.row.Status==='冻结'&&scope.row.FreezeReason)">
+
+                <el-tooltip content="此客户存在长期且反复申请试用,但从未签约的情况,请谨慎领取" placement="top" :open-delay="500" 
+                v-if="RaiSellerRole && scope.row.IsScrounge == 1">
+                  <img width="16" style="cursor: pointer;" src="../../../assets/img/icons/warning_triangle_yellow.png" />
+                </el-tooltip>
+              </div>
+						</template>
+					</el-table-column>
+					<el-table-column label="To-Do" prop="todo" align="center" min-width="5.14%" sortable="custom">
+						<template #header>
+							<div class="todolabel" :class="{sort:SortByTodo}" style="display:inline-block;">
+								<span>To-Do</span>
+							</div>
+						</template>
+						<template #default="scope">
+							<div class="todo-btn">
+								<p class="hint" :style="`background-color:${getTodoBtnColor(scope.row.TodoButtonColor)}`"></p>
+								<div class="btnwrap">
+									<span class="item" 
+									v-for="item in getToDoBtn(scope.row)" 
+									:key="item.key"
+									:style="item.style"
+									@click="!item.disable&&handleToDoBtnClick(scope.row,item.key)"
+									>{{item.label}}</span>
+								</div>
+							</div>
+						</template>
+					</el-table-column>
+					<el-table-column label="DL" prop="deadline" align="center" min-width="5%" sortable="custom">
+						<template #header>
+							<div class="todolabel" :class="{sort:sort_param==='deadline'}" style="display:inline-block;">
+								<span>DL</span>
+								<el-tooltip 
+									effect="dark" 
+									placement="top-start"
+									content="未完成To Do任务的截止日期-当前日期"
+								>
+									<i class="el-icon-info"/>
+								</el-tooltip>
+								<!-- <img :src="todoSrc" style="margin-left:3px;width:16px;height:16px;padding:3px;"/> -->
+							</div>
+						</template>
+						<template #default="{row}">
+							<span>{{row.Deadline||'--'}}</span>
+      			</template>
+					</el-table-column>
+					<el-table-column
+            prop="CompanyType"
+            label="类型"
+            align="center"
+            min-width="4.14%"
+					>
+						<template #default="{row}"> 
+
+							<template v-if="row.CompanyType.indexOf('/')!==-1">
+								<span :style="row.IsSuspend===1?'color:#bbb':''">{{row.CompanyType.split('/')[0]}}</span><br/>
+								<span v-if="row.FiccPackageType"  class="ficc-package">{{row.FiccPackageType == 1 ? '大套餐': '小套餐'}}</span>
+								<br   v-if="row.FiccPackageType"/>
+								<span :style="row.IsSuspend===1?'color:#bbb':''">{{row.CompanyType.split('/')[1]}}</span>
+							</template>
+							<template v-else>
+								<span :style="row.IsSuspend===1?'color:#bbb':''">{{row.CompanyType}}</span>
+								<span v-if="row.FiccPackageType&&row.CompanyType.includes('ficc')"  class="ficc-package">{{row.FiccPackageType == 1 ? '大套餐': '小套餐'}}</span>
+							</template>
+						</template>
+					</el-table-column>
+					<el-table-column
+					prop="IndustryName"
+					label="所属行业"
+					min-width="6.14%"
+					align="center">
+						<template #default="scope"> 
+							<!-- <span :style="scope.row.IsSuspend===1?'color:#bbb':''">{{scope.row.IndustryName}}</span>  -->
+							<div :style="scope.row.IsSuspend===1?'color:#bbb':''">
+								<p :style="scope.row.IsSuspend===1?'color:#bbb':''" v-for="item in scope.row.IndustryName.split('/')" :key="item">{{item}}</p>
+							</div> 
+						</template>
+					</el-table-column>
+					<el-table-column
+					prop="City"
+					label="客户地址"
+					min-width="6.14%"
+					align="center">
+						<template #default="scope">
+						<!--  <span v-if="scope.row.Province && scope.row.City" :style="scope.row.IsSuspend===1?'color:#bbb':''">{{scope.row.Province+'/'+scope.row.City}}</span> --> 
+						 <span v-if="scope.row.Province && scope.row.City" :style="scope.row.IsSuspend===1?'color:#bbb':''">{{scope.row.Province}}<br/>{{scope.row.City}}</span> 
+						 <span v-else :style="scope.row.IsSuspend===1?'color:#bbb':''">{{scope.row.RegionType}}</span> 
+						 </template>
+					</el-table-column>
+					<el-table-column
+					prop="SellerName"
+					label="销售"
+					min-width="6.14%"
+					align="center">
+						<template #default="scope"> 
+							<!-- <span :style="scope.row.IsSuspend===1?'color:#bbb':''">{{scope.row.SellerName}}</span>  -->
+							<p :style="scope.row.IsSuspend===1?'color:#bbb':''" v-for="item in scope.row.SellerName.split('/')" :key="item">{{item}}</p>
+						</template>
+					</el-table-column>
+					<el-table-column
+					prop="Status"
+					label="状态"
+					min-width="7.14%"
+					align="center" :sortable="act_status==='试用'&&act_trialTag===0?'custom':false" style="background:red">
+					<template #header>
+							<div class="todolabel" :class="{sort:sort_param==='tryStage'}" style="display:inline-block;">
+								<span>状态</span>
+							</div>
+					</template>
+					<template #default="scope"> 
+						<!-- <span :style="scope.row.IsSuspend===1?'color:#bbb':''">{{scope.row.Status+(scope.row.ApproveStatus?'('+scope.row.ApproveStatus+')':'')}}</span>  -->
+						<p :style="scope.row.IsSuspend===1?'color:#bbb;margin:3px 0':'margin:3px 0'" v-for="(item,index) in scope.row.Status.split('/')" :key="item">
+							{{ item }}
+							<template v-if="item === '试用' && scope.row.TryStageSlice">
+								<el-select 
+									v-model="scope.row.TryStageSlice[index].TryStage" 
+									v-if="scope.row.Status === '试用/试用'"
+									:disabled="!scope.row.TryStageSlice[index].HasPermission"
+									size="mini" 
+									style="width: 50px" 
+									placeholder=""
+									@change="changeTrialHandle(scope.row,scope.row.TryStageSlice[index])"
+								>
+									<el-option
+										v-for="item in trialTags"
+										:key="item.value"
+										:label="item.label"
+										:value="item.value">
+									</el-option>
+								</el-select>
+								<el-select 
+									v-model="scope.row.TryStageSlice[0].TryStage"
+									:disabled="!scope.row.TryStageSlice[0].HasPermission"
+									v-else
+									size="mini" 
+									style="width: 50px" 
+									placeholder=""
+									@change="changeTrialHandle(scope.row,scope.row.TryStageSlice[0])"
+								>
+									<el-option
+										v-for="item in trialTags"
+										:key="item.value"
+										:label="item.label"
+										:value="item.value">
+									</el-option>
+								</el-select>
+							</template>
+						</p>
+						<!-- 共享客户显示咨询组销售 -->
+						<span v-if="scope.row.IsShare==1 && scope.row.ShareSeller">{{ scope.row.ShareSeller }}</span>
+					</template>
+					</el-table-column>
+          <el-table-column
+					label="累计试用天数"
+					align="center"
+					min-width="5.14%"
+					prop="tryOutDay"
+					sortable="custom">
+						<template #default="{row}">
+							<el-tooltip :disabled="row.IsSuspend===1||(row.FiccTryOutDay+row.RaiTryOutDay===0)">
+                <template #content>
+                  <div>
+                    <p v-if="row.FiccTryOutDay">FICC累计试用天数:{{row.FiccTryOutDay}}</p>
+                    <p v-if="row.RaiTryOutDay">权益累计试用天数:{{row.RaiTryOutDay}}</p>
+                  </div>
+                </template>
+								<span :style="row.IsSuspend===1?'color:#bbb':'color:#409EFF;cursor:pointer;'" @click="handleTotalDayClick(row)">
+									{{row.FiccTryOutDay+row.RaiTryOutDay}}
+								</span>
+							</el-tooltip>
+						</template>
+					</el-table-column>
+					<el-table-column
+					label="阅读"
+					align="center"
+					min-width="5.14%"
+					prop="viewTotal"
+					sortable="custom">
+						<template #default="{row}">
+							<el-tooltip :disabled="row.IsSuspend===1 || (row.FiccView+row.RaiView)===0">
+                <template #content>
+								  <div>
+                    <p v-if="row.FiccView">FICC报告阅读次数:{{row.FiccView}}</p><p v-if="row.RaiView">权益报告阅读次数:{{row.RaiView}}</p>
+                  </div>
+                </template>
+								<span :style="row.IsSuspend===1?'color:#bbb':'color:#409EFF;cursor:pointer;'">
+									<!-- {{row.FiccView+row.RaiView}} -->
+									<!-- 阅读次数拆分 -->
+									{{row.AllViewTotal}}
+								</span>
+							</el-tooltip>
+						</template>
+					</el-table-column>
+					<el-table-column
+					label="路演"
+					align="center"
+					min-width="5.14%"
+					prop="roadShowTotal"
+					sortable="custom">
+						<template #default="scope">
+							<span :style="scope.row.IsSuspend===1?'color:#bbb':''" @click="accumulativeFrequencyClick(scope)" class="editsty" v-if="scope.row.RoadShowTotal > 0">{{scope.row.RoadShowTotal}}</span>
+							<span  :style="scope.row.IsSuspend===1?'color:#bbb':''" v-else>{{scope.row.RoadShowTotal}}</span>
+						</template>
+					</el-table-column>
+					<el-table-column
+					label="最近阅读"
+					min-width="8.14%"
+					align="center"
+					prop="viewTime"
+					sortable="custom">
+						<template #default="scope">
+						 <p v-if="scope.row.FiccLastViewTime" :style="scope.row.IsSuspend===1?'color:#bbb':''">ficc: {{$moment(scope.row.FiccLastViewTime).format('YYYY.MM.DD')}}</p> 
+						 <p v-else-if="scope.row.RaiLastViewTime" :style="scope.row.IsSuspend===1?'color:#bbb':''">权益: {{$moment(scope.row.RaiLastViewTime).format('YYYY.MM.DD')}}</p>
+						 <p v-else :style="scope.row.IsSuspend===1?'color:#bbb':''">--</p> 
+						 </template>
+					</el-table-column>
+					<el-table-column
+					prop="EndDate"
+					:label="act_status=='冻结'?'冻结期限':'服务期限'"
+					align="center"
+					min-width="6.14%">
+						<template #default="scope">
+							<span :style="scope.row.IsSuspend===1?'color:#bbb':''">
+								<!-- 正常的时间显示 -->
+								<template v-if="scope.row.StartDate.indexOf('/')==-1">
+									<template v-if="act_status=='流失'">
+										创建时间:{{formatTime(scope.row.CreatedTime)}}
+									</template>
+									<template v-else-if="scope.row.Status == '永续'">
+										永久
+									</template>
+									<template v-else-if="act_status == '冻结'">
+										{{scope.row.FreezeStartDate}}~{{scope.row.FreezeEndDate}}
+									</template>
+									<template v-else>
+										{{scope.row.StartDate}}~{{scope.row.EndDate}}
+									</template>
+								</template>
+								<!-- 公用客户的时间显示 -->
+								<template v-else>
+									{{scope.row.StartDate.substr(0,10)}}~{{scope.row.EndDate.substr(0,10)}}/{{scope.row.StartDate.substr(11)}}~{{scope.row.EndDate.substr(11)}}
+								</template>
+							</span>
+						</template>
+					</el-table-column>
+					<el-table-column
+					prop="expireDay"
+					:label="act_status=='冻结'?'解冻':'到期'"
+					align="center"
+					min-width="5.14%"
+					sortable="custom">
+						<template #default="scope">
+							<span :style="scope.row.IsSuspend===1?'color:#bbb':''">
+								<template v-if="act_status=='冻结'">
+									{{scope.row.FreezeExpireDays||'--'}}
+								</template>
+								<template v-else>
+								 	{{scope.row.ExpireDay||'--'}}
+								</template>
+							</span> 
+						</template>
+					</el-table-column>
+					<el-table-column
+					prop="createTime"
+					:label="
+						act_status=='冻结'?'冻结时间'
+						:act_status=='正式'?'转正时间'
+						:act_status=='流失'?'流失时间'
+						:act_status=='关闭'?'关闭时间':'创建时间'"
+					sortable="custom"
+					align="center" min-width="6.14%">
+						<template #default="scope">
+							<span :style="scope.row.IsSuspend===1?'color:#bbb':''">
+								<template v-if="act_status=='冻结'">
+									{{$moment(scope.row.FreezeTime).format('YYYY.MM.DD')}}
+								</template>
+								<template v-else-if="act_status=='正式'">
+									{{$moment(scope.row.FormalTime).format('YYYY.MM.DD')}}
+								</template>
+								<template v-else-if="act_status=='流失'">
+									<!-- {{scope.row.LossTime?$moment(scope.row.LossTime.replaceAll('.','-')).format('YYYY.MM.DD'):''}} -->
+                                    {{scope.row.LossTime
+                                        ?(`${scope.row.LossTime.split('/')[0].substr(0,10)}`)
+                                        :''}}
+                                    {{scope.row.LossTime&&scope.row.IsShared&&scope.row.LossTime.split('/')[1]
+                                        ? `/${scope.row.LossTime.split('/')[1].substr(0,10)}`
+                                        :''}}
+								</template>
+								<template v-else-if="act_status=='关闭'">
+									{{$moment(scope.row.CloseTime).format('YYYY.MM.DD')}}
+								</template>
+								<template v-else>
+									{{$moment(scope.row.CreatedTime).format('YYYY.MM.DD')}}
+								</template>
+							</span> 
+						</template>
+					</el-table-column>
+					<el-table-column label="操作" align="center" min-width="7.14%">
+						<template #default="scope" v-if="!scope.row.ApproveStatus">
+							<!-- 新操作栏 -->
+							<div style="color:#4099ef; font-size:24px;display:flex;align-content: center;justify-content: center;align-items: center;">
+								<div class="tool" style="display: flex;flex-direction: column;">
+									<span :class="item==='BtnDelete'?'deletesty':'editsty'" style="margin: 0 5px;" @click.stop="itemclickHandle({type:btnName(item,scope.row),data:scope.row})"
+								v-for="item,index in btnList(scope.row.BtnItem,'front')" :key="index">{{btnName(item,scope.row)}}</span>
+								</div>
+								<el-dropdown size="medium" placement="bottom-start" @command="itemclickHandle"
+								v-if="btnList(scope.row.BtnItem,'back').length" style="height: 16px;">
+                    <span class="el-dropdown-link">
+                      <i class="el-icon-more el-icon--right"></i>  
+                    </span>
+                    <template #dropdown>
+                      <el-dropdown-menu>
+                        <el-dropdown-item :command="{type:btnName(item,scope.row),data:scope.row}" 
+                        v-for="item,index in btnList(scope.row.BtnItem,'back')" :key="index">
+                          <span>{{btnName(item,scope.row)}}</span>
+                        </el-dropdown-item>
+                      </el-dropdown-menu>
+                    </template>
+								</el-dropdown>
+							</div>
+						</template>
+					</el-table-column>
+          <template #empty>
+            <div style="lineHeight: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>
+          </template>
+				</el-table>
+				<div class="toolbar fixedbar">
+					<el-pagination 
+					layout="prev,pager,next" 
+					background
+					:current-page="page_no"
+					@current-change="handleCurrentChange"
+					:page-size="pageSize" 
+					@size-change="handleSizeChange" 
+					:total="total"
+					style="float:right;">
+					</el-pagination>
+				</div>
+			</div>
+		</div>
+
+		<!-- 申请弹窗 -->
+		<Capplydia
+		:isApply="isApply"
+		:title="applyTit"
+		:formdata="applyForm"
+		:contactFormData="contactFormData"
+		@cancelHandle="cancelHandle">
+		</Capplydia>
+
+		<!-- 查看权限弹窗 -->
+		<permissionView :isLook="isLook" :lookTitle="lookTitle" :lookAuthList="lookAuthList" :lookAuthListEquity="lookAuthListEquity"
+     @closeDia="closeDia"></permissionView>
+
+		<!-- 增开试用弹窗 -->
+		<el-dialog
+		v-model="isAddTrial"
+		:close-on-click-modal="false"
+		:modal-append-to-body='false'
+		@close="isAddTrial=false"
+		width="800px"
+		draggable
+		center>
+      <template #header>
+        <div style="display:flex;alignItems:center;">
+          <!-- <img :src="$icons.auth" style="color:#fff;width:16px;height:16px;marginRight:5px;"> -->
+          <span style="fontSize:16px;">增开试用(默认两个月)</span>
+        </div>
+      </template>
+			<Cauthlist
+			:autharr="authList"
+			:id="addTryId"
+			@addOver="addTryOver"
+			@close="isAddTrial=false"/>
+		</el-dialog>
+
+		<!-- 修改销售弹窗 -->
+		<el-dialog
+		draggable
+		v-model="isMove"
+		:close-on-click-modal="false"
+		:modal-append-to-body='false'
+		@close="cancelMove"
+		center
+		width="30%">
+      <template #header>
+        <div style="display:flex;alignItems:center;">
+          <img :src="$icons.edit" style="color:#fff;width:16px;height:16px;marginRight:5px;">
+          <span style="fontSize:16px;">修改销售</span>
+        </div>
+      </template>
+			<el-form :model="moveform" :rules="moveRule" ref="moveform" label-width="100px" style="marginTop:15px;">
+				<el-form-item label="客户名称" prop="name">
+					<span style="fontSize:16px;">{{moveform.companyName}}</span>
+				</el-form-item>
+				<el-form-item label="当前销售" prop="name">
+					<span style="fontSize:16px;">{{moveform.sellerName}}</span>
+				</el-form-item>
+				<el-form-item label="移至销售" prop="sale">
+					<el-cascader
+						v-model="moveform.sale"
+						placeholder="请选择修改的销售"
+						style="width: 70%"
+						:options="modifysalesArr"
+						:props="{multiple: false,label:'RealName',children:'ChildrenList',value:'AdminId'}"
+						:show-all-levels="false"
+						clearable
+						filterable>
+					</el-cascader>
+				</el-form-item>
+			</el-form>	
+			<div style="display:flex;justify-content:center;margin:75px 0 26px;">
+				<el-button type="primary" style="width:80px;marginRight:24px;" @click="saveMove">保存</el-button>
+				<el-button  style="width:80px;" @click="cancelMove">取消</el-button>
+			</div>
+		</el-dialog>
+
+		<!-- 添加联系人弹窗 -->
+		<Contactdia
+		:id="addCompanyId"
+		:title="'新增联系人'"
+		:userForm="diaform"
+		:custom_name="moveform.companyName"
+		:needCard="true"
+		:isShowclose="isShowclose"
+		:isPickLoss="isPickLoss"
+		:isPickSelf="isPickSelf"
+		:regionType="regionType"
+		:isAddContact="isAddContact"
+		@cancel="cancelConcatdia"
+		@addContactNext="addContactNext">
+		</Contactdia>
+
+		<!-- 冻结理由弹窗 -->
+		<el-dialog
+		v-model="isFreezeReason"
+		:close-on-click-modal="false"
+		:modal-append-to-body='false'
+		@close="closeFreezeReason"
+		width="800px"
+		draggable
+		center>
+      <template #header>
+        <div style="display:flex;alignItems:center;">
+          <img src="../../../assets/img/freeze-icon.png" alt="" width="16" style="margin-right:10px">
+          <span style="fontSize:16px;">冻结</span>
+        </div>
+      </template>
+			<el-input
+				type="textarea"
+				:rows="6"
+				placeholder="请输入冻结理由"
+				v-model="freezeData.reason">
+			</el-input>
+			<div style="text-align:center;margin:30px 0;">
+				<el-button type="primary" @click="handleConfirmFreeze">确定</el-button>
+				<el-button type="primary" plain @click="closeFreezeReason">取消</el-button>
+			</div>
+		</el-dialog>
+
+		<!-- 补全信息弹窗 -->
+		<CompleteInfo
+			:form="completeForm"
+			@cancel="cancelCompleteInfo($event)"
+		></CompleteInfo>
+
+		<!-- 申请转正、续约申请、补充协议选择申请合同模式弹窗 -->
+		<el-dialog
+			v-model="contractModel.show"
+			:modal-append-to-body='false'
+			width="800px"
+			class="self-dialog"
+			draggable
+		>
+			<div style="text-align:center;margin:30px 0 100px 0">
+				<img width="191" src="../../../assets/img/cus_m/bzht.png" @click="handleContractModel('标准')" style="margin-right:80px;cursor: pointer;">
+				<img width="191" src="../../../assets/img/cus_m/fbzht.png" @click="handleContractModel('非标准')" style="cursor: pointer;">
+				<p style="font-size:15px;color:#333;text-align:left;padding-left:100px;margin-top:30px">
+					注:<br>
+					系统生成合同请选择标准合同入口<br>
+					非系统生成合同请选择非标准合同入口(包含已走完邮件流程的标准合同)</p>
+			</div>
+		</el-dialog>
+
+		<!-- 申请转正、续约申请、补充协议标准合同模式下 合同信息弹窗 -->
+		<ContractInfo 
+			:initData="contractDialog" 
+			@contractInfoDialogClose="contractInfoDialogClose"
+		></ContractInfo>
+
+		<!-- 查看备注弹窗 -->
+		<el-dialog
+		v-model="isRemarkLook"
+		:close-on-click-modal="false"
+		:modal-append-to-body="true"
+		:append-to-body="true"
+		@close="closeDia"
+		width="800px"
+		draggable
+		center>
+      <template #header>
+        <div style="display:flex;alignItems:center;">
+          <img :src="$icons.auth" style="color:#fff;width:16px;height:16px;marginRight:5px;">
+          <span style="fontSize:16px;">{{lookRemarkTitle}}</span>
+        </div>
+      </template>
+			<template>
+				<div v-if="(RoleIdentity == 'rai_seller' || RoleIdentity == 'ficc_seller') || (SellerAdminId == lookRemarkItem.SellerId)">
+					<el-input
+						type="textarea"
+						:rows="3"
+						placeholder="请输入文字"
+						v-model="lookRemarkTextarea">
+					</el-input>
+					<div class="look-remark-commit" @click="lookRemarkAdd">保存</div>
+				</div>
+				<el-table
+          :data="lookRemarkList"
+          border
+          max-height="300"
+          style="width: 100%; margin-top: 20px;margin-bottom: 20px"
+        >
+          <el-table-column label="备注内容"  key="Remark"  align="center">
+            <template #default="scope">{{scope.row.Remark}}</template>
+          </el-table-column>
+          <el-table-column label="客户类型" align="center" key="ProductName" v-if="lookRemarkItem.IsShared && (RoleIdentity != 'rai_seller' && RoleIdentity != 'ficc_seller')">
+            <template #default="scope">{{scope.row.ProductName}}</template>
+          </el-table-column>
+          <el-table-column label="创建时间"  key="CreateTime" align="center">
+            <template #default="scope">{{scope.row.CreateTime}}</template>
+          </el-table-column>
+          <el-table-column label="操作" align="center">
+            <template #default="{row}">
+              <el-button type="text" size="small" style="color:red;" v-if="row.ButtonDel"
+                @click="lookRemarkDelete(row)">删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+			</template>
+			<div style="padding:20px 0;"></div>
+		</el-dialog>
+
+		<!-- 查看备注弹窗 -->
+		<accumulative-frequency-dlg :accumulativeFrequencyDlg="accumulativeFrequencyDlg" :accumulativeFrequencyItem="accumulativeFrequencyItem" />
+
+		<!-- 新建/编辑销售To Do的弹窗 -->
+		<Modify-to-do-dialog 
+			:todoInfo="todoInfo" 
+			:type="modifyToDoType"
+			:isModifyDialogShow="isModifyDialogShow"
+			@modify="handleModifyToDo"
+		></Modify-to-do-dialog>
+
+		<check-to-do-dialog 
+			:todoInfo="todoInfo" 
+			:ischeckToDoDialogShow="ischeckToDoDialogShow"
+			@check="handleApprove"
+		></check-to-do-dialog>
+
+		<history-to-do-dialog :todoInfo="todoInfo" :isHistoryDialogShow="isHistoryDialogShow"></history-to-do-dialog>
+
+    <!-- 累计试用天数弹窗 -->
+    <total-day-dialog 
+      :isTotalDayDialogShow="isTotalDayDialogShow"
+      :customInfo="customInfo"
+    />
+
+		<!-- 服务记录弹窗 -->
+		<share-list-dialog 
+			:isShareRecodeDialogShow="isShareRecodeDialogShow"
+			:customInfo="customInfo"
+			:allowEdit="false"
+			@close="isShareRecodeDialogShow=false"/>
+
+		<!-- 关闭客户弹窗 -->
+		<el-dialog
+      v-model="isCloseCustomDialogShow"
+      :close-on-click-modal="false"
+      :modal-append-to-body='false'
+      title="关闭"
+      @close="isCloseCustomDialogShow=false"
+      width="800px"
+      draggable
+      center
+    >
+			<div class="close-custom-dialog">
+				<p>是否确认将试用客户【{{customInfo.CompanyName}}】转为关闭客户?若关闭,请填写关闭理由!</p>
+				<textarea  rows="6" v-model="closeReason" placeholder="关闭理由描述"></textarea>
+				<div class="btn-list">
+					<el-button type="primary" plain @click="isCloseCustomDialogShow=false">取消</el-button>
+					<el-button type="primary" @click="closeCustom">确定</el-button>
+				</div>
+				
+			</div>
+		</el-dialog>
+	</div>
 </template>
-<style scoped lang="scss">
+<style lang='scss' scoped>
+	.self-dialog{
+		width: 100% !important;
+		max-width: 100% !important;
+		:deep(.el-dialog__header){
+			background-color: #fff;
+			.el-dialog__close.el-icon.el-icon-close{
+				color: #666;
+			}
+		}
+	}
+	.ficc-package {
+		display: inline-block;
+		font-size: 12px;
+		padding:0 5px;
+		border-radius: 5px;
+		color: #3994fb;
+		background-color: #dcecfc;
+	}
+  .color-red{
+    color:red !important;
+  }
+	.isShared::after{
+		content: '共享';
+		font-size: 12px;
+		// padding: 0px 0px 0px 2px;
+		width: 30px;
+		color: #3994fb;
+		background-color: #dcecfc;
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		border-top-right-radius: 5px;
+	}
+.customList_container {
+	:deep(.mx-datepicker) {
+		width: 200px !important;
+	}
+	:deep(.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner) {
+		background-color: #409EFF !important;
+		border-color: #409EFF;
+	}
+	:deep(.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner) {
+		background-color: #409EFF !important;
+		border-color: #409EFF;
+	}
+	.customList_bot_top {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 28px;
+		padding: 20px 30px;
+		background: #fff;
+		border: 1px solid #ECECEC;
+		border-radius: 4px;
+		box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+	}
+	.customList_bot {
+		min-height: calc(100vh - 324px);
+		padding: 20px 30px 80px;
+		background: #fff;
+		position: relative;
+		border: 1px solid #ECECEC;
+		border-radius: 4px;
+		box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+		.customList_top {
+			padding: 20px 0 30px;
+			background: #fff;
+			.el-cascader__search-input{
+				min-width: 30px;
+			}
+		}
+		.tabs_cont {
+			display: flex;
+			align-items: center;
+			color: #333;
+			margin-bottom: 30px;
+			&.trial-ul {
+				padding: 0 30px;
+			}
+			
+			.tab {
+				width: 129px;
+				height: 22px;
+				line-height: 22px;
+				text-align: center;
+				font-size: 14px;
+				border-right:1px solid #707070;
+				cursor: pointer;
+				transition-delay: 0.05s;
+				&:hover {
+					color: #409EFF;
+				}
+				&.act {
+					// padding: 9px 24px;
+					height: 40px;
+					line-height: 40px;
+					background: #409EFF;
+					border-radius: 4px;
+					color: #fff;
+					border-color: #409EFF;
+					transform: scale(1.014);
+				}
+				&:last-child {
+					border: none;
+				}
+			}
+			.trial-item {
+				cursor: pointer;
+				margin-right: 30px;
+				&:hover {
+					color: #409EFF;
+				}
+				&.act {
+					color: #409EFF;
+					position: relative;
+					&::after {
+						content: "";
+						width: 100%;
+						height: 2px;
+						position: absolute;
+						bottom: -10px;
+						left: 50%;
+						transform: translateX(-50%);
+						background: #409EFF;
+					}
+				}
+			}
+		}
+		.try_style {
+			color: #BBBBBB;
+		}
+		.bot_cont{
+			//padding-bottom: 20px;
+			.fixedbar{
+				position: fixed;
+    			right: 45px;
+    			bottom: 20px;
+				background-color: transparent;
+        z-index: 2;
+			}
+		}
+		.todo-btn{
+			display: flex;
+			justify-content: space-around;
+    		align-items: center;
+			/* padding: 0 10px; */
+			.hint{
+				width: 8px;
+				height: 8px;
+				background-color: #D1433A;
+				border-radius: 50%;
+			}
+			.btnwrap{
+				display: flex;
+				align-content: space-around;
+				flex-direction: column;
+				justify-content: space-between;
+				span.item{
+					margin-right: 10px;
+					font-size: 14px;
+					color:#409EFF;
+					cursor: pointer;
+					&:last-child{
+						margin-right: none;
+					}
+				}
+			}
+			
+			
+		}
+		.todolabel{
+			&+span.caret-wrapper{
+				.sort-caret.ascending{
+					border-bottom-color: #C0C4CC;
+				}
+				.sort-caret.descending{
+					border-top-color: #C0C4CC
+				}
+			}
+		}
+		.todolabel.sort{
+			&+span.caret-wrapper{
+				.sort-caret.ascending{
+					border-bottom-color: #409EFF;
+				}
+			}
+		}
+		.todolabel.hidden{
+			&+span.caret-wrapper{
+				display: none;
+			}
+		}
+	}
+	.menu_lists {
+		padding: 40px 18px;
+		border-radius: 4px;
+		.menu_item {
+			display: flex;
+			// align-items: center;
+			margin-bottom: 30px;
+			&:last-child {
+				margin-bottom: 0;
+			}
+			.list_item {
+				margin-right: 20px;
+				margin-bottom: 10px;
+				&:last-child {
+					margin-right: 0;
+				}
+			}
+		}
+	}
+	.mouse-enter {
+		&:hover {
+			text-decoration:underline;
+		}
+	}
+	.close-custom-dialog{
+		padding: 0 20px;
+		p{
+			font-weight: bold;
+			font-size: 16px;
+		}
+		textarea{
+			margin: 20px 0;
+			width:100%;
+			resize: none;
+			border-radius: 4px;
+			border:1px solid #DCDFE6;
+			box-sizing: border-box;
+			padding:15px;
+		}
+		.btn-list{
+			text-align: center;
+			margin: 25px 0;
+		}
+	}
+}
+</style>
 
+<style lang="scss" scoped>
+.customList_container {
+	:deep(.el-input--mini) {
+		.el-input__inner{
+			padding: 0 6px !important;
+			height: 24px;
+			line-height: 24px;
+			color: #409EFF;
+			background: #ECF5FF;
+			border-color: #409EFF;
+			text-align: center;
+		}
+		.el-input__suffix {
+			right: -22px;
+		}
+		&.is-disabled {
+			.el-input__inner {
+				border-color: #E4E7ED;
+			}
+			.el-input__suffix {
+				display: none;
+			}
+		}
+	}
+}
+</style>
+<style lang="scss" scoped>
+.look-remark-commit{
+	width: 426px;
+	height: 41px;
+	background: #409EFF;
+	margin:  30px auto;
+	text-align: center;
+	line-height: 41px;
+	color: #fff;
+	box-shadow: 0px 2px 6px 1px rgba(64, 158, 255, 0.05);
+	border-radius: 4px 4px 4px 4px;
+	cursor: pointer;
+}
 </style>

+ 10 - 3
src/views/custom_manage/custom/hooks/customlistHook.js

@@ -106,7 +106,10 @@ export function useList() {
 		let type = localStorage.getItem('AdminId') || '';
 		return type;
 	})
-
+	//管理权限
+	const ManageType = computed(() => {
+		return localStorage.getItem('ManageType') || '';
+	})
 
 	return {
 		btnCommandList,
@@ -122,7 +125,7 @@ export function useList() {
 		RoleType,
 		RoleIdentity,
 		SellerAdminId,
-
+		ManageType
 	}
 }
 
@@ -601,7 +604,11 @@ export function useMoveSaleDia() {
 	} 
 
 	return {
-
+		isMove,
+		moveRule,
+		moveform,
+		updateSale,
+		cancelMove
 	}
 }
 

+ 9 - 8
src/views/custom_manage/custom/updateServe.vue

@@ -38,11 +38,12 @@ const formRule = {
 }
 
 /* 获取历史签约 */
+const companyInfo = ref(JSON.parse(sessionStorage.getItem('companyInfo')) || {})//客户基本信息
 const dealList = ref([])//合同列表
 const isPreview = ref(false)//合同弹窗
 function getDealList() {
   customInterence.historydeal({
-    CompanyId:companyInfo.CompanyId,
+    CompanyId:companyInfo.value.CompanyId,
     CompanyType:companyInfo.value.CompanyType
   }).then(res => {
     if(res.Ret === 200) {
@@ -58,13 +59,13 @@ function getDealList() {
     }
   })
 }
+getDealList()
 /* 查看历史签约 */
 function previewHistory() {
   isPreview.value = true
 }
 
 
-const companyInfo = ref(JSON.parse(sessionStorage.getItem('companyInfo')) || {})//客户基本信息
 const pickerOptions = ref({})
 const dataForm = reactive({
   contract_type:$route.path=='/updateCustom'?'续约合同':'补充协议',
@@ -102,6 +103,8 @@ async function getLastedContractInfo(){
   }
   
 }
+getLastedContractInfo()
+
 // 续约申请处理数据
 function initUpdateTypeData() {
   	let RoleType=companyInfo.value.CompanyType
@@ -130,6 +133,7 @@ function formatDate(date){
 //选择时间 权益:续约合同期限与上一份合同期限有重叠时,不能勾选同一行业.
 		// 选择的时间和temContractData 中的时间比较 然后格式化权限选择列表
 function dateChange(){
+  if(!dataForm.term) return 
   if(parseInt((new Date() - new Date(dataForm.term[1]))/(1000*3600*24)) > 0) {
     ElMessage.error('结束日期不能小于今天!')
     dataForm.term = []
@@ -283,7 +287,7 @@ function getAuthBasic() {
           }
         })
         let obj = {
-          checkAll:item.Items.length>0?temarr.length==item.Items.length:false,
+          checkAll:item.Items.length>0?temarr.length===item.Items.length:false,
           isIndeterminate:item.Items.length>0?temarr.length==item.Items.length?false:item.Items.some(_e=>_e.IsPublic==1):false,
           ...item,
         }
@@ -446,7 +450,7 @@ function handleChecked(item) {
 
 /* 预览 */
 const isPreviewimg = ref(false)
-const	preAct = ref("")
+const	preAct = ref(0)
 const	isShowToggle = ref(false)//是否显示切换
 function preview(id,index,img) {
   // $('#'+id).click()
@@ -533,9 +537,6 @@ function fileSelected(){  //选择文件上传
 
 
 
-
-
-
 </script>
 <template>
   <div class="updateServer_container">
@@ -746,7 +747,7 @@ function fileSelected(){  //选择文件上传
 </template>
 <style scoped lang="scss">
 .updateServer_container {
-	min-width: 1570px;
+	/* min-width: 1570px; */
 	*{
 		box-sizing: border-box;
 	}

部分文件因文件數量過多而無法顯示