Merge remote-tracking branch 'origin/0.8.X' into 0.8.X
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
:clearable="clearable"
|
||||
:disabled="disabled"
|
||||
:size="size"
|
||||
:multiple="multiple"
|
||||
filterable
|
||||
@change="onChange"
|
||||
style="width: 100%"
|
||||
@@ -30,9 +31,13 @@ export default {
|
||||
name: 'ActualWarehouseL1L2Select',
|
||||
props: {
|
||||
value: {
|
||||
type: [Number, String],
|
||||
type: [Number, String, Array, null],
|
||||
default: null
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择实际库区'
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
:clearable="clearable"
|
||||
:disabled="disabled"
|
||||
:size="size"
|
||||
:multiple="multiple"
|
||||
filterable
|
||||
@change="onChange"
|
||||
style="width: 100%"
|
||||
@@ -30,9 +31,13 @@ export default {
|
||||
name: 'WarehouseSelect',
|
||||
props: {
|
||||
value: {
|
||||
type: [Number, String, null],
|
||||
type: [Number, String, Array, null],
|
||||
default: null
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择仓库'
|
||||
@@ -62,10 +67,12 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
console.log('[WarehouseSelect] value changed:', val, 'type:', typeof val, 'isArray:', Array.isArray(val));
|
||||
this.selected = val;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log('[WarehouseSelect] mounted, initial value:', this.value, 'multiple:', this.multiple);
|
||||
this.loadOptions();
|
||||
},
|
||||
methods: {
|
||||
@@ -136,7 +143,11 @@ export default {
|
||||
},
|
||||
onChange(val) {
|
||||
if (val) {
|
||||
this.updateWarehouseUsage(val);
|
||||
if (this.multiple && Array.isArray(val)) {
|
||||
val.forEach(function(id) { this.updateWarehouseUsage(id); }, this);
|
||||
} else {
|
||||
this.updateWarehouseUsage(val);
|
||||
}
|
||||
}
|
||||
this.$emit('input', val);
|
||||
this.$emit('change', val);
|
||||
|
||||
@@ -28,9 +28,13 @@
|
||||
subtitle="Application"
|
||||
emptyText="请在左侧列表中选择一条盘库计划"
|
||||
@submit-approval="handleSubmitApproval"
|
||||
@approve="handlePlanApprove"
|
||||
@reject="handleReject"
|
||||
@edit-plan="handleUpdate"
|
||||
@delete-plan="handleDelete"
|
||||
@bind-warehouse="handleAddWarehouse"
|
||||
@edit-warehouse="handleEditWarehouse"
|
||||
@delete-warehouse="handleDeleteWarehouse"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -41,29 +45,43 @@
|
||||
<el-form-item label="计划名称" prop="planName"><el-input v-model="planForm.planName" placeholder="请输入计划名称" /></el-form-item>
|
||||
<el-form-item label="盘库日期" prop="countDate"><el-date-picker v-model="planForm.countDate" type="date" value-format="yyyy-MM-dd" placeholder="请选择盘库日期" style="width:100%" /></el-form-item>
|
||||
<el-form-item label="截止时间" prop="deadlineTime"><el-date-picker v-model="planForm.deadlineTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择截止时间" style="width:100%" /></el-form-item>
|
||||
<el-form-item label="盘点人"><el-input v-model="planForm.countUserName" placeholder="请输入盘点人" /></el-form-item>
|
||||
<el-form-item label="负责人"><el-input v-model="planForm.principalUserName" placeholder="请输入负责人" /></el-form-item>
|
||||
<el-form-item label="参与人"><el-input v-model="planForm.participantNames" placeholder="请输入参与人员" /></el-form-item>
|
||||
<el-form-item label="盘点人"><el-select v-model="planForm.countUserName" filterable allow-create default-first-option placeholder="请输入盘点人" style="width:100%"><el-option v-for="e in employeeList" :key="e" :label="e" :value="e" /></el-select></el-form-item>
|
||||
<el-form-item label="负责人"><el-select v-model="planForm.principalUserName" filterable allow-create default-first-option placeholder="请输入负责人" style="width:100%"><el-option v-for="e in employeeList" :key="e" :label="e" :value="e" /></el-select></el-form-item>
|
||||
<el-form-item label="参与人"><el-select v-model="participantNamesArr" multiple filterable allow-create default-first-option placeholder="请输入参与人员" style="width:100%"><el-option v-for="e in employeeList" :key="e" :label="e" :value="e" /></el-select></el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="planForm.remark" type="textarea" :rows="3" placeholder="请输入备注" /></el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer"><el-button :loading="btnLoading" type="primary" @click="submitPlan">确定</el-button><el-button @click="planDialogOpen = false">取消</el-button></div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="绑定库区" :visible.sync="whDialogOpen" width="550px" append-to-body>
|
||||
<el-form :model="whForm" label-width="120px">
|
||||
<el-form-item label="逻辑库区"><WarehouseSelect ref="wsRef" v-model="whForm.warehouseId" @change="onWhChange" /></el-form-item>
|
||||
<el-form-item label="实际库区"><ActualWarehouseL1L2Select ref="awsRef" v-model="whForm.actualWarehouseId" @change="onAwhChange" /></el-form-item>
|
||||
<el-dialog :title="whDialogTitle" :visible.sync="whDialogOpen" width="550px" append-to-body>
|
||||
<el-form :model="whForm" label-width="120px" :key="'wh-form-' + whDialogMode + '-' + (editingRelId || 0)">
|
||||
<el-form-item label="逻辑库区"><WarehouseSelect ref="wsRef" v-model="whForm.warehouseIds" multiple @change="onWhChange" /></el-form-item>
|
||||
<el-form-item label="实际库区"><ActualWarehouseL1L2Select ref="awsRef" v-model="whForm.actualWarehouseIds" multiple @change="onAwhChange" /></el-form-item>
|
||||
<el-form-item label="出入库起始"><el-date-picker v-model="whForm.ioStartTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width:100%" /></el-form-item>
|
||||
<el-form-item label="出入库截止"><el-date-picker v-model="whForm.ioEndTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width:100%" /></el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer"><el-button :loading="whBtnLoading" type="primary" @click="submitWh">确定</el-button><el-button @click="whDialogOpen = false">取消</el-button></div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 驳回审批对话框 -->
|
||||
<el-dialog title="驳回审批" :visible.sync="rejectDialogVisible" width="520px" append-to-body>
|
||||
<div class="reject-quick-reasons">
|
||||
<span class="reject-quick-label">快捷理由:</span>
|
||||
<el-tag v-for="(r, i) in rejectQuickReasons" :key="i" class="reject-tag" size="small" @click="rejectReason = r">{{ r }}</el-tag>
|
||||
</div>
|
||||
<el-input v-model="rejectReason" type="textarea" :rows="4" placeholder="请输入驳回原因" style="margin-top:10px;" />
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="danger" @click="confirmReject" :disabled="!rejectReason.trim()">确认驳回</el-button>
|
||||
<el-button @click="rejectDialogVisible = false">取消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listCountPlan, addCountPlan, updateCountPlan, delCountPlan } from "@/api/flow/countPlan";
|
||||
import { addCountPlanWarehouse } from "@/api/flow/countPlanWarehouse";
|
||||
import { addCountPlanWarehouse, updateCountPlanWarehouse, delCountPlanWarehouse } from "@/api/flow/countPlanWarehouse";
|
||||
import { listEmployeeInfo } from "@/api/wms/employeeInfo";
|
||||
import DragResizePanel from "@/components/DragResizePanel/index.vue";
|
||||
import PlanDetailPanel from "./components/PlanDetailPanel.vue";
|
||||
import WarehouseSelect from "@/components/KLPService/WarehouseSelect/index.vue";
|
||||
@@ -77,25 +95,32 @@ export default {
|
||||
return {
|
||||
loading: false, btnLoading: false, whBtnLoading: false, submitLoading: false, total: 0, dataList: [], currentRow: null,
|
||||
queryParams: { pageNum: 1, pageSize: 10, planCode: undefined, planStatus: 0 },
|
||||
planDialogOpen: false, planDialogTitle: '', planForm: {},
|
||||
whDialogOpen: false, whForm: { warehouseId: undefined, actualWarehouseId: undefined, warehouseName: '', actualWarehouseName: '', ioStartTime: undefined, ioEndTime: undefined }
|
||||
planDialogOpen: false, planDialogTitle: '', planForm: {}, employeeList: [], participantNamesArr: [],
|
||||
whDialogOpen: false, whDialogTitle: '绑定库区', whDialogMode: 'add', editingRelId: null, whForm: { warehouseIds: [], actualWarehouseIds: [], warehouseName: '', actualWarehouseName: '', ioStartTime: undefined, ioEndTime: undefined },
|
||||
rejectDialogVisible: false, rejectReason: '', rejectQuickReasons: ['盘点计划信息不完整,请补充后重新提交', '库区绑定有误,请核实库区信息', '盘点时间安排不合理,请调整', '盘点人员安排需调整', '缺少必要的备注说明']
|
||||
};
|
||||
},
|
||||
created() { this.getList(); },
|
||||
created() { this.getList(); this.loadEmployees(); },
|
||||
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; },
|
||||
handleAdd() { this.planForm = { planName: new Date().toLocaleDateString().replace(/\//g, '-') + '盘库计划' }; this.planDialogTitle = '新增盘库计划'; this.planDialogOpen = true; },
|
||||
handleUpdate(row) { this.planForm = Object.assign({}, row); this.planDialogTitle = '修改'; this.planDialogOpen = true; },
|
||||
submitPlan() { var self = this; this.btnLoading = true; this.planForm.planCode = this.planForm.planName; var api = this.planForm.planId ? updateCountPlan : addCountPlan; api(this.planForm).then(function() { self.$modal.msgSuccess('成功'); self.planDialogOpen = false; self.getList(); }).finally(function() { self.btnLoading = false; }); },
|
||||
loadEmployees() { var self = this; listEmployeeInfo({ pageNum: 1, pageSize: 9999 }).then(function(r) { self.employeeList = (r.rows || []).map(function(e) { return e.name || ''; }).filter(Boolean); }); },
|
||||
handleAdd() { this.planForm = { planName: new Date().toLocaleDateString().replace(/\//g, '-') + '盘库计划' }; this.participantNamesArr = []; this.planDialogTitle = '新增盘库计划'; this.planDialogOpen = true; },
|
||||
handleUpdate(row) { this.planForm = Object.assign({}, row); this.participantNamesArr = row.participantNames ? row.participantNames.split(',') : []; this.planDialogTitle = '修改'; this.planDialogOpen = true; },
|
||||
submitPlan() { var self = this; this.btnLoading = true; this.planForm.planCode = this.planForm.planName; this.planForm.participantNames = this.participantNamesArr.join(','); var api = this.planForm.planId ? updateCountPlan : addCountPlan; api(this.planForm).then(function() { self.$modal.msgSuccess('成功'); self.planDialogOpen = false; self.getList(); }).finally(function() { self.btnLoading = false; }); },
|
||||
handleDelete(row) { var self = this; this.$modal.confirm('确认删除?').then(function() { return delCountPlan(row.planId); }).then(function() { self.$modal.msgSuccess('已删除'); self.currentRow = null; self.getList(); }).catch(function() {}); },
|
||||
handleSubmitApproval() { var self = this; this.$modal.confirm('确认提交审批?').then(function() { self.submitLoading = true; return updateCountPlan({ planId: self.currentRow.planId, planStatus: 1 }); }).then(function() { self.$modal.msgSuccess('已提交'); self.getList(); self.currentRow = null; }).finally(function() { self.submitLoading = false; }); },
|
||||
handleAddWarehouse() { this.whForm = { warehouseId: undefined, actualWarehouseId: undefined, warehouseName: '', actualWarehouseName: '', ioStartTime: undefined, ioEndTime: undefined }; this.whDialogOpen = true; },
|
||||
onWhChange(val) { if (val && this.$refs.wsRef) { var o = this.$refs.wsRef.warehouseOptions; var f = o.find(function(x) { return x.warehouseId === val; }); this.whForm.warehouseName = f ? f.warehouseName : ''; } else this.whForm.warehouseName = ''; },
|
||||
onAwhChange(val) { if (val && this.$refs.awsRef) { var o = this.$refs.awsRef.options; var f = o.find(function(x) { return x.actualWarehouseId === val; }); this.whForm.actualWarehouseName = f ? f.actualWarehouseName : ''; } else this.whForm.actualWarehouseName = ''; },
|
||||
submitWh() { var self = this; if (!this.whForm.warehouseId && !this.whForm.actualWarehouseId) { this.$modal.msgWarning('请至少选择一个库区'); return; } this.whBtnLoading = true; addCountPlanWarehouse({ planId: this.currentRow.planId, warehouseId: this.whForm.warehouseId || undefined, actualWarehouseId: this.whForm.actualWarehouseId || undefined, warehouseName: this.whForm.warehouseName || undefined, actualWarehouseName: this.whForm.actualWarehouseName || undefined, ioStartTime: this.whForm.ioStartTime, ioEndTime: this.whForm.ioEndTime }).then(function() { self.$modal.msgSuccess('绑定成功'); self.whDialogOpen = false; self.$refs.detailPanel.refresh(); }).finally(function() { self.whBtnLoading = false; }); }
|
||||
handlePlanApprove() { var self = this; this.$modal.confirm('确认通过审批?通过后进入盘库执行阶段。').then(function() { return updateCountPlan({ planId: self.currentRow.planId, planStatus: 2 }); }).then(function() { self.$modal.msgSuccess('审批通过'); self.getList(); self.currentRow = null; }); },
|
||||
handleReject() { this.rejectReason = ''; this.rejectDialogVisible = true; },
|
||||
confirmReject() { var self = this; var targetStatus = self.currentRow.planStatus === 3 ? 2 : 0; var rejectMsg = targetStatus === 2 ? '驳回至盘库执行' : '驳回至草稿'; updateCountPlan({ planId: self.currentRow.planId, planStatus: targetStatus, remark: self.rejectReason }).then(function() { self.$modal.msgSuccess('已' + rejectMsg); self.rejectDialogVisible = false; self.currentRow = null; self.getList(); }); },
|
||||
handleAddWarehouse() { this.whDialogMode = 'add'; this.editingRelId = null; this.whDialogTitle = '绑定库区'; this.whForm = { warehouseIds: [], actualWarehouseIds: [], warehouseName: '', actualWarehouseName: '', ioStartTime: undefined, ioEndTime: undefined }; this.whDialogOpen = true; },
|
||||
handleEditWarehouse(wh) { console.log('[apply] wh:', JSON.parse(JSON.stringify(wh))); this.whDialogMode = 'edit'; this.editingRelId = wh.relId; this.whDialogTitle = '编辑库区'; var ids = wh.warehouseIds ? String(wh.warehouseIds).split(',') : []; var aids = wh.actualWarehouseIds ? String(wh.actualWarehouseIds).split(',') : []; console.log('[apply] parsed ids:', ids, 'aids:', aids); this.whForm = { warehouseIds: ids, actualWarehouseIds: aids, warehouseName: wh.warehouseName || '', actualWarehouseName: wh.actualWarehouseName || '', ioStartTime: wh.ioStartTime || undefined, ioEndTime: wh.ioEndTime || undefined }; console.log('[apply] whForm.warehouseIds:', this.whForm.warehouseIds, 'actualWarehouseIds:', this.whForm.actualWarehouseIds); this.whDialogOpen = true; },
|
||||
handleDeleteWarehouse(wh) { var self = this; this.$modal.confirm('确认删除库区"' + (wh.warehouseName || wh.actualWarehouseName || '') + '"?').then(function() { return delCountPlanWarehouse(wh.relId); }).then(function() { self.$modal.msgSuccess('已删除'); self.$refs.detailPanel.refresh(); }).catch(function() {}); },
|
||||
onWhChange(val) { if (val && val.length && this.$refs.wsRef) { var o = this.$refs.wsRef.warehouseOptions; var names = val.map(function(id) { var f = o.find(function(x) { return x.warehouseId == id; }); return f ? f.warehouseName : ''; }).filter(Boolean); this.whForm.warehouseName = names.join(','); } else this.whForm.warehouseName = ''; },
|
||||
onAwhChange(val) { if (val && val.length && this.$refs.awsRef) { var o = this.$refs.awsRef.options; var names = val.map(function(id) { var f = o.find(function(x) { return x.actualWarehouseId == id; }); return f ? f.actualWarehouseName : ''; }).filter(Boolean); this.whForm.actualWarehouseName = names.join(','); } else this.whForm.actualWarehouseName = ''; },
|
||||
submitWh() { var self = this; if ((!this.whForm.warehouseIds || this.whForm.warehouseIds.length === 0) && (!this.whForm.actualWarehouseIds || this.whForm.actualWarehouseIds.length === 0)) { this.$modal.msgWarning('请至少选择一个库区'); return; } this.whBtnLoading = true; var data = { planId: this.currentRow.planId, warehouseIds: (this.whForm.warehouseIds && this.whForm.warehouseIds.length) ? this.whForm.warehouseIds.join(',') : undefined, actualWarehouseIds: (this.whForm.actualWarehouseIds && this.whForm.actualWarehouseIds.length) ? this.whForm.actualWarehouseIds.join(',') : undefined, warehouseName: this.whForm.warehouseName || undefined, actualWarehouseName: this.whForm.actualWarehouseName || undefined, ioStartTime: this.whForm.ioStartTime, ioEndTime: this.whForm.ioEndTime }; if (this.whDialogMode === 'edit') { data.relId = this.editingRelId; } var api = this.whDialogMode === 'edit' ? updateCountPlanWarehouse : addCountPlanWarehouse; api(data).then(function() { self.$modal.msgSuccess(self.whDialogMode === 'edit' ? '修改成功' : '绑定成功'); self.whDialogOpen = false; self.$refs.detailPanel.refresh(); }).finally(function() { self.whBtnLoading = false; }); }
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -137,4 +162,8 @@ export default {
|
||||
.section-title .en-sub { font-size: 11px; font-weight: 400; color: #8c8c8c; 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; }
|
||||
.reject-quick-reasons { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
||||
.reject-quick-label { font-size: 13px; color: #606266; flex-shrink: 0; }
|
||||
.reject-tag { cursor: pointer; user-select: none; }
|
||||
.reject-tag:hover { opacity: 0.8; }
|
||||
</style>
|
||||
|
||||
@@ -46,6 +46,26 @@
|
||||
|
||||
<el-divider v-if="currentRow.planStatus === 0" />
|
||||
|
||||
<!-- 计划待审批 (1) 操作 -->
|
||||
<div v-if="currentRow.planStatus === 1" class="section-title">
|
||||
<span>流程操作 <span class="en-sub">· Actions</span></span>
|
||||
</div>
|
||||
<div class="flow-actions" v-if="currentRow.planStatus === 1">
|
||||
<el-button type="danger" size="small" icon="el-icon-close" @click="$emit('reject')">驳回</el-button>
|
||||
<el-button type="primary" size="small" icon="el-icon-check" @click="$emit('approve')">审批通过</el-button>
|
||||
</div>
|
||||
<el-divider v-if="currentRow.planStatus === 1" />
|
||||
|
||||
<!-- 差异审批中 (3) 操作 -->
|
||||
<div v-if="currentRow.planStatus === 3" class="section-title">
|
||||
<span>流程操作 <span class="en-sub">· Actions</span></span>
|
||||
</div>
|
||||
<div class="flow-actions" v-if="currentRow.planStatus === 3">
|
||||
<el-button type="danger" size="small" icon="el-icon-close" @click="$emit('reject')">驳回</el-button>
|
||||
<el-button type="primary" size="small" icon="el-icon-check" @click="$emit('diff-approve')">审批通过</el-button>
|
||||
</div>
|
||||
<el-divider v-if="currentRow.planStatus === 3" />
|
||||
|
||||
<div class="section-title">库区盘点明细 <span class="en-sub">· Warehouses</span>
|
||||
<el-button v-if="currentRow.planStatus === 0" size="mini" type="primary" plain icon="el-icon-plus" style="margin-left:8px;" @click="$emit('bind-warehouse')">绑定库区</el-button>
|
||||
</div>
|
||||
@@ -53,12 +73,11 @@
|
||||
<WarehouseDetailPanel ref="whPanel"
|
||||
:planId="currentRow.planId"
|
||||
:planStatus="currentRow.planStatus"
|
||||
@approve="$emit('approve')"
|
||||
@diff-approve="$emit('diff-approve')"
|
||||
@reject="$emit('reject')"
|
||||
@archive="$emit('archive')"
|
||||
@process-disc="$emit('process-disc', $event)"
|
||||
@submit-disc-approval="$emit('submit-disc-approval')"
|
||||
@edit-warehouse="$emit('edit-warehouse', $event)"
|
||||
@delete-warehouse="$emit('delete-warehouse', $event)"
|
||||
/>
|
||||
|
||||
<div class="section-gap" />
|
||||
|
||||
@@ -96,6 +96,10 @@
|
||||
<span class="wh-detail-label">出入库查询截止</span>
|
||||
<span class="wh-detail-value">{{ wh.ioEndTime ? formatTime(wh.ioEndTime) : '-' }}</span>
|
||||
</div>
|
||||
<div v-if="planStatus === 0" class="wh-detail-actions">
|
||||
<el-button size="mini" type="primary" plain icon="el-icon-edit" @click="$emit('edit-warehouse', wh)">编辑</el-button>
|
||||
<el-button size="mini" type="danger" plain icon="el-icon-delete" @click="$emit('delete-warehouse', wh)">删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -130,18 +134,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 计划待审批 (1) 操作 ===== -->
|
||||
<div v-if="planStatus === 1" style="text-align:right;margin-bottom:8px;">
|
||||
<el-button size="small" type="danger" icon="el-icon-close" @click="$emit('reject')">驳回</el-button>
|
||||
<el-button size="small" type="primary" icon="el-icon-check" @click="$emit('approve')">审批通过</el-button>
|
||||
</div>
|
||||
|
||||
<!-- ===== 差异审批中 (3) 操作 ===== -->
|
||||
<div v-if="planStatus === 3" style="text-align:right;margin-bottom:8px;">
|
||||
<el-button size="small" type="danger" icon="el-icon-close" @click="$emit('reject')">驳回</el-button>
|
||||
<el-button size="small" type="primary" icon="el-icon-check" @click="$emit('diff-approve')">审批通过</el-button>
|
||||
</div>
|
||||
|
||||
<!-- ===== 差异处理中 (4) 操作 ===== -->
|
||||
<div v-if="planStatus === 4" style="text-align:right;margin-bottom:8px;">
|
||||
<el-button size="small" type="success" icon="el-icon-circle-check" @click="$emit('archive')">归档封存</el-button>
|
||||
@@ -461,9 +453,9 @@ export default {
|
||||
async doGenSnapshot(wh) {
|
||||
if (!wh) return;
|
||||
var p = { dataType: 1, status: 0 };
|
||||
if (wh.warehouseId) p.warehouseId = String(wh.warehouseId);
|
||||
if (wh.actualWarehouseId) p.actualWarehouseId = String(wh.actualWarehouseId);
|
||||
if (!p.warehouseId && !p.actualWarehouseId) { this.$message.warning('无库区条件'); return; }
|
||||
if (wh.warehouseIds) p.warehouseIds = String(wh.warehouseIds);
|
||||
if (wh.actualWarehouseIds) p.actualWarehouseIds = String(wh.actualWarehouseIds);
|
||||
if (!p.warehouseIds && !p.actualWarehouseIds) { this.$message.warning('无库区条件'); return; }
|
||||
this.genLoading = true;
|
||||
try {
|
||||
var resp = await exportCoilWithAll(p);
|
||||
@@ -622,6 +614,7 @@ export default {
|
||||
.wh-detail-row:last-child { border-bottom: none; }
|
||||
.wh-detail-label { width: 120px; flex-shrink: 0; color: #606266; font-weight: 500; }
|
||||
.wh-detail-value { color: #303133; }
|
||||
.wh-detail-actions { display: flex; gap: 6px; padding: 8px 14px; border-top: 1px solid #f0ece6; justify-content: flex-end; }
|
||||
.doc-tabs-header { display: flex; border-bottom: 1px solid #d4d0c8; margin-bottom: 12px; }
|
||||
.doc-tab-item { padding: 8px 16px; cursor: pointer; color: #8c8c8c; font-size: 13px; font-weight: 500; border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color 0.2s, border-color 0.2s; display: flex; align-items: center; gap: 6px; user-select: none; }
|
||||
.doc-tab-item:hover { color: #1a3c6e; }
|
||||
|
||||
@@ -76,6 +76,8 @@
|
||||
@reject="handleReject"
|
||||
@process-disc="handleProcessFromPanel"
|
||||
@submit-disc-approval="handleSubmitDiscApproval"
|
||||
@edit-warehouse="handleEditWarehouse"
|
||||
@delete-warehouse="handleRemoveWarehouse"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -95,13 +97,13 @@
|
||||
placeholder="请选择截止时间" style="width:100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="盘点人" prop="countUserId">
|
||||
<el-input v-model="form.countUserName" placeholder="请选择盘点人" />
|
||||
<el-select v-model="form.countUserName" filterable allow-create default-first-option placeholder="请选择盘点人" style="width:100%"><el-option v-for="e in employeeList" :key="e" :label="e" :value="e" /></el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="principalUserId">
|
||||
<el-input v-model="form.principalUserName" placeholder="请选择负责人" />
|
||||
<el-select v-model="form.principalUserName" filterable allow-create default-first-option placeholder="请选择负责人" style="width:100%"><el-option v-for="e in employeeList" :key="e" :label="e" :value="e" /></el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="参与人员" prop="participantIds">
|
||||
<el-input v-model="form.participantNames" placeholder="请输入参与人员" />
|
||||
<el-select v-model="participantNamesArr" multiple filterable allow-create default-first-option placeholder="请输入参与人员" style="width:100%"><el-option v-for="e in employeeList" :key="e" :label="e" :value="e" /></el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
@@ -113,13 +115,13 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="绑定盘库库区" :visible.sync="warehouseDialogVisible" width="550px" append-to-body>
|
||||
<el-form ref="warehouseForm" :model="warehouseForm" label-width="120px">
|
||||
<el-form-item label="逻辑库区" prop="warehouseId">
|
||||
<WarehouseSelect ref="whSelect" v-model="warehouseForm.warehouseId" placeholder="请选择逻辑库区" @change="handleWarehouseChange" />
|
||||
<el-dialog :title="warehouseDialogTitle" :visible.sync="warehouseDialogVisible" width="550px" append-to-body>
|
||||
<el-form ref="warehouseForm" :model="warehouseForm" label-width="120px" :key="'wh-form-' + whDialogMode + '-' + (editingRelId || 0)">
|
||||
<el-form-item label="逻辑库区" prop="warehouseIds">
|
||||
<WarehouseSelect ref="whSelect" v-model="warehouseForm.warehouseIds" multiple placeholder="请选择逻辑库区" @change="handleWarehouseChange" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实际库区" prop="actualWarehouseId">
|
||||
<ActualWarehouseL1L2Select ref="actualWhSelect" v-model="warehouseForm.actualWarehouseId" placeholder="请选择实际库区(一级/二级)" @change="handleActualWarehouseChange" />
|
||||
<el-form-item label="实际库区" prop="actualWarehouseIds">
|
||||
<ActualWarehouseL1L2Select ref="actualWhSelect" v-model="warehouseForm.actualWarehouseIds" multiple placeholder="请选择实际库区(一级/二级)" @change="handleActualWarehouseChange" />
|
||||
</el-form-item>
|
||||
<el-form-item label="出入库查询起始" prop="ioStartTime">
|
||||
<el-date-picker clearable v-model="warehouseForm.ioStartTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
|
||||
@@ -206,12 +208,26 @@
|
||||
<el-button @click="discDialogVisible = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 驳回审批对话框 -->
|
||||
<el-dialog title="驳回审批" :visible.sync="rejectDialogVisible" width="520px" append-to-body>
|
||||
<div class="reject-quick-reasons">
|
||||
<span class="reject-quick-label">快捷理由:</span>
|
||||
<el-tag v-for="(r, i) in rejectQuickReasons" :key="i" class="reject-tag" size="small" @click="rejectReason = r">{{ r }}</el-tag>
|
||||
</div>
|
||||
<el-input v-model="rejectReason" type="textarea" :rows="4" placeholder="请输入驳回原因" style="margin-top:10px;" />
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="danger" @click="confirmReject" :disabled="!rejectReason.trim()">确认驳回</el-button>
|
||||
<el-button @click="rejectDialogVisible = false">取消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listCountPlan, getCountPlan, addCountPlan, updateCountPlan, delCountPlan } from "@/api/flow/countPlan";
|
||||
import { addCountPlanWarehouse, delCountPlanWarehouse, updateCountPlanWarehouse } from "@/api/flow/countPlanWarehouse";
|
||||
import { listEmployeeInfo } from "@/api/wms/employeeInfo";
|
||||
import { updateCountDiscrepancy } from "@/api/flow/countDiscrepancy";
|
||||
import { exportCoilWithAll } from "@/api/wms/coil";
|
||||
import { uploadFile } from "@/api/system/oss";
|
||||
@@ -323,18 +339,32 @@ export default {
|
||||
planStatus: undefined
|
||||
},
|
||||
form: {},
|
||||
employeeList: [],
|
||||
participantNamesArr: [],
|
||||
warehouseList: [],
|
||||
discrepancyMap: {},
|
||||
discrepancyLoadingMap: {},
|
||||
warehouseForm: {
|
||||
warehouseId: undefined,
|
||||
actualWarehouseId: undefined,
|
||||
warehouseIds: [],
|
||||
actualWarehouseIds: [],
|
||||
warehouseName: '',
|
||||
actualWarehouseName: '',
|
||||
ioStartTime: undefined,
|
||||
ioEndTime: undefined
|
||||
},
|
||||
warehouseDialogTitle: '绑定盘库库区',
|
||||
whDialogMode: 'add',
|
||||
editingRelId: null,
|
||||
discForm: {},
|
||||
rejectDialogVisible: false,
|
||||
rejectReason: '',
|
||||
rejectQuickReasons: [
|
||||
'盘点计划信息不完整,请补充后重新提交',
|
||||
'库区绑定有误,请核实库区信息',
|
||||
'盘点时间安排不合理,请调整',
|
||||
'盘点人员安排需调整',
|
||||
'缺少必要的备注说明'
|
||||
],
|
||||
uploadFileList: [],
|
||||
// 实盘导入相关
|
||||
importDialogVisible: false,
|
||||
@@ -362,9 +392,11 @@ export default {
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
this.loadEmployees();
|
||||
},
|
||||
methods: {
|
||||
parseTime,
|
||||
loadEmployees() { var self = this; listEmployeeInfo({ pageNum: 1, pageSize: 9999 }).then(function(r) { self.employeeList = (r.rows || []).map(function(e) { return e.name || ''; }).filter(Boolean); }); },
|
||||
getList() {
|
||||
this.loading = true;
|
||||
var self = this;
|
||||
@@ -406,6 +438,7 @@ export default {
|
||||
},
|
||||
handleAdd() {
|
||||
this.form = { planName: new Date().toLocaleDateString().replace(/\//g, '-') + '盘库计划' };
|
||||
this.participantNamesArr = [];
|
||||
this.open = true;
|
||||
this.title = "新增盘库计划";
|
||||
},
|
||||
@@ -415,6 +448,7 @@ export default {
|
||||
var planId = row.planId;
|
||||
getCountPlan(planId).then(function(response) {
|
||||
self.form = response.data;
|
||||
self.participantNamesArr = response.data.participantNames ? response.data.participantNames.split(',') : [];
|
||||
self.open = true;
|
||||
self.title = "修改盘库计划";
|
||||
});
|
||||
@@ -447,6 +481,7 @@ export default {
|
||||
if (valid) {
|
||||
self.buttonLoading = true;
|
||||
self.form.planCode = self.form.planName;
|
||||
self.form.participantNames = self.participantNamesArr.join(',');
|
||||
if (self.form.planId != null) {
|
||||
updateCountPlan(self.form).then(function() {
|
||||
self.$modal.msgSuccess("修改成功");
|
||||
@@ -513,12 +548,19 @@ export default {
|
||||
}).catch(function() { });
|
||||
},
|
||||
handleReject() {
|
||||
this.rejectReason = '';
|
||||
this.rejectDialogVisible = true;
|
||||
},
|
||||
confirmReject() {
|
||||
var self = this;
|
||||
var targetStatus = self.currentRow.planStatus === 3 ? 2 : 0;
|
||||
var rejectMsg = targetStatus === 2 ? '驳回至盘库执行' : '驳回至草稿';
|
||||
this.$prompt('请输入驳回原因', '驳回审批', { inputType: 'textarea', inputValidator: function(v) { return v ? true : '驳回原因不能为空'; } }).then(function({ value }) {
|
||||
return updateCountPlan({ planId: self.currentRow.planId, planStatus: targetStatus, remark: value });
|
||||
}).then(function() { self.$modal.msgSuccess("已" + rejectMsg); self.currentRow = null; self.getList(); });
|
||||
updateCountPlan({ planId: self.currentRow.planId, planStatus: targetStatus, remark: self.rejectReason }).then(function() {
|
||||
self.$modal.msgSuccess("已" + rejectMsg);
|
||||
self.rejectDialogVisible = false;
|
||||
self.currentRow = null;
|
||||
self.getList();
|
||||
});
|
||||
},
|
||||
// 打开导入实盘Excel对话框
|
||||
handleUploadExcel(wh) {
|
||||
@@ -838,16 +880,16 @@ export default {
|
||||
// 先收集所有需要导出的参数
|
||||
var exports = [];
|
||||
// 1) 逻辑库区钢卷明细快照 → snapshotCoilLogic
|
||||
if (warehouse.warehouseId) {
|
||||
exports.push({ key: 'snapshotCoilLogic', params: { warehouseIds: String(warehouse.warehouseId) }, label: '逻辑库区', isMain: true });
|
||||
if (warehouse.warehouseIds) {
|
||||
exports.push({ key: 'snapshotCoilLogic', params: { warehouseIds: String(warehouse.warehouseIds) }, label: '逻辑库区', isMain: true });
|
||||
}
|
||||
// 2) 实际库区钢卷明细快照 → snapshotCoilActual
|
||||
if (warehouse.actualWarehouseId) {
|
||||
exports.push({ key: 'snapshotCoilActual', params: { actualWarehouseIds: String(warehouse.actualWarehouseId) }, label: '实际库区', isMain: !warehouse.warehouseId });
|
||||
if (warehouse.actualWarehouseIds) {
|
||||
exports.push({ key: 'snapshotCoilActual', params: { actualWarehouseIds: String(warehouse.actualWarehouseIds) }, label: '实际库区', isMain: !warehouse.warehouseIds });
|
||||
}
|
||||
// 3) 实际库区出入库记录快照 → snapshotIoRecord
|
||||
if (warehouse.actualWarehouseId && warehouse.ioStartTime && warehouse.ioEndTime) {
|
||||
exports.push({ key: 'snapshotIoRecord', params: { actualWarehouseIds: String(warehouse.actualWarehouseId), startTime: warehouse.ioStartTime, endTime: warehouse.ioEndTime }, label: 'IO记录' });
|
||||
if (warehouse.actualWarehouseIds && warehouse.ioStartTime && warehouse.ioEndTime) {
|
||||
exports.push({ key: 'snapshotIoRecord', params: { actualWarehouseIds: String(warehouse.actualWarehouseIds), startTime: warehouse.ioStartTime, endTime: warehouse.ioEndTime }, label: 'IO记录' });
|
||||
}
|
||||
|
||||
var mainResponse = null;
|
||||
@@ -857,7 +899,7 @@ export default {
|
||||
dataType: 1,
|
||||
status: 0
|
||||
});
|
||||
var labelName = warehouse.warehouseName || warehouse.actualWarehouseName || warehouse.warehouseId || warehouse.actualWarehouseId || '';
|
||||
var labelName = warehouse.warehouseName || warehouse.actualWarehouseName || warehouse.warehouseIds || warehouse.actualWarehouseIds || '';
|
||||
var ossId = await this.uploadSnapshotBlob(
|
||||
response,
|
||||
this.currentRow.planCode + '_' + labelName + '_' + exp.label,
|
||||
@@ -914,9 +956,12 @@ export default {
|
||||
return { count: count, totalWeight: Math.round(totalWeight * 100) / 100 };
|
||||
},
|
||||
handleAddWarehouse() {
|
||||
this.whDialogMode = 'add';
|
||||
this.editingRelId = null;
|
||||
this.warehouseDialogTitle = '绑定盘库库区';
|
||||
this.warehouseForm = {
|
||||
warehouseId: undefined,
|
||||
actualWarehouseId: undefined,
|
||||
warehouseIds: [],
|
||||
actualWarehouseIds: [],
|
||||
warehouseName: '',
|
||||
actualWarehouseName: '',
|
||||
ioStartTime: undefined,
|
||||
@@ -924,6 +969,24 @@ export default {
|
||||
};
|
||||
this.warehouseDialogVisible = true;
|
||||
},
|
||||
handleEditWarehouse(wh) {
|
||||
console.log('[index] handleEditWarehouse wh:', JSON.parse(JSON.stringify(wh)));
|
||||
this.whDialogMode = 'edit';
|
||||
this.editingRelId = wh.relId;
|
||||
this.warehouseDialogTitle = '编辑盘库库区';
|
||||
var ids = wh.warehouseIds ? String(wh.warehouseIds).split(',') : [];
|
||||
var aids = wh.actualWarehouseIds ? String(wh.actualWarehouseIds).split(',') : [];
|
||||
console.log('[index] parsed ids:', ids, 'aids:', aids);
|
||||
this.warehouseForm = {
|
||||
warehouseIds: ids,
|
||||
actualWarehouseIds: aids,
|
||||
warehouseName: wh.warehouseName || '',
|
||||
actualWarehouseName: wh.actualWarehouseName || '',
|
||||
ioStartTime: wh.ioStartTime || undefined,
|
||||
ioEndTime: wh.ioEndTime || undefined
|
||||
};
|
||||
this.warehouseDialogVisible = true;
|
||||
},
|
||||
// 切换仓库主tab时自动加载差异数据
|
||||
handleWarehouseTabChange(tab) {
|
||||
var idx = tab.name || tab;
|
||||
@@ -963,7 +1026,7 @@ export default {
|
||||
this.$modal.msgError('Excel预览失败,请下载查看');
|
||||
},
|
||||
submitWarehouseForm() {
|
||||
if (!this.warehouseForm.warehouseId && !this.warehouseForm.actualWarehouseId) {
|
||||
if ((!this.warehouseForm.warehouseIds || this.warehouseForm.warehouseIds.length === 0) && (!this.warehouseForm.actualWarehouseIds || this.warehouseForm.actualWarehouseIds.length === 0)) {
|
||||
this.$modal.msgWarning("请至少选择一个库区(逻辑库区或实际库区)");
|
||||
return;
|
||||
}
|
||||
@@ -971,35 +1034,39 @@ export default {
|
||||
var self = this;
|
||||
var data = {
|
||||
planId: this.currentRow.planId,
|
||||
warehouseId: this.warehouseForm.warehouseId || undefined,
|
||||
actualWarehouseId: this.warehouseForm.actualWarehouseId || undefined,
|
||||
warehouseIds: (this.warehouseForm.warehouseIds && this.warehouseForm.warehouseIds.length) ? this.warehouseForm.warehouseIds.join(',') : undefined,
|
||||
actualWarehouseIds: (this.warehouseForm.actualWarehouseIds && this.warehouseForm.actualWarehouseIds.length) ? this.warehouseForm.actualWarehouseIds.join(',') : undefined,
|
||||
warehouseName: this.warehouseForm.warehouseName || undefined,
|
||||
actualWarehouseName: this.warehouseForm.actualWarehouseName || undefined,
|
||||
ioStartTime: this.warehouseForm.ioStartTime,
|
||||
ioEndTime: this.warehouseForm.ioEndTime
|
||||
};
|
||||
addCountPlanWarehouse(data).then(function() {
|
||||
self.$modal.msgSuccess("绑定库区成功");
|
||||
if (this.whDialogMode === 'edit') {
|
||||
data.relId = this.editingRelId;
|
||||
}
|
||||
var api = this.whDialogMode === 'edit' ? updateCountPlanWarehouse : addCountPlanWarehouse;
|
||||
api(data).then(function() {
|
||||
self.$modal.msgSuccess(self.whDialogMode === 'edit' ? '修改成功' : '绑定库区成功');
|
||||
self.warehouseDialogVisible = false;
|
||||
self.$refs.detailPanel.refresh();
|
||||
}).finally(function() { self.whButtonLoading = false; });
|
||||
},
|
||||
// 选择逻辑库区时记录名称
|
||||
handleWarehouseChange(val) {
|
||||
if (val && this.$refs.whSelect) {
|
||||
if (val && val.length && this.$refs.whSelect) {
|
||||
var options = this.$refs.whSelect.warehouseOptions || [];
|
||||
var found = options.find(function(item) { return item.warehouseId === val; });
|
||||
this.warehouseForm.warehouseName = found ? found.warehouseName : '';
|
||||
var names = val.map(function(id) { var f = options.find(function(item) { return item.warehouseId == id; }); return f ? f.warehouseName : ''; }).filter(Boolean);
|
||||
this.warehouseForm.warehouseName = names.join(',');
|
||||
} else {
|
||||
this.warehouseForm.warehouseName = '';
|
||||
}
|
||||
},
|
||||
// 选择实际库区时记录名称
|
||||
handleActualWarehouseChange(val) {
|
||||
if (val && this.$refs.actualWhSelect) {
|
||||
if (val && val.length && this.$refs.actualWhSelect) {
|
||||
var options = this.$refs.actualWhSelect.options || [];
|
||||
var found = options.find(function(item) { return item.actualWarehouseId === val; });
|
||||
this.warehouseForm.actualWarehouseName = found ? found.actualWarehouseName : '';
|
||||
var names = val.map(function(id) { var f = options.find(function(item) { return item.actualWarehouseId == id; }); return f ? f.actualWarehouseName : ''; }).filter(Boolean);
|
||||
this.warehouseForm.actualWarehouseName = names.join(',');
|
||||
} else {
|
||||
this.warehouseForm.actualWarehouseName = '';
|
||||
}
|
||||
@@ -1642,4 +1709,10 @@ export default {
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
/* 驳回快捷理由 */
|
||||
.reject-quick-reasons { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
||||
.reject-quick-label { font-size: 13px; color: #606266; flex-shrink: 0; }
|
||||
.reject-tag { cursor: pointer; user-select: none; }
|
||||
.reject-tag:hover { opacity: 0.8; }
|
||||
|
||||
</style>
|
||||
|
||||
@@ -294,6 +294,20 @@ export default {
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.formCoilList = [];
|
||||
// 根据当前日期自动生成售后编号,格式: SH + yyyyMMddHHmmss
|
||||
const now = new Date();
|
||||
const pad = (n, len) => String(n).padStart(len, '0');
|
||||
const dateStr = [
|
||||
now.getFullYear(),
|
||||
pad(now.getMonth() + 1, 2),
|
||||
pad(now.getDate(), 2),
|
||||
pad(now.getHours(), 2),
|
||||
pad(now.getMinutes(), 2),
|
||||
pad(now.getSeconds(), 2)
|
||||
].join('');
|
||||
this.form.complaintNo = 'SH' + dateStr;
|
||||
// 自动填写当前日期
|
||||
this.form.complaintDate = this.parseTime(now, '{y}-{m}-{d}');
|
||||
this.open = true;
|
||||
this.title = "新增售后单";
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user