Procházet zdrojové kódy

feat: 批量重计费、手工入账订单操作

lyc před 2 týdny
rodič
revize
4a516dde8b

binární
public/xlsx/settlementFee.xlsx


+ 72 - 1
src/api/notification/notification.ts

@@ -89,4 +89,75 @@ export function SendArrearsFile(data){
       },
     })
   }
-  
+  
+export const GetReComputeVerType = async () => {
+  return axios({
+    url: VUE_APP_BASE_API + "/BaseInfo/GetReComputeVerType",
+    method: "get",
+    timeout: 60 * 1000,
+    headers: {
+      "Content-Type": "application/json",
+      Token: "132A7468DE079C6CEB59F383A661E612",
+    },
+  })
+};
+
+export const GetReCustomerComputeType = async () => {
+  return axios({
+    url: VUE_APP_BASE_API + "/BaseInfo/GetReCustomerComputeType",
+    method: "get",
+    timeout: 60 * 1000,
+    headers: {
+      "Content-Type": "application/json",
+      Token: "132A7468DE079C6CEB59F383A661E612",
+    },
+  })
+};
+
+export function GetReCustomerComputeNew(data) {
+  return axios({
+    url: VUE_APP_BASE_API + '/Finance/ReCustomerComputeNew?systemno='+data.systemNo+'&reCustomerCompute='+data.reCustomerComputeType+'&reComputeVerType='+data.reComputeVerType,
+    data,
+    method: "get",
+    timeout: 60 * 1000,
+    headers: {
+      "Content-Type": "application/json",
+      Token: "132A7468DE079C6CEB59F383A661E612",
+    },
+  })
+}
+
+
+/**
+ * 导入结算
+ */
+export function GetArtificialSaveBranchCompanyFee(data) {
+  return axios({
+    url: VUE_APP_BASE_API + "/finance/GetArtificialSaveBranchCompanyFee",
+    data,
+    method: "post",
+    timeout: 60 * 1000,
+    headers: {
+      "Content-Type": "multipart/form-data;charset=UTF-8",
+      Token: "132A7468DE079C6CEB59F383A661E612",
+    },
+  })
+}
+
+/**
+ * 保存结算入账的数据
+ * @param {*} data
+ * @returns
+ */
+export function GetAsyncArtificialSaveBranchCompanyFee(data) {
+  return axios({
+    url: VUE_APP_BASE_API + "/finance/AsyncArtificialSaveBranchCompanyFee",
+    data,
+    method: "post",
+    timeout: 60 * 1000,
+    headers: {
+      "Content-Type": "application/json",
+      Token: "132A7468DE079C6CEB59F383A661E612",
+    },
+  })
+}

+ 4 - 0
src/style.scss

@@ -84,6 +84,10 @@
     text-align: right;
 }
 
+.text-center {
+    text-align: center;
+}
+
 // 高度
 .h-xl {
     height: 120px;

+ 32 - 0
src/utils/dateFormate.ts

@@ -33,4 +33,36 @@ export function strFormatDateTime(strDate?: string) {
   const strDateArr = strDate.split(" ")
   const newStrDate = strDateArr.length !== 2 ? formatDateTime(`${strDate} 00:00:00`) : strDate
   return newStrDate
+}
+
+/**
+ * 获取当前时间年月日时分秒
+ * @returns
+ */
+export function getCurrentDateTime(hoursTag = ':') {
+  const now = new Date();
+  const year = now.getFullYear(); // 获取当前年份
+  let month: any = now.getMonth() + 1; // 获取当前月份(注意:月份从0开始,需要加1)
+  let day: any = now.getDate(); // 获取当前日期
+  let hours: any = now.getHours(); // 获取当前小时
+  let minutes: any = now.getMinutes(); // 获取当前分钟
+  let seconds: any = now.getSeconds(); // 获取当前秒钟
+  // 如果月、日、小时、分钟、秒钟小于10,在前面补0
+  if (month < 10) {
+    month = '0' + month;
+  }
+  if (day < 10) {
+    day = '0' + day;
+  }
+  if (hours < 10) {
+    hours = '0' + hours;
+  }
+  if (minutes < 10) {
+    minutes = '0' + minutes;
+  }
+  if (seconds < 10) {
+    seconds = '0' + seconds;
+  }
+  const datetime = year + '-' + month + '-' + day + ' ' + hours + hoursTag + minutes + hoursTag + seconds;
+  return datetime;
 }

+ 22 - 1
src/utils/index.ts

@@ -70,4 +70,25 @@ export function flattenMenuArray<T = any>(arr: Recordable[]): T[] {
         }
     });
     return result as T[];
-}
+}
+
+/**
+ * 函数节流
+ * @param {*} func
+ * @param {*} delay
+ * @returns
+ */
+export function defineThrottle(callback, delay) {
+    let timeoutId
+    let lastTriggerTime = 0
+    return function () {
+      const now = Date.now()
+      if (now - lastTriggerTime >= delay) {
+        lastTriggerTime = now
+        callback()
+      } else {
+        clearTimeout(timeoutId)
+        timeoutId = setTimeout(callback, delay)
+      }
+    }
+  }

+ 417 - 0
src/views/orderOperation/manualSettlement.vue

@@ -0,0 +1,417 @@
+<template>
+  <div class="app-container">
+    <div class="batch-import-weight">
+      <el-divider content-position="left">
+        手工结算入账
+      </el-divider>
+      <div class="p-4">
+        <el-alert
+          :closable="false"
+          type="info"
+        >
+          <div class="info-text">
+            <span class="font-size">根据指定模板文件进行手工结算入账导入,点击此处</span><el-link
+              type="primary"
+              class="font-size"
+            >
+              <a
+                href="javascript:;"
+                @click="downloadXlsx('settlementFee')"
+              >
+                下载模板
+              </a>
+            </el-link>
+          </div>
+        </el-alert>
+        <el-form
+          class="define-form"
+          inline
+        >
+          <el-form-item class="upload-item">
+            <el-upload
+              ref="importUploadRef"
+              action="/"
+              accept=".xlsx"
+              :disabled="confirmLoading"
+              :multiple="false"
+              :auto-upload="false"
+              :show-file-list="false"
+              :on-change="uploadSuccess"
+            >
+              <el-button
+                type="primary"
+                plain
+                :loading="confirmLoading"
+              >
+                选择文件
+              </el-button>
+            </el-upload>
+          </el-form-item>
+          <el-form-item>
+            <el-button
+              v-show="isSaveShow"
+              type="success"
+              plain
+              :loading="accountEntryLoading"
+              @click="onSaveSettlementAccounting"
+            >
+              保存手工结算入账
+            </el-button>
+            <el-button
+              v-show="isAbnormalShow"
+              type="danger"
+              plain
+              :loading="exportLoading"
+              @click="onExportAbnormalData"
+            >
+              导出异常数据
+            </el-button>
+          </el-form-item>
+        </el-form>
+        <vxe-table
+          ref="xTableSettlement"
+          border
+          :data="pageManualSettlement"
+          :loading="customerWeightLoading"
+          :row-config="{isHover: true}"
+          :row-class-name="rowClassName"
+          :height="tableHeight"
+          :header-row-style="{
+            background: '#E6F7FF',
+            borderRight: '1px solid #ccc',
+          }"
+          :scroll-y="{enabled: false}"
+          :column-config="{ resizable: true }"
+        >
+          <vxe-column
+            title="单号"
+            field="Number"
+            :min-width="260"
+          />
+          <vxe-column
+            title="实际总成本"
+            field="TotalCost"
+            :min-width="110"
+          />
+          <vxe-column
+            title="结算重量"
+            field="TotalWeight"
+            :min-width="100"
+          />
+          <vxe-column
+            title="内部结算成本单价"
+            field="AvgHandingCharge"
+            :min-width="150"
+          />
+          <vxe-column
+            title="内部结算成本总计"
+            field="TotahHandlingCharge"
+            :min-width="130"
+          />
+          <vxe-column
+            title="结算总计"
+            field="SumHandlingCharge"
+            :min-width="100"
+          />
+          <vxe-column
+            title="是否已有结算价"
+            field="HasHandingCharge"
+            :min-width="130"
+          >
+            <template #default="{ row }">
+              <el-tag :type="row.HasHandingCharge ? '': 'info'">
+                {{ row.HasHandingCharge ? '是': '否' }}
+              </el-tag>
+            </template>
+          </vxe-column>
+          <vxe-column
+            title="已有结算总计"
+            field="OldSumHandlingCharge"
+            :min-width="120"
+          />
+          <vxe-column
+            title="处理方案"
+            field="Solution"
+            :min-width="120"
+          >
+            <template #default="{ row }">
+              {{ getSolutionText(row.Solution) }}
+            </template>
+          </vxe-column>
+          <vxe-column
+            field="Error"
+            :min-width="240"
+            title="异常信息"
+          />
+          <vxe-column
+            field="ResultStatus"
+            :min-width="60"
+            title="提示"
+          >
+            <template #default="{ row }">
+              {{ row.ResultStatus === 200 ? '成功' : '' }}
+            </template>
+          </vxe-column>
+        </vxe-table>
+        <el-pagination
+          :page-sizes="[100, 200, 300, 400, 500]"
+          :current-page="pagerDto.PageIndex"
+          :page-size="pagerDto.PageSize"
+          background
+          layout="prev, pager, next ,total ,jumper,sizes,slot "
+          :total="totalManualSettlement"
+          @current-change="pageManualSettlementChange"
+          @size-change="sizeManualSettlementChange"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { ElMessage } from "element-plus";
+import { GetArtificialSaveBranchCompanyFee, GetAsyncArtificialSaveBranchCompanyFee } from '@/api/notification/notification';
+import { defineComponent } from "vue";
+import { getCurrentDateTime } from '@/utils/dateFormate';
+import { cloneDeep } from '@/utils/cloneDeep';
+import { defineThrottle } from '@/utils';
+
+export default defineComponent({
+  name: 'ManualSettlement',
+  data() {
+    return {
+      loading: false,
+      countingThrowingList: [] as Recordable[],
+      weightThrowingData: [] as Recordable[],
+      dialogWeight: false,
+      editWeightId: undefined,
+      batchListSource: [],
+      confirmLoading: false,
+      accountEntryLoading: false,
+      exportLoading: false,
+      tableHeight: 480,
+      throttledResize: null as unknown as any,
+      weightThrowingDataPage: 1,
+      weightThrowingDataSize: 100,
+      listSourceSize: 100,
+      pageWeightThrowingLoading: false,
+      customerWeightLoading: false,
+      manualSettlementData: [] as Recordable[],
+      pageManualSettlement: [] as Recordable[],
+      pagerDto: {
+        PageIndex: 1,
+        PageSize: 100
+      }
+    }
+  },
+  computed: {
+    totalManualSettlement() {
+      // @ts-ignore
+      return this.manualSettlementData.length;
+    },
+    isSaveShow() {
+      // @ts-ignore
+      return this.pageManualSettlement && this.pageManualSettlement.length > 0
+    },
+    isAbnormalShow() {
+      // @ts-ignore
+      const filterList = this.pageManualSettlement.filter(item => !!item.Error)
+      return filterList.length > 0
+    },
+  },
+  mounted() {
+    this.createThrottledResize()
+    window.addEventListener('resize', this.throttledResize)
+  },
+  beforeUnmount() {
+    window.removeEventListener('resize', this.throttledResize)
+  },
+  deactivated() {
+    window.removeEventListener('resize', this.throttledResize)
+  },
+  methods: {
+    getSolutionText(val) {
+      switch (val) {
+        case 0:
+          return '未重复无须处理'
+        case 1:
+          return '跳过'
+        case 2:
+          return '覆盖'
+      }
+    },
+    async onSaveSettlementAccounting() {
+      const filterList = this.pageManualSettlement.filter(item => !item.Error)
+      if (filterList.length === 0) {
+        ElMessage({ type: 'warning', message: '暂无数据保存!' })
+        return
+      }
+      // 同步
+      const deepCloneList = cloneDeep(this.pageManualSettlement)
+      const pageList = deepCloneList.map(obj => {
+        delete obj['_X_ROW_KEY'];
+        delete obj['ResultStatus'];
+        return obj;
+      });
+      try {
+        this.accountEntryLoading = true
+        for await (const rowData of pageList) {
+          if (!rowData.Error) {
+            const res = await GetAsyncArtificialSaveBranchCompanyFee(rowData)
+            if (res.data && res.data.Code === 200) {
+              const findIndex = this.pageManualSettlement.findIndex(item => item.Number == rowData.Number)
+              this.manualSettlementData[findIndex].ResultStatus = 200
+            }
+          }
+        }
+        ElMessage({ type: 'success', message: '保存成功' })
+      } finally {
+        this.accountEntryLoading = false
+        this.settlementSortList()
+      }
+    },
+    initPageManualSettlement() {
+      const start = (this.pagerDto.PageIndex - 1) * this.pagerDto.PageSize;
+      const end = start + this.pagerDto.PageSize;
+      this.pageManualSettlement = this.manualSettlementData.slice(start, end);
+    },
+    settlementSortList() {
+      this.pageManualSettlement = this.manualSettlementData.sort((a, b) => {
+        if (a.ResultStatus === 200 && b.ResultStatus !== 200) {
+          return 1;
+        } else if (a.ResultStatus !== 200 && b.ResultStatus === 200) {
+          return -1;
+        } else {
+          return 0;
+        }
+      });
+    },
+    onExportAbnormalData() {
+      const currentDate = getCurrentDateTime('-')
+      const filename = '结算异常数据' + currentDate
+      this.exportLoading = true
+      // @ts-ignore
+      this.$refs.xTableSettlement.exportData({
+        dataFilterMethod({ row }) {
+          return !!row.Error;
+        },
+        filename
+      })
+      this.exportLoading = false
+    },
+    // 明细分页-前端
+    pageManualSettlementChange(page) {
+      this.pagerDto.PageIndex = page;
+      this.initPageManualSettlement()
+    },
+    sizeManualSettlementChange(size) {
+      this.pagerDto.PageIndex = 1;
+      this.pagerDto.PageSize = size;
+      this.initPageManualSettlement()
+    },
+    // 表格错误样式
+    rowClassName({ row }) {
+      if(!!row.Error) return 'text-red'
+    },
+    // 计算表格的高度
+    getTableHeight: function() {
+      const tableHeight = window.innerHeight - 330
+      this.tableHeight = tableHeight <= 480 ? 480 : tableHeight
+    },
+    createThrottledResize() {
+      this.getTableHeight()
+      this.throttledResize = defineThrottle(this.getTableHeight, 1000); // 使用lodash的throttle方法,设置节流的时间间隔为500ms
+    },
+    downloadXlsx(name) {
+      const fileUrl = `/xlsx/${name}.xlsx`
+      const link = document.createElement('a')
+      link.href = fileUrl
+      link.setAttribute('download', `${name}.xlsx`) // 设置下载属性和文件名
+      document.body.appendChild(link)
+      link.click()
+      document.body.removeChild(link) // 点击后移除链接
+    },
+    // 上传xlsx文件
+    uploadSuccess(file) {
+      const _this = this
+      // 处理文件选择的逻辑
+      const excelFile = file.raw;
+      const isXlsx = excelFile.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
+      if (!isXlsx) {
+        ElMessage({ message: '只能上传 xlsx 文件!', type: 'error' })
+        return
+      }
+      const formData = new FormData()
+      formData.append('file', excelFile)
+      _this.confirmLoading = true
+      // _this.pageWeightThrowingLoading = true
+      _this.customerWeightLoading = true
+      // _this.hanleOpenEditWeight()
+      GetArtificialSaveBranchCompanyFee(formData).then((res) => {
+        if (res.data && res.data.length > 0) {
+          _this.manualSettlementData = res.data
+          _this.weightThrowingData = res.data
+          _this.initPageManualSettlement()
+        }
+      }).finally(() => {
+        _this.confirmLoading = false
+        // _this.pageWeightThrowingLoading = false
+        _this.customerWeightLoading = false
+      })
+    },
+    // 显示隐藏
+    hanleOpenEditWeight() {
+      this.dialogWeight = true
+    },
+    closeDialogWeight() {
+      this.dialogWeight = false
+      this.editWeightId = undefined
+      this.weightThrowingData = []
+    }
+  }
+})
+</script>
+
+<style lang="scss" scoped>
+  .batch-import-weight-form .el-input-number ::v-deep .el-input__inner {
+    text-align: left !important;
+  }
+  .batch-import-weight {
+    .info-text {
+      display: inline-flex;
+      padding: 6px 0;
+      .font-size {
+        font-size: 15px;
+      }
+    }
+    .define-form {
+      margin: 10px 0;
+      .el-form-item {
+        margin-bottom: 0;
+      }
+      .upload-item {
+        margin-right: 12px;
+      }
+    }
+    .count-warp {
+      padding-bottom: 10px;
+      line-height: 1.3;
+      font-size: 14px;
+      font-weight: bold;
+      color: #606266;
+
+      .total {
+        font-size: 17px;
+        color: #1A73E8;
+      }
+      .error {
+        font-size: 17px;
+        color: red;
+      }
+      .success {
+        font-size: 17px;
+        color: #67C23A;
+      }
+    }
+  }
+</style>

+ 353 - 0
src/views/orderOperation/orderBatchRecharging.vue

@@ -0,0 +1,353 @@
+<template>
+  <div class="app-container">
+    <div class="filter-container">
+      <el-divider content-position="left"> 订单批量重计费 </el-divider>
+      <div class="recharing-order-warp">
+        <div class="itemGroup">
+          <el-form v-loading="loading" :model="paramsDto">
+            <el-form-item label="重算类型" label-width="100px">
+              <el-select
+                v-model="paramsDto.reCustomerComputeType"
+                placeholder="重算类型"
+                clearable
+                filterable
+              >
+                <el-option
+                  v-for="item in reCustomerComputeType"
+                  :key="item.Value"
+                  :label="item.Name"
+                  :value="item.Value"
+                />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="版本类型" label-width="100px">
+              <el-select
+                v-model="paramsDto.reComputeVerType"
+                placeholder="版本类型"
+                clearable
+                filterable
+              >
+                <el-option
+                  v-for="item in reComputeVerType"
+                  :key="item.Value"
+                  :label="item.Name"
+                  :value="item.Value"
+                />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="系统单号" label-width="100px">
+              <div class="systemNo">
+                <el-input
+                  v-model="paramsDto.systemNo"
+                  type="textarea"
+                  placeholder="请输入单号,每行一个"
+                  :autosize="{ minRows: 18, maxRows: 500 }"
+                  class="item-form"
+                />
+                <span class="define-right"
+                  >{{ currentRowNum }}/{{ maxRowNum }}</span
+                >
+              </div>
+            </el-form-item>
+          </el-form>
+          <div class="text-center footer-btns">
+            <el-button
+              type="success"
+              :loading="confirmLoading"
+              :disabled="isBatchConfirm"
+              @click="confirmBatchChannelOrder"
+            >
+              批量提交
+            </el-button>
+            <el-button
+              class="error-btn"
+              type="primary"
+              :loading="confirmLoading"
+              @click="hanleRefreshError"
+            >
+              错误重试
+            </el-button>
+          </div>
+        </div>
+        <div class="batch-warp">
+          <vxe-table
+            border
+            :data="batchListSource"
+            :row-config="{ isHover: true }"
+            :row-class-name="rowClassName"
+            :header-row-style="{
+              background: '#E6F7FF',
+              borderRight: '1px solid #ccc',
+            }"
+            :scroll-y="{ enabled: false }"
+            :column-config="{ resizable: true }"
+          >
+            <vxe-column title="提交时间" field="CreateTime" :min-width="120" />
+            <vxe-column title="系统单号" field="SystemNo" :min-width="200" />
+            <vxe-column title="提示内容" field="ResultMessage" :min-width="180">
+              <template #default="{ row }">
+                <div v-show="row.ResultMessage !== '-'">
+                  {{ row.ResultMessage }}
+                </div>
+                <el-button
+                  v-show="row.ResultMessage === '-'"
+                  type="text"
+                  :loading="row.ResultMessage === '-'"
+                />
+              </template>
+            </vxe-column>
+          </vxe-table>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from "vue";
+import { ElMessage } from "element-plus";
+import {
+  GetReComputeVerType,
+  GetReCustomerComputeNew,
+  GetReCustomerComputeType,
+} from "@/api/notification/notification";
+import { getCurrentDateTime } from "@/utils/dateFormate";
+
+export default defineComponent({
+  name: "OrderBatchRecharging",
+  data: function () {
+    return {
+      loading: false,
+      paramsDto: {
+        systemNo: null,
+        reCustomerComputeType: null,
+        reComputeVerType: null,
+      },
+      reComputeVerType: [] as Recordable[],
+      reCustomerComputeType: [] as Recordable[],
+      confirmLoading: false,
+      batchListSource: [] as Recordable[],
+      currentRowNum: 0,
+      maxRowNum: 500,
+    };
+  },
+  watch: {
+    // 监听跟踪单号
+    "paramsDto.systemNo"(newValue, oldValue) {
+      const rowNum = this.getRow();
+      const maxRowNum = this.maxRowNum;
+      this.currentRowNum = rowNum === maxRowNum ? maxRowNum : rowNum;
+      if (rowNum > maxRowNum) {
+        this.paramsDto.systemNo = oldValue;
+      }
+    },
+  },
+  computed: {
+    isBatchConfirm() {
+      // @ts-ignore
+      return !this.paramsDto.reCustomerComputeType || !this.paramsDto.reComputeVerType || !this.paramsDto.systemNo
+    }
+  },
+  created() {
+    GetReCustomerComputeType().then((response) => {
+      const results = response.data.data
+      if (results) this.reCustomerComputeType = results;
+    });
+    GetReComputeVerType().then((response) => {
+      const results = response.data.data
+      if (results) this.reComputeVerType = results;
+    });
+  },
+  methods: {
+    getCancelOrder(rowData, rowIndex) {
+      const type = this.paramsDto.reCustomerComputeType;
+      const reComputeVerType = this.paramsDto.reComputeVerType;
+
+      return new Promise((resolve) => {
+        if (rowData.SystemNo) {
+          // 初始化时间
+          const createTime = getCurrentDateTime();
+          this.batchListSource[rowIndex].CreateTime = createTime;
+          const currentIndex = this.batchListSource.findIndex(
+            (i) => i.id === rowData.id
+          );
+          GetReCustomerComputeNew({
+            systemNo: rowData.SystemNo,
+            reCustomerComputeType: type,
+            reComputeVerType: reComputeVerType,
+          })
+            .then((res) => {
+              const results = res.data.data
+              if (results && results.length > 0 && currentIndex >= 0) {
+                const currentObj = results[0];
+                this.batchListSource[currentIndex] = currentObj;
+              } else {
+                this.batchListSource[currentIndex].ResultMessage = "操作成功";
+                this.batchListSource[currentIndex].ResultState = 200;
+              }
+            })
+            .catch((error) => {
+              if (currentIndex >= 0) {
+                const resultMessage = error.response.data.message || error
+                this.batchListSource[currentIndex].ResultMessage = resultMessage;
+                this.batchListSource[currentIndex].ResultState = 500;
+              }
+            })
+            .finally(() => {
+              if (currentIndex >= 0) {
+                // 更新时间
+                this.batchListSource[rowIndex].CreateTime = createTime;
+                this.channelsOrderSortList();
+                resolve(true);
+              }
+              const isEvery = this.batchListSource.every(
+                (item) => item.ResultMessage !== "-"
+              );
+              if (isEvery) this.confirmLoading = false;
+            });
+        }
+      });
+    },
+    // 批量取消渠道订单
+    async updateBatchChannelOrder(systemNoList) {
+      const list: Recordable[] = [];
+      systemNoList.forEach((order, index) => {
+        if (order) {
+          list.push({
+            id: `${index}_systemNo`,
+            CreateTime: "-",
+            SystemNo: order.trim(),
+            ResultMessage: "-",
+          });
+        }
+      });
+      this.batchListSource = list;
+      // 同步
+      for await (const [rowIndex, rowData] of list.entries()) {
+        if (rowData.SystemNo) {
+          await this.getCancelOrder(rowData, rowIndex);
+        }
+      }
+    },
+    // 批量提交
+    confirmBatchChannelOrder() {
+      const systemNo = this.paramsDto.systemNo as unknown as string;
+      if (!systemNo) {
+        ElMessage({
+          type: "warning",
+          message: "请输入系统单号",
+        });
+        return;
+      }
+      const systemNoes = systemNo.split("\n");
+      const systemNoList = systemNoes.filter((item) => item);
+      if (systemNoList.length === 0) {
+        ElMessage({
+          type: "warning",
+          message: "请输入系统单号",
+        });
+        return;
+      }
+      this.confirmLoading = true;
+      this.updateBatchChannelOrder(systemNoList);
+    },
+    // 错误重试
+    async hanleRefreshError() {
+      const isEvery = this.batchListSource.every(
+        (item) => item.ResultState === 200
+      );
+      if (isEvery) {
+        ElMessage({
+          type: "warning",
+          message: "暂无系统单号重试",
+        });
+        return;
+      }
+      this.confirmLoading = true;
+      // 同步
+      for await (const [rowIndex, rowData] of this.batchListSource.entries()) {
+        if (rowData.ResultState === 500) {
+          await this.getCancelOrder(rowData, rowIndex);
+        }
+      }
+    },
+    // 错误排序
+    channelsOrderSortList() {
+      this.batchListSource = this.batchListSource.sort((a, b) => {
+        // 根据错误排序
+        if (a.ResultState === 500 && b.ResultState === 200) {
+          return -1;
+        } else if (a.ResultState === 200 && b.ResultState === 500) {
+          return 1;
+        } else {
+          // 根据时间排序
+          const CreateTimeB: any = new Date(b.CreateTime);
+          const CreateTimeA: any = new Date(a.CreateTime);
+          return CreateTimeB - CreateTimeA;
+        }
+      });
+    },
+    // 获取当前跟踪单号文本框的行数
+    getRow() {
+      const systemNo = this.paramsDto.systemNo as unknown as string;
+      if (!systemNo) return 0;
+      let row = 0;
+      const systemNoList = systemNo.split("\n");
+      systemNoList.forEach((item) => {
+        if (item.length === 0) {
+          row += 1;
+        } else {
+          row += Math.ceil(item.replace(/[\u0391-\uFFE5]/g, "aa").length / 50);
+        }
+      });
+      return row;
+    },
+    // 表格错误样式
+    rowClassName({ row }) {
+      if (row.ResultState === 500) return "text-red";
+    },
+  },
+});
+</script>
+
+<style scoped>
+.recharing-order-warp {
+  display: flex;
+  overflow-y: scroll;
+}
+.recharing-order-warp .itemGroup {
+  position: relative;
+  height: 78vh;
+  overflow: auto;
+  flex-basis: 43%;
+  flex-shrink: 0;
+  margin: 10px;
+  border: 1px solid #d3d4d6;
+  padding: 30px 10px 0px 10px;
+}
+.recharing-order-warp .itemGroup .footer-btns {
+  position: sticky;
+  bottom: 0;
+  padding-bottom: 30px;
+  background-color: #ffffff;
+}
+.recharing-order-warp .itemGroup .systemNo {
+  position: relative;
+  width: 100%;
+}
+.recharing-order-warp .itemGroup .define-right {
+  position: absolute;
+  color: #909399;
+  font-size: 12px;
+  top: 0;
+  right: 42px;
+}
+.recharing-order-warp .itemGroup .item-form {
+  width: 95%;
+}
+.recharing-order-warp .batch-warp {
+  flex: 1;
+  margin: 10px;
+  border: 1px solid #d3d4d6;
+}
+</style>