|
@@ -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>
|