1. 新增批量新增盘库差异记录API 2. 新增盘库Excel对比工具函数 3. 新增盘库申请页面与库区明细组件 4. 优化流程图页面,新增流程图下载功能 5. 重构盘库主页面流程状态与操作逻辑 6. 新增多组件拆分与页面模块化改造
144 lines
9.0 KiB
Vue
144 lines
9.0 KiB
Vue
<template>
|
||
<div class="app-container count-container">
|
||
<DragResizePanel :initialSize="280" :minSize="280" :maxSize="600">
|
||
<template #panelA>
|
||
<div class="left-panel">
|
||
<div class="panel-header">
|
||
<div class="header-title">
|
||
<i class="el-icon-s-data"></i>
|
||
<span>差异处理</span>
|
||
<el-button size="mini" type="text" icon="el-icon-refresh" @click="getList" title="刷新列表" />
|
||
</div>
|
||
</div>
|
||
<div class="search-row">
|
||
<el-input v-model="queryParams.planCode" placeholder="搜索计划编号..." clearable prefix-icon="el-icon-search" size="small" @keyup.enter.native="handleQuery" @clear="handleQuery" />
|
||
</div>
|
||
<div v-loading="loading" class="list-body">
|
||
<div v-for="item in dataList" :key="item.planId" class="list-item"
|
||
:class="{ active: currentRow && currentRow.planId === item.planId }" @click="handleRowClick(item)">
|
||
<div class="item-main"><span class="item-title">{{ item.planCode }}</span><span class="item-sub">{{ item.planName }}</span></div>
|
||
<div class="item-meta"><el-tag type="danger" size="mini">差异处理中</el-tag></div>
|
||
</div>
|
||
<div v-if="dataList.length === 0 && !loading" class="list-empty"><i class="el-icon-folder-opened"></i><span>暂无差异处理中的计划</span></div>
|
||
</div>
|
||
<div class="list-footer"><pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" /></div>
|
||
</div>
|
||
</template>
|
||
<template #panelB>
|
||
<div class="right-panel">
|
||
<div v-if="!currentRow" class="empty-tip"><i class="el-icon-info"></i><span>请在左侧列表中选择一条盘库计划</span></div>
|
||
<div v-else v-loading="detailLoading" class="detail-content">
|
||
<div class="doc-header">
|
||
<div class="doc-header-top">
|
||
<div class="doc-title-group"><div class="doc-title">{{ currentRow.planCode }}</div><div class="doc-subtitle">Discrepancy Processing</div></div>
|
||
<div class="doc-header-right"><el-button size="mini" type="text" icon="el-icon-refresh" @click="handleRefreshDetail">刷新</el-button></div>
|
||
</div>
|
||
<div class="doc-status-row"><span class="doc-status-label">Status / 状态:</span><el-tag type="danger" size="small">差异处理中</el-tag></div>
|
||
</div>
|
||
<div class="detail-meta">
|
||
<span><i class="el-icon-document"></i>{{ currentRow.planName }}</span>
|
||
<span v-if="currentRow.countUserName"><i class="el-icon-user-solid"></i>{{ currentRow.countUserName }}</span>
|
||
</div>
|
||
<CountFlowSection :planStatus="3" />
|
||
<el-divider />
|
||
|
||
<WarehouseDetailPanel ref="whPanel"
|
||
:planId="currentRow.planId"
|
||
:planStatus="3"
|
||
@process-disc="handleProcessDisc"
|
||
/>
|
||
|
||
<div class="section-gap" />
|
||
<div class="section-title">备注 <span class="en-sub">· Remarks</span></div>
|
||
<div class="remark-content">{{ currentRow.remark || '无' }}</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</DragResizePanel>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { listCountPlan, getCountPlan, updateCountPlan } from "@/api/flow/countPlan";
|
||
import { updateCountDiscrepancy } from "@/api/flow/countDiscrepancy";
|
||
import DragResizePanel from "@/components/DragResizePanel/index.vue";
|
||
import CountFlowSection from "./components/CountFlowSection.vue";
|
||
import WarehouseDetailPanel from "./components/WarehouseDetailPanel.vue";
|
||
import { parseTime } from '@/utils/klp'
|
||
|
||
export default {
|
||
name: "InvCountExecute",
|
||
components: { DragResizePanel, CountFlowSection, WarehouseDetailPanel },
|
||
data() {
|
||
return {
|
||
loading: false, detailLoading: false, total: 0,
|
||
queryParams: { pageNum: 1, pageSize: 10, planCode: undefined, planStatus: 3 },
|
||
dataList: [], currentRow: null
|
||
};
|
||
},
|
||
created() { this.getList(); },
|
||
methods: {
|
||
parseTime,
|
||
getList() { var self = this; this.loading = true; listCountPlan(this.queryParams).then(function(r) { self.dataList = r.rows; self.total = r.total; }).finally(function() { self.loading = false; }); },
|
||
handleQuery() { this.queryParams.pageNum = 1; this.getList(); },
|
||
handleRowClick(row) { this.currentRow = row; this.detailLoading = true; getCountPlan(row.planId).then(function(r) { self.currentRow = r.data; }).finally(function() { self.detailLoading = false; }); },
|
||
handleRefreshDetail() { if (this.currentRow) { var self = this; this.detailLoading = true; getCountPlan(this.currentRow.planId).then(function(r) { self.currentRow = r.data; }).finally(function() { self.detailLoading = false; }); } },
|
||
handleProcessDisc({ row, relId }) {
|
||
var self = this;
|
||
this.$modal.confirm('确认将该差异项标记为已处理?', '处理确认', { confirmButtonText: '确认处理', cancelButtonText: '取消', type: 'warning' }).then(function() {
|
||
var now = new Date();
|
||
var pad = function(n) { return n < 10 ? '0' + n : '' + n; };
|
||
return updateCountDiscrepancy({
|
||
discrepancyId: row.discrepancyId,
|
||
processResult: row._processResult || '',
|
||
processStatus: 2,
|
||
processTime: now.getFullYear() + '-' + pad(now.getMonth() + 1) + '-' + pad(now.getDate()) + ' ' + pad(now.getHours()) + ':' + pad(now.getMinutes()) + ':' + pad(now.getSeconds())
|
||
});
|
||
}).then(function() {
|
||
self.$modal.msgSuccess('已处理');
|
||
self.$refs.whPanel.refreshOneDisc(relId);
|
||
}).catch(function(err) { if (err !== 'cancel') self.$modal.msgError('处理失败'); });
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
.count-container { height: calc(100vh - 84px); }
|
||
.left-panel { display: flex; flex-direction: column; height: 100%; background: #f5f7fa; border-right: 1px solid #e4e7ed; }
|
||
.panel-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px 8px; background: #f5f7fa; }
|
||
.header-title { display: flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 600; color: #303133; }
|
||
.header-title i { color: #409eff; font-size: 16px; }
|
||
.search-row { display: flex; align-items: center; gap: 6px; padding: 0 14px 10px; background: #f5f7fa; }
|
||
.list-body { flex: 1; overflow-y: auto; padding: 0 6px; }
|
||
.list-item { display: flex; align-items: center; padding: 10px 12px; margin-bottom: 2px; cursor: pointer; border-radius: 6px; transition: all 0.15s; }
|
||
.list-item:hover { background: #ebeef5; }
|
||
.list-item.active { background: #d9ecff; }
|
||
.list-item.active .item-title { color: #409eff; font-weight: 600; }
|
||
.item-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
|
||
.item-title { font-size: 13px; font-weight: 500; color: #303133; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.item-sub { font-size: 12px; color: #909399; }
|
||
.item-meta { flex-shrink: 0; margin: 0 8px; }
|
||
.list-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 60px 0; color: #c0c4cc; font-size: 13px; gap: 8px; }
|
||
.list-empty i { font-size: 32px; }
|
||
.list-footer { border-top: 1px solid #e4e7ed; padding: 2px 8px 0; background: #f5f7fa; }
|
||
.right-panel { height: 100%; overflow-y: auto; padding: 12px 16px; background: #faf8f5; }
|
||
.detail-content { margin: 0 auto; background: #fff; padding: 28px 32px 36px; box-shadow: 0 1px 4px rgba(0,0,0,0.06), 0 2px 12px rgba(0,0,0,0.04); min-height: 100%; }
|
||
.empty-tip { display: flex; align-items: center; justify-content: center; height: 100%; color: #909399; font-size: 14px; gap: 8px; }
|
||
.doc-header { margin-bottom: 18px; padding-bottom: 14px; border-bottom: 2px solid #1a3c6e; }
|
||
.doc-header-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
|
||
.doc-title-group { flex: 1; min-width: 0; }
|
||
.doc-title { font-size: 24px; font-weight: 700; color: #1a1a1a; line-height: 1.3; letter-spacing: 0.5px; }
|
||
.doc-subtitle { font-size: 12px; color: #8c8c8c; font-style: italic; letter-spacing: 0.8px; margin-top: 2px; }
|
||
.doc-header-right { flex-shrink: 0; }
|
||
.doc-status-row { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
|
||
.doc-status-label { font-size: 11px; color: #8c8c8c; letter-spacing: 0.3px; }
|
||
.detail-meta { display: flex; flex-wrap: wrap; gap: 16px; font-size: 12px; color: #909399; margin-bottom: 16px; padding-bottom: 12px; border-bottom: 1px solid #e0dcd6; }
|
||
.detail-meta span { display: inline-flex; align-items: center; gap: 4px; }
|
||
.detail-meta i { font-size: 13px; }
|
||
.section-title { font-size: 15px; font-weight: 700; color: #1a1a1a; margin: 22px 0 12px; padding: 0 0 10px; border-bottom: 1px solid #d4d0c8; display: flex; align-items: center; gap: 10px; }
|
||
.section-title .en-sub { font-size: 11px; font-weight: 400; color: #8c8c8c; letter-spacing: 0.5px; font-style: italic; }
|
||
.remark-content { padding: 12px 16px; background: #faf8f5; border: 1px solid #e8e4de; border-radius: 2px; font-size: 13px; line-height: 1.8; color: #1a1a1a; }
|
||
.section-gap { height: 16px; }
|
||
</style>
|