wujianwei
2025-08-18 972e9a97cdd913935c7634527dcc45cdb6e145a6
ui/admin-ui3/src/views/cwgl/pendingSettlementBusiness/index.vue
@@ -1,268 +1,597 @@
<template>
  <basicContainer >
    <avue-crud
        :option="option"
        :table-loading="pageF.loading"
        :data="tableData"
        :page="page"
        :permission="permissionList"
        :before-open="beforeOpen"
        v-model="form"
        ref="crudRef"
        @row-update="rowUpdate"
        @row-save="rowSave"
        @refresh-change="refreshChange"
        @row-del="rowDel"
        @search-change="searchChange"
        @search-reset="searchReset"
        @selection-change="selectionChange"
        @current-change="currentChange"
        @size-change="sizeChange"
        @on-load="onLoad"
    >
  <basicContainer>
    <avue-crud :option="option" v-model:search="queryParams" :table-loading="pageF.loading" :data="tableData"
      :page="page" :permission="permissionList" :before-open="beforeOpen" v-model="form" ref="crudRef"
      @row-update="rowUpdate" @row-save="rowSave" @refresh-change="refreshChange" @row-del="rowDel"
      @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
      @current-change="currentChange" @size-change="sizeChange" @on-load="onLoad">
      <template #menu-left>
        <el-button
            type="success"
            icon="Edit"
            :disabled="pageF.single"
            v-hasPermi="['cwgl:pendingSettlementBusiness:edit']"
            @click="handleUpdate">修改
        <el-button type="success" :disabled="generateDisabled" @click="handleGenerate"
          v-hasPermi="['cwgl:pendingSettlementBusiness:add']">生成账单
        </el-button>
        <el-button
            type="danger"
            icon="Delete"
            :disabled="pageF.multiple"
            @click="handleDelete"
            v-hasPermi="['cwgl:pendingSettlementBusiness:remove']"
        >删除
        <!-- <el-button type="success" icon="Edit" :disabled="pageF.single"
          v-hasPermi="['cwgl:pendingSettlementBusiness:edit']" @click="handleUpdate">修改
        </el-button> -->
        <!-- <el-button type="danger" icon="Delete" :disabled="pageF.multiple" @click="handleDelete"
          v-hasPermi="['cwgl:pendingSettlementBusiness:remove']">删除
        </el-button> -->
        <el-button type="warning" plain icon="Download" @click="handleExport"
          v-hasPermi="['cwgl:pendingSettlementBusiness:export']">导出
        </el-button>
        <el-button
            type="warning"
            plain
            icon="Download"
            @click="handleExport"
            v-hasPermi="['cwgl:pendingSettlementBusiness:export']"
        >导出
        </el-button>
      </template>
      <template #menu="{ size, row, index }">
        <el-link class="link-btn" type="primary" :underline="false" plain :size="size" @click="handleFy(row)"
          v-hasPermi="['cwgl:pendingSettlementBusiness:query']"> 费用明细
        </el-link>
      </template>
    </avue-crud>
    <el-dialog v-model="dialog.visible" :title="dialog.title" width="1000px">
      <el-form ref="storagesTransferRef" :model="form" :rules="rules" label-width="120px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="账单名称" prop="billName">
              <el-input v-model="form.billName" placeholder="请输入账单名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="客户名称" prop="customerName">
              <el-input v-model="form.customerName" disabled placeholder="请输入客户名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="调度单数量" prop="count">
              <el-input-number v-model="form.count" disabled :min="0" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="结算金额" prop="price">
              <el-input-number v-model="form.price" disabled :min="0" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
    <el-dialog v-model="dialog.detail" :title="dialog.title" width="1000px">
      <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
        <el-tab-pane label="成本" name="first"></el-tab-pane>
        <el-tab-pane label="收入" name="second"></el-tab-pane>
      </el-tabs>
      <el-table :data="tableDataList" show-summary :summary-method="getSummaries" style="width: 100%">
        <el-table-column prop="feeName" label="费用名称" />
        <el-table-column prop="estimatedAmount" label="费用金额" />
        <el-table-column prop="currency" label="费用币制" />
      </el-table>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </basicContainer>
</template>
<script setup name="pendingSettlementBusiness" lang="ts">
  import {PendingSettlementBusinessI,addPendingSettlementBusiness, delPendingSettlementBusiness, exportPendingSettlementBusiness, getPendingSettlementBusiness, listPendingSettlementBusiness, updatePendingSettlementBusiness} from "@/api/cwgl/pendingSettlementBusiness";
  import useCurrentInstance from "@/utils/useCurrentInstance";
  import {computed,reactive, ref, toRefs} from "vue";
  import {PagesInterface, PageQueryInterface} from "@/utils/globalInterface";
  import {usePagePlus} from "@/hooks/usePagePlus";
  import {hasPermission} from "@/utils/permissionUtils";
import {
  PendingSettlementBusinessI, addPendingSettlementBusiness, delPendingSettlementBusiness, exportPendingSettlementBusiness, getPendingSettlementBusiness, listPendingSettlementBusiness, updatePendingSettlementBusiness,
  getPendingSettlementBusinessBill, getCwglPendingSettlementBusinessBillList, getSelectCustomNam, cwglPendingSettlementBusinessCreateBill, pendingSettlementBusinessCreateBillList
} from "@/api/cwgl/pendingSettlementBusiness";
import { listEstimatedReceivable } from "@/api/cwgl/estimatedReceivable";
  const { proxy } = useCurrentInstance();
  const crudRef = ref();
  const permissionList = computed(()=>{
    return {
      addBtn: hasPermission(["cwgl:pendingSettlementBusiness:add"]),
      delBtn: hasPermission(["cwgl:pendingSettlementBusiness:remove"]),
      editBtn: hasPermission(["cwgl:pendingSettlementBusiness:edit"]),
      viewBtn: hasPermission(["cwgl:pendingSettlementBusiness:query"]),
import useCurrentInstance from "@/utils/useCurrentInstance";
import { computed, reactive, ref, toRefs } from "vue";
import { PagesInterface, PageQueryInterface } from "@/utils/globalInterface";
import { usePagePlus } from "@/hooks/usePagePlus";
import { hasPermission } from "@/utils/permissionUtils";
const { proxy } = useCurrentInstance();
const crudRef = ref();
const permissionList = computed(() => {
  return {
    addBtn: hasPermission(["cwgl:pendingSettlementBusiness:add"]),
    delBtn: hasPermission(["cwgl:pendingSettlementBusiness:remove"]),
    editBtn: hasPermission(["cwgl:pendingSettlementBusiness:edit"]),
    viewBtn: hasPermission(["cwgl:pendingSettlementBusiness:query"]),
    generate: hasPermission(["cwgl:pendingSettlementBusiness:generate"]),
  }
})
const data = reactive({
  form: <PendingSettlementBusinessI & any>{
    billName: '',
    customerNa: '',
    count: 0,
    price: 0
  },
  selectCustomName: [],
  queryParams: <PendingSettlementBusinessI & PageQueryInterface>{},
  page: <PagesInterface>{
    pageSize: 10,
    total: 0,
    currentPage: 1,
  },
  selectionList: [],
  tableDataList: [],
  rules: {
    billName: [
      { required: true, message: '账单名称不能为空', trigger: 'blur' }
    ],
  },
  generateDisabled: false, // 控制生成账单按钮的禁用状态
})
const { queryParams, form, page, selectionList, generateDisabled, rules, tableDataList,
  selectCustomName
} = toRefs(data);
const getSelectCustomName = () => {
  getSelectCustomNam().then((res) => {
    if (res.code === 200) {
      // selectCustomName.value = res.data;
      selectCustomName.value = res.data.map(item => ({
        dictLabel: item,
        dictValue: item
      }));
      option.value.column.customerName.dicData = selectCustomName.value || [];
    }
  })
}
getSelectCustomName()
const option = ref({
  pageKey: 'PendingSettlementBusiness',
  rowKey: 'id',
  addBtn: false,
  generateDisabled: true,
  editBtn: false,
  delBtn: false,
  viewBtn: false,
  selection: true,
  generate: false,
  searchSpan: 5,
  searchLabelWidth: 100,
  column: {
    // id: {
    //   label: 'ID',
    // },
    projectName: {
      fixed: 'left',
      label: '项目名称', search: true,
      minWidth: 150,
  const data = reactive({
    form:<PendingSettlementBusinessI>{},
    queryParams:<PendingSettlementBusinessI&PageQueryInterface>{},
    page: <PagesInterface>{
      pageSize: 10,
      total: 0,
      currentPage: 1,
    },
    selectionList:[],
  })
  const {queryParams,form,page,selectionList} = toRefs(data);
  const option = ref({
    pageKey: 'PendingSettlementBusiness',
    rowKey: 'id',
    column: {
                                id: {
          label: 'ID',
                            },
                                bookingNo: {
          label: '客户订单号',
                            },
                                customerId: {
          label: '客户id',
                            },
                                carrierId: {
          label: '承运商id',
                            },
                                projectName: {
          label: '项目名称',
                            },
                                dispatchNo: {
          label: '调度单号',
                                rules: [
              {
                required: true,
                message: "调度单号不能为空", trigger: "blur" }
            ],                  },
                                createdTime: {
          label: '下单时间',
                            },
                                transportMode: {
          label: '运输方式',
                            },
                                productId: {
          label: '服务产品',
                            },
                                customerName: {
          label: '客户名称',
                            },
                                operationMode: {
          label: '运营模式',
                            },
                                carrierName: {
          label: '承运商',
                            },
                                departureLocation: {
          label: '出发地',
                            },
                                arrivalLocation: {
          label: '目的地',
                            },
                                vehicleId: {
          label: '运输工具ID',
                            },
                                licensePlateNumber: {
          label: '车牌',
                            },
                                vehicleType: {
          label: '车型',
                            },
                                mainDriver: {
          label: '主驾驶员',
                            },
                                assistantDriver: {
          label: '副驾驶员',
                            },
                                pointNum: {
          label: '提送货点数',
                            },
                                businessContact: {
          label: '业务联系人',
                            },
                                estimatedTotalIncome: {
          label: '预估总收入',
                            },
                                estimatedTotalCost: {
          label: '预估总成本',
                            },
                                estimatedProfit: {
          label: '预估利润',
                            },
                                electronicLock: {
          label: '电子锁',
                            },
                                reWeighingWeight: {
          label: '复磅重量',
                            },
                                quantity: {
          label: '件数',
                            },
                                actualDepartureTime: {
          label: '实际出发时间',
                            },
                                requiredArrivalTime: {
          label: '要求到达时间',
                            },
                                actualArrivalTime: {
          label: '实际到达时间',
                            },
                                beReturn: {
          label: '是否回程',
                            },
                                dispatchQuantity: {
          label: '实发件数',
                            },
                                dispatchWeight: {
          label: '实发重量',
                            },
                                dispatchVolume: {
          label: '实发体积(立方)',
                            },
                                emptyMileage: {
          label: '空载里程',
                            },
                                emptyFuel: {
          label: '空载油耗',
                            },
                                heavyMileage: {
          label: '重载里程',
                            },
                                heavyFuel: {
          label: '重载油耗',
                            },
                                beScheduled: {
          label: '是否按班次',
                            },
                                trackingNo: {
          label: '快递单号',
                            },
                                sealNo: {
          label: '铅封号',
                            },
                                scheduleNo: {
          label: '班次号',
                            },
                                transportStatus: {
          label: '运输状态',
                            },
                                estimatedBillId: {
          label: '预估账单ID',
                            },
                                settlementBillId: {
          label: '结算账单ID',
                            },
                                settlementStatus: {
          label: '结算状态',
                            },
                                createTime: {
          label: '创建时间',
                                rules: [
              {
                required: true,
                message: "创建时间不能为空", trigger: "blur" }
            ],                  },
                                updateTime: {
          label: '更新时间',
                                rules: [
              {
                required: true,
                message: "更新时间不能为空", trigger: "blur" }
            ]                  },
          }
  })
    dispatchNo: {
      label: '调度单号',
      minWidth: 150,
      search: true,
      rules: [
        {
          required: true,
          message: "调度单号不能为空", trigger: "blur"
        }
      ],
    },
    customerName: {
      label: '客户名称',
      search: true,
      minWidth: 220,
  const { tableData,pageF,rowSave,rowUpdate,rowDel,beforeOpen,searchChange,
    searchReset,selectionChange,onLoad,currentChange,sizeChange,handleDelete,handleExport,handleUpdate,refreshChange} = usePagePlus({
    form:form,
    option:option,
    queryParams:queryParams,
    idKey:'id',
    page:page.value,
    getListApi:listPendingSettlementBusiness,
    getDetailApi:getPendingSettlementBusiness,
    exportApi:exportPendingSettlementBusiness,
    deleteApi:delPendingSettlementBusiness,
    addApi:addPendingSettlementBusiness,
    updateApi:updatePendingSettlementBusiness,
    handleUpdateFunc:()=>{
      type: 'select',           // 设置为下拉框类型
      dicData: [], // 使用 selectCustomName 作为数据源
      disabled: false  // 根据需要设置是否禁用
    },
    licensePlateNumber: {
      label: '车牌', search: true,
      minWidth: 120,
    },
    vehicleType: {
      label: '车型', search: true,
    },
    createdTime: {
      label: '下单时间',
      display: false,
      search: true,
      type: 'date',
      format: 'YYYY-MM-DD',
      searchSpan: 5, minWidth: 120,
      valueFormat: 'YYYY-MM-DD',
    },
    operationMode: {
      label: '运营模式',
    },
    createTime: {
      label: '创建时间', display: false, hide: true, type: 'date',
      format: 'YYYY-MM-DD', searchSpan: 5, minWidth: 100, searchLabelWidth: 110,
      valueFormat: 'YYYY-MM-DD',
    },
    // bookingNo: {
    //   label: '客户订单号', showOverflowTooltip: true,
    // },
    // customerId: {
    //   label: '客户id',
    // },
    // carrierId: {
    //   label: '承运商id',
    // },
    // createdTime: {
    //   label: '下单时间',
    // },
    transportMode: {
      label: '运输方式', hide: true,
    },
    productId: {
      label: '服务产品', hide: true,
    },
    carrierName: {
      label: '承运商',
      minWidth: 210,
    },
    departureLocation: {
      label: '出发地',
      minWidth: 200,
    },
    arrivalLocation: {
      label: '目的地',
      minWidth: 200,
    },
    // vehicleId: {
    //   label: '运输工具ID',hide: true,
    // },
    mainDriver: {
      label: '主驾驶员',
      minWidth: 120,
    },
    assistantDriver: {
      label: '副驾驶员',
      minWidth: 120,
    },
    pointNum: {
      label: '提送货点数',
      minWidth: 100,
    },
    businessContact: {
      label: '业务联系人',
      minWidth: 120,
    },
    estimatedTotalIncome: {
      label: '预估总收入',
      minWidth: 120,
    },
    estimatedTotalCost: {
      label: '预估总成本',
      minWidth: 120,
    },
    estimatedProfit: {
      label: '预估利润',
      minWidth: 120,
    },
    confirmedTotalIncome: {
      label: '确认总收入',
      minWidth: 120,
    },
    confirmedTotalCost: {
      label: '确认总成本',
      minWidth: 120,
    },
      relatedBillName: {
      label: '关联联账单名称',
      fixed: 'right',
      minWidth: 120,
    },
    isIncomeMatched: {
      label: '是否匹配收入',
      type: 'select',
      dataType: 'string',
      minWidth: 120,
      dicUrl: '/system/dict/data/type/sys_matching_status',
    },
    isCostMatched: {
      label: '是否匹配成本',
      type: 'select',
      dataType: 'string',
      minWidth: 120,
      dicUrl: '/system/dict/data/type/sys_matching_status',
    },
    isCreate: {
      label: '是否已入账', dataType: 'string',
      type: 'select',
      fixed: 'right',
      minWidth: 120,
      dicUrl: '/system/dict/data/type/sys_whether_type',
    },
    relatedBillStatus: {
      minWidth: 120,
      label: '关联账单状态',
      dataType: 'string',
      type: 'select',
      dicUrl: '/system/dict/data/type/sys_related_status',
      //    formatter: (row, value) => {
      // // 自定义格式化逻辑(如果需要)
      //   return value;
      //  }
    },
    // electronicLock: {
    //   label: '电子锁',
    // },
    // reWeighingWeight: {
    //   label: '复磅重量',
    // },
    // quantity: {
    //   label: '件数',
    // },
    // actualDepartureTime: {
    //   label: '实际出发时间',
    // },
    // requiredArrivalTime: {
    //   label: '要求到达时间',
    // },
    // actualArrivalTime: {
    //   label: '实际到达时间',
    // },
    // beReturn: {
    //   label: '是否回程',
    // },
    // dispatchQuantity: {
    //   label: '实发件数',
    // },
    // dispatchWeight: {
    //   label: '实发重量',
    // },
    // dispatchVolume: {
    //   label: '实发体积(立方)',
    // },
    // emptyMileage: {
    //   label: '空载里程',
    // },
    // emptyFuel: {
    //   label: '空载油耗',
    // },
    // heavyMileage: {
    //   label: '重载里程',
    // },
    // heavyFuel: {
    //   label: '重载油耗',
    // },
    // beScheduled: {
    //   label: '是否按班次',
    // },
    // trackingNo: {
    //   label: '快递单号',
    // },
    // sealNo: {
    //   label: '铅封号',
    // },
    // scheduleNo: {
    //   label: '班次号',
    // },
    // transportStatus: {
    //   label: '运输状态',
    // },
    // estimatedBillId: {
    //   label: '预估账单ID',
    // },
    // settlementBillId: {
    //   label: '结算账单ID',
    // },
    // settlementStatus: {
    //   label: '结算状态',
    // },
    // updateTime: {
    //   label: '更新时间',
    //   rules: [
    //     {
    //       required: true,
    //       message: "更新时间不能为空", trigger: "blur"
    //     }
    //   ]
    // },
  }
})
const { tableData, pageF, rowSave, rowUpdate, rowDel, beforeOpen, searchChange,
  searchReset, selectionChange, onLoad, currentChange, sizeChange, handleDelete, handleExport, handleUpdate, refreshChange } = usePagePlus({
    form: form,
    option: option,
    queryParams: queryParams,
    idKey: 'id',
    page: page.value,
    getListApi: listPendingSettlementBusiness,
    getDetailApi: getPendingSettlementBusiness,
    exportApi: exportPendingSettlementBusiness,
    deleteApi: delPendingSettlementBusiness,
    addApi: addPendingSettlementBusiness,
    updateApi: updatePendingSettlementBusiness,
    handleUpdateFunc: () => {
      crudRef.value.rowEdit(selectionList.value[0]);
    },
    handleSelectionChangeFunc:(selection:any)=>{
    handleSelectionChangeFunc: (selection: any) => {
      if (selection.every((item: any) => item.isCreate == '0')) {
        generateDisabled.value = false;
      } else {
        generateDisabled.value = true;
        if (selection.length > 0) {
          proxy.$message.warning('请选择未入账的记录');
        }
      }
      selectionList.value = selection;
      selectionList.value = selection;
    }
  })
const dialog = reactive({
  visible: false,
  detail: false,
  title: '',
})
const selectedIds = ref<string>('');
const handleGenerate = () => {
  form.value = {};
  dialog.title = '生成账单';
  if (selectionList.value.length > 0) {
    selectedIds.value = selectionList.value.map(item => item.id).join(',');
  }
  if (selectionList.value.length === 0) {
    if (queryParams.value.customerName == '') {
      proxy.$message.warning('请选择客户名称');
      return;
    }
    getCwglPendingSettlementBusinessBillList({ customerName: queryParams.value.customerName }).then((res) => {
      if (res.code === 200) {
        form.value = res.data;
        // option.value.generate = true;
        dialog.visible = true;
      }
    })
  } else {
    getPendingSettlementBusinessBill(selectedIds.value).then((res) => {
      if (res.code === 200) {
        form.value = res.data;
        // option.value.generate = true;
        dialog.visible = true;
      }
    })
  }
}
const storagesTransferRef = ref<FormInstance>()
const submitForm = () => {
  storagesTransferRef.value!.validate(valid => {
    if (valid) {
      if (selectionList.value.length == 0) {
        pendingSettlementBusinessCreateBillList(form.value).then((res) => {
          if (res.code === 200) {
            proxy.$message.success(res.msg);
            dialog.visible = false;
            onLoad(page.value)
          }
        });
      } else {
        cwglPendingSettlementBusinessCreateBill(form.value, selectedIds.value).then((res) => {
          if (res.code === 200) {
            proxy.$message.success(res.msg);
            dialog.visible = false;
            onLoad(page.value)
          }
        });
      }
    }
  })
}
const cancel = () => {
  form.value = {};
  dialog.visible = false;
  dialog.detail = false;
  proxy.resetForm(storagesTransferRef.value)
  option.value.generate = false;
}
const activeName = ref('first')
const dispatchNo = ref('');
const handleClick = (tab: TabsPaneContext, event: Event) => {
  if (tab.props.name == 'first') {
    getListVable(dispatchNo.value, 1);
  } else if (tab.props.name == 'second') {
    getListVable(dispatchNo.value, 0);
  }
}
const handleFy = (row: any) => {
  dispatchNo.value = row.dispatchNo;
  dialog.title = '费用明细';
  if (activeName.value == 'first') {
    listEstimatedReceivable({ dispatchNo: row.dispatchNo, feeType: 1 }).then((res) => {
      if (res.code === 200) {
        dialog.detail = true;
        tableDataList.value = res.rows || [];
      }
    })
  } else if (activeName.value == 'second') {
    // 这里可以添加查询收入相关的逻辑
    listEstimatedReceivable({ dispatchNo: row.dispatchNo, feeType: 0 }).then((res) => {
      if (res.code === 200) {
        dialog.detail = true;
        tableDataList.value = res.rows || [];
      }
    })
  }
}
const getListVable = (dispatchNo, feeType) => {
  listEstimatedReceivable({ dispatchNo: dispatchNo, feeType: feeType }).then((res) => {
    if (res.code === 200) {
      tableDataList.value = res.rows || [];
    }
  })
}
// 添加合计方法
const getSummaries = (param) => {
  const { columns, data } = param;
  const sums = [];
  columns.forEach((column, index) => {
    if (index === 0) {
      sums[index] = '合计';
      return;
    }
    if (column.property === 'estimatedAmount') {
      const values = data.map(item => Number(item.estimatedAmount));
      if (!values.every(value => Number.isNaN(value))) {
        sums[index] = values.reduce((prev, curr) => {
          const value = Number(curr);
          if (!Number.isNaN(value)) {
            return prev + curr;
          } else {
            return prev;
          }
        }, 0);
        sums[index] = sums[index].toFixed(2);
      } else {
        sums[index] = 'N/A';
      }
    } else {
      sums[index] = '';
    }
  });
  return sums;
}
</script>