Files
klp-oa/klp-ui/src/views/wms/post/InvCount/components/PlanDetailPanel.vue
砂糖 3d5c0a7281 feat(wms盘库): 完成多项功能升级与体验优化
1. 新增仓库选择组件多选支持,适配批量库区操作
2. 售后单新增自动生成编号与当前日期填充
3. 盘点计划新增流程审批操作按钮,支持驳回与审批通过
4. 优化库区绑定页面,支持编辑删除已绑定库区
5. 替换人员选择为可搜索下拉框,支持多选参与人
6. 新增驳回审批弹窗,提供快捷驳回理由
7. 优化表单提交逻辑,适配多库区数据格式
2026-06-27 14:38:33 +08:00

147 lines
7.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div v-if="!currentRow" class="empty-tip"><i class="el-icon-info"></i><span>{{ emptyText }}</span></div>
<div v-else v-loading="loading" 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">{{ subtitle }}</div>
</div>
<div class="doc-header-right">
<el-button size="mini" type="text" icon="el-icon-refresh" @click="refresh">刷新</el-button>
<el-button v-if="currentRow.planStatus === 0" size="mini" type="text" icon="el-icon-edit" @click="$emit('edit-plan', currentRow)">编辑</el-button>
<el-button v-if="currentRow.planStatus === 0" size="mini" type="text" icon="el-icon-delete" @click="$emit('delete-plan', currentRow)">删除</el-button>
<el-button v-if="currentRow.planStatus === 4" size="mini" type="success" icon="el-icon-circle-check" @click="$emit('archive')">归档封存</el-button>
</div>
</div>
<div class="doc-status-row">
<span class="doc-status-label">Status</span>
<el-tag v-if="currentRow.planStatus === 0" type="info" size="small">草稿</el-tag>
<el-tag v-else-if="currentRow.planStatus === 1" size="small">计划待审批</el-tag>
<el-tag v-else-if="currentRow.planStatus === 2" type="warning" size="small">盘库执行中</el-tag>
<el-tag v-else-if="currentRow.planStatus === 3" size="small">差异审批中</el-tag>
<el-tag v-else-if="currentRow.planStatus === 4" type="danger" size="small">差异处理中</el-tag>
<el-tag v-else-if="currentRow.planStatus === 5" type="success" size="small">已归档</el-tag>
</div>
</div>
<div class="detail-meta">
<span><i class="el-icon-document"></i>{{ currentRow.planName }}</span>
<span v-if="currentRow.countDate"><i class="el-icon-date"></i>{{ formatTime(currentRow.countDate, '{y}-{m}-{d}') }}</span>
<span v-if="currentRow.countUserName"><i class="el-icon-user-solid"></i>{{ currentRow.countUserName }}</span>
<span v-if="currentRow.principalUserName"><i class="el-icon-s-custom"></i>{{ currentRow.principalUserName }}</span>
</div>
<CountFlowSection :planStatus="currentRow.planStatus" />
<el-divider />
<!-- 流程操作按钮 -->
<div v-if="currentRow.planStatus === 0" class="section-title">
<span>流程操作 <span class="en-sub">· Actions</span></span>
</div>
<div class="flow-actions" v-if="currentRow.planStatus === 0">
<el-button type="primary" size="small" icon="el-icon-s-promotion" @click="$emit('submit-approval')">提交审批</el-button>
</div>
<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>
<WarehouseDetailPanel ref="whPanel"
:planId="currentRow.planId"
:planStatus="currentRow.planStatus"
@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" />
<div class="section-title">备注 <span class="en-sub">· Remarks</span></div>
<div class="remark-content">{{ currentRow.remark || '无' }}</div>
</div>
</template>
<script>
import { getCountPlan } from "@/api/flow/countPlan";
import CountFlowSection from "./CountFlowSection.vue";
import WarehouseDetailPanel from "./WarehouseDetailPanel.vue";
import { parseTime } from '@/utils/klp';
export default {
name: 'PlanDetailPanel',
components: { CountFlowSection, WarehouseDetailPanel },
props: {
planId: { type: [Number, String], default: null },
emptyText: { type: String, default: '请在左侧列表中选择一条盘库计划' },
subtitle: { type: String, default: 'Inventory Count Plan' }
},
data() {
return { loading: false, currentRow: null };
},
watch: {
planId: {
immediate: true,
handler(val) {
if (!val) { this.currentRow = null; return; }
this.loadDetail(val);
}
}
},
methods: {
formatTime(val, fmt) { if (!val) return ''; return parseTime(val, fmt); },
loadDetail(planId) {
this.loading = true; var self = this;
getCountPlan(planId).then(function(r) { self.currentRow = r.data; self.$emit('loaded', r.data); }).finally(function() { self.loading = false; });
},
refresh() { if (this.currentRow) this.loadDetail(this.currentRow.planId); if (this.$refs.whPanel) this.$refs.whPanel.refreshAll(); }
}
};
</script>
<style scoped>
.empty-tip { display: flex; align-items: center; justify-content: center; height: 100%; color: #909399; font-size: 14px; gap: 8px; }
.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%; }
.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; letter-spacing: 0.3px; }
.section-title:first-child { margin-top: 0; }
.section-title .en-sub { font-size: 11px; font-weight: 400; color: #8c8c8c; letter-spacing: 0.5px; font-style: italic; }
.flow-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.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>