hbchen 2 år sedan
förälder
incheckning
31d6829da1

+ 16 - 0
src/api/crm.js

@@ -48,3 +48,19 @@ export function getContractSearchList(data) {
       params:data
   })
 }
+
+// 合同套餐及品种
+ /**
+  * 
+  * @param {
+ * contract_id - 合同ID - 必填
+ * } data 
+ * @returns 
+ */
+export function getServiceDetail(data) {
+ return request({
+     url:'/crm/contract/service_detail',
+     method:'get',
+     params:data
+ })
+}

+ 59 - 0
src/api/financialMana.js

@@ -142,4 +142,63 @@ export function registerDelete(data) {
   })
 }
 
+// 开票、到款列表
+//获取列表
+ /**
+  * 
+  * @param {
+ * page_size - 每页数据量 - 必填
+ * current - 页码 - 必填
+ * contract_code - 关键词-合同编号 - 非必填
+ * start_date - 开始日期:格式2022-11-22 - 非必填
+ * end_date - 结束日期:格式2022-11-22 - 非必填
+ * min_amount - 开票金额区间-最小值 - 非必填
+ * max_amount - 开票金额区间-最大值 - 非必填
+ * invoice_type - 类型: 1-开票登记; 2-到款登记 - 必填
+ * } data 
+ * @returns 
+ */
+export function getIandPList(data) {
+ return request({
+     url:'/contract/register/invoice_list',
+     method:'get',
+     params:data
+ })
+}
+//导出excel
+ /**
+  * 
+  * @param {
+ * contract_code - 关键词-合同编号 - 非必填
+ * start_date - 开始日期:格式2022-11-22 - 非必填
+ * end_date - 结束日期:格式2022-11-22 - 非必填
+ * min_amount - 开票金额区间-最小值 - 非必填
+ * max_amount - 开票金额区间-最大值 - 非必填
+ * invoice_type - 类型: 1-开票登记; 2-到款登记 - 必填
+ * } data 
+ * @returns 
+ */
+export function exportIandPList(data) {
+ return request({
+     url:'/contract/register/invoice_export',
+     method:'get',
+     responseType:'blob',
+     params:data
+ })
+}
 
+// 合规登记-导入
+ /**
+  * 
+  * @param {
+ * File - 文件formData - 必填
+ * } data 
+ * @returns 
+ */
+export function importDataApi(data) {
+ return request({
+     url:'/contract/register/import',
+     method:'post',
+     data
+ })
+}

+ 38 - 3
src/directives/modules/buttonPermisson.js

@@ -1,18 +1,53 @@
 // 权限指令
+/**
+ * 接受参数类型 - 字符串-单个权限
+ *             - 数组-多个权限 
+ * 数组最后一个参数为类型:or-只要一个满足 and-全部都满足
+ * 最后一个参数类型不为or或者and,类型默认为or,且会取全部的数组
+ * 
+ */
 import store from "@/store"
 
 export const permission={
   mounted(el,binding) {
     let {value} = binding
+    // 拿出所有按钮的code
+    let buttonCodes = store.getters.permissionButtons.map(item => item.button_code)
     if(value && typeof(value)=='string'){
-      // 拿出所有按钮的code
-      let buttonCodes = store.getters.permissionButtons.map(item => item.button_code)
+      // 字符类型
       if(!buttonCodes.includes(value)){
         // 没有权限,删除dom
         el.parentNode && el.parentNode.removeChild(el)
       }
+    }else if(Array.isArray(value)){
+      // 数组类型
+      /**
+       * 权限类型 type
+       * or-只要一个满足 and-全部都满足
+       */
+      let type;
+      let hasType=['or','and'].includes(value[value.length-1].toLocaleLowerCase())
+      if(hasType){
+        //参数中有标明type
+        type=value[value.length-1].toLocaleLowerCase()
+        // 去掉最后一个权限类型参数
+        value.pop()
+        // console.log(value,true);
+        let operation = type=='or'?'some':'every'
+        if(!value[operation](item => buttonCodes.includes(item))){
+          // 没有权限,删除dom
+          el.parentNode && el.parentNode.removeChild(el)
+        }
+      }else{
+        type='or'
+        // console.log(value,false);
+        if(!value.some(item => buttonCodes.includes(item))){
+          // 没有权限,删除dom
+          el.parentNode && el.parentNode.removeChild(el)
+        }
+      }
     }else{
-      throw new Error('permission指令只接受字符串类型')
+      throw new Error('permission指令参数类型错误')
     }
 
   },

+ 153 - 0
src/views/financialManagement/components/permissionDia.vue

@@ -0,0 +1,153 @@
+<script setup>
+
+import {getPermissionList} from '@/api/crm'
+  const props=defineProps({
+    visible:{
+      type:Boolean,
+      default:false
+    },
+    hasCheckedPermission:{
+      type:Array,
+      default:()=>[]
+    },
+    // view - 查看 edit - 编辑
+    type:{
+      type:String,
+      default:'view'
+    }
+  })
+
+  const emits=defineEmits(['update:visible','selectFinish'])
+
+  const permissionDia=reactive({
+    permissionList:[],
+    permissionChecked:[]
+  })
+
+  watch(()=>props.visible,(newVal)=>{
+    // console.log(newVal);
+    if(newVal){
+      // 初始化
+      permissionDia.permissionList.length>0&&permissionDia.permissionList.map(item=>{
+        item.check_list = [];
+        item.checked = false;
+        item.indeterminate = false;
+        item.Items?.map(it => {
+          it.checked=false
+        })
+      })
+      permissionDia.permissionChecked=[...props.hasCheckedPermission]
+      U:for (let i = 0,len=permissionDia.permissionChecked.length; i < len; i++) {
+        const chart_permission_id = +permissionDia.permissionChecked[i];
+        for (let j = 0,jLen=permissionDia.permissionList.length; j < jLen; j++) {
+          const element = permissionDia.permissionList[j];
+          let index=element.items.findIndex(it => it.chart_permission_id==chart_permission_id)
+          // console.log(index);
+          if(index!=-1){
+            element.items[index].checked=true
+            element.check_list.push(chart_permission_id)
+            continue U
+          }
+        }
+      }
+      permissionDia.permissionList.map(item=>{
+        permissionCheckedChange(item)
+      })
+    }
+  },{immediately:true})
+
+  // -------method
+  const getPermissionData=()=>{
+    // 获得所有的权限
+    getPermissionList().then(res=>{
+      let arr = res.data.List || []
+      arr.forEach((item) => {
+        item.check_list = [];
+        item.checked = false;
+        item.indeterminate = false;
+      });
+      permissionDia.permissionList=arr
+    })
+  }
+  const permissionCheckedChange=(e)=>{
+    e.checked = e.check_list.length == e.items.length
+    e.indeterminate = e.check_list.length>0 && e.check_list.length < e.items.length
+  }
+  const permissionAllChecked=(e)=>{
+    // console.log(e);
+    let arr = e.items.map((item) => {
+      return item.chart_permission_id;
+    });
+    e.check_list = e.checked ? arr : [];
+    e.indeterminate = false;
+  }
+ 
+  const submit=()=>{
+    permissionDia.permissionList.map(item =>{
+      permissionDia.permissionChecked=[...permissionDia.permissionChecked,...item.check_list]
+    })
+    emits('selectFinish',permissionDia.permissionChecked)
+    closeDia()
+  }
+
+  const closeDia=()=>{
+    emits('update:visible',false)
+  }
+
+  // --------------created
+  getPermissionData()
+</script>
+
+
+<template>
+    <div id="permission-container">
+      <el-dialog title="选择品种" :model-value="props.visible"
+       :close-on-click-modal="false" width="940" @close="closeDia">
+       <div class="variety-box" >
+        <div v-for="item in permissionDia.permissionList" class="variety-item" :key="item.classify_name" >
+            <el-checkbox v-model="item.checked" :indeterminate="item.check_list.length>0 && item.check_list.length < item.items.length" 
+              @change="permissionAllChecked(item)" :disabled="props.type=='view'">
+            {{item.classify_name}}:</el-checkbox>
+            <el-checkbox-group v-model="item.check_list" @change="permissionCheckedChange(item)" :disabled="props.type=='view'">
+              <el-checkbox :label="it.chart_permission_id" v-for="it in item.items" :key="it.chart_permission_id">{{it.permission_name}}</el-checkbox>
+            </el-checkbox-group>
+          </div>
+        </div>
+        <template #footer v-if="props.type!='view'">
+          <div class="permission-buttons-zone">
+            <el-button type="primary" @click="submit" style="color: white;">保存</el-button>
+            <el-button @click="closeDia">取消</el-button>
+          </div>
+        </template> 
+      </el-dialog>
+    </div>
+</template>
+  
+<style lang="scss" scoped>
+  #permission-container{
+    .variety-box{
+      padding: 10px 45px 0 45px;
+      .variety-item{
+        display: flex;
+        margin-bottom: 30px;
+        &:last-child{
+          margin-bottom: 0;
+        }
+      }
+    }
+    .permission-buttons-zone{
+      padding-bottom: 20px;
+    }
+  }
+</style>
+<style lang="scss">
+  #permission-container{
+    .el-checkbox-group{
+      margin-left:-16px ;
+      .el-checkbox{
+        margin-right: 0;
+        margin-left: 16px;
+      }
+    }
+  }
+</style>

+ 137 - 0
src/views/financialManagement/composition/IandPList.js

@@ -0,0 +1,137 @@
+
+import {useRouter} from 'vue-router'
+import {getIandPList,exportIandPList} from '@/api/financialMana'
+import { downloadByFlow } from '@/utils/common-methods'
+export default function getIandPListCom(type) {
+  const router = useRouter()
+
+  const placement=reactive({
+    searchParams:{
+      current:1,
+      page_size:10,
+      contract_code:'',
+      start_date:'',
+      end_date:'',
+      min_amount:'',
+      max_amount:'',
+      invoice_type:type
+    },
+    dateRange:[],
+    tableData:[],
+    total:0,
+    amountTotal:0
+  })
+
+
+  watch(()=>placement.dateRange,(newVal)=>{
+    // console.log(newVal);
+    if(newVal && newVal.length>0){
+      placement.searchParams.start_date=newVal[0]
+      placement.searchParams.end_date=newVal[1]
+    }else{
+      placement.searchParams.start_date=placement.searchParams.end_date=''
+    }
+    searchPlacement()
+  })
+
+  const placementList=()=>{
+    getIandPList(placement.searchParams).then(res=>{
+      // console.log(res);
+      placement.tableData=res.data.list || []
+      placement.total=res.data.page&&res.data.page.total || 0
+      let amount=placement.tableData.reduce((pre,item)=>{
+        return pre+item.amount
+      },0)
+      // 防止失真
+      placement.amountTotal=Math.round(amount*100)/100
+    })
+  }
+  
+  const searchPlacement=()=>{
+    console.log('search');
+    placement.searchParams.current = 1
+    placementList()
+  }
+  // 搜索项-开始金额和结束金额改变
+  const moneyChange=(value,prop)=>{
+    let trimValue = value.trim()
+    let numerValue=parseFloat(trimValue)
+    // 如果输入不是 以.结尾&&只有一个. 或者 不是零结尾的话,就赋值为转为成数字后的值
+    // 考虑到类似12.02的情况
+    if((value.endsWith('.') && value.indexOf('.')==(value.length-1)) || 
+    (value.endsWith('0') && value.indexOf('.')==(value.length-2))){
+      return
+    }
+    // console.log(numerValue);
+    if((!numerValue)&&trimValue&&numerValue!=0){
+      setTimeout(()=>{
+        placement.searchParams[prop]=''
+      },500)
+      ElMessage.warning('金额必须是数字')
+      return
+    }
+    if(numerValue<0){
+      setTimeout(()=>{
+        placement.searchParams[prop]=''
+      },500)
+      ElMessage.warning('金额必须大于等于零')
+      return
+    }
+    // if(!numerValue) return 
+    // 开始金额大于结束金额 就不查询
+    if(placement.searchParams.max_amount &&
+    placement.searchParams.min_amount &&
+      parseFloat(placement.searchParams.min_amount) > placement.searchParams.max_amount){
+      return 
+    }
+    placement.searchParams[prop]=numerValue || ''
+    searchPlacement()
+  }
+  // 搜索项-判断开始金额是否大于结束金额
+  const checkMoney=()=>{
+    if(placement.searchParams.max_amount &&
+    placement.searchParams.min_amount &&
+    parseFloat(placement.searchParams.min_amount) > placement.searchParams.max_amount){
+      ElMessage.warning('开始金额不能大于结束金额')
+    }
+  }
+
+  // 切换每页的数量
+  const changePageSize=(pageSize)=>{
+    placement.searchParams.page_size = pageSize
+    placementList()
+  }
+  const changePageNo = (pageNo)=>{
+    placement.searchParams.current = pageNo
+    placementList()
+  }
+  
+  const placementDetail=(row,detailType)=>{
+    router.push({path:'/financial/list/contractProgress',query:{type:detailType,complianceId:row.contract_register_id}})
+  }
+  const placementExport=()=>{
+    let params={
+      contract_code:placement.searchParams.contract_code,
+      start_date:placement.searchParams.start_date,
+      end_date:placement.searchParams.end_date,
+      min_amount:placement.searchParams.min_amount,
+      max_amount:placement.searchParams.max_amount,
+      invoice_type:type
+    }
+    exportIandPList(params).then(res=>{
+      let fileName = type==1?'开票列表':'到款列表'
+      downloadByFlow(res,'xlxs',fileName)
+    })
+  }
+  return {
+    data:placement,
+    placementList,
+    searchPlacement,
+    moneyChange,
+    placementExport,
+    placementDetail,
+    changePageNo,
+    changePageSize,
+    checkMoney
+  }
+}

+ 241 - 126
src/views/financialManagement/contractProgress.vue

@@ -1,10 +1,10 @@
 
 <script setup>
-  import serviceVarietyDia from './components/serviceVarietyDia.vue'
+  import permissionDia from './components/permissionDia.vue'
   import {useRouter,useRoute} from 'vue-router'
   import {useStore} from 'vuex'
   import {ElMessage} from 'element-plus'
-  import {getSellerList,getContractSearchList} from '@/api/crm'
+  import {getSellerList,getContractSearchList,getServiceDetail} from '@/api/crm'
   import {getServiceList,registerAdd,registerDetail,registerEdit,registerInvoice,registerPayment} from '@/api/financialMana'
   import scrollableSelect from '@/components/scrollable-select/index.vue'
 
@@ -20,7 +20,7 @@
 
   const contractSourceArray=['非CRM合同导入','CRM合同导入']
   const contractStatusArray=[{id:1,label:"已审批"},{id:2,label:"单章寄回"},{id:3,label:"已签回"}]
-  const contractTypeArray=[{id:1,label:"新签"},{id:2,label:"续约"}]
+  const contractTypeArray=[{id:1,label:"新签合同"},{id:2,label:"续约合同"},{id:3,label:"代付合同"},{id:4,label:"补充协议"}]
   const operationType=[{op_type:1,label:"合规登记"},{op_type:2,label:"开票登记"},{op_type:3,label:"到款登记"},
   {op_type:4,label:"修改合同状态"},{op_type:5,label:"删除合同登记"},{op_type:6,label:"合规编辑"}]
 
@@ -52,10 +52,13 @@
       end_date:'',
       contract_amount:'',
       contract_type:'',
+      has_payment:'',
+      relate_contract_code:'',
+      actual_company_name:'',
       sign_date:'',
       agreed_pay_time:'',
       services:[],
-      register_status:'',
+      service_remark:'',
       remark:""
     },
     rules:{
@@ -77,8 +80,11 @@
         trigger:'blur'
       }],
       contract_type:{required:true,message:'合同类型不能为空',trigger:'change'},
-      sign_date:{required:true,message:'签订日不能为空',trigger:'change'},
-      agreed_pay_time:{required:true,message:'约定付款时间不能为空',trigger:'blur'}
+      has_payment:{required:true,message:'请选择是否是代付',trigger:'change'},
+      // sign_date:{required:true,message:'签订日不能为空',trigger:'change'},
+      // agreed_pay_time:{required:true,message:'约定付款时间不能为空',trigger:'blur'}
+      actual_company_name:{required:true,message:'实际使用方不能为空',trigger:'blur'},
+      // relate_contract_code:{required:true,message:'关联合同不能为空',trigger:'blur'}
 
     },
     moneyData:{
@@ -107,13 +113,12 @@
     contractNoTotal:0,
     contractNoLoading:false,
     // --------------套餐信息
-    // 选中的套餐
+    // // 选中的套餐
     checkedService:[],
-    //套餐列表
+    // //套餐列表
     serviceArray:[],
-    // 当前小套餐选中的品种
-    currentSmallService:{},
-    // checkedServiceDetail:{},
+    // 小套餐选中的品种
+    checkedPermission:[],
     // 查看套餐弹窗
     serviceShow:false,
     // 显示选择品种 - FICC小套餐
@@ -122,6 +127,7 @@
     serviceType:0,
     // 品种选择
     varietyDiaShow:false,
+    varietyDiaType:'view',
     // -----------------登记进度
     progressList:[],
   })
@@ -130,20 +136,20 @@
     invoiceData:[
       {
         amount:'',
-        invoice_date:''
+        invoice_date:'',
+        remark:''
       }
-    ],
-    rowErrorShow:''
+    ]
   })
   // ---------------到款信息
   const placementForm=reactive({
     placementData:[
       {
         amount:'',
-        invoice_date:''
+        invoice_date:'',
+        remark:''
       }
-    ],
-    rowErrorShow:''
+    ]
   })
   // 查看套餐报价单 图片
   const previewImage=ref('')
@@ -231,34 +237,60 @@
       end_date:'',
       contract_amount:'',
       contract_type:'',
+      has_payment:'',
+      relate_contract_code:'',
+      actual_company_name:'',
       sign_date:'',
       agreed_pay_time:'',
+      services:[],
+      service_remark:'',
       remark:""
     }
+    contractInfo.checkedService=[]
+    // 小套餐选中的品种
+    contractInfo.checkedPermission=[]
+    // 1-大套餐  2-小套餐
+    contractInfo.serviceType=0,
+    // 品种选择
+    contractInfo.serviceVarietyShow=false
     contractInfo.contractValidityDate=[]
     setTimeout(()=>{
       // 去除错误信息
       contractInfoForm.value && contractInfoForm.value.clearValidate()
     },0)
   }
+  // 合同类型改变
+  const contractTypeChange=(value)=>{
+    // console.log(value);
+    if(value!=3){
+      contractInfo.form.relate_contract_code=''
+    }else{
+      contractInfo.form.has_payment=''
+    }
+    if(value!=4 && value!=3){
+      contractInfo.form.actual_company_name=''
+    }
+  }
+
   // 服务改变
   const serciveChange=(value,type,openDia=true)=>{
     // console.log(value,type);
     if(type==2){
       contractInfo.serviceVarietyShow=value
+      contractInfo.varietyDiaType='edit'
       contractInfo.varietyDiaShow=openDia&&value
     }
     contractInfo.serviceType = value?type:0
   }
-  const getVarieties=(item)=>{
-    contractInfo.currentSmallService= { 
-      service_template_id: item.service_template_id,
-      Value: item.Value,
-      tableData: item.tableData, 
-      chart_permission_ids:item.chart_permission_ids,
-      tableHeadData: item.tableHeadData 
-    }
-    // console.log(item);
+  // 选择品种
+  const selectVariety=()=>{
+    contractInfo.varietyDiaType='edit'
+    contractInfo.varietyDiaShow=true
+  }
+
+  const getPermissionChecked=(list)=>{
+    console.log(list);
+    contractInfo.checkedPermission=list
   }
   // 合同编号远程搜索
   const contractNoSearch=(value)=>{
@@ -287,6 +319,21 @@
   const selectContractNo=(value)=>{
     let selectItem=contractInfo.contractNoArray.find(item=>item.contract_code == value)
     // console.log(selectItem);
+    // 获取套餐详情
+    getServiceDetail({contract_id:selectItem.contract_id}).then(res=>{
+      // console.log(res);
+      contractInfo.form.services = res.data?res.data.Service||[]:[]
+      // 小套餐
+      let smallService = contractInfo.form.services.find(item => item.ServiceTemplateId==2)
+      // 是否有大套餐
+      let hasBigService = contractInfo.form.services.some(item => item.ServiceTemplateId==1)
+
+      contractInfo.serviceVarietyShow=!!smallService
+      contractInfo.varietyDiaType='edit'
+      contractInfo.serviceType = !!smallService?2:hasBigService?1:0
+      contractInfo.checkedService=contractInfo.form.services.map(item => item.ServiceTemplateId)
+      contractInfo.checkedPermission=smallService?smallService.ChartPermissionIds||[]:[]
+    })
     contractInfo.form.company_name=selectItem.company_name
     contractInfo.form.crm_contract_id=selectItem.contract_id
     contractInfo.form.start_date=selectItem.start_date
@@ -296,10 +343,12 @@
     contractInfo.form.seller_name=selectItem.seller_name
     contractInfo.form.seller_id=selectItem.seller_id
     contractInfo.form.contract_type=selectItem.contract_type_key
+    contractInfo.form.relate_contract_code=selectItem.relate_contract_code
+    contractInfo.form.actual_company_name=selectItem.actual_company_name
     contractInfoForm.value && 
     contractInfoForm.value.validateField([
       'contract_code','company_name','contract_type','seller_id',
-      'start_date','contract_amount','contract_type'
+      'start_date','contract_amount','relate_contract_code','actual_company_name'
     ])
   }
   // 销售选中
@@ -317,27 +366,39 @@
       placementSubmit()
     }
   }
+  // 添加行
+  const addTableRow=(type)=>{
+    if(type=='invoice'){
+      invoiceForm.invoiceData.push({amount:'',invoice_date:'',remark:''})
+    }else{
+      placementForm.placementData.push({amount:'',invoice_date:'',remark:''})
+    }
+  }
+
   // 表格添加行
   const addRow=(type,index)=>{
     if(type=='invoice'){
-      invoiceForm.invoiceData.splice((index+1),0,{amount:'',invoice_date:''})
+      invoiceForm.invoiceData.splice((index+1),0,{amount:'',invoice_date:'',remark:''})
     }else{
-      placementForm.placementData.splice((index+1),0,{amount:'',invoice_date:''})
+      placementForm.placementData.splice((index+1),0,{amount:'',invoice_date:'',remark:''})
     }
   }
   // 表格删除行
   const deleteRow=(type,index)=>{
     let tempArr=[]
+    let word='开票'
     if(type=='invoice'){
       tempArr=invoiceForm.invoiceData
+      word='开票'
     }else{
       tempArr=placementForm.placementData
+      word='到款'
     }
     if(tempArr[index].amount=='' && tempArr[index].invoice_date==''){
       // 没有内容 直接删除
       tempArr.splice(index,1)
     }else{
-      ElMessageBox.confirm('删除后不可恢复,是否删除该条开票记录?',
+      ElMessageBox.confirm(`是否删除该条${word}记录?`,
       '提示',    
       {
         confirmButtonText: '确定',
@@ -347,7 +408,7 @@
         // 有金额才进行删除后的运算
         if(tempArr[index].amount!=''){
           tempArr.splice(index,1)
-          let money=0
+          let money=0                                           
           tempArr.map(item =>{
             money+=parseFloat(item.amount) || 0
             // console.log(money);
@@ -414,14 +475,15 @@
   }
   // 合规登记-提交
   const complianceSubmit=()=>{
-    console.log(contractInfo.checkedService);
+    // console.log(contractInfo.checkedService);
     contractInfoForm.value.validate(valid=>{
       if(valid){
         if(contractInfo.checkedService.length==0){
           ElMessage.warning('请选择套餐')
           return 
         }
-        if(!contractInfo.currentSmallService.Value && contractInfo.checkedService.some(serviceId =>serviceId==2)){
+        if((!contractInfo.checkedPermission || contractInfo.checkedPermission.length==0) 
+        && contractInfo.checkedService.some(serviceId =>serviceId==2)){
           ElMessage.warning('请保存FICC小套餐品种')
           return 
         }
@@ -431,10 +493,9 @@
           // 小套餐
           if(serviceId==2){
             contractInfo.form.services.push({
-              service_template_id:contractInfo.currentSmallService.service_template_id,
-              value:contractInfo.currentSmallService.Value,
-              chart_permission_ids:contractInfo.currentSmallService.chart_permission_ids,
-              detail:[contractInfo.currentSmallService.tableHeadData,...contractInfo.currentSmallService.tableData],
+              service_template_id:serviceItem.service_template_id,
+              value:'',
+              chart_permission_ids:contractInfo.checkedPermission?contractInfo.checkedPermission.join(','):'',
               chart_permission_id:serviceItem.chart_permission_id,
               title:serviceItem.title
             })
@@ -443,6 +504,8 @@
           }
         })
         contractInfo.form.contract_amount = parseFloat(contractInfo.form.contract_amount)
+        if(!contractInfo.form.has_payment) contractInfo.form.has_payment=0
+        console.log(contractInfo.form);
         if(contractInfo.form.contract_register_id){
           // 编辑
           registerEdit(contractInfo.form).then(res=>{
@@ -470,13 +533,6 @@
   const invoiceSubmit=()=>{
     invoiceFormRef.value.validate(valid=>{
       if(valid){
-        invoiceForm.rowErrorShow=''
-        if(contractInfo.moneyData.waitInvoiceMoney<0){
-          ElMessage.error('总开票金额大于合同金额,请检查')
-          // 让金额这一列标红
-          invoiceForm.rowErrorShow='true'
-          return
-        }
         // 转化
         invoiceForm.invoiceData.forEach(element => {
           element.amount = parseFloat(element.amount)
@@ -484,7 +540,7 @@
         let param={
           contract_register_id:contractInfo.form.contract_register_id,
           invoice_type:1,
-          amount_list:invoiceForm.invoiceData
+          amount_list:invoiceForm.invoiceData,
         }
         registerInvoice(param).then(res=>{
           let messageHint=ElMessage.success('开票登记成功')
@@ -498,15 +554,8 @@
   }
   // 到款登记保存
   const placementSubmit=()=>{
-    placementForm.rowErrorShow=''
     placementFormRef.value.validate(valid=>{
       if(valid){
-        if(contractInfo.moneyData.waitPlacementMoney<0){
-          ElMessage.error('总开票金额大于合同金额,请检查')
-          // 让金额这一列标红
-          placementForm.rowErrorShow='true'
-          return
-        }
         // 转化
         placementForm.placementData.forEach(element => {
           element.amount = parseFloat(element.amount)
@@ -536,6 +585,11 @@
   // 查看套餐
   const viewService=(serviceTemplateId)=>{
     if(!canServiceShow(serviceTemplateId)) return 
+    if(serviceTemplateId==2){
+      contractInfo.varietyDiaShow=true
+      contractInfo.varietyDiaType='view'
+      return 
+    }
     let viewItem=contractInfo.form.services.find(item => item.service_template_id == serviceTemplateId)
     previewImageTitle.value = viewItem.title
     previewImage.value=viewItem.value
@@ -567,13 +621,31 @@
         end_date:res.data.end_date,
         contract_amount:res.data.contract_amount,
         contract_type:res.data.contract_type,
+        has_payment:res.data.has_payment,
+        relate_contract_code:res.data.relate_contract_code,
+        actual_company_name:res.data.actual_company_name,
         sign_date:res.data.sign_date,
         agreed_pay_time:res.data.agreed_pay_time,
+        service_remark:res.data.service_remark,
         remark:res.data.remark,
-        register_status:res.data.register_status,
         contract_source:res.data.contract_source,
-        services:res.data.service_list
       }
+      res.data.service_list.map(item =>{
+          // 小套餐
+          if(item.service_template_id==2){
+            contractInfo.form.services.push({
+              service_template_id:item.service_template_id,
+              value:item.value,
+              chart_permission_ids:item.chart_permission_ids,
+              chart_permission_id:item.chart_permission_id,
+              title:item.title
+            })
+            contractInfo.checkedPermission=item.chart_permission_ids.split(',')
+          }else{
+            contractInfo.form.services.push(item)
+          }
+      })
+      console.log(contractInfo.form.services);
       contractInfo.contractValidityDate=[res.data.start_date,res.data.end_date]
       contractInfo.checkedService=res.data.service_list.map(item => {
         let serviceId=item.service_template_id
@@ -589,56 +661,39 @@
         invoiceForm.invoiceData=[]
         res.data.invoice_list.map(item=>{
           invoiceForm.invoiceData.push({
-            invoice_id:item.invoice_id,
+            invoice_id:item.contract_invoice_id,
             amount:item.amount,
-            invoice_date:item.invoice_time
+            invoice_date:item.invoice_time,
+            remark:item.remark
           })
         })
+        // 添加一行空的
+        if(contractInfo.operationtype=='invoice'){
+          invoiceForm.invoiceData.push({
+            amount:'',
+            invoice_date:'',
+            remark:''
+          })
+        }
       }
       // 到款
       if(res.data.payment_list.length>0){
         placementForm.placementData=[]
         res.data.payment_list.map(item=>{
           placementForm.placementData.push({
-            invoice_id:item.invoice_id,
+            invoice_id:item.contract_invoice_id,
             amount:item.amount,
-            invoice_date:item.invoice_time
+            invoice_date:item.invoice_time,
+            remark:item.remark
           })
         })
-      }
-      let samllService=contractInfo.form.services.find(item => item.service_template_id==2)
-      if(contractInfo.operationtype=='compliance' && samllService){
-        // 合规编辑
-        /**
-         * 有可能服务模板的接口数据还没返回
-         * 这时更改contractInfo.currentSmallService会触发子组件的监听函数,导致空指针错误
-         * 创建一个 setInterval 询问contractInfo.serviceArray数据是否返回,已返回就更新contractInfo.currentSmallService
-         */
-         let temarr = samllService.detail.map((rowItem) => {
-          let rowArr = [];
-          for (let key in rowItem) {
-              if (key.substr(0, 3) === "col" && rowItem[key] !== "") {
-                rowArr.push(JSON.parse(rowItem[key]));
-              }
-            }
-            return rowArr;
-          });
-          let paramsTemp={
-            tableHeadData:temarr[0],
-            tableData:temarr.slice(1),
-            service_template_id:samllService.service_template_id,
-            Value:samllService.value,
-            chart_permission_ids:samllService.chart_permission_ids
-          }
-        if(contractInfo.serviceArray.length==0){
-          let timer=setInterval(()=>{
-            if(contractInfo.serviceArray.length>0){
-              contractInfo.currentSmallService=paramsTemp
-              clearInterval(timer)
-            }
-          },100)
-        }else{
-          contractInfo.currentSmallService=paramsTemp
+        // 添加一行空的
+        if(contractInfo.operationtype=='placement'){
+          placementForm.placementData.push({
+            amount:'',
+            invoice_date:'',
+            remark:''
+          })
         }
       }
     })
@@ -681,11 +736,10 @@
                       <el-option :label="item.real_name" :value="item.admin_id" v-for="item in contractInfo.sellerList" :key="item.admin_id"></el-option>
                     </el-select>
                   </el-form-item>
-                  <el-form-item label="合同状态" prop="contract_status">
-                    <el-select v-model="contractInfo.form.contract_status" 
-                     placeholder="请选择合同状态" >
-                      <el-option :label="item.label" :value="item.id" v-for="item in contractStatusArray" :key="item.id"></el-option>
-                    </el-select>
+                  <el-form-item label="合同金额"
+                  prop="contract_amount">
+                    <el-input v-model.trim="contractInfo.form.contract_amount"
+                    placeholder="请输入合同金额" />
                   </el-form-item>
                   <el-form-item label="合同有效期" 
                   prop="start_date">
@@ -695,17 +749,32 @@
                     :clearable="false">
                     </el-date-picker>
                   </el-form-item>
-                  <el-form-item label="合同金额"
-                  prop="contract_amount">
-                    <el-input v-model.trim="contractInfo.form.contract_amount"
-                    placeholder="请输入合同金额" />
-                  </el-form-item>
                   <el-form-item label="合同类型" prop="contract_type">
                     <el-select v-model="contractInfo.form.contract_type"
-                    placeholder="请选择合同类型" >
+                    placeholder="请选择合同类型" @change="contractTypeChange">
                       <el-option :label="item.label" :value="item.id" v-for="item in contractTypeArray" :key="item.id"></el-option>
                     </el-select>
                   </el-form-item>
+                  <el-form-item label="是否代付" prop="has_payment" v-if="[1,2,4].includes(contractInfo.form.contract_type)">
+                    <el-radio-group v-model="contractInfo.form.has_payment" style="min-width:286px;width: 15vw;">
+                      <el-radio :label="1">是</el-radio>
+                      <el-radio :label="0">否</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                  <el-form-item label="实际使用方" prop="actual_company_name" v-if="contractInfo.form.contract_type==3">
+                    <el-input v-model="contractInfo.form.actual_company_name"
+                    placeholder="请输入实际使用方" />
+                  </el-form-item>
+                  <el-form-item label="关联合同" prop="relate_contract_code" v-if="contractInfo.form.contract_type==3 || contractInfo.form.contract_type==4">
+                    <el-input v-model="contractInfo.form.relate_contract_code"
+                    placeholder="请输入关联合同" />
+                  </el-form-item>
+                  <el-form-item label="合同状态" prop="contract_status">
+                    <el-select v-model="contractInfo.form.contract_status" 
+                     placeholder="请选择合同状态" >
+                      <el-option :label="item.label" :value="item.id" v-for="item in contractStatusArray" :key="item.id"></el-option>
+                    </el-select>
+                  </el-form-item>
                   <el-form-item label="签订日" prop="sign_date">
                     <el-date-picker v-model="contractInfo.form.sign_date"
                     placeholder="请选择签订日" value-format="YYYY-MM-DD"
@@ -737,7 +806,7 @@
                     {{contractInfo.serviceArray[1]?.title}}
                   </el-checkbox>
                   <span v-if="(contractInfo.serviceVarietyShow&&contractInfo.operationtype=='compliance')" 
-                  @click="contractInfo.varietyDiaShow=true">选择品种</span>
+                  @click="selectVariety">选择品种</span>
                 </div>
                 <!-- 市场策略 -->
                 <el-checkbox :label="contractInfo.serviceArray[2]?.service_template_id" style="margin-right: 0;" 
@@ -750,14 +819,19 @@
                   {{contractInfo.serviceArray[3]?.title}}
                 </el-checkbox>
               </el-checkbox-group>
+              <div class="info-service-remark">
+                <span style="white-space: nowrap;font-size: 14px;margin-right: 20px;">套餐备注</span>
+                <el-input style="flex-grow: 1;" :disabled="contractInfo.operationtype!='compliance'"
+                    v-model="contractInfo.form.service_remark" placeholder="请输入备注"
+                  />
+              </div>
             </div>
             <div class="info-row">
                 <div class="info-row-title">备注</div>
                 <div class="info-row-remark">
                   <span style="white-space: nowrap;font-size: 14px;margin-right: 20px;">备注</span>
                   <el-input style="flex-grow: 1;" :disabled="contractInfo.operationtype!='compliance'"
-                    v-model="contractInfo.form.remark"
-                    placeholder="请输入备注"
+                    v-model="contractInfo.form.remark" placeholder="请输入备注"
                   />
                 </div>
             </div>
@@ -767,7 +841,8 @@
             </div>
           </div>
           <!-- 开票登记 -->
-          <div class="info-box" v-if="contractInfo.operationtype!='compliance'" style="margin-top:20px ;" id="info-invoice-box">
+          <div class="info-box" v-show="contractInfo.operationtype!='compliance' && contractInfo.form.has_payment!=1" 
+          style="margin-top:20px ;" id="info-invoice-box" v-permission="['financial:list:invoice','financial:list:placement','financial:list:viewIandP','or']">
             <div class="info-box-head">开票登记{{contractInfo.moneyData.waitInvoiceMoney==0?'':'(待开票)'}}</div>
             <div class="info-row" >
               <div class="info-row-title">开票信息</div>
@@ -775,9 +850,11 @@
                 <div class="invoice-payment-title">
                   <div style="margin-right: 30px;">已开票金额(元):<span class="invoice-payment-money">{{moneyFormatter(contractInfo.moneyData?.haveInvoiceMoney)}}</span></div>
                   <div>剩余开票金额(元):<span class="invoice-payment-money">{{moneyFormatter(contractInfo.moneyData?.waitInvoiceMoney)}}</span></div>
+                  <el-button type="primary" style="margin: 0 0 0 auto;" @click="addTableRow('invoice')" 
+                  v-if="contractInfo.operationtype=='invoice'&&invoiceForm.invoiceData.length==0">添加开票信息</el-button>
                 </div>
                 <el-form ref="invoiceFormRef" :model="invoiceForm" :disabled="contractInfo.operationtype!='invoice'">
-                  <el-table :data="invoiceForm.invoiceData" border> 
+                  <el-table :data="invoiceForm.invoiceData" border v-if="invoiceForm.invoiceData.length>0"> 
                     <el-table-column label="序号" width="80" align="center">
                       <template #default="{row,$index}">
                         {{$index+1}}
@@ -789,9 +866,8 @@
                       </template>
                       <template #default="{row,$index}">
                         <el-form-item :prop="`invoiceData.${$index}.amount`" :show-message="false" 
-                        :error="invoiceForm.rowErrorShow"
                         :rules="{required:true,message:()=>{ ElMessage.error('开票金额不能为空')},trigger:'blur'}">
-                          <el-input v-model.trim="row.amount" style="width: 124px;" 
+                          <el-input v-model.trim="row.amount" style="width: 124px;" :disabled="row.invoice_id?true:false"
                           placeholder="请输入金额" @input="(e)=>moneyChange('invoice',e,$index)"></el-input>
                         </el-form-item>
                       </template>
@@ -800,18 +876,26 @@
                       <template #header>
                         <span style="color: #FF3400;">*</span>开票日期
                       </template>
-                      <template #default="{row,$index}">
+                      <template #default="{row,$index}" >
                         <el-form-item :prop="`invoiceData.${$index}.invoice_date`" :show-message="false"
                         :rules="{required:true,message:()=>{ ElMessage.error('请选择开票日期')},trigger:'change'}">             
-                          <el-date-picker v-model="row.invoice_date" style="width: 124px;"
+                          <el-date-picker v-model="row.invoice_date" style="width: 124px;" :disabled="row.invoice_id?true:false"
                           placeholder="请选择日期" value-format="YYYY-MM-DD" :clearable="false" ></el-date-picker>
                         </el-form-item>
                       </template>
+                    </el-table-column >
+                    <el-table-column label="备注" width="180" align="center" prop="remark" show-overflow-tooltip >
+                      <template #default="{row}">
+                        <el-form-item  v-if="row.invoice_id?false:true">             
+                          <el-input v-model="row.remark" style="width: 124px;" placeholder="请输入备注" />
+                        </el-form-item>
+                        <span v-else>{{row.remark || '--'}}</span>
+                      </template>
                     </el-table-column>
                     <el-table-column label="操作" width="180" align="center" v-if="contractInfo.operationtype=='invoice'">
                       <template #default="{row,$index}" >
-                        <span class="table-operation-button" v-if="(invoiceForm.invoiceData.length>1)"
-                        style="color: #FF3400;margin-right: 16px;" @click="deleteRow('invoice',$index)">删除</span>
+                        <span class="table-operation-button" style="color: #FF3400;margin-right: 16px;" 
+                        @click="deleteRow('invoice',$index)">删除</span>
                         <span class="table-operation-button" @click="addRow('invoice',$index)">添加</span>
                       </template>
                     </el-table-column>
@@ -819,9 +903,15 @@
                 </el-form>
               </div>
             </div>
+            <!-- <div class="contract-operation" v-if="contractInfo.operationtype=='invoice'">
+              <el-button class="operation-button" style="margin-right: 30px;" @click="registrationCancel">取消</el-button>
+              <el-button type="primary" @click="submit" class="operation-button">保存</el-button>
+            </div> -->
           </div>
           <!-- 到款登记 -->
-          <div class="info-box" v-if="contractInfo.operationtype!='compliance'" style="margin-top:20px ;" id="info-invoice-box">
+          <div class="info-box" v-show="contractInfo.operationtype!='compliance' && contractInfo.form.has_payment!=1" 
+          v-permission="['financial:list:invoice','financial:list:placement','financial:list:viewIandP','or']"
+          style="margin-top:20px ;" id="info-invoice-box">
             <div class="info-box-head">到款登记{{contractInfo.moneyData.waitPlacementMoney==0?'':'(待到款)'}}</div>
             <div class="info-row" >
               <div class="info-row-title">到款信息</div>
@@ -829,9 +919,11 @@
                 <div class="invoice-payment-title">
                   <div style="margin-right: 30px;">已到款金额(元):<span class="invoice-payment-money">{{moneyFormatter(contractInfo.moneyData.havePlacementMoney)}}</span></div>
                   <div>剩余到款金额(元):<span class="invoice-payment-money">{{moneyFormatter(contractInfo.moneyData.waitPlacementMoney)}}</span></div>
+                  <el-button type="primary" style="margin: 0 0 0 auto;" @click="addTableRow('placement')" 
+                  v-if="contractInfo.operationtype=='placement'&&placementForm.placementData.length==0">添加到款信息</el-button>
                 </div>
                 <el-form ref="placementFormRef" :model="placementForm" :disabled="contractInfo.operationtype!='placement'">
-                  <el-table :data="placementForm.placementData" border> 
+                  <el-table :data="placementForm.placementData" border v-if="placementForm.placementData.length>0"> 
                     <el-table-column label="序号" width="80" align="center">
                       <template #default="{row,$index}">
                         {{$index+1}}
@@ -843,9 +935,8 @@
                       </template>
                       <template #default="{row,$index}">
                         <el-form-item :prop="`placementData.${$index}.amount`" :show-message="false" 
-                        :error="placementForm.rowErrorShow"
                         :rules="{required:true,message:()=>{ ElMessage.error('到款金额不能为空')},trigger:'blur'}">
-                          <el-input v-model="row.amount" style="width: 124px;" 
+                          <el-input v-model="row.amount" style="width: 124px;" :disabled="row.invoice_id?true:false"
                           placeholder="请输入金额" @input="(e)=>moneyChange('placement',e,$index)"></el-input>
                         </el-form-item>
                       </template>
@@ -857,15 +948,24 @@
                       <template #default="{row,$index}">
                         <el-form-item :prop="`placementData.${$index}.invoice_date`" :show-message="false"
                         :rules="{required:true,message:()=>{ ElMessage.error('请选择到款日期')},trigger:'change'}">             
-                          <el-date-picker v-model="row.invoice_date" style="width: 124px;" :clearable="false"
+                          <el-date-picker v-model="row.invoice_date" style="width: 124px;" :clearable="false" 
+                          :disabled="row.invoice_id?true:false"
                           placeholder="请选择日期" value-format="YYYY-MM-DD" format="YYYY-MM-DD"></el-date-picker>
                         </el-form-item>
                       </template>
                     </el-table-column>
+                    <el-table-column label="备注" width="180" align="center" prop="remark" show-overflow-tooltip >
+                      <template #default="{row}">
+                        <el-form-item  v-if="row.invoice_id?false:true">             
+                          <el-input v-model="row.remark" style="width: 124px;" placeholder="请输入备注"/>
+                        </el-form-item>
+                        <span v-else>{{row.remark || '--'}}</span>
+                      </template>
+                    </el-table-column>
                     <el-table-column label="操作" width="180" align="center" v-if="contractInfo.operationtype=='placement'">
                       <template #default="{row,$index}">
                         <span class="table-operation-button" @click="deleteRow('placement',$index)"
-                        v-if="(placementForm.placementData.length>1)" style="color: #FF3400;margin-right: 16px;">删除</span>
+                        style="color: #FF3400;margin-right: 16px;">删除</span>
                         <span class="table-operation-button" @click="addRow('placement',$index)">添加</span>
                       </template>
                     </el-table-column>
@@ -873,7 +973,7 @@
                 </el-form>
               </div>
             </div>
-            <div class="contract-operation" v-if="contractInfo.operationtype=='placement' || contractInfo.operationtype=='invoice'">
+            <div class="contract-operation" v-if="contractInfo.operationtype=='placement'">
               <el-button class="operation-button" style="margin-right: 30px;" @click="registrationCancel">取消</el-button>
               <el-button type="primary" @click="submit" class="operation-button">保存</el-button>
             </div>
@@ -895,7 +995,12 @@
                     </div>
                   </template>
                   <div class="progress-item-title">{{operationType[item.op_type-1]?.label}}</div>
-                  <div class="progress-item-info">{{item.admin_name}}</div>
+                  <div class="progress-item-info">
+                    <span>{{item.admin_name}}</span>
+                    <span style="margin-left: 6px;" v-permission="['financial:list:invoice','financial:list:placement','financial:list:viewIandP','or']">
+                      {{item.amount_remark}}
+                    </span>
+                  </div>
                   <div class="progress-item-info">{{item.create_time}}</div>
                   <div class="progress-item-info" v-show="item.remark">备注:{{item.remark}}</div>
                 </el-timeline-item>
@@ -904,8 +1009,8 @@
         </el-scrollbar>
       </div>
       <!-- 小套餐选择品种弹窗 -->
-      <service-variety-dia v-model:visible="contractInfo.varietyDiaShow" @selectFinish="getVarieties" 
-      :service="contractInfo.serviceArray.find(item=>item.service_template_id==2)" :currentService="contractInfo.currentSmallService" ></service-variety-dia>
+      <permission-dia v-model:visible="contractInfo.varietyDiaShow" :type="contractInfo.varietyDiaType"
+      @selectFinish="getPermissionChecked" :hasCheckedPermission="contractInfo.checkedPermission"></permission-dia>
       <!-- 查看套餐弹窗 -->
       <el-dialog v-model="contractInfo.serviceShow" style="min-width: 800px;" title="" width="70vw" top="5vh">
         <template #header>
@@ -991,6 +1096,12 @@
                 }
               }
             }
+            .info-service-remark{
+              display: flex;
+              padding-left: 50px;
+              align-items: center;
+              margin-top: 20px;
+            }
             // 备注
             .info-row-remark{
               display: flex;
@@ -1000,13 +1111,17 @@
             // 开票欣喜
             .info-row-invoice-payment{
               padding-left: 80px;
-              display: inline-block;
+              display: flex;
+              flex-direction: column;
+              align-items: flex-start;
               .invoice-payment-title{
+                height: 32px;
+                min-width: 560px;
                 font-size: 14px;
                 color: #333333;
                 display: flex;
                 align-items: center;
-                margin-bottom: 20px;
+                margin-bottom: 10px;
                 .invoice-payment-money{
                   font-weight: 600;
                   font-size: 14px;

+ 47 - 9
src/views/financialManagement/financialList.vue

@@ -2,13 +2,13 @@
 import { Search } from '@element-plus/icons-vue'
 import {useRouter,useRoute} from 'vue-router'
 import {getServiceList,getRegisterList,updateRegisterStatus,
-  registerDelete,registerListExport} from '@/api/financialMana'
+  registerDelete,registerListExport,importDataApi} from '@/api/financialMana'
 import {downloadByFlow} from '@/utils/common-methods'
 
 const router = useRouter()
 const route = useRoute()
 const changeStatusForm=ref(null)
-const contractTypeArray=[{id:1,label:"新签"},{id:2,label:"续约"}]
+const contractTypeArray=[{id:1,label:"新签合同"},{id:2,label:"续约合同"},{id:3,label:"代付合同"},{id:4,label:"补充协议"}]
 const contractStatusArray=[{id:1,label:"已审批"},{id:2,label:"单章寄回"},{id:3,label:"已签回"}]
 const statusArray=[{id:1,label:"进行中"},{id:2,label:"已完成"}]
 
@@ -48,7 +48,8 @@ const statusArray=[{id:1,label:"进行中"},{id:2,label:"已完成"}]
       contract_register_id:'',
       contract_status:''
     },
-    currentStatusRow:{}
+    currentStatusRow:{},
+    importLoading:false
   })
 
   // 监听
@@ -113,6 +114,30 @@ const statusArray=[{id:1,label:"进行中"},{id:2,label:"已完成"}]
       downloadByFlow(res,'xlsx','财务列表')
     })
   }
+
+  // 导入数据
+  const importData=(e)=>{
+    if(financial.importLoading){
+      ElMessage.warning('正在导入中,请勿重复导入')
+      return
+    }
+    let {file}=e
+    if(!file.name.endsWith('xlsx')){
+      ElMessage.warning('请上传以.xlsx结尾的文件')
+      return
+    }
+    financial.importLoading=true
+    let formData = new FormData()
+    formData.append('File',file)
+    importDataApi(formData).then(res=>{
+      ElMessage.success('导入成功')
+      searchFinancial()
+    }).finally(()=>{
+      financial.importLoading=false
+    })
+  }
+
+
   // 显示开票详情
   const invoiceDetail=(row)=>{
     // console.log(row);
@@ -178,7 +203,7 @@ const statusArray=[{id:1,label:"进行中"},{id:2,label:"已完成"}]
         <div class="financial-list-container" id="financial-list-container" > 
           <!-- 搜索区域 -->
           <div class="financial-search-zone">
-            <el-input v-model="financial.searchParams.keyword" placeholder="合同编号/客户姓名/销售" :prefix-icon="Search"
+            <el-input v-model="financial.searchParams.keyword" placeholder="合同编号/客户姓名/销售/实际使用方" :prefix-icon="Search"
             style="width: 286px;margin-bottom: 8px;" @input="searchFinancial" clearable />
             <el-date-picker v-model="financial.createtime" start-placeholder="登记日期-开始"
             end-placeholder="登记日期-结束" style="margin-right: 30px;max-width: 286px;margin-bottom: 8px;"
@@ -201,7 +226,18 @@ const statusArray=[{id:1,label:"进行中"},{id:2,label:"已完成"}]
           <div class="financial-top-option-zone">
               <el-button type="primary" size="large" style="width: 130px;margin-right: 30px;" v-permission="'financial:list:complianceAdd'"
               @click="registration('compliance')">合规登记</el-button>
-              <el-button @click="exportData" size="large" style="width: 130px;margin-left: 0;" >导出</el-button>
+              <el-button @click="exportData" size="large" style="width: 130px;margin: 0 30px 0 0;" >导出</el-button>
+              <el-upload
+                class="upload-demo"
+                accept=".xlsx"
+                :show-file-list="false"
+                :http-request="importData"
+                v-permission="'financial:list:complianceImport'"
+              >
+                <el-button size="large" :loading="financial.importLoading"
+                style="width: 130px;margin-left: 0;"  >导入</el-button>
+              </el-upload>
+              
           </div>
           <div class="financial-table-zone">
             <!-- 表格 -->
@@ -234,12 +270,14 @@ const statusArray=[{id:1,label:"进行中"},{id:2,label:"已完成"}]
                   {{contractStatusArray[row.contract_status-1].label}}
                 </template>
               </el-table-column>
-              <el-table-column label="已开票金额" align="center" prop="invoiced_amount" width="100">
+              <el-table-column label="已开票金额" align="center" prop="invoiced_amount" width="100"
+              v-permission="['financial:list:invoice','financial:list:placement','financial:list:viewIandP','or']">
                 <template #default="{row}">
                   <span style="color: var(--themeColor);cursor: pointer;" @click="invoiceDetail(row)">{{row.invoiced_amount}}</span>
                 </template>
               </el-table-column>
-              <el-table-column label="已到款金额" align="center" prop="payment_amount" width="100">
+              <el-table-column label="已到款金额" align="center" prop="payment_amount" width="100"
+              v-permission="['financial:list:invoice','financial:list:placement','financial:list:viewIandP','or']">
                 <template #default="{row}">
                   <span style="color: var(--themeColor);cursor: pointer;" @click="refundDetail(row)">{{row.payment_amount}}</span>
                 </template>
@@ -290,11 +328,11 @@ const statusArray=[{id:1,label:"进行中"},{id:2,label:"已完成"}]
                         删除
                       </span>
                       <span class="table-option-buttons" v-permission="'financial:list:invoice'"
-                      @click="registration('invoice',row.contract_register_id)">
+                      @click="registration('invoice',row.contract_register_id)" v-if="row.has_payment!=1">
                         开票登记
                       </span>
                       <span class="table-option-buttons" v-permission="'financial:list:placement'"
-                      @click="registration('placement',row.contract_register_id)">
+                      @click="registration('placement',row.contract_register_id)" v-if="row.has_payment!=1">
                         到款登记
                       </span>
                       <span class="table-option-buttons" @click="changeContractStatus(row)">

+ 95 - 0
src/views/financialManagement/invoice/invoiceList.vue

@@ -0,0 +1,95 @@
+<script setup>
+
+import getCom from '../composition/IandPList'
+
+const invoice=getCom(1)
+const data = invoice.data
+
+// --------created
+invoice.placementList()
+
+</script>
+
+<template>
+    <div id="invoice-list-container">
+      <div class="invoice-search-zone">
+        <div class="invoice-search-box">
+          <el-input v-model="data.searchParams.contract_code" placeholder="请输入合同编号"
+          style="width: 309px;margin-left: 40px;margin-bottom: 8px;" clearable @input="invoice.searchPlacement" ></el-input>
+          <el-date-picker v-model="data.dateRange" start-placeholder="起始日期"
+            end-placeholder="结束日期" style="margin-left: 40px;max-width: 321px;margin-bottom: 8px;"
+            value-format="YYYY-MM-DD" type="daterange" ></el-date-picker>
+          <div style="margin-left: 40px;margin-bottom: 8px;">
+            开票金额
+            <el-input v-model.trim="data.searchParams.min_amount" @blur="invoice.checkMoney"
+            @input="(value)=>invoice.moneyChange(value,'min_amount')" style="width: 104px;margin:0 8px" clearable></el-input>
+            至
+            <el-input v-model.trim="data.searchParams.max_amount" @blur="invoice.checkMoney"
+            @input="(value)=>invoice.moneyChange(value,'max_amount')"
+            style="width: 104px;margin:0 8px" clearable></el-input>
+          </div>
+        </div>
+      </div>
+      <div class="invoice-table-container">
+        <div class="invoice-table-top">
+          <span style="font-size:14px">已开票金额:{{ data.amountTotal }}元</span>
+          <el-button type="primary" style="width: 80px;" size="large" @click="invoice.placementExport">导出</el-button>
+        </div>
+        <!-- 表格 -->
+        <el-table :data="data.tableData" border max-height="560px" size="default" style="position: sticky;"> 
+          <el-table-column label="合同编号" align="center" prop="contract_code" show-overflow-tooltip></el-table-column>
+          <el-table-column label="开票金额" align="center" prop="amount" show-overflow-tooltip></el-table-column>
+          <el-table-column label="开票日期" align="center" prop="invoice_time" show-overflow-tooltip></el-table-column>
+          <el-table-column label="操作" width="120" align="center">
+            <template #default="{row}">
+              <div class="table-options" style="justify-content: center;">
+                <span class="table-option-buttons" style="margin-right: 0;"
+                @click="invoice.placementDetail(row,'invoice')">
+                  详情
+                </span>
+              </div>
+            </template>
+          </el-table-column>
+          <template #empty>
+            <div class="table-no-data">
+              <img src="@/assets/img/icon/empty-data.png" />
+              <span>暂无数据</span>
+            </div>
+          </template>
+        </el-table>
+      </div>
+      <!-- 分页 -->
+      <m-page :pageSize="data.searchParams.page_size" :page_no="data.searchParams.current" 
+      style="display: flex;justify-content: flex-end;margin-top: 20px;" 
+      :total="data.total" @handleCurrentChange="invoice.changePageNo" @handleSizeChange="invoice.changePageSize"/>
+    </div>
+</template>
+  
+<style lang="scss" scoped>
+  #invoice-list-container{
+    min-height: 100%;
+    .invoice-search-zone{
+      border: 1px solid #ECECEC;
+      background-color: white;
+      padding: 18px 30px 12px;
+      box-sizing: border-box;
+      .invoice-search-box{
+        margin-left: -40px;
+        display: flex;
+        flex-wrap: wrap;
+      }
+    }
+    .invoice-table-container{
+      border: 1px solid #ECECEC;
+      background-color: white;
+      margin-top: 18px;
+      padding: 18px 30px 26px;
+      .invoice-table-top{
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        margin-bottom: 18px;
+      }
+    }
+  }
+</style>

+ 97 - 0
src/views/financialManagement/placement/placementList.vue

@@ -0,0 +1,97 @@
+<script setup>
+
+import getCom from '../composition/IandPList'
+
+const placement=getCom(2)
+const data = placement.data
+
+// ---------------method
+
+// --------created
+placement.placementList()
+
+</script>
+
+<template>
+    <div id="placement-list-container">
+      <div class="placement-search-zone">
+        <div class="placement-search-box">
+          <el-input v-model="data.searchParams.contract_code" placeholder="请输入合同编号"
+          style="width: 309px;margin-left: 40px;margin-bottom: 8px;" clearable @input="placement.searchPlacement" ></el-input>
+          <el-date-picker v-model="data.dateRange" start-placeholder="起始日期"
+            end-placeholder="结束日期" style="margin-left: 40px;max-width: 321px;margin-bottom: 8px;"
+            value-format="YYYY-MM-DD" type="daterange" ></el-date-picker>
+          <div style="margin-left: 40px;margin-bottom: 8px;">
+            到款金额
+            <el-input v-model.trim="data.searchParams.min_amount" @blur="placement.checkMoney"
+            @input="(value)=>placement.moneyChange(value,'min_amount')" style="width: 104px;margin:0 8px" clearable></el-input>
+            至
+            <el-input v-model.trim="data.searchParams.max_amount" @blur="placement.checkMoney"
+            @input="(value)=>placement.moneyChange(value,'max_amount')"
+            style="width: 104px;margin:0 8px" clearable></el-input>
+          </div>
+        </div>
+      </div>
+      <div class="placement-table-container">
+        <div class="placement-table-top">
+          <span style="font-size:14px">已到款金额:{{ data.amountTotal }}元</span>
+          <el-button type="primary" style="width: 80px;" size="large" @click="placement.placementExport">导出</el-button>
+        </div>
+        <!-- 表格 -->
+        <el-table :data="data.tableData" border max-height="560px" size="default" style="position: sticky;"> 
+          <el-table-column label="合同编号" align="center" prop="contract_code" show-overflow-tooltip></el-table-column>
+          <el-table-column label="到款金额" align="center" prop="amount" show-overflow-tooltip></el-table-column>
+          <el-table-column label="到款日期" align="center" prop="invoice_time" show-overflow-tooltip></el-table-column>
+          <el-table-column label="操作" width="120" align="center">
+            <template #default="{row}">
+              <div class="table-options" style="justify-content: center;">
+                <span class="table-option-buttons" style="margin-right: 0;"
+                @click="placement.placementDetail(row,'placement')">
+                  详情
+                </span>
+              </div>
+            </template>
+          </el-table-column>
+          <template #empty>
+            <div class="table-no-data">
+              <img src="@/assets/img/icon/empty-data.png" />
+              <span>暂无数据</span>
+            </div>
+          </template>
+        </el-table>
+      </div>
+      <!-- 分页 -->
+      <m-page :pageSize="data.searchParams.page_size" :page_no="data.searchParams.current" 
+      style="display: flex;justify-content: flex-end;margin-top: 20px;" 
+      :total="data.total" @handleCurrentChange="placement.changePageNo" @handleSizeChange="placement.changePageSize"/>
+    </div>
+</template>
+  
+<style lang="scss" scoped>
+  #placement-list-container{
+    min-height: 100%;
+    .placement-search-zone{
+      border: 1px solid #ECECEC;
+      background-color: white;
+      padding: 18px 30px 12px;
+      box-sizing: border-box;
+      .placement-search-box{
+        margin-left: -40px;
+        display: flex;
+        flex-wrap: wrap;
+      }
+    }
+    .placement-table-container{
+      border: 1px solid #ECECEC;
+      background-color: white;
+      margin-top: 18px;
+      padding: 18px 30px 26px;
+      .placement-table-top{
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        margin-bottom: 18px;
+      }
+    }
+  }
+</style>