sen
2026-03-26 030b6b200408629f2d957ff3ff9a930ff0b62a6a
ui/admin-ui3/src/views/tms/generationCost/index.vue
@@ -1,63 +1,30 @@
<template>
  <basicContainer>
    <avue-crud
        :option="option"
        :table-loading="pageF.loading"
        :data="tableData"
        :page="page"
        :permission="permissionList"
        :before-open="beforeOpen"
        v-model="form" v-model:search="queryParams"
        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"
    >
    <avue-crud :option="option" :table-loading="pageF.loading" :data="tableData" :page="page"
      :permission="permissionList" :before-open="beforeOpen" v-model="form" v-model:search="queryParams" 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="warning"
            plain
            icon="Download"
            @click="handleExport"
            v-hasPermi="['tms:tmsDispatchOrder:export']"
        >导出
        <el-button type="warning" plain icon="Download" @click="handleExport"
          v-hasPermi="['tms:tmsDispatchOrder:export']">导出
        </el-button>
          <el-button
              type="primary"
              icon="Promotion"
              :disabled="pageF.multiple"
              @click="handleYSGenerate"
              v-hasPermi="['tms:tmsDispatchOrder:generate']"
          >生成应收费用
        <el-button type="primary" icon="Promotion" :disabled="pageF.multiple" @click="handleYSGenerate"
          v-hasPermi="['tms:tmsDispatchOrder:generate']">生成应收费用
          </el-button>
          <el-button
              type="success"
              icon="Promotion"
              :disabled="pageF.multiple"
              @click="handleYFGenerate"
              v-hasPermi="['tms:tmsDispatchOrder:generate']"
          >生成应付费用
        <el-button type="success" icon="Promotion" :disabled="pageF.multiple" @click="handleYFGenerate"
          v-hasPermi="['tms:tmsDispatchOrder:generate']">生成应付费用
          </el-button>
      </template>
      <template #menu-before="{row}">
        <el-link size="small" type="primary" v-if="[0,1,2,3].includes(row.status)" @click="handleClose(row)" class="link-btn"
                 v-hasPermi="['tms:tmsDispatchOrder:closeOrder']"
                 :underline="false" icon="el-icon-close">作废
        <el-link size="small" type="primary" v-if="[0, 1, 2, 3].includes(row.status)" @click="handleClose(row)"
          class="link-btn" v-hasPermi="['tms:tmsDispatchOrder:closeOrder']" :underline="false" icon="el-icon-close">作废
        </el-link>
        <el-link size="small" type="primary" v-if="![0,1].includes(row.status)" @click="handleLogItinerary(row)"
                 v-hasPermi="['tms:tmsTrip:list']"
                 class="link-btn" :underline="false" icon="el-icon-view">查看行程
          v-hasPermi="['tms:tmsTrip:list']" class="link-btn" :underline="false" icon="el-icon-view">查看行程
        </el-link>
        <el-link size="small" type="primary" v-if="row.accountsReceivableStatus == 0" @click="handleAddFinance(row)"
                 class="link-btn" v-hasPermi="['tms:tmsFinanceDetail:add']"
                 :underline="false" icon="el-icon-edit-pen">费用登记
          class="link-btn" v-hasPermi="['tms:tmsFinanceDetail:add']" :underline="false" icon="el-icon-edit-pen">费用登记
        </el-link>
      </template>
      <template #menu="{row}">
@@ -68,8 +35,7 @@
      <template #body>
        <avue-tabs :option="tabsOption"
                   @change="handleChange"></avue-tabs>
        <avue-tabs :option="tabsOption" @change="handleChange"></avue-tabs>
      </template>
    </avue-crud>
    <el-dialog title="费用登记" v-model="pageF.open" class="avue-dialog avue-dialog--top" width="80%">
@@ -81,22 +47,16 @@
        <el-descriptions-item label="车型">{{form.$actualVehicleType}}</el-descriptions-item>
        <el-descriptions-item label="车牌">{{form.licensePlate}}</el-descriptions-item>
      </el-descriptions>
      <avue-tabs :option="tabsOption2" ref="tabsOption2Ref"
                 @change="handleChange2"></avue-tabs>
      <avue-tabs :option="tabsOption2" ref="tabsOption2Ref" @change="handleChange2"></avue-tabs>
      <div v-if="active === 'tab1'">
        <avue-crud
                   :option="itemsTableOption" ref="itemsTableRef"
                   :data="itemsTableData"
                   @selection-change="selectionChange2"
        >
        <avue-crud :option="itemsTableOption" ref="itemsTableRef" :data="itemsTableData"
          @selection-change="selectionChange2">
          <template #count="{row}">
            <el-input-number v-model="row.count" @change="countChange(row)" placeholder="请输入计费数量"
                             :min="0"></el-input-number>
          </template>
          <template #isYF="{row}">
            <el-checkbox v-model="row.isYF"
                         :true-value="1"
                         :false-value="0"
            <el-checkbox v-model="row.isYF" :true-value="1" :false-value="0"
                         @change="(e:number) =>isYFChange(e, row)" ></el-checkbox>
          </template>
          <template #remark="{row}">
@@ -105,30 +65,25 @@
          <template #expand="{row}">
            <el-descriptions :column="3" border v-if="row.isYF == 1">
              <el-descriptions-item label="服务商">
                <el-select v-model="row.serviceProviderId"  placeholder="请选择服务商"
                           @change="serviceProviderChange(row)"
                <el-select v-model="row.serviceProviderId" placeholder="请选择服务商" @change="serviceProviderChange(row)"
                           :filterable="true">
                  <el-option v-for="item in row.serviceProviderData"
                             :key="item.id" :label="item.serviceShortName"
                  <el-option v-for="item in row.serviceProviderData" :key="item.id" :label="item.serviceShortName"
                              :value="item.id"></el-option>
                </el-select>
              </el-descriptions-item>
              <el-descriptions-item label="是否存在应付报价">
                <span :style="{color: row.isCZYF == 0? 'red': ''}">{{row.isCZYF == 0? '否': row.isCZYF == 1? '是': ''}}</span>
                <span :style="{ color: row.isCZYF == 0 ? 'red' : '' }">{{ row.isCZYF == 0 ? '否' : row.isCZYF == 1 ? '是' :
                  ''}}</span>
              </el-descriptions-item>
              <el-descriptions-item label="计费金额">
                <el-input v-model="row.yfPrice" :min="1"
                          @change="yfPriceChange(row)"
                          type="number" placeholder="请输入金额"></el-input>
                <el-input v-model="row.yfPrice" :min="1" @change="yfPriceChange(row)" type="number"
                  placeholder="请输入金额"></el-input>
              </el-descriptions-item>
              <el-descriptions-item label="币制">
                <el-radio-group v-model="row.yfCurrency" >
                  <el-radio
                      v-for="dict in sys_currency"
                      :key="dict.value"
                      :label="dict.value"
                  >{{ dict.label }}</el-radio>
                  <el-radio v-for="dict in sys_currency" :key="dict.value" :label="dict.value">{{ dict.label
                    }}</el-radio>
                </el-radio-group>
              </el-descriptions-item>
              <el-descriptions-item label="计费数量">
@@ -143,48 +98,35 @@
      </div>
      <div v-if="active === 'tab2'">
        <h2>实报实销费用</h2>
        <avue-form  v-model="boxForm" ref="boxFormRef"
                   :option="boxFormOption">
        <avue-form v-model="boxForm" ref="boxFormRef" :option="boxFormOption">
        </avue-form>
        <avue-crud
            :option="boxTableOption"
            :data="boxTableData"
        >
        <avue-crud :option="boxTableOption" :data="boxTableData">
          <template #isYF="{row}">
            <el-checkbox v-model="row.isYF"
                         :true-value="1"
                         :false-value="0"
            <el-checkbox v-model="row.isYF" :true-value="1" :false-value="0"
                         @change="(e:number) =>isYFChange(e, row)" ></el-checkbox>
          </template>
          <template #yfServiceProviderId="{row}">
            <el-select v-model="row.yfServiceProviderIdType"  placeholder="请选择服务商"
                      @change="(e:any)=>ysServiceProviderChange(e,row)"
                      :filterable="true">
              @change="(e: any) => ysServiceProviderChange(e, row)" :filterable="true">
              <el-option v-for="item in serviceProviderList"
                         :key="item.serviceProviderId + '_'+ item.serviceProviderType" :label="item.serviceProviderName"
                         :value="item.serviceProviderId + '_'+ item.serviceProviderType"></el-option>
            </el-select>
          </template>
          <template #yfPrice="{row}">
            <el-input v-model="row.yfPrice" :min="1"
                      type="number" placeholder="请输入金额"></el-input>
            <el-input v-model="row.yfPrice" :min="1" type="number" placeholder="请输入金额"></el-input>
          </template>
          <template #yfCurrency="{row}">
              <el-radio-group v-model="row.yfCurrency" >
                <el-radio
                    v-for="dict in sys_currency"
                    :key="dict.value"
                    :label="dict.value"
                >{{ dict.label }}</el-radio>
              <el-radio v-for="dict in sys_currency" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
              </el-radio-group>
          </template>
        </avue-crud>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     :loading="pageF.isUploading" @click="submitForm">
          <el-button type="primary" :loading="pageF.isUploading" @click="submitForm">
            {{ pageF.isUploading ? '提交中' : '确 定' }}
          </el-button>
@@ -197,20 +139,12 @@
    <el-dialog :title="pageF.title" v-model="open" class="avue-dialog avue-dialog--top" width="80%">
      <avue-crud
          :option="boxTableOption" ref="itemsTableRef"
          :data="boxTableData"
      >
      <avue-crud :option="boxTableOption" ref="itemsTableRef" :data="boxTableData">
        <template #expand="{row}">
          <avue-crud v-if="optionType === 'ysGenerate'"
              :option="boxItemTableOption" ref="itemsTableRef2"
              :data="row.tmsReceivableFeeItems"
          >
          <avue-crud v-if="optionType === 'ysGenerate'" :option="boxItemTableOption" ref="itemsTableRef2"
            :data="row.tmsReceivableFeeItems">
          </avue-crud>
          <avue-crud v-else
              :option="boxItemTableOption" ref="itemsTableRef2"
              :data="row.payableFeeItems"
          >
          <avue-crud v-else :option="boxItemTableOption" ref="itemsTableRef2" :data="row.payableFeeItems">
          </avue-crud>
        </template>
@@ -229,8 +163,7 @@
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" v-if="optionType != 'view'"
                     :loading="pageF.isUploading" @click="submitGenerate">
          <el-button type="primary" v-if="optionType != 'view'" :loading="pageF.isUploading" @click="submitGenerate">
            {{ pageF.isUploading ? '提交中' : '确 定' }}
          </el-button>
@@ -249,14 +182,12 @@
        <el-descriptions-item label="车牌">{{form.licensePlate}}</el-descriptions-item>
      </el-descriptions>
      <avue-form  v-model="boxForm" ref="boxFormRef"
                  :option="boxFormOption">
      <avue-form v-model="boxForm" ref="boxFormRef" :option="boxFormOption">
      </avue-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     :loading="pageF.isUploading" @click="submitForm5">
          <el-button type="primary" :loading="pageF.isUploading" @click="submitForm5">
            {{ pageF.isUploading ? '提交中' : '确 定' }}
          </el-button>
@@ -613,25 +544,28 @@
  column: {
    dispatchNo: {
      label: '调度单号', minWidth: 120,
      label: '调度单号', minWidth: 140,
      display: false,
      search: true,
    },
    customerName: {
      label: '客户',
      display: false, minWidth: 120,
      display: false, minWidth: 200,
      search: true,
      overHidden: true
    },
    projectName: {
      label: '项目名称',
      display: false, minWidth: 120,
      display: false, minWidth: 150,
      search: true,
      overHidden: true
    },
    contractName: {
      label: '关联合同名称', minWidth: 120,
      label: '关联合同名称', minWidth: 160,
      display: false,
      search: true,
      overHidden: true
    },
    orderType: {
      label: '订单类型',
@@ -704,13 +638,15 @@
    shipperName: {
      label: '装货点名称',
      display: false, minWidth: 120,
      display: false, minWidth: 160,
      search: true,
      overHidden: true
    },
    receiverName: {
      label: '卸货点名称', minWidth: 120,
      label: '卸货点名称', minWidth: 160,
      display: false,
      search: true,
      overHidden: true
    },
    // accountsReceivableStatus: {
    //   label: '应收费用生成状态', minWidth: 160,
@@ -780,22 +716,22 @@
    },
    updateTimeRange: {
      label: '更新时间', display: false, search: true, searchRange: true, type: 'date',
      format: 'YYYY-MM-DD', hide: true, searchSpan: 5,
      format: 'YYYY-MM-DD', hide: true, searchSpan: 6,
      valueFormat: 'YYYY-MM-DD',
    },
    confirmTimeRange: {
      label: '确认时间', display: false, search: true, searchRange: true, type: 'date',
      format: 'YYYY-MM-DD', hide: true, searchSpan: 5,
      format: 'YYYY-MM-DD', hide: true, searchSpan: 6,
      valueFormat: 'YYYY-MM-DD',
    },
    okTimeRange: {
      label: '完成时间', display: false, search: true, searchRange: true, type: 'date',
      format: 'YYYY-MM-DD', hide: true, searchSpan: 5,
      format: 'YYYY-MM-DD', hide: true, searchSpan: 6,
      valueFormat: 'YYYY-MM-DD',
    },
    orderTimeRange: {
      label: '下单时间', display: false, search: true, searchRange: true, type: 'date',
      format: 'YYYY-MM-DD', hide: true, searchSpan: 5,
      format: 'YYYY-MM-DD', hide: true, searchSpan: 6,
      valueFormat: 'YYYY-MM-DD',
    },
@@ -972,6 +908,17 @@
    actualFeeAmount: {
      label: '金额',
      display: true,
    },
    currency: {
      label: '币制',
      display: true,
      type: 'radio', dataType: 'string', dicUrl: '/system/dict/data/type/sys_currency',
      rules: [
        {
          required: true,
          message: "币制不能为空", trigger: "change"
        }
      ],
    },
    feeVoucherUrl: {
      label: '费用凭证',
@@ -1250,12 +1197,51 @@
    isLoad.value = isLoad.value == 0 && !pageF.single ? 0 : -1;
    console.log(pageF.single)
  },
  getBeginListFunc: (params = {}) => {
    queryParams.value = proxy.addDateRangeNew(queryParams.value, queryParams.value?.createTimeRange, 'createTime') || {};
    queryParams.value = proxy.addDateRangeNew(queryParams.value, queryParams.value?.updateTimeRange, 'updateTime') || {};
    queryParams.value = proxy.addDateRangeNew(queryParams.value, queryParams.value?.confirmTimeRange, 'confirmTime') || {};
    queryParams.value = proxy.addDateRangeNew(queryParams.value, queryParams.value?.okTimeRange, 'okTime') || {};
    return params;
    // 1. 日期转换
    let newParams = <any>{ ...params };
    if (newParams) {
      // 1. 定义日期字段映射 (数组名 : 接口需要的前缀)
      // 这样写的好处是:如果你有多个日期,直接在这里添加一行即可
      const dateMap = {
        createTimeRange: 'createTime',
        updateTimeRange: 'updateTime',
        confirmTimeRange: 'confirmTime',
        okTimeRange: 'okTime',
      };
      // 2. 遍历处理日期
      Object.keys(dateMap).forEach(arrayKey => {
        const prefix = dateMap[arrayKey];
        const range = newParams[arrayKey];
        if (Array.isArray(range) && range.length > 0) {
          // 赋值 Begin 和 End
          newParams[`${prefix}Begin`] = range[0];
          newParams[`${prefix}End`] = range[1];
        }
        // 【核心改动】:无论是否有值,处理完后都把原始的 Array 字段删掉
        // 这样请求里就不会出现 confirmTimeRangeArray: [...]
        delete newParams[arrayKey];
      });
      // 3. 通用清洗:删除所有空字符串、null 或 undefined 的其他字段
      Object.keys(newParams).forEach(key => {
        const val = newParams[key];
        if (val === '' || val === null || val === undefined) {
          delete newParams[key];
        }
      });
    } else {
      newParams = {};
    }
    return newParams;
    },
})