sen
2026-01-29 fea2d693c33fdbcb4c8304a96a4e584829cb437b
ui/admin-ui3/src/views/tms/paymentTmsQuotePlan/index.vue
@@ -47,7 +47,38 @@
      </template>
      <template #menu-before="{row}">
        <el-link size="small" type="primary" @click="goToDetail(row)"  class="link-btn" :underline="false" icon="el-icon-d-arrow-right">报价明细</el-link>
        <el-link size="small" type="primary" @click="goToDetail(row)" v-if="row.providerType == 0" class="link-btn" :underline="false" icon="el-icon-d-arrow-right">运费报价</el-link>
      </template>
      <template #items-form="scope">
        <avue-crud
            :option="{...itemsTableOption,selection: !scope.disabled}"          @selection-change="selectionChange2"
            :data="form.items" ref="itemsCrudRef"
        >
          <template #unit="{row}">
            <el-select  v-model="row.unit" :disabled="scope.disabled || !rowKeys.includes(row.rowKey)" placeholder="请选择计费单位">
              <el-option
                  v-for="dict in sys_unit"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
              ></el-option>
            </el-select>
          </template>
          <template #price="{row}">
            <el-input v-model="row.price" :min="1" :disabled="scope.disabled || !rowKeys.includes(row.rowKey)" type="number" placeholder="请输入金额"></el-input>
          </template>
          <template #currency="{row}">
            <el-radio-group v-model="row.currency"  :disabled="scope.disabled || !rowKeys.includes(row.rowKey)">
              <el-radio
                  v-for="dict in sys_currency"
                  :key="dict.value"
                  :label="dict.value"
              >{{ dict.label }}</el-radio>
            </el-radio-group>
          </template>
        </avue-crud>
      </template>
    </avue-crud>
  </basicContainer>
@@ -64,15 +95,20 @@
  updateTmsQuotePlan
} from "@/api/tms/tmsQuotePlan";
import useCurrentInstance from "@/utils/useCurrentInstance";
import {computed, reactive, ref, toRefs} from "vue";
import {computed, nextTick, reactive, ref, toRefs} from "vue";
import {PagesInterface, PageQueryInterface} from "@/utils/globalInterface";
import {usePagePlus} from "@/hooks/usePagePlus";
import {hasPermission} from "@/utils/permissionUtils";
import router from "@/router";
import {getTmsProject, listTmsProject} from "@/api/tms/tmsProject";
import {getTmsServiceProvider, listTmsServiceProvider} from "@/api/tms/tmsServiceProvider";
import {getTmsCustomsServiceProvider, listTmsCustomsServiceProvider} from "@/api/tms/tmsCustomsServiceProvider";
import {getTmsLoadingServiceProvider, listTmsLoadingServiceProvider} from "@/api/tms/tmsLoadingServiceProvider";
import {randomId} from "@smallwei/avue";
const {proxy} = useCurrentInstance();
const crudRef = ref();
const {sys_quotation_items,sys_unit,sys_currency} =
    proxy.useDict("sys_quotation_items","sys_unit","sys_currency");
const permissionList = computed(() => {
  return {
    addBtn: hasPermission(["tms:tmsQuotePlan:add"]),
@@ -91,11 +127,14 @@
    currentPage: 1,
  },
  selectionList: [],
  selectionList2: <any>[],
  activeProviderType:<any> undefined,
})
const {queryParams, form, page, selectionList} = toRefs(data);
const {queryParams, form, page, selectionList,activeProviderType,selectionList2} = toRefs(data);
const option = ref({
  pageKey: 'TmsQuotePlan',
  rowKey: 'id',
  rowKey: 'id',labelWidth:100,
  group:[
    {
      label: '基本信息',
@@ -103,7 +142,7 @@
      column:{
        planName: {
          label: '方案名称',
          display: true,
          display: true,row:true,
          rules: [
            {
              required: true,
@@ -111,128 +150,243 @@
            }
          ],
        },
        projectId: {
          label: '关联项目',
          display: true,
        providerType:{
          label: '服务商类型',
          type: 'select',dataType: 'string',dicUrl: '/system/dict/data/type/provider_type',
          rules: [
            {
              required: true,
              message: "关联项目不能为空", trigger: "change"
              message: "服务商类型不能为空", trigger: "blur"
            }
          ],
          change: (val: any) => {
            const table = crudRef.value?.getPropRef?.('projectId')?.$refs?.temp;
            if (!table) return;
            let active = table.active;
            if (Array.isArray(active)) active = active[0];
            if (active) {
              Object.assign(form.value, {
                projectId: active.id,
                projectName: active.projectName,
                customerId: active.relatedCustomerId,
                customerName: active.relatedCustomerName,
                contractId: active.relatedContractId,
                contractName: active.relatedContractName,
              });
          change : (val: any) => {
              if (activeProviderType.value != val.value){
                Object.assign(form.value, {
                  providerId: '',
                  providerName: '',
                });
              }
            activeProviderType.value = val.value;
          },
        },
        providerId:{
          label : '服务商名称',
          rules: [
            {
              required: true,
              message: "服务商名称不能为空", trigger: "change"
            }
          ],
          type: 'table',suffixIcon:'search',dataType: 'string',
            change: (val: any) => {
              const table = crudRef.value?.getPropRef?.('providerId')?.$refs?.temp;
              if (!table) return;
              let active = table.active;
              if (Array.isArray(active)) active = active[0];
              if (active) {
                Object.assign(form.value, {
                  providerId: active.id,
                  providerName: active.serviceShortName,
                });
              }
            },
          children: {
            border: true,
            column:{
              serviceCode: {
                label: '服务商编码',
                search: true,
              },
              serviceShortName: {
                label: '服务商简称',minWidth:150,
                search: true,
              },
              serviceName: {
                label: '服务商全称',search: true,
              },
              serviceType: {
                label: '服务类型',minWidth:150,
                type: 'select', dataType: 'string', dicUrl: '/system/dict/data/type/service_type',
                multiple:true,
                search: true,
              },
            }
          },
          type: 'table',suffixIcon:'search',
          children:{
            border: true,
            searchMenuSpan: 5,
            column:{
              projectName: {
                label: '项目名称', minWidth: 130,
                search: true,
              },
              projectCode: {
                label: '项目编号',minWidth: 120,
                search: true,
              },
              relatedContractName: {
                label: '关联合同',
                display: false,minWidth: 150,
                search: true,
              },
              relatedCustomerName: {
                label: '关联客户',
                display: false,minWidth: 150,
                search: true,
              },
              status: {
                label: '状态',dataType: 'string',
                type: 'radio', dicUrl: '/system/dict/data/type/data_status',
                addDisplay: false,minWidth: 150,
                editDisplay: false,
                viewDisplay: true,
                hide: false,
                search: true,
                rules: [
                  {
                    required: true,
                    message: "状态不能为空", trigger: "blur"
                  }
                ],
              },
            },
          },
          props:{
            label: 'projectName',
            label: 'serviceShortName',
            value: 'id'
          },
          onLoad: ({ page, value, data }: { page: any, value: any, data: any }, callback:any) => {
          onLoad: async ({ page, value, data }: { page: any, value: any, data: any }, callback:any) => {
            if (form.value.providerType != 0 && !form.value.providerType ){
              return callback({
                total: 0,
                data: [],
              })
            }
            if (value){
              let id = value;
              if (Array.isArray(value)){
                id = value[0]
              }
              getTmsProject(id).then(res=>{
                return callback(res.data||{})
              })
              let res:any;
              if (form.value.providerType == 0){
                res = await getTmsServiceProvider(id)
              }else if (form.value.providerType == 1){
                res = await getTmsCustomsServiceProvider(id)
              }else if (form.value.providerType == 2){
                res = await getTmsLoadingServiceProvider(id)
              }
              return callback(res.data||{})
            }else{
              listTmsProject({pageSize:page.pageSize,pageNum:page.currentPage,...data}).then(res=>{
                return callback({
                  total: res.total,
                  data: res.rows||[],
                })
              let res:any;
              if (form.value.providerType == 0){
                res = await listTmsServiceProvider({pageSize:page.pageSize,pageNum:page.currentPage,...data})
              }else if (form.value.providerType == 1){
                res = await listTmsCustomsServiceProvider({pageSize:page.pageSize,pageNum:page.currentPage,...data})
              }else if (form.value.providerType == 2){
                res = await listTmsLoadingServiceProvider({pageSize:page.pageSize,pageNum:page.currentPage,...data})
              }
              return callback({
                total: res.total,
                data: res.rows||[],
              })
            }
          }
        },
        },
        customerName: {
          label: '所属客户',
          display: true,disabled:true,
          rules: [
            {
              required: true,
              message: "所属客户不能为空", trigger: "change"
            }
          ],
        },
        contractName: {
          label: '关联合同',
          display: true,disabled:true,
          rules: [
            {
              required: true,
              message: "关联合同不能为空", trigger: "change"
            }
          ],
        },
        effectiveDate: {
          label: '生效日期',
          type: 'date', valueFormat: 'YYYY-MM-DD',
          display: true,
        },
        // projectId: {
        //   label: '关联项目',
        //   display: true,
        //   rules: [
        //     {
        //       required: true,
        //       message: "关联项目不能为空", trigger: "change"
        //     }
        //   ],
        //   change: (val: any) => {
        //     const table = crudRef.value?.getPropRef?.('projectId')?.$refs?.temp;
        //     if (!table) return;
        //     let active = table.active;
        //     if (Array.isArray(active)) active = active[0];
        //     if (active) {
        //       Object.assign(form.value, {
        //         projectId: active.id,
        //         projectName: active.projectName,
        //         customerId: active.relatedCustomerId,
        //         customerName: active.relatedCustomerName,
        //         contractId: active.relatedContractId,
        //         contractName: active.relatedContractName,
        //       });
        //     }
        //   },
        //   type: 'table',suffixIcon:'search',
        //   children:{
        //     border: true,
        //     searchMenuSpan: 5,
        //     column:{
        //       projectName: {
        //         label: '项目名称', minWidth: 130,
        //         search: true,
        //       },
        //       projectCode: {
        //         label: '项目编号',minWidth: 120,
        //         search: true,
        //       },
        //       relatedContractName: {
        //         label: '关联合同',
        //         display: false,minWidth: 150,
        //         search: true,
        //       },
        //
        //       relatedCustomerName: {
        //         label: '关联客户',
        //         display: false,minWidth: 150,
        //         search: true,
        //       },
        //       status: {
        //         label: '状态',dataType: 'string',
        //         type: 'radio', dicUrl: '/system/dict/data/type/data_status',
        //         addDisplay: false,minWidth: 150,
        //         editDisplay: false,
        //         viewDisplay: true,
        //         hide: false,
        //         search: true,
        //         rules: [
        //           {
        //             required: true,
        //             message: "状态不能为空", trigger: "blur"
        //           }
        //         ],
        //       },
        //     },
        //
        //   },
        //   props:{
        //     label: 'projectName',
        //     value: 'id'
        //   },
        //   onLoad: ({ page, value, data }: { page: any, value: any, data: any }, callback:any) => {
        //     if (value){
        //       let id = value;
        //       if (Array.isArray(value)){
        //         id = value[0]
        //       }
        //       getTmsProject(id).then(res=>{
        //         return callback(res.data||{})
        //       })
        //     }else{
        //       listTmsProject({pageSize:page.pageSize,pageNum:page.currentPage,...data}).then(res=>{
        //         return callback({
        //           total: res.total,
        //           data: res.rows||[],
        //         })
        //       })
        //     }
        //
        //   }
        //
        // },
        // customerName: {
        //   label: '所属客户',
        //   display: true,disabled:true,
        //   rules: [
        //     {
        //       required: true,
        //       message: "所属客户不能为空", trigger: "change"
        //     }
        //   ],
        // },
        // contractName: {
        //   label: '关联合同',
        //   display: true,disabled:true,
        //   rules: [
        //     {
        //       required: true,
        //       message: "关联合同不能为空", trigger: "change"
        //     }
        //   ],
        // },
        // effectiveDate: {
        //   label: '生效日期',
        //   type: 'date', valueFormat: 'YYYY-MM-DD',
        //   display: true,
        // },
        expiryDate: {
          label: '失效日期',
          type: 'date', valueFormat: 'YYYY-MM-DD',
          display: true,
        },
      }
    },
    {
      label: '应付费用报价',
      prop: 'bjxm',
      column:{
        items:{
          label: '', labelWidth:0,span:24,
        }
      }
    },
    {
@@ -291,32 +445,43 @@
    },
    planName: {
      label: '方案名称',
      display: false,minWidth: 120,
      display: false,minWidth: 150,
      search: true,
    },
    customerName: {
      label: '所属客户',
    providerType: {
      label: '服务商类型',
      display: false,minWidth: 120,
      type: 'select',dataType: 'string',dicUrl: '/system/dict/data/type/provider_type',
      search: true,
    },
    projectName: {
      label: '关联项目',
      display: false,minWidth: 120,
    providerName:{
      label: '服务商名称',
      display: false,minWidth: 150,
      search: true,
    },
    contractName: {
      label: '关联合同',
      display: false,minWidth: 120,
      search: true,
    },
    effectiveDate: {
      label: '生效日期',
      type: 'date', valueFormat: 'YYYY-MM-DD',
      display: false,minWidth: 120,
      search: true,
    },
    // customerName: {
    //   label: '所属客户',
    //   display: false,minWidth: 120,
    //   search: true,
    // },
    //
    // projectName: {
    //   label: '关联项目',
    //   display: false,minWidth: 120,
    //   search: true,
    // },
    //
    // contractName: {
    //   label: '关联合同',
    //   display: false,minWidth: 120,
    //   search: true,
    // },
    // effectiveDate: {
    //   label: '生效日期',
    //   type: 'date', valueFormat: 'YYYY-MM-DD',
    //   display: false,minWidth: 120,
    //   search: true,
    // },
    status: {
      label: '状态',dataType: 'string',
      type: 'radio', dicUrl: '/system/dict/data/type/sys_normal_disable',
@@ -339,6 +504,27 @@
  }
})
const itemsTableOption = ref({
  pageKey: 'itemsTable',
  rowKey: 'rowKey',
  header: false,
  addBtn: false,menu: false,
  column:{
    freeName:{
      label: '费用名称',
    },
    unit:{
      label: '*计量单位',
    },
    price:{
      label: '*计费金额',
    },
    currency:{
      label: '币制',
    }
  }
})
const itemsCrudRef =ref()
const {
  tableData,
  pageF,
@@ -376,11 +562,82 @@
  },
  getBeginListFunc:()=>{
    queryParams.value.planType = '1'
  },
  handleBeforeOpenFunc:(type:string)=>{
    form.value.items = [];
    if (type === 'add'){
      form.value.items = sys_quotation_items.value.map((item:any)=>{
        return { rowKey: randomId() ,freeName: item.label,unit: '次'}
      })
    }
  },
  rowSaveBegin:(row:any,loading:any)=>{
    if (selectionList2.value.length > 0){
      let filter = selectionList2.value.filter((item:any)=>{
        return !item.price || !item.currency
      });
      if (filter.length > 0){
        proxy.$modal.msgError("请填写所有必填项");
        loading();
        throw new Error("请填写所有必填项")
      }
      row.quoteItems = selectionList2.value;
    }
  },
  rowUpdateBegin(row:any,loading:any){
    if (selectionList2.value.length > 0){
      let filter = selectionList2.value.filter((item:any)=>{
        return !item.price || !item.currency
      });
      if (filter.length > 0){
        proxy.$modal.msgError("请填写所有必填项");
        loading();
        throw new Error("请填写所有必填项")
      }
      row.quoteItems = selectionList2.value;
    }
  },
  handleEndOpenFunc:(type:string,res:any)=>{
    activeProviderType.value = form.value.providerType;
    if (type === 'edit'){
      selectionList2.value = (res.data.quoteItems || []).map((item:any)=>{
        item.rowKey =randomId()
        return item;
      });
      form.value.items = sys_quotation_items.value.map((item:any)=>{
        let find = selectionList2.value.find((ele:any)=>
            ele.freeName === item.label
        );
        if ( find){
          return find;
        }else{
          return { rowKey: randomId() ,freeName: item.label,unit: '次'}
        }
      })
      nextTick( ()=>{
        selectionList2.value.map((find:any)=>{
          itemsCrudRef.value.toggleRowSelection(find,true)
        })
      })
    }else{
      form.value.items = res.data.quoteItems || [];
    }
  }
})
const goToDetail = (row?:any) => {
  router.push("/basic/tmsQuoteDetail?quotePlanType=1&quotePlanId=" + row.id);
  router.push("/basic/tmsQuoteDetail?quotePlanType=1&quotePlanId=" + row.id+"&providerId=" + row.providerId);
}
const rowKeys = ref<any>([]);
const selectionChange2 = (selection?: any[]) => {
  selectionList2.value = selection;
  rowKeys.value = selection?.map((item:any)=>item.rowKey);
}
</script>