Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X
This commit is contained in:
@@ -64,3 +64,13 @@ export function listTodayOrder(query) {
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 导出正式订单主列表(业务精简字段)
|
||||
export function exportOrder(query) {
|
||||
return request({
|
||||
url: '/crm/order/exportDetail',
|
||||
method: 'post',
|
||||
data: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -42,3 +42,13 @@ export function delOrderItem(itemId) {
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 导出正式订单明细列表(业务精简字段)
|
||||
export function exportOrderItem(query) {
|
||||
return request({
|
||||
url: '/crm/orderItem/exportDetail',
|
||||
method: 'post',
|
||||
data: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="app-container cost-trend-page">
|
||||
<!-- 筛选区 -->
|
||||
<el-card class="mb8">
|
||||
<el-card class="mb8 filter-card">
|
||||
<div class="filter-bar">
|
||||
<el-radio-group
|
||||
v-model="selectedLine"
|
||||
@@ -16,7 +16,6 @@
|
||||
{{ line.lineName }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
|
||||
<el-button type="primary" size="small" icon="el-icon-search" :loading="loading" @click="fetchData">
|
||||
查询
|
||||
</el-button>
|
||||
@@ -47,10 +46,10 @@
|
||||
multiple
|
||||
collapse-tags
|
||||
placeholder="成本类别(全部)"
|
||||
size="small"
|
||||
style="width:160px"
|
||||
@change="onCategoryChange"
|
||||
clearable
|
||||
size="small"
|
||||
style="width:150px"
|
||||
@change="onCategoryChange"
|
||||
>
|
||||
<el-option label="原料" value="原料" />
|
||||
<el-option label="能耗" value="能耗" />
|
||||
@@ -67,10 +66,10 @@
|
||||
collapse-tags
|
||||
filterable
|
||||
placeholder="成本项(全部)"
|
||||
size="small"
|
||||
style="width:220px"
|
||||
@change="onItemChange"
|
||||
clearable
|
||||
size="small"
|
||||
style="width:200px"
|
||||
@change="onItemChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="it in filteredItemOptions"
|
||||
@@ -81,13 +80,21 @@
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<!-- 图表区 -->
|
||||
<div class="chart-box" v-loading="loading">
|
||||
<div ref="trendChart" class="chart-body" />
|
||||
</div>
|
||||
|
||||
<div v-if="summary.seriesCount > 15" class="legend-hint">
|
||||
<i class="el-icon-info" /> 图例较多,可在下方图例区滚动查看,或缩小筛选范围以减少趋势线数量
|
||||
<!-- 迷你图表网格 -->
|
||||
<div v-loading="loading" class="mini-charts-grid">
|
||||
<template v-if="seriesList.length">
|
||||
<div v-for="s in seriesList" :key="s.key" class="mini-chart-card">
|
||||
<div class="mini-chart-header">
|
||||
<span class="mini-chart-dot" :style="{ background: s.color }" />
|
||||
<span class="mini-chart-name">{{ s.name }}</span>
|
||||
<span class="mini-chart-max">峰值 {{ formatMiniMax(s.maxVal) }}</span>
|
||||
</div>
|
||||
<div ref="miniCharts" class="mini-chart-body" />
|
||||
</div>
|
||||
</template>
|
||||
<div v-else-if="!loading && reports.length" class="empty-hint">
|
||||
暂无匹配的成本项数据
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -116,7 +123,8 @@ export default {
|
||||
selectedItems: [],
|
||||
allItems: [],
|
||||
loading: false,
|
||||
chart: null,
|
||||
chartInstances: [],
|
||||
seriesList: [],
|
||||
reports: [],
|
||||
cachedDetails: [],
|
||||
summary: { seriesCount: 0, maxLabel: '-' }
|
||||
@@ -128,10 +136,6 @@ export default {
|
||||
if (!this.selectedLine || !this.productionLines.length) return null
|
||||
return this.productionLines.find(l => l.lineId === this.selectedLine) || null
|
||||
},
|
||||
lineNameDisplay() {
|
||||
const line = this.selectedLineObj
|
||||
return line ? line.lineName : ''
|
||||
},
|
||||
filteredItemOptions() {
|
||||
if (!this.selectedCategories.length) return this.allItems
|
||||
return this.allItems.filter(it => this.selectedCategories.includes(it.category))
|
||||
@@ -143,12 +147,12 @@ export default {
|
||||
this.$nextTick(() => this.fetchData())
|
||||
})
|
||||
this.loadItems()
|
||||
this._resizeHandler = () => { if (this.chart) this.chart.resize() }
|
||||
this._resizeHandler = () => this.resizeAllCharts()
|
||||
window.addEventListener('resize', this._resizeHandler)
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this._resizeHandler)
|
||||
if (this.chart) { this.chart.dispose(); this.chart = null }
|
||||
this.disposeAllCharts()
|
||||
},
|
||||
methods: {
|
||||
initDefaultLine() {
|
||||
@@ -186,11 +190,9 @@ export default {
|
||||
this.allItems = r.rows || []
|
||||
} catch (e) { /* ignore */ }
|
||||
},
|
||||
|
||||
|
||||
async fetchData() {
|
||||
if (this.selectedLine == null) {
|
||||
return
|
||||
}
|
||||
if (this.selectedLine == null) return
|
||||
|
||||
this.loading = true
|
||||
try {
|
||||
@@ -204,13 +206,13 @@ export default {
|
||||
const allReports = (reportRes.rows || []).sort((a, b) => {
|
||||
return (a.reportDate || '').localeCompare(b.reportDate || '')
|
||||
})
|
||||
console.log('[CostTrend] reports:', allReports.length, allReports.map(r => ({ id: r.reportId, title: r.reportTitle, date: r.reportDate })))
|
||||
|
||||
if (!allReports.length) {
|
||||
this.$modal.msgWarning('该产线暂无报表')
|
||||
this.reports = []
|
||||
this.seriesList = []
|
||||
this.summary = { seriesCount: 0, maxLabel: '-' }
|
||||
if (this.chart) this.chart.clear()
|
||||
this.disposeAllCharts()
|
||||
return
|
||||
}
|
||||
this.reports = allReports
|
||||
@@ -224,15 +226,11 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 成本项模式 ====================
|
||||
async fetchDetailsAndCache(reports) {
|
||||
const allDetailResults = await Promise.all(
|
||||
reports.map(r =>
|
||||
listProdDetail({ reportId: r.reportId, pageNum: 1, pageSize: 99999 })
|
||||
.then(res => {
|
||||
console.log('[CostTrend] detail for report', r.reportId, 'rows:', (res.rows || []).length)
|
||||
return { reportId: r.reportId, rows: res.rows || [] }
|
||||
})
|
||||
.then(res => ({ reportId: r.reportId, rows: res.rows || [] }))
|
||||
.catch(e => {
|
||||
console.error('[CostTrend] detail fetch error for report', r.reportId, e)
|
||||
return { reportId: r.reportId, rows: [] }
|
||||
@@ -279,7 +277,7 @@ export default {
|
||||
})
|
||||
|
||||
const xLabels = reports.map(r => this.reportLabel(r))
|
||||
const series = []
|
||||
const list = []
|
||||
let globalMax = 0
|
||||
|
||||
Array.from(allItemIds).forEach((key, idx) => {
|
||||
@@ -288,115 +286,121 @@ export default {
|
||||
const data = reports.map(r => {
|
||||
const sums = reportSums[r.reportId] || {}
|
||||
const val = sums[key] ?? null
|
||||
if (val != null && val > globalMax) globalMax = val
|
||||
return val
|
||||
})
|
||||
if (data.every(v => v === null)) return
|
||||
|
||||
series.push({
|
||||
const maxVal = Math.max(...data.filter(v => v != null))
|
||||
if (maxVal > globalMax) globalMax = maxVal
|
||||
|
||||
list.push({
|
||||
key,
|
||||
name,
|
||||
type: 'line',
|
||||
color: COLORS[idx % COLORS.length],
|
||||
data,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 6,
|
||||
lineStyle: { width: 2, color: COLORS[idx % COLORS.length] },
|
||||
itemStyle: { color: COLORS[idx % COLORS.length] },
|
||||
emphasis: { focus: 'series' }
|
||||
xLabels,
|
||||
maxVal
|
||||
})
|
||||
})
|
||||
|
||||
this.seriesList = list
|
||||
this.summary = {
|
||||
seriesCount: series.length,
|
||||
seriesCount: list.length,
|
||||
maxLabel: this.formatMoney(globalMax)
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => this.renderChart(xLabels, series, '数量'), 50)
|
||||
this.$nextTick(() => this.renderMiniCharts())
|
||||
},
|
||||
|
||||
// ==================== 迷你图表渲染 ====================
|
||||
disposeAllCharts() {
|
||||
this.chartInstances.forEach(c => {
|
||||
try { c.dispose() } catch (e) { /* ignore */ }
|
||||
})
|
||||
this.chartInstances = []
|
||||
},
|
||||
|
||||
resizeAllCharts() {
|
||||
this.chartInstances.forEach(c => {
|
||||
try { c.resize() } catch (e) { /* ignore */ }
|
||||
})
|
||||
},
|
||||
|
||||
// ==================== 图表渲染 ====================
|
||||
renderChart(xLabels, series, yAxisName) {
|
||||
console.log('[CostTrend] renderChart called, ref:', !!this.$refs.trendChart, 'series:', series.length, 'xLabels:', xLabels.length)
|
||||
if (!this.$refs.trendChart) return
|
||||
if (this.chart) this.chart.dispose()
|
||||
this.chart = echarts.init(this.$refs.trendChart)
|
||||
renderMiniCharts() {
|
||||
this.disposeAllCharts()
|
||||
|
||||
if (!series.length) {
|
||||
this.chart.setOption({
|
||||
title: { text: '暂无数据', left: 'center', top: 'center', textStyle: { color: '#999', fontSize: 14 } },
|
||||
xAxis: { show: false },
|
||||
yAxis: { show: false },
|
||||
series: []
|
||||
})
|
||||
return
|
||||
}
|
||||
const containers = this.$refs.miniCharts
|
||||
if (!containers || !containers.length) return
|
||||
|
||||
this.chart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function (params) {
|
||||
if (!params || !params.length) return ''
|
||||
let html = '<b>' + params[0].axisValue + '</b><br/>'
|
||||
params.forEach(p => {
|
||||
if (p.value != null) {
|
||||
html += '<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:' +
|
||||
p.color + ';margin-right:5px;"></span>' +
|
||||
p.seriesName + ': <b>' +
|
||||
Number(p.value).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) +
|
||||
'</b><br/>'
|
||||
}
|
||||
})
|
||||
return html
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
bottom: 0,
|
||||
textStyle: { fontSize: 11 },
|
||||
pageIconSize: 12,
|
||||
pageTextStyle: { fontSize: 11 }
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
top: '3%',
|
||||
bottom: series.length > 20 ? '18%' : (series.length > 10 ? '14%' : '10%'),
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xLabels,
|
||||
boundaryGap: false,
|
||||
axisLabel: {
|
||||
fontSize: 11,
|
||||
rotate: xLabels.length > 8 ? 30 : 0
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: yAxisName,
|
||||
axisLabel: {
|
||||
fontSize: 11,
|
||||
formatter: function (v) {
|
||||
if (v >= 10000) return (v / 10000).toFixed(1) + '万'
|
||||
return v
|
||||
this.seriesList.forEach((s, idx) => {
|
||||
const el = containers[idx]
|
||||
if (!el) return
|
||||
|
||||
const chart = echarts.init(el)
|
||||
chart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function(params) {
|
||||
if (!params || !params.length) return ''
|
||||
const p = params[0]
|
||||
return '<b>' + p.axisValue + '</b><br/>' +
|
||||
'<span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:' +
|
||||
p.color + ';margin-right:4px;"></span>' +
|
||||
p.seriesName + ': <b>' +
|
||||
Number(p.value).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) +
|
||||
'</b>'
|
||||
}
|
||||
},
|
||||
splitLine: { lineStyle: { type: 'dashed', color: '#e8e8e8' } }
|
||||
},
|
||||
dataZoom: xLabels.length > 10 ? [
|
||||
{
|
||||
type: 'slider',
|
||||
bottom: series.length > 10 ? (series.length > 20 ? 60 : 50) : 35,
|
||||
height: 16,
|
||||
textStyle: { fontSize: 10 }
|
||||
grid: {
|
||||
left: 8,
|
||||
right: 12,
|
||||
top: 8,
|
||||
bottom: 24,
|
||||
containLabel: true
|
||||
},
|
||||
{ type: 'inside' }
|
||||
] : [],
|
||||
series
|
||||
}, true)
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: s.xLabels,
|
||||
boundaryGap: false,
|
||||
axisLabel: {
|
||||
fontSize: 10,
|
||||
rotate: s.xLabels.length > 8 ? 25 : 0,
|
||||
interval: s.xLabels.length > 12 ? 'auto' : 0
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: { lineStyle: { color: '#ddd' }}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
fontSize: 10,
|
||||
formatter: function(v) {
|
||||
if (v >= 10000) return (v / 10000).toFixed(1) + '万'
|
||||
return v
|
||||
}
|
||||
},
|
||||
splitLine: { lineStyle: { type: 'dashed', color: '#eee' }},
|
||||
splitNumber: 3
|
||||
},
|
||||
series: [{
|
||||
name: s.name,
|
||||
type: 'line',
|
||||
data: s.data,
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
lineStyle: { width: 1.5, color: s.color },
|
||||
itemStyle: { color: s.color },
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: s.color + '30' },
|
||||
{ offset: 1, color: s.color + '05' }
|
||||
])
|
||||
}
|
||||
}]
|
||||
}, true)
|
||||
|
||||
this.chartInstances.push(chart)
|
||||
})
|
||||
},
|
||||
|
||||
reportLabel(r) {
|
||||
@@ -411,78 +415,132 @@ export default {
|
||||
const num = Number(val)
|
||||
if (num >= 10000) return (num / 10000).toFixed(2) + '万'
|
||||
return num.toFixed(2)
|
||||
},
|
||||
|
||||
formatMiniMax(val) {
|
||||
if (val == null || isNaN(val)) return '-'
|
||||
if (val >= 10000) return (val / 10000).toFixed(1) + '万'
|
||||
return Number(val).toFixed(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mb8 { margin-bottom: 10px; }
|
||||
.mb8 { margin-bottom: 8px; }
|
||||
|
||||
.filter-card {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
}
|
||||
.filter-card >>> .el-card__body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* 统计摘要 */
|
||||
.stats-row {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
gap: 6px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.stat-item {
|
||||
flex: 1;
|
||||
min-width: 100px;
|
||||
min-width: 80px;
|
||||
background: #fff;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 2px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 4px;
|
||||
padding: 8px 10px;
|
||||
text-align: center;
|
||||
}
|
||||
.stat-val {
|
||||
display: block;
|
||||
font-size: 22px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.stat-label {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
font-size: 11px;
|
||||
color: #909399;
|
||||
margin-top: 2px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
.stat-blue .stat-val { color: #409eff; }
|
||||
.stat-orange .stat-val { color: #e6a23c; }
|
||||
.stat-green .stat-val { color: #67c23a; }
|
||||
|
||||
.chart-box {
|
||||
background: #fff;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 2px;
|
||||
}
|
||||
/* 图表筛选 */
|
||||
.chart-filter-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.chart-filter-bar .filter-label {
|
||||
font-size: 13px;
|
||||
font-size: 12px;
|
||||
color: #606266;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.chart-body {
|
||||
width: 100%;
|
||||
height: 480px;
|
||||
|
||||
/* 迷你图表网格 */
|
||||
.mini-charts-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
.legend-hint {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
|
||||
.mini-chart-card {
|
||||
background: #fff;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mini-chart-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
gap: 6px;
|
||||
padding: 8px 10px 0 10px;
|
||||
font-size: 13px;
|
||||
color: #303133;
|
||||
}
|
||||
.mini-chart-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.mini-chart-name {
|
||||
font-weight: 500;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.mini-chart-max {
|
||||
margin-left: auto;
|
||||
font-size: 11px;
|
||||
color: #909399;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mini-chart-body {
|
||||
width: 100%;
|
||||
height: 220px;
|
||||
}
|
||||
|
||||
.empty-hint {
|
||||
grid-column: 1 / -1;
|
||||
text-align: center;
|
||||
padding: 60px 0;
|
||||
font-size: 13px;
|
||||
color: #909399;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
/>
|
||||
<el-button type="primary" size="small" icon="el-icon-search" @click="handleQuery">筛选</el-button>
|
||||
<el-button size="small" icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button size="small" icon="el-icon-download" @click="handleExport">导出</el-button>
|
||||
<span v-if="total > 0" class="result-count">共 {{ total }} 条记录</span>
|
||||
</div>
|
||||
|
||||
@@ -130,6 +131,14 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 业务员 -->
|
||||
<el-table-column label="业务员" width="110">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.salesman" size="small" class="editable-cell" style="width: 100%" @change="saveRow(scope.row)">
|
||||
<el-option v-for="item in dict.type.wip_pack_saleman" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 签订日期 -->
|
||||
<el-table-column label="签订日期" prop="signTime" width="100">
|
||||
<template slot-scope="scope">
|
||||
@@ -421,8 +430,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listOrder, updateOrder } from '@/api/crm/order'
|
||||
import { listOrder, updateOrder, exportOrder } from '@/api/crm/order'
|
||||
import { listCustomer } from '@/api/crm/customer'
|
||||
import { blobValidate } from "@/utils/klp";
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
const STATUS_MAP = {
|
||||
'0': { label: '草稿', type: 'info' },
|
||||
@@ -433,6 +444,7 @@ const STATUS_MAP = {
|
||||
|
||||
export default {
|
||||
name: 'ContractDetailEdit',
|
||||
dicts: ['wip_pack_saleman'],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
@@ -628,7 +640,38 @@ export default {
|
||||
}
|
||||
this.customerDialogVisible = false
|
||||
this.saveRow(row)
|
||||
}
|
||||
},
|
||||
|
||||
// 导出合同明细(按当前筛选条件)
|
||||
handleExport() {
|
||||
const params = {}
|
||||
if (this.contractQuery.contractCode) params.contractCode = this.contractQuery.contractCode
|
||||
if (this.contractQuery.supplier) params.supplier = this.contractQuery.supplier
|
||||
if (this.contractQuery.customer) params.customer = this.contractQuery.customer
|
||||
if (this.contractQuery.status !== undefined && this.contractQuery.status !== null) params.status = this.contractQuery.status
|
||||
if (this.contractQuery.signDateStart) params.signDateStart = this.contractQuery.signDateStart
|
||||
if (this.contractQuery.signDateEnd) params.signDateEnd = this.contractQuery.signDateEnd
|
||||
if (this.contractQuery.deliveryDateStart) params.deliveryDateStart = this.contractQuery.deliveryDateStart
|
||||
if (this.contractQuery.deliveryDateEnd) params.deliveryDateEnd = this.contractQuery.deliveryDateEnd
|
||||
if (this.contractQuery.signLocation) params.signLocation = this.contractQuery.signLocation
|
||||
exportOrder(params).then((res) => {
|
||||
this.handleExportBlob(res, '合同编辑详情.xlsx')
|
||||
}).catch(() => {})
|
||||
},
|
||||
|
||||
// 处理blob文件导出
|
||||
async handleExportBlob(res, fileName) {
|
||||
const isBlob = blobValidate(res);
|
||||
if (isBlob) {
|
||||
saveAs(res, fileName);
|
||||
this.$message.success('导出成功!');
|
||||
} else {
|
||||
const resText = await res.text();
|
||||
const rspObj = JSON.parse(resText);
|
||||
const errMsg = rspObj.msg || '导出失败';
|
||||
this.$message.error(errMsg);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -727,6 +770,22 @@ export default {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/* 业务员下拉框样式 */
|
||||
.select-salesman ::v-deep .el-input__inner {
|
||||
background-color: #f3f0ff;
|
||||
border-color: transparent;
|
||||
padding: 0 8px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.select-salesman ::v-deep .el-input__inner:focus {
|
||||
border-color: #5F7BA0;
|
||||
background-color: #fff;
|
||||
overflow: visible;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/* 日期选择器样式 */
|
||||
.editable-cell-date ::v-deep .el-input__inner {
|
||||
background-color: #e6f7ff;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
<div class="toolbar">
|
||||
<el-button type="danger" size="small" icon="el-icon-delete" :disabled="!selection.length" @click="handleBatchDelete">批量删除</el-button>
|
||||
<el-button type="primary" size="small" icon="el-icon-download" @click="handleExport">导出</el-button>
|
||||
<span class="toolbar-tip">合同列为只读;明细列失焦自动保存(需有修改权限)</span>
|
||||
</div>
|
||||
|
||||
@@ -50,6 +51,9 @@
|
||||
<el-table-column label="供方" min-width="120" show-overflow-tooltip>
|
||||
<template slot-scope="{ row }">{{ (row.orderInfo && row.orderInfo.supplier) || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="业务员" min-width="80" show-overflow-tooltip>
|
||||
<template slot-scope="{ row }">{{ (row.orderInfo && row.orderInfo.salesman) || row.salesman || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="签订时间" width="110">
|
||||
<template slot-scope="{ row }">{{ row.orderInfo && row.orderInfo.signTime ? parseTime(row.orderInfo.signTime, '{y}-{m}-{d}') : '-' }}</template>
|
||||
</el-table-column>
|
||||
@@ -201,7 +205,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listOrderItem, updateOrderItem, delOrderItem } from '@/api/crm/orderItem'
|
||||
import { listOrderItem, updateOrderItem, delOrderItem, exportOrderItem } from '@/api/crm/orderItem'
|
||||
import { blobValidate } from "@/utils/klp";
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
const ITEM_PAYLOAD_KEYS = [
|
||||
'itemId',
|
||||
@@ -354,7 +360,36 @@ export default {
|
||||
console.error('批量删除失败:', err)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// 导出订单明细(按当前筛选条件)
|
||||
handleExport() {
|
||||
const params = {}
|
||||
if (this.queryParams.contractCode) params.contractCode = this.queryParams.contractCode
|
||||
if (this.queryParams.customer) params.customer = this.queryParams.customer
|
||||
if (this.queryParams.material) params.material = this.queryParams.material
|
||||
if (this.queryParams.orderId) {
|
||||
const n = Number(this.queryParams.orderId)
|
||||
params.orderId = Number.isNaN(n) ? this.queryParams.orderId : n
|
||||
}
|
||||
exportOrderItem(params).then((res) => {
|
||||
this.handleExportBlob(res, '正式订单明细.xlsx')
|
||||
}).catch(() => {})
|
||||
},
|
||||
|
||||
// 处理blob文件导出
|
||||
async handleExportBlob(res, fileName) {
|
||||
const isBlob = blobValidate(res);
|
||||
if (isBlob) {
|
||||
saveAs(res, fileName);
|
||||
this.$modal.msgSuccess('导出成功!');
|
||||
} else {
|
||||
const resText = await res.text();
|
||||
const rspObj = JSON.parse(resText);
|
||||
const errMsg = rspObj.msg || '导出失败';
|
||||
this.$modal.msgError(errMsg);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
/>
|
||||
<el-button type="primary" size="small" icon="el-icon-search" @click="handleQuery">筛选</el-button>
|
||||
<el-button size="small" icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button size="small" icon="el-icon-download" @click="handleExport">导出</el-button>
|
||||
<span class="sort-hint">已按合同签订日期默认当月,结果按交货日期倒序排列</span>
|
||||
</div>
|
||||
|
||||
@@ -96,6 +97,11 @@
|
||||
<span class="contract-info" :title="row.customer">{{ row.customer }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="业务员" width="80">
|
||||
<template slot-scope="{ row }">
|
||||
<span class="contract-info">{{ row._order && row._order.salesman ? row._order.salesman : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="签订日期" prop="signTime" width="100">
|
||||
<template slot-scope="{ row }">
|
||||
<span class="contract-info contract-date">{{ formatDate(row.signTime) }}</span>
|
||||
@@ -270,8 +276,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listOrder, updateOrder } from '@/api/crm/order'
|
||||
import { listOrder, updateOrder, exportOrder } from '@/api/crm/order'
|
||||
import { parseProductContent, stringifyProductContent, calculateProductFields, recalculateTotals } from '@/utils/productContent'
|
||||
import { blobValidate } from "@/utils/klp";
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
export default {
|
||||
name: 'OrderItemList',
|
||||
@@ -555,6 +563,34 @@ export default {
|
||||
this.getList()
|
||||
},
|
||||
|
||||
// 导出订单明细(按当前筛选条件)
|
||||
handleExport() {
|
||||
const params = {}
|
||||
if (this.queryParams.contractCode) params.contractCode = this.queryParams.contractCode
|
||||
if (this.queryParams.customer) params.customer = this.queryParams.customer
|
||||
if (this.queryParams.signDateStart) params.signDateStart = this.queryParams.signDateStart
|
||||
if (this.queryParams.signDateEnd) params.signDateEnd = this.queryParams.signDateEnd
|
||||
if (this.queryParams.deliveryDateStart) params.deliveryDateStart = this.queryParams.deliveryDateStart
|
||||
if (this.queryParams.deliveryDateEnd) params.deliveryDateEnd = this.queryParams.deliveryDateEnd
|
||||
exportOrder(params).then((res) => {
|
||||
this.handleExportBlob(res, '订单明细列表.xlsx')
|
||||
}).catch(() => {})
|
||||
},
|
||||
|
||||
// 处理blob文件导出
|
||||
async handleExportBlob(res, fileName) {
|
||||
const isBlob = blobValidate(res);
|
||||
if (isBlob) {
|
||||
saveAs(res, fileName);
|
||||
this.$message.success('导出成功!');
|
||||
} else {
|
||||
const resText = await res.text();
|
||||
const rspObj = JSON.parse(resText);
|
||||
const errMsg = rspObj.msg || '导出失败';
|
||||
this.$message.error(errMsg);
|
||||
}
|
||||
},
|
||||
|
||||
groupRowClassName({ row, rowIndex }) {
|
||||
if (row.productIndex === 0) {
|
||||
return 'group-row-a'
|
||||
|
||||
@@ -56,7 +56,12 @@
|
||||
<el-col :span="14">
|
||||
<div class="chart-card">
|
||||
<div class="chart-header">
|
||||
<span class="chart-title"><i class="el-icon-data-line" /> 每日磨削趋势</span>
|
||||
<span class="chart-title"><i class="el-icon-data-line" /> {{ trendChartTitle }}</span>
|
||||
<el-radio-group v-model="trendDimension" size="mini" @change="onTrendDimensionChange" style="margin-left:12px">
|
||||
<el-radio-button label="day">按天</el-radio-button>
|
||||
<el-radio-button label="week">按周</el-radio-button>
|
||||
<el-radio-button label="month">按月</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div ref="trendChartRef" class="chart-container" style="height:340px"></div>
|
||||
<div v-if="!dailyTrend.length" class="chart-empty">暂无数据</div>
|
||||
@@ -131,6 +136,38 @@
|
||||
<el-empty v-else description="暂无磨削记录" />
|
||||
</div>
|
||||
|
||||
<!-- 月度产线汇总二维表 -->
|
||||
<div class="table-card mt16">
|
||||
<div class="card-header">
|
||||
<span class="card-title"><i class="el-icon-s-data" /> 月度产线汇总</span>
|
||||
<span class="card-subtitle" v-if="monthlyPivot.length">{{ monthlyPivotMonths.length }} 个月 · {{ monthlyPivot.length }} 条产线</span>
|
||||
<el-button size="mini" type="primary" plain icon="el-icon-download" style="margin-left:8px" @click="exportMonthlyPivot" :disabled="!monthlyPivot.length">导出</el-button>
|
||||
</div>
|
||||
<div style="overflow-x:auto" v-if="monthlyPivot.length">
|
||||
<el-table :data="monthlyPivot" size="small" border stripe style="min-width:100%"
|
||||
:header-cell-style="{ textAlign: 'center', fontWeight: 600 }">
|
||||
<el-table-column label="产线" prop="lineName" fixed="left" width="140" align="center" />
|
||||
<el-table-column v-for="m in monthlyPivotMonths" :key="m" :label="m" align="center">
|
||||
<el-table-column label="磨削次数" align="center" min-width="80">
|
||||
<template slot-scope="{row}">{{ row[m + '_count'] || 0 }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="磨削量(mm)" align="right" min-width="110">
|
||||
<template slot-scope="{row}">{{ (row[m + '_amount'] || 0).toFixed(2) }}</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="合计" align="center">
|
||||
<el-table-column label="磨削次数" align="center" min-width="80">
|
||||
<template slot-scope="{row}">{{ row.totalCount }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="磨削量(mm)" align="right" min-width="110">
|
||||
<template slot-scope="{row}">{{ row.totalAmount.toFixed(2) }}</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-empty v-else description="暂无磨削记录" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -139,12 +176,19 @@ import * as echarts from 'echarts'
|
||||
import * as XLSX from 'xlsx'
|
||||
import { getRollStats, listRollInfo } from '@/api/mes/roll/rollInfo'
|
||||
import { listRollGrindAll } from '@/api/mes/roll/rollGrind'
|
||||
import { mapGetters } from 'vuex'
|
||||
import rollLineMixin from '../rollLineMixin'
|
||||
|
||||
export default {
|
||||
name: 'RollReport',
|
||||
mixins: [rollLineMixin],
|
||||
dicts: ['mes_roll_operator'],
|
||||
computed: {
|
||||
...mapGetters(['productionLines']),
|
||||
trendChartTitle() {
|
||||
return { day: '每日磨削趋势', week: '每周磨削趋势', month: '每月磨削趋势' }[this.trendDimension] || '磨削趋势'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const now = new Date()
|
||||
const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
|
||||
@@ -161,7 +205,10 @@ export default {
|
||||
trendChart: null,
|
||||
pieChart: null,
|
||||
_beginTime: fmt(sevenDaysAgo),
|
||||
_endTime: fmt(now)
|
||||
_endTime: fmt(now),
|
||||
monthlyPivot: [],
|
||||
monthlyPivotMonths: [],
|
||||
trendDimension: 'day'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -197,8 +244,8 @@ export default {
|
||||
this.stats = statsRes.data || {}
|
||||
}
|
||||
|
||||
// 2. 获取全部轧辊(用于辊型映射)
|
||||
const rollRes = await listRollInfo({ pageNum: 1, pageSize: 99999, lineId: this.lineId || undefined })
|
||||
// 2. 获取全部轧辊(用于辊型映射和产线关联)
|
||||
const rollRes = await listRollInfo({ pageNum: 1, pageSize: 99999 })
|
||||
const rolls = rollRes.rows || []
|
||||
const rollMap = {}
|
||||
rolls.forEach(r => { rollMap[r.rollId] = r })
|
||||
@@ -211,10 +258,20 @@ export default {
|
||||
const allRecords = grindRes.data || []
|
||||
|
||||
// 4. 汇总计算
|
||||
this.autoDetectTrendDimension()
|
||||
this.computeSummary(allRecords, rollMap)
|
||||
this.computeDailyTrend(allRecords)
|
||||
this.computeTrendData(allRecords)
|
||||
this.computeRollTypeDist(allRecords, rollMap)
|
||||
this.computeOperatorStats(allRecords, rollMap)
|
||||
|
||||
// 5. 月度产线汇总(跨全部产线,不受当前 lineId 限制)
|
||||
await this.$store.dispatch('productionLine/getProductionLines')
|
||||
const allParams = {}
|
||||
if (this._beginTime) allParams.beginTime = this._beginTime
|
||||
if (this._endTime) allParams.endTime = this._endTime + ' 23:59:59'
|
||||
const allGrindRes = await listRollGrindAll(allParams)
|
||||
this.computeMonthlyPivot(allGrindRes.data || [], rollMap)
|
||||
|
||||
this.updateCharts()
|
||||
} catch (e) {
|
||||
console.error('加载报表数据失败', e)
|
||||
@@ -249,6 +306,56 @@ export default {
|
||||
})
|
||||
this.dailyTrend = Object.values(dateMap).sort((a, b) => a.grindDate.localeCompare(b.grindDate))
|
||||
},
|
||||
computeWeeklyTrend(records) {
|
||||
const weekMap = {}
|
||||
const pad = n => String(n).padStart(2, '0')
|
||||
records.forEach(r => {
|
||||
if (!r.grindTime) return
|
||||
const d = new Date(r.grindTime)
|
||||
const dayOfWeek = d.getDay() || 7
|
||||
const monday = new Date(d)
|
||||
monday.setDate(d.getDate() - dayOfWeek + 1)
|
||||
const sunday = new Date(monday)
|
||||
sunday.setDate(monday.getDate() + 6)
|
||||
const key = `${monday.getFullYear()}-${pad(monday.getMonth() + 1)}-${pad(monday.getDate())}`
|
||||
const label = `${pad(monday.getMonth() + 1)}-${pad(monday.getDate())}~${pad(sunday.getMonth() + 1)}-${pad(sunday.getDate())}`
|
||||
if (!weekMap[key]) weekMap[key] = { grindDate: label, grindCount: 0, totalGrindAmount: 0, _sort: key }
|
||||
weekMap[key].grindCount++
|
||||
weekMap[key].totalGrindAmount += Number(r.grindAmount || 0)
|
||||
})
|
||||
this.dailyTrend = Object.values(weekMap).sort((a, b) => a._sort.localeCompare(b._sort))
|
||||
},
|
||||
computeMonthlyTrend(records) {
|
||||
const monthMap = {}
|
||||
records.forEach(r => {
|
||||
if (!r.grindTime) return
|
||||
const m = r.grindTime.substring(0, 7)
|
||||
if (!monthMap[m]) monthMap[m] = { grindDate: m, grindCount: 0, totalGrindAmount: 0 }
|
||||
monthMap[m].grindCount++
|
||||
monthMap[m].totalGrindAmount += Number(r.grindAmount || 0)
|
||||
})
|
||||
this.dailyTrend = Object.values(monthMap).sort((a, b) => a.grindDate.localeCompare(b.grindDate))
|
||||
},
|
||||
computeTrendData(records) {
|
||||
this._cachedRecords = records
|
||||
if (this.trendDimension === 'week') this.computeWeeklyTrend(records)
|
||||
else if (this.trendDimension === 'month') this.computeMonthlyTrend(records)
|
||||
else this.computeDailyTrend(records)
|
||||
},
|
||||
autoDetectTrendDimension() {
|
||||
const [b, e] = this.dateRange
|
||||
if (!b || !e) return
|
||||
const days = (new Date(e) - new Date(b)) / (24 * 60 * 60 * 1000)
|
||||
if (days <= 31) this.trendDimension = 'day'
|
||||
else if (days <= 90) this.trendDimension = 'week'
|
||||
else this.trendDimension = 'month'
|
||||
},
|
||||
onTrendDimensionChange() {
|
||||
if (this._cachedRecords) {
|
||||
this.computeTrendData(this._cachedRecords)
|
||||
this.updateTrendChart()
|
||||
}
|
||||
},
|
||||
computeRollTypeDist(records, rollMap) {
|
||||
const typeMap = {}
|
||||
records.forEach(r => {
|
||||
@@ -420,6 +527,79 @@ export default {
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
},
|
||||
computeMonthlyPivot(records, rollMap) {
|
||||
const lineMonthMap = {}
|
||||
const monthSet = new Set()
|
||||
records.forEach(r => {
|
||||
if (!r.grindTime) return
|
||||
const month = r.grindTime.substring(0, 7)
|
||||
const roll = rollMap[r.rollId]
|
||||
const lid = Number(roll?.lineId) || 0
|
||||
if (!lineMonthMap[lid]) {
|
||||
const line = this.productionLines.find(l => Number(l.lineId) === lid)
|
||||
lineMonthMap[lid] = { lineId: lid, lineName: line ? line.lineName : (r.lineName || '未知产线'), months: {} }
|
||||
}
|
||||
if (!lineMonthMap[lid].months[month]) {
|
||||
lineMonthMap[lid].months[month] = { grindCount: 0, totalGrindAmount: 0 }
|
||||
}
|
||||
lineMonthMap[lid].months[month].grindCount++
|
||||
lineMonthMap[lid].months[month].totalGrindAmount += Number(r.grindAmount || 0)
|
||||
monthSet.add(month)
|
||||
})
|
||||
const months = [...monthSet].sort()
|
||||
const rows = this.productionLines.map(line => {
|
||||
const ld = lineMonthMap[line.lineId]
|
||||
const row = { lineId: line.lineId, lineName: line.lineName, totalCount: 0, totalAmount: 0 }
|
||||
months.forEach(m => {
|
||||
if (ld && ld.months[m]) {
|
||||
row[m + '_count'] = ld.months[m].grindCount
|
||||
row[m + '_amount'] = Number(ld.months[m].totalGrindAmount.toFixed(2))
|
||||
row.totalCount += ld.months[m].grindCount
|
||||
row.totalAmount += ld.months[m].totalGrindAmount
|
||||
} else {
|
||||
row[m + '_count'] = 0
|
||||
row[m + '_amount'] = 0
|
||||
}
|
||||
})
|
||||
row.totalAmount = Number(row.totalAmount.toFixed(2))
|
||||
return row
|
||||
})
|
||||
this.monthlyPivotMonths = months
|
||||
this.monthlyPivot = rows
|
||||
},
|
||||
exportMonthlyPivot() {
|
||||
const months = this.monthlyPivotMonths
|
||||
const header1 = ['产线']
|
||||
const header2 = ['']
|
||||
months.forEach(m => { header1.push(m, ''); header2.push('磨削次数', '磨削量(mm)') })
|
||||
header1.push('合计', '')
|
||||
header2.push('磨削次数', '磨削量(mm)')
|
||||
const rows = [header1, header2]
|
||||
this.monthlyPivot.forEach(row => {
|
||||
const r = [row.lineName]
|
||||
months.forEach(m => { r.push(row[m + '_count'] || 0, (row[m + '_amount'] || 0).toFixed(2)) })
|
||||
r.push(row.totalCount, row.totalAmount.toFixed(2))
|
||||
rows.push(r)
|
||||
})
|
||||
const ws = XLSX.utils.aoa_to_sheet(rows)
|
||||
// merge header row 1 for month groups
|
||||
ws['!merges'] = []
|
||||
let col = 1
|
||||
months.forEach(() => { ws['!merges'].push({ s: { r: 0, c: col }, e: { r: 0, c: col + 1 } }); col += 2 })
|
||||
ws['!merges'].push({ s: { r: 0, c: col }, e: { r: 0, c: col + 1 } })
|
||||
const wb = XLSX.utils.book_new()
|
||||
XLSX.utils.book_append_sheet(wb, ws, '月度产线汇总')
|
||||
const buf = XLSX.write(wb, { bookType: 'xlsx', type: 'array' })
|
||||
const blob = new Blob([buf], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = `月度产线汇总_${this._beginTime || ''}_${this._endTime ? this._endTime.substring(0, 10) : ''}.xlsx`
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -431,6 +611,7 @@ export default {
|
||||
min-height: 100%;
|
||||
}
|
||||
.mb16 { margin-bottom: 16px; }
|
||||
.mt16 { margin-top: 16px; }
|
||||
|
||||
/* 筛选栏 */
|
||||
.filter-panel {
|
||||
|
||||
40
klp-ui/src/views/micro/pages/dr/components/Inventory.vue
Normal file
40
klp-ui/src/views/micro/pages/dr/components/Inventory.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div class="inventory-container">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="querys"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { DR_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'DrInventory',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
querys: {
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
},
|
||||
warehouseOptions: DR_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.inventory-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
39
klp-ui/src/views/micro/pages/dr/components/Processing.vue
Normal file
39
klp-ui/src/views/micro/pages/dr/components/Processing.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="processing-container">
|
||||
<el-tabs v-model="activeTab" type="border-card">
|
||||
<el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.title" :name="tab.name">
|
||||
<DoPage
|
||||
v-if="activeTab === tab.name"
|
||||
:label="tab.label"
|
||||
:tabs="tab.tabs"
|
||||
:useSpecialSplit="tab.useSpecialSplit"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DoPage from '@/views/wms/coil/panels/do.vue'
|
||||
import { DR_PROCESSING_TABS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'DrProcessing',
|
||||
components: {
|
||||
DoPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'process',
|
||||
tabs: DR_PROCESSING_TABS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.processing-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
92
klp-ui/src/views/micro/pages/dr/components/Quality.vue
Normal file
92
klp-ui/src/views/micro/pages/dr/components/Quality.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<div class="quality-container">
|
||||
<el-tabs v-model="activeTab" class="quality-tabs">
|
||||
<el-tab-pane label="异常钢卷" name="abnormal">
|
||||
<div v-if="activeTab === 'abnormal'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="abnormalQuerys"
|
||||
:labelType="'2'"
|
||||
:hideType="false"
|
||||
:showAbnormal="true"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="次品钢卷" name="defect">
|
||||
<div v-if="activeTab === 'defect'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="defectQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="O卷" name="oil">
|
||||
<div v-if="activeTab === 'oil'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="oilQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { DR_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'DrQuality',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'abnormal',
|
||||
abnormalQuerys: {
|
||||
dataType: 1,
|
||||
orderByAbnormal: true,
|
||||
},
|
||||
defectQuerys: {
|
||||
dataType: 1,
|
||||
OnlyScrap: true,
|
||||
},
|
||||
oilQuerys: {
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
qualityStatus: 'O',
|
||||
},
|
||||
warehouseOptions: DR_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.quality-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.quality-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
67
klp-ui/src/views/micro/pages/dr/components/Report.vue
Normal file
67
klp-ui/src/views/micro/pages/dr/components/Report.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="report-container">
|
||||
<el-tabs v-model="activeTab" class="report-tabs">
|
||||
<el-tab-pane label="综合报表" name="comprehensive">
|
||||
<Comprehensive v-if="activeTab === 'comprehensive'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="日报表" name="day">
|
||||
<DayReport v-if="activeTab === 'day'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="月报表" name="month">
|
||||
<MonthReport v-if="activeTab === 'month'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="年报表" name="year">
|
||||
<YearReport v-if="activeTab === 'year'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="损耗报表" name="loss">
|
||||
<LossReport v-if="activeTab === 'loss'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="产出报表" name="out">
|
||||
<OutReport v-if="activeTab === 'out'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="班报表" name="team">
|
||||
<TeamReport v-if="activeTab === 'team'" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Comprehensive from '@/views/wms/report/shuang/comprehensive.vue'
|
||||
import DayReport from '@/views/wms/report/shuang/day.vue'
|
||||
import MonthReport from '@/views/wms/report/shuang/month.vue'
|
||||
import YearReport from '@/views/wms/report/shuang/year.vue'
|
||||
import LossReport from '@/views/wms/report/shuang/loss.vue'
|
||||
import OutReport from '@/views/wms/report/shuang/out.vue'
|
||||
import TeamReport from '@/views/wms/report/shuang/team.vue'
|
||||
|
||||
export default {
|
||||
name: 'DrReport',
|
||||
components: {
|
||||
Comprehensive,
|
||||
DayReport,
|
||||
MonthReport,
|
||||
YearReport,
|
||||
LossReport,
|
||||
OutReport,
|
||||
TeamReport,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'comprehensive',
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.report-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
79
klp-ui/src/views/micro/pages/dr/components/Shipping.vue
Normal file
79
klp-ui/src/views/micro/pages/dr/components/Shipping.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div class="shipping-container">
|
||||
<el-tabs v-model="activeTab" class="shipping-tabs">
|
||||
<el-tab-pane label="配卷情况" name="waybill">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:showWaybill="true"
|
||||
:showNewExport="true"
|
||||
:querys="waybillQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="发货记录" name="ship">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="shipQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showExportTime="true"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { DR_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'DrShipping',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'waybill',
|
||||
waybillQuerys: {
|
||||
dataType: 1,
|
||||
includeBindInfo: true,
|
||||
},
|
||||
shipQuerys: {
|
||||
dataType: 1,
|
||||
status: 1,
|
||||
},
|
||||
warehouseOptions: DR_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shipping-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.shipping-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
28
klp-ui/src/views/micro/pages/dr/config.js
Normal file
28
klp-ui/src/views/micro/pages/dr/config.js
Normal file
@@ -0,0 +1,28 @@
|
||||
export const DR_WAREHOUSE_OPTIONS = [
|
||||
{ value: '1992873386047643650', label: '双机架原料库' },
|
||||
{ value: '1992873437713080322', label: '双机架成品库' },
|
||||
{ value: '1988151076996706306', label: '镀铬原料库' },
|
||||
]
|
||||
|
||||
export const DR_PROCESSING_TABS = [
|
||||
{
|
||||
title: '双机架工序',
|
||||
name: 'process',
|
||||
label: '双机架工序',
|
||||
tabs: DR_WAREHOUSE_OPTIONS,
|
||||
useSpecialSplit: true,
|
||||
},
|
||||
{
|
||||
title: '合卷',
|
||||
name: 'merge',
|
||||
label: '双机架合卷',
|
||||
useSpecialSplit: false,
|
||||
},
|
||||
{
|
||||
title: '双机架修复',
|
||||
name: 'repair',
|
||||
label: '双机架修复工序',
|
||||
tabs: DR_WAREHOUSE_OPTIONS,
|
||||
useSpecialSplit: true,
|
||||
},
|
||||
]
|
||||
@@ -2,6 +2,26 @@
|
||||
<div class="dr-container">
|
||||
<div class="dr-sidebar">
|
||||
<el-menu :default-active="activeMenu" class="sidebar-menu" @select="handleMenuSelect">
|
||||
<el-menu-item index="inventory">
|
||||
<i class="el-icon-box"></i>
|
||||
<span slot="title">库存</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="processing">
|
||||
<i class="el-icon-s-operation"></i>
|
||||
<span slot="title">WIP</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="report">
|
||||
<i class="el-icon-document"></i>
|
||||
<span slot="title">报表</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="shipping">
|
||||
<i class="el-icon-truck"></i>
|
||||
<span slot="title">发货</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="quality">
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
<span slot="title">品质</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="plan">
|
||||
<i class="el-icon-s-order"></i>
|
||||
<span slot="title">计划</span>
|
||||
@@ -23,19 +43,42 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Plan from './components/Plan.vue'
|
||||
import Plan from './components/Plan.vue'
|
||||
import ProcessSpec from './components/ProcessSpec.vue'
|
||||
import Actual from './components/Actual.vue'
|
||||
import Actual from './components/Actual.vue'
|
||||
import Inventory from './components/Inventory.vue'
|
||||
import Processing from './components/Processing.vue'
|
||||
import Report from './components/Report.vue'
|
||||
import Shipping from './components/Shipping.vue'
|
||||
import Quality from './components/Quality.vue'
|
||||
|
||||
export default {
|
||||
name: 'DrSystem',
|
||||
components: { Plan, ProcessSpec, Actual },
|
||||
components: {
|
||||
Plan,
|
||||
ProcessSpec,
|
||||
Actual,
|
||||
Inventory,
|
||||
Processing,
|
||||
Report,
|
||||
Shipping,
|
||||
Quality,
|
||||
},
|
||||
data() {
|
||||
return { activeMenu: 'plan' }
|
||||
return { activeMenu: 'inventory' }
|
||||
},
|
||||
computed: {
|
||||
currentComponent() {
|
||||
return { plan: 'Plan', processSpec: 'ProcessSpec', actual: 'Actual' }[this.activeMenu]
|
||||
return {
|
||||
plan: 'Plan',
|
||||
processSpec: 'ProcessSpec',
|
||||
actual: 'Actual',
|
||||
inventory: 'Inventory',
|
||||
processing: 'Processing',
|
||||
report: 'Report',
|
||||
shipping: 'Shipping',
|
||||
quality: 'Quality',
|
||||
}[this.activeMenu]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -45,6 +88,10 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.dr-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
40
klp-ui/src/views/micro/pages/duge/components/Inventory.vue
Normal file
40
klp-ui/src/views/micro/pages/duge/components/Inventory.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div class="inventory-container">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="querys"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { DUGE_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'DugeInventory',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
querys: {
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
},
|
||||
warehouseOptions: DUGE_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.inventory-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
39
klp-ui/src/views/micro/pages/duge/components/Processing.vue
Normal file
39
klp-ui/src/views/micro/pages/duge/components/Processing.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="processing-container">
|
||||
<el-tabs v-model="activeTab" type="border-card">
|
||||
<el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.title" :name="tab.name">
|
||||
<DoPage
|
||||
v-if="activeTab === tab.name"
|
||||
:label="tab.label"
|
||||
:tabs="tab.tabs"
|
||||
:useSpecialSplit="tab.useSpecialSplit"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DoPage from '@/views/wms/coil/panels/do.vue'
|
||||
import { DUGE_PROCESSING_TABS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'DugeProcessing',
|
||||
components: {
|
||||
DoPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'process',
|
||||
tabs: DUGE_PROCESSING_TABS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.processing-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
92
klp-ui/src/views/micro/pages/duge/components/Quality.vue
Normal file
92
klp-ui/src/views/micro/pages/duge/components/Quality.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<div class="quality-container">
|
||||
<el-tabs v-model="activeTab" class="quality-tabs">
|
||||
<el-tab-pane label="异常钢卷" name="abnormal">
|
||||
<div v-if="activeTab === 'abnormal'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="abnormalQuerys"
|
||||
:labelType="'2'"
|
||||
:hideType="false"
|
||||
:showAbnormal="true"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="次品钢卷" name="defect">
|
||||
<div v-if="activeTab === 'defect'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="defectQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="O卷" name="oil">
|
||||
<div v-if="activeTab === 'oil'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="oilQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { DUGE_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'DugeQuality',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'abnormal',
|
||||
abnormalQuerys: {
|
||||
dataType: 1,
|
||||
orderByAbnormal: true,
|
||||
},
|
||||
defectQuerys: {
|
||||
dataType: 1,
|
||||
OnlyScrap: true,
|
||||
},
|
||||
oilQuerys: {
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
qualityStatus: 'O',
|
||||
},
|
||||
warehouseOptions: DUGE_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.quality-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.quality-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
67
klp-ui/src/views/micro/pages/duge/components/Report.vue
Normal file
67
klp-ui/src/views/micro/pages/duge/components/Report.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="report-container">
|
||||
<el-tabs v-model="activeTab" class="report-tabs">
|
||||
<el-tab-pane label="综合报表" name="comprehensive">
|
||||
<Comprehensive v-if="activeTab === 'comprehensive'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="日报表" name="day">
|
||||
<DayReport v-if="activeTab === 'day'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="月报表" name="month">
|
||||
<MonthReport v-if="activeTab === 'month'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="年报表" name="year">
|
||||
<YearReport v-if="activeTab === 'year'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="损耗报表" name="loss">
|
||||
<LossReport v-if="activeTab === 'loss'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="产出报表" name="out">
|
||||
<OutReport v-if="activeTab === 'out'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="班报表" name="team">
|
||||
<TeamReport v-if="activeTab === 'team'" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Comprehensive from '@/views/wms/report/duge/comprehensive.vue'
|
||||
import DayReport from '@/views/wms/report/duge/day.vue'
|
||||
import MonthReport from '@/views/wms/report/duge/month.vue'
|
||||
import YearReport from '@/views/wms/report/duge/year.vue'
|
||||
import LossReport from '@/views/wms/report/duge/loss.vue'
|
||||
import OutReport from '@/views/wms/report/duge/out.vue'
|
||||
import TeamReport from '@/views/wms/report/duge/team.vue'
|
||||
|
||||
export default {
|
||||
name: 'DugeReport',
|
||||
components: {
|
||||
Comprehensive,
|
||||
DayReport,
|
||||
MonthReport,
|
||||
YearReport,
|
||||
LossReport,
|
||||
OutReport,
|
||||
TeamReport,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'comprehensive',
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.report-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
79
klp-ui/src/views/micro/pages/duge/components/Shipping.vue
Normal file
79
klp-ui/src/views/micro/pages/duge/components/Shipping.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div class="shipping-container">
|
||||
<el-tabs v-model="activeTab" class="shipping-tabs">
|
||||
<el-tab-pane label="配卷情况" name="waybill">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:showWaybill="true"
|
||||
:showNewExport="true"
|
||||
:querys="waybillQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="发货记录" name="ship">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="shipQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showExportTime="true"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { DUGE_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'DugeShipping',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'waybill',
|
||||
waybillQuerys: {
|
||||
dataType: 1,
|
||||
includeBindInfo: true,
|
||||
},
|
||||
shipQuerys: {
|
||||
dataType: 1,
|
||||
status: 1,
|
||||
},
|
||||
warehouseOptions: DUGE_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shipping-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.shipping-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
27
klp-ui/src/views/micro/pages/duge/config.js
Normal file
27
klp-ui/src/views/micro/pages/duge/config.js
Normal file
@@ -0,0 +1,27 @@
|
||||
export const DUGE_WAREHOUSE_OPTIONS = [
|
||||
{ value: '1988151076996706306', label: '镀铬原料库' },
|
||||
{ value: '1988151132361519105', label: '镀铬成品库' },
|
||||
]
|
||||
|
||||
export const DUGE_PROCESSING_TABS = [
|
||||
{
|
||||
title: '镀铬工序',
|
||||
name: 'process',
|
||||
label: '镀铬工序',
|
||||
tabs: DUGE_WAREHOUSE_OPTIONS,
|
||||
useSpecialSplit: true,
|
||||
},
|
||||
{
|
||||
title: '合卷',
|
||||
name: 'merge',
|
||||
label: '镀铬合卷',
|
||||
useSpecialSplit: false,
|
||||
},
|
||||
{
|
||||
title: '镀铬修复',
|
||||
name: 'repair',
|
||||
label: '镀铬修复工序',
|
||||
tabs: DUGE_WAREHOUSE_OPTIONS,
|
||||
useSpecialSplit: true,
|
||||
},
|
||||
]
|
||||
129
klp-ui/src/views/micro/pages/duge/index.vue
Normal file
129
klp-ui/src/views/micro/pages/duge/index.vue
Normal file
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div class="duge-container">
|
||||
<div class="duge-sidebar">
|
||||
<el-menu :default-active="activeMenu" class="sidebar-menu" @select="handleMenuSelect">
|
||||
<el-menu-item index="inventory">
|
||||
<i class="el-icon-box"></i>
|
||||
<span slot="title">库存</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="processing">
|
||||
<i class="el-icon-s-operation"></i>
|
||||
<span slot="title">WIP</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="report">
|
||||
<i class="el-icon-document"></i>
|
||||
<span slot="title">报表</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="shipping">
|
||||
<i class="el-icon-truck"></i>
|
||||
<span slot="title">发货</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="quality">
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
<span slot="title">品质</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
<div class="duge-content">
|
||||
<component :is="currentComponent" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Inventory from './components/Inventory.vue'
|
||||
import Processing from './components/Processing.vue'
|
||||
import Report from './components/Report.vue'
|
||||
import Shipping from './components/Shipping.vue'
|
||||
import Quality from './components/Quality.vue'
|
||||
|
||||
export default {
|
||||
name: 'DugeSystem',
|
||||
components: {
|
||||
Inventory,
|
||||
Processing,
|
||||
Report,
|
||||
Shipping,
|
||||
Quality,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeMenu: 'inventory',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentComponent() {
|
||||
const componentMap = {
|
||||
inventory: 'Inventory',
|
||||
processing: 'Processing',
|
||||
report: 'Report',
|
||||
shipping: 'Shipping',
|
||||
quality: 'Quality',
|
||||
}
|
||||
return componentMap[this.activeMenu]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleMenuSelect(index) {
|
||||
this.activeMenu = index
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.duge-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: calc(100vh - 84px);
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.duge-sidebar {
|
||||
width: 100px;
|
||||
background-color: #fff;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.sidebar-menu {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
border-right: none;
|
||||
|
||||
::v-deep .el-menu-item {
|
||||
color: #606266;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
background-color: #ecf5ff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background-color: #ecf5ff;
|
||||
color: #409eff;
|
||||
border-right: 3px solid #409eff;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 18px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.duge-content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
42
klp-ui/src/views/micro/pages/lajiao/components/Inventory.vue
Normal file
42
klp-ui/src/views/micro/pages/lajiao/components/Inventory.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="inventory-container">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="querys"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { LAJIAO_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'LajiaoInventory',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 拉矫平整集成库存直接复用钢卷基础查询面板,仅切换逻辑库区范围。
|
||||
querys: {
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
},
|
||||
// 这里使用拉矫平整主链路库区,避免把技术部/废品库等外围库区混入集成入口。
|
||||
warehouseOptions: LAJIAO_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.inventory-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="processing-container">
|
||||
<el-tabs v-model="activeTab" type="border-card">
|
||||
<el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.title" :name="tab.name">
|
||||
<DoPage
|
||||
v-if="activeTab === tab.name"
|
||||
:label="tab.label"
|
||||
:tabs="tab.tabs"
|
||||
:useSpecialSplit="tab.useSpecialSplit"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DoPage from '@/views/wms/coil/panels/do.vue'
|
||||
import { LAJIAO_PROCESSING_TABS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'LajiaoProcessing',
|
||||
components: {
|
||||
DoPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 拉矫平整 WIP 复用现有工序待办组件,只切换为拉矫平整工序标签与对应逻辑库区。
|
||||
activeTab: 'process',
|
||||
// 配置集中定义在 config.js,便于后续同步调整工序名称与库区映射。
|
||||
tabs: LAJIAO_PROCESSING_TABS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.processing-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
97
klp-ui/src/views/micro/pages/lajiao/components/Quality.vue
Normal file
97
klp-ui/src/views/micro/pages/lajiao/components/Quality.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="quality-container">
|
||||
<el-tabs v-model="activeTab" class="quality-tabs">
|
||||
<el-tab-pane label="异常钢卷" name="abnormal">
|
||||
<div v-if="activeTab === 'abnormal'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="abnormalQuerys"
|
||||
:labelType="'2'"
|
||||
:hideType="false"
|
||||
:showAbnormal="true"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="次品钢卷" name="defect">
|
||||
<div v-if="activeTab === 'defect'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="defectQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="O卷" name="oil">
|
||||
<div v-if="activeTab === 'oil'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="oilQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { LAJIAO_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'LajiaoQuality',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 品质页复用现有异常/次品/O 卷查询逻辑,只切换拉矫平整库区范围。
|
||||
activeTab: 'abnormal',
|
||||
abnormalQuerys: {
|
||||
// 异常钢卷默认按异常信息排序,便于品质人员优先处理。
|
||||
dataType: 1,
|
||||
orderByAbnormal: true,
|
||||
},
|
||||
defectQuerys: {
|
||||
// 次品钢卷使用现有 scrap 口径。
|
||||
dataType: 1,
|
||||
OnlyScrap: true,
|
||||
},
|
||||
oilQuerys: {
|
||||
// O 卷通过质量状态过滤,不额外增加专用接口。
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
qualityStatus: 'O',
|
||||
},
|
||||
// 品质板块的库区范围与拉矫平整集成其余板块一致,保证筛选口径统一。
|
||||
warehouseOptions: LAJIAO_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.quality-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.quality-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
69
klp-ui/src/views/micro/pages/lajiao/components/Report.vue
Normal file
69
klp-ui/src/views/micro/pages/lajiao/components/Report.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="report-container">
|
||||
<el-tabs v-model="activeTab" class="report-tabs">
|
||||
<el-tab-pane label="综合报表" name="comprehensive">
|
||||
<Comprehensive v-if="activeTab === 'comprehensive'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="日报表" name="day">
|
||||
<DayReport v-if="activeTab === 'day'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="月报表" name="month">
|
||||
<MonthReport v-if="activeTab === 'month'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="年报表" name="year">
|
||||
<YearReport v-if="activeTab === 'year'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="损耗报表" name="loss">
|
||||
<LossReport v-if="activeTab === 'loss'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="产出报表" name="out">
|
||||
<OutReport v-if="activeTab === 'out'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="班报表" name="team">
|
||||
<TeamReport v-if="activeTab === 'team'" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Comprehensive from '@/views/wms/report/lajiao/comprehensive.vue'
|
||||
import DayReport from '@/views/wms/report/lajiao/day.vue'
|
||||
import MonthReport from '@/views/wms/report/lajiao/month.vue'
|
||||
import YearReport from '@/views/wms/report/lajiao/year.vue'
|
||||
import LossReport from '@/views/wms/report/lajiao/loss.vue'
|
||||
import OutReport from '@/views/wms/report/lajiao/out.vue'
|
||||
import TeamReport from '@/views/wms/report/lajiao/team.vue'
|
||||
|
||||
export default {
|
||||
name: 'LajiaoReport',
|
||||
components: {
|
||||
Comprehensive,
|
||||
DayReport,
|
||||
MonthReport,
|
||||
YearReport,
|
||||
LossReport,
|
||||
OutReport,
|
||||
TeamReport,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 报表页直接复用 wms/report/lajiao 下的既有报表资源,
|
||||
// 集成页只负责聚合入口,不额外改写报表查询逻辑。
|
||||
activeTab: 'comprehensive',
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.report-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
83
klp-ui/src/views/micro/pages/lajiao/components/Shipping.vue
Normal file
83
klp-ui/src/views/micro/pages/lajiao/components/Shipping.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<div class="shipping-container">
|
||||
<el-tabs v-model="activeTab" class="shipping-tabs">
|
||||
<el-tab-pane label="配卷情况" name="waybill">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:showWaybill="true"
|
||||
:showNewExport="true"
|
||||
:querys="waybillQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="发货记录" name="ship">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="shipQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showExportTime="true"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { LAJIAO_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'LajiaoShipping',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 发货板块沿用现有钢卷发运能力,仅将过滤库区限定为拉矫平整工序链路。
|
||||
activeTab: 'waybill',
|
||||
waybillQuerys: {
|
||||
// 配卷情况需要带上发货绑定信息,便于直接查看配卷结果。
|
||||
dataType: 1,
|
||||
includeBindInfo: true,
|
||||
},
|
||||
shipQuerys: {
|
||||
// 发货记录仅查看已发货数据。
|
||||
dataType: 1,
|
||||
status: 1,
|
||||
},
|
||||
// 发货板块与库存/WIP 保持相同库区口径,避免统计口径不一致。
|
||||
warehouseOptions: LAJIAO_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shipping-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.shipping-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
40
klp-ui/src/views/micro/pages/lajiao/config.js
Normal file
40
klp-ui/src/views/micro/pages/lajiao/config.js
Normal file
@@ -0,0 +1,40 @@
|
||||
// 拉矫平整集成页公共配置。
|
||||
// 这里统一维护五个板块共用的逻辑库区,保持库存、WIP、发货、品质口径一致。
|
||||
|
||||
// 拉矫平整主链路逻辑库区:
|
||||
// 1. 拉矫原料库:拉矫平整工序入口原料
|
||||
// 2. 拉矫成品库:拉矫平整工序产出成品
|
||||
// 3. 双机架原料库:拉矫下游衔接库区
|
||||
export const LAJIAO_WAREHOUSE_OPTIONS = [
|
||||
{ value: '1988150854442741762', label: '拉矫原料库' },
|
||||
{ value: '1988150915591499777', label: '拉矫成品库' },
|
||||
{ value: '1992873386047643650', label: '双机架原料库' },
|
||||
]
|
||||
|
||||
// 拉矫平整 WIP 直接复用现有 WMS 工序组件:
|
||||
// - 拉矫平整工序、拉矫修复工序走 specialSplit 流程
|
||||
// - 拉矫平整合卷走普通待办流程
|
||||
export const LAJIAO_PROCESSING_TABS = [
|
||||
{
|
||||
title: '拉矫平整工序',
|
||||
name: 'process',
|
||||
label: '拉矫平整工序',
|
||||
// 拉矫平整工序和修复工序都限定在主链路库区内操作。
|
||||
tabs: LAJIAO_WAREHOUSE_OPTIONS,
|
||||
useSpecialSplit: true,
|
||||
},
|
||||
{
|
||||
title: '合卷',
|
||||
name: 'merge',
|
||||
label: '拉矫平整合卷',
|
||||
// 合卷沿用待办单模式,不需要传入库区页签。
|
||||
useSpecialSplit: false,
|
||||
},
|
||||
{
|
||||
title: '拉矫修复',
|
||||
name: 'repair',
|
||||
label: '拉矫修复工序',
|
||||
tabs: LAJIAO_WAREHOUSE_OPTIONS,
|
||||
useSpecialSplit: true,
|
||||
},
|
||||
]
|
||||
133
klp-ui/src/views/micro/pages/lajiao/index.vue
Normal file
133
klp-ui/src/views/micro/pages/lajiao/index.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div class="lajiao-container">
|
||||
<div class="lajiao-sidebar">
|
||||
<el-menu :default-active="activeMenu" class="sidebar-menu" @select="handleMenuSelect">
|
||||
<!-- 拉矫平整集成页按需求只保留五个核心业务板块 -->
|
||||
<el-menu-item index="inventory">
|
||||
<i class="el-icon-box"></i>
|
||||
<span slot="title">库存</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="processing">
|
||||
<i class="el-icon-s-operation"></i>
|
||||
<span slot="title">WIP</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="report">
|
||||
<i class="el-icon-document"></i>
|
||||
<span slot="title">报表</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="shipping">
|
||||
<i class="el-icon-truck"></i>
|
||||
<span slot="title">发货</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="quality">
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
<span slot="title">品质</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
<div class="lajiao-content">
|
||||
<component :is="currentComponent" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Inventory from './components/Inventory.vue'
|
||||
import Processing from './components/Processing.vue'
|
||||
import Report from './components/Report.vue'
|
||||
import Shipping from './components/Shipping.vue'
|
||||
import Quality from './components/Quality.vue'
|
||||
|
||||
export default {
|
||||
name: 'LajiaoSystem',
|
||||
components: {
|
||||
Inventory,
|
||||
Processing,
|
||||
Report,
|
||||
Shipping,
|
||||
Quality,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 默认先展示库存板块,与酸轧、镀锌、脱脂集成入口保持一致。
|
||||
activeMenu: 'inventory',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentComponent() {
|
||||
// 集成页只作为业务导航壳,具体业务能力由各子组件承载。
|
||||
const componentMap = {
|
||||
inventory: 'Inventory',
|
||||
processing: 'Processing',
|
||||
report: 'Report',
|
||||
shipping: 'Shipping',
|
||||
quality: 'Quality',
|
||||
}
|
||||
return componentMap[this.activeMenu]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleMenuSelect(index) {
|
||||
// 左侧菜单切换时,仅替换右侧业务面板,不做额外路由跳转。
|
||||
this.activeMenu = index
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.lajiao-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: calc(100vh - 84px);
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.lajiao-sidebar {
|
||||
width: 100px;
|
||||
background-color: #fff;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.sidebar-menu {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
border-right: none;
|
||||
|
||||
::v-deep .el-menu-item {
|
||||
color: #606266;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
background-color: #ecf5ff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background-color: #ecf5ff;
|
||||
color: #409eff;
|
||||
border-right: 3px solid #409eff;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 18px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lajiao-content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
41
klp-ui/src/views/micro/pages/split/components/Inventory.vue
Normal file
41
klp-ui/src/views/micro/pages/split/components/Inventory.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="inventory-container">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="querys"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { SPLIT_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'SplitInventory',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 分条集成库存直接复用钢卷基础查询面板,仅切换到分条成品链路库区。
|
||||
querys: {
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
},
|
||||
warehouseOptions: SPLIT_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.inventory-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
40
klp-ui/src/views/micro/pages/split/components/Processing.vue
Normal file
40
klp-ui/src/views/micro/pages/split/components/Processing.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div class="processing-container">
|
||||
<el-tabs v-model="activeTab" type="border-card">
|
||||
<el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.title" :name="tab.name">
|
||||
<DoPage
|
||||
v-if="activeTab === tab.name"
|
||||
:label="tab.label"
|
||||
:tabs="tab.tabs"
|
||||
:useSpecialSplit="tab.useSpecialSplit"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DoPage from '@/views/wms/coil/panels/do.vue'
|
||||
import { SPLIT_PROCESSING_TABS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'SplitProcessing',
|
||||
components: {
|
||||
DoPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 纵剪分条 WIP 目前仅复用现有“纵剪分条工序”能力,不额外引入不存在的合卷/修复页签。
|
||||
activeTab: 'process',
|
||||
tabs: SPLIT_PROCESSING_TABS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.processing-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
93
klp-ui/src/views/micro/pages/split/components/Quality.vue
Normal file
93
klp-ui/src/views/micro/pages/split/components/Quality.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div class="quality-container">
|
||||
<el-tabs v-model="activeTab" class="quality-tabs">
|
||||
<el-tab-pane label="异常钢卷" name="abnormal">
|
||||
<div v-if="activeTab === 'abnormal'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="abnormalQuerys"
|
||||
:labelType="'2'"
|
||||
:hideType="false"
|
||||
:showAbnormal="true"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="次品钢卷" name="defect">
|
||||
<div v-if="activeTab === 'defect'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="defectQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="O卷" name="oil">
|
||||
<div v-if="activeTab === 'oil'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="oilQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { SPLIT_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'SplitQuality',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 品质页复用现有异常/次品/O 卷查询逻辑,只切换分条成品链路库区范围。
|
||||
activeTab: 'abnormal',
|
||||
abnormalQuerys: {
|
||||
dataType: 1,
|
||||
orderByAbnormal: true,
|
||||
},
|
||||
defectQuerys: {
|
||||
dataType: 1,
|
||||
OnlyScrap: true,
|
||||
},
|
||||
oilQuerys: {
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
qualityStatus: 'O',
|
||||
},
|
||||
warehouseOptions: SPLIT_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.quality-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.quality-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
68
klp-ui/src/views/micro/pages/split/components/Report.vue
Normal file
68
klp-ui/src/views/micro/pages/split/components/Report.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div class="report-container">
|
||||
<el-tabs v-model="activeTab" class="report-tabs">
|
||||
<el-tab-pane label="综合报表" name="comprehensive">
|
||||
<Comprehensive v-if="activeTab === 'comprehensive'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="日报表" name="day">
|
||||
<DayReport v-if="activeTab === 'day'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="月报表" name="month">
|
||||
<MonthReport v-if="activeTab === 'month'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="年报表" name="year">
|
||||
<YearReport v-if="activeTab === 'year'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="损耗报表" name="loss">
|
||||
<LossReport v-if="activeTab === 'loss'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="产出报表" name="out">
|
||||
<OutReport v-if="activeTab === 'out'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="班报表" name="team">
|
||||
<TeamReport v-if="activeTab === 'team'" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Comprehensive from '@/views/wms/report/split/comprehensive.vue'
|
||||
import DayReport from '@/views/wms/report/split/day.vue'
|
||||
import MonthReport from '@/views/wms/report/split/month.vue'
|
||||
import YearReport from '@/views/wms/report/split/year.vue'
|
||||
import LossReport from '@/views/wms/report/split/loss.vue'
|
||||
import OutReport from '@/views/wms/report/split/out.vue'
|
||||
import TeamReport from '@/views/wms/report/split/team.vue'
|
||||
|
||||
export default {
|
||||
name: 'SplitReport',
|
||||
components: {
|
||||
Comprehensive,
|
||||
DayReport,
|
||||
MonthReport,
|
||||
YearReport,
|
||||
LossReport,
|
||||
OutReport,
|
||||
TeamReport,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 报表页直接复用 wms/report/split 下的既有报表资源。
|
||||
activeTab: 'comprehensive',
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.report-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
80
klp-ui/src/views/micro/pages/split/components/Shipping.vue
Normal file
80
klp-ui/src/views/micro/pages/split/components/Shipping.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div class="shipping-container">
|
||||
<el-tabs v-model="activeTab" class="shipping-tabs">
|
||||
<el-tab-pane label="配卷情况" name="waybill">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:showWaybill="true"
|
||||
:showNewExport="true"
|
||||
:querys="waybillQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="发货记录" name="ship">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="shipQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showExportTime="true"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { SPLIT_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'SplitShipping',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 发货板块沿用现有钢卷发运能力,仅将过滤库区限定为分条成品链路。
|
||||
activeTab: 'waybill',
|
||||
waybillQuerys: {
|
||||
dataType: 1,
|
||||
includeBindInfo: true,
|
||||
},
|
||||
shipQuerys: {
|
||||
dataType: 1,
|
||||
status: 1,
|
||||
},
|
||||
warehouseOptions: SPLIT_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shipping-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.shipping-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
34
klp-ui/src/views/micro/pages/split/config.js
Normal file
34
klp-ui/src/views/micro/pages/split/config.js
Normal file
@@ -0,0 +1,34 @@
|
||||
// 纵剪分条集成页公共配置。
|
||||
// 分条模块与镀锌/脱脂不同:WIP 关注待分条工序链路,库存/发货/品质更关注分条成品去向。
|
||||
|
||||
// 纵剪分条成品链路逻辑库区:
|
||||
// 1. 酸连轧分条成品
|
||||
// 2. 退火分条成品
|
||||
// 3. 镀锌分条成品
|
||||
// 4. 拉矫分条成品
|
||||
// 5. 包装用内部仓
|
||||
export const SPLIT_WAREHOUSE_OPTIONS = [
|
||||
{ value: '1988150210872930306', label: '酸连轧分条成品' },
|
||||
{ value: '1988150800092950529', label: '退火分条成品' },
|
||||
{ value: '1988150380649967617', label: '镀锌分条成品' },
|
||||
{ value: '1988151027466170370', label: '拉矫分条成品' },
|
||||
{ value: '2027272581575487489', label: '包装用内部仓' },
|
||||
]
|
||||
|
||||
// 纵剪分条 WIP 复用现有 WMS 工序组件。
|
||||
// 这里沿用现有工序页签定义:首项“原料库”由原模块保留空 value 作为前置入口占位。
|
||||
export const SPLIT_PROCESSING_TABS = [
|
||||
{
|
||||
title: '纵剪分条工序',
|
||||
name: 'process',
|
||||
label: '纵剪分条工序',
|
||||
tabs: [
|
||||
{ value: '', label: '原料库' },
|
||||
{ value: '1988150210872930306', label: '酸连轧分条成品' },
|
||||
{ value: '1988150800092950529', label: '退火分条成品' },
|
||||
{ value: '1988150380649967617', label: '镀锌分条成品' },
|
||||
{ value: '1988151027466170370', label: '拉矫分条成品' },
|
||||
],
|
||||
useSpecialSplit: true,
|
||||
},
|
||||
]
|
||||
131
klp-ui/src/views/micro/pages/split/index.vue
Normal file
131
klp-ui/src/views/micro/pages/split/index.vue
Normal file
@@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<div class="split-container">
|
||||
<div class="split-sidebar">
|
||||
<el-menu :default-active="activeMenu" class="sidebar-menu" @select="handleMenuSelect">
|
||||
<!-- 纵剪分条集成页按需求只保留五个核心业务板块 -->
|
||||
<el-menu-item index="inventory">
|
||||
<i class="el-icon-box"></i>
|
||||
<span slot="title">库存</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="processing">
|
||||
<i class="el-icon-s-operation"></i>
|
||||
<span slot="title">WIP</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="report">
|
||||
<i class="el-icon-document"></i>
|
||||
<span slot="title">报表</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="shipping">
|
||||
<i class="el-icon-truck"></i>
|
||||
<span slot="title">发货</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="quality">
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
<span slot="title">品质</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
<div class="split-content">
|
||||
<component :is="currentComponent" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Inventory from './components/Inventory.vue'
|
||||
import Processing from './components/Processing.vue'
|
||||
import Report from './components/Report.vue'
|
||||
import Shipping from './components/Shipping.vue'
|
||||
import Quality from './components/Quality.vue'
|
||||
|
||||
export default {
|
||||
name: 'SplitSystem',
|
||||
components: {
|
||||
Inventory,
|
||||
Processing,
|
||||
Report,
|
||||
Shipping,
|
||||
Quality,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 默认先展示库存板块,与其他集成入口保持一致。
|
||||
activeMenu: 'inventory',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentComponent() {
|
||||
const componentMap = {
|
||||
inventory: 'Inventory',
|
||||
processing: 'Processing',
|
||||
report: 'Report',
|
||||
shipping: 'Shipping',
|
||||
quality: 'Quality',
|
||||
}
|
||||
return componentMap[this.activeMenu]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleMenuSelect(index) {
|
||||
this.activeMenu = index
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.split-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: calc(100vh - 84px);
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.split-sidebar {
|
||||
width: 100px;
|
||||
background-color: #fff;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.sidebar-menu {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
border-right: none;
|
||||
|
||||
::v-deep .el-menu-item {
|
||||
color: #606266;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
background-color: #ecf5ff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background-color: #ecf5ff;
|
||||
color: #409eff;
|
||||
border-right: 3px solid #409eff;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 18px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.split-content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
42
klp-ui/src/views/micro/pages/tuozhi/components/Inventory.vue
Normal file
42
klp-ui/src/views/micro/pages/tuozhi/components/Inventory.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="inventory-container">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="querys"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { TUOZHI_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'TuozhiInventory',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 脱脂集成库存直接复用钢卷基础查询面板,仅切换逻辑库区范围。
|
||||
querys: {
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
},
|
||||
// 这里使用脱脂主链路库区,避免把技术部/废品库等外围库区混入集成入口。
|
||||
warehouseOptions: TUOZHI_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.inventory-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="processing-container">
|
||||
<el-tabs v-model="activeTab" type="border-card">
|
||||
<el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.title" :name="tab.name">
|
||||
<DoPage
|
||||
v-if="activeTab === tab.name"
|
||||
:label="tab.label"
|
||||
:tabs="tab.tabs"
|
||||
:useSpecialSplit="tab.useSpecialSplit"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DoPage from '@/views/wms/coil/panels/do.vue'
|
||||
import { TUOZHI_PROCESSING_TABS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'TuozhiProcessing',
|
||||
components: {
|
||||
DoPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 脱脂 WIP 复用现有工序待办组件,只切换为脱脂工序标签与对应逻辑库区。
|
||||
activeTab: 'process',
|
||||
// 配置集中定义在 config.js,便于后续同步调整工序名称与库区映射。
|
||||
tabs: TUOZHI_PROCESSING_TABS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.processing-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
97
klp-ui/src/views/micro/pages/tuozhi/components/Quality.vue
Normal file
97
klp-ui/src/views/micro/pages/tuozhi/components/Quality.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="quality-container">
|
||||
<el-tabs v-model="activeTab" class="quality-tabs">
|
||||
<el-tab-pane label="异常钢卷" name="abnormal">
|
||||
<div v-if="activeTab === 'abnormal'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="abnormalQuerys"
|
||||
:labelType="'2'"
|
||||
:hideType="false"
|
||||
:showAbnormal="true"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="次品钢卷" name="defect">
|
||||
<div v-if="activeTab === 'defect'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="defectQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="O卷" name="oil">
|
||||
<div v-if="activeTab === 'oil'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="oilQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { TUOZHI_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'TuozhiQuality',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 品质页复用现有异常/次品/O 卷查询逻辑,只切换脱脂库区范围。
|
||||
activeTab: 'abnormal',
|
||||
abnormalQuerys: {
|
||||
// 异常钢卷默认按异常信息排序,便于品质人员优先处理。
|
||||
dataType: 1,
|
||||
orderByAbnormal: true,
|
||||
},
|
||||
defectQuerys: {
|
||||
// 次品钢卷使用现有 scrap 口径。
|
||||
dataType: 1,
|
||||
OnlyScrap: true,
|
||||
},
|
||||
oilQuerys: {
|
||||
// O 卷通过质量状态过滤,不额外增加专用接口。
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
qualityStatus: 'O',
|
||||
},
|
||||
// 品质板块的库区范围与脱脂集成其余板块一致,保证筛选口径统一。
|
||||
warehouseOptions: TUOZHI_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.quality-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.quality-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
69
klp-ui/src/views/micro/pages/tuozhi/components/Report.vue
Normal file
69
klp-ui/src/views/micro/pages/tuozhi/components/Report.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="report-container">
|
||||
<el-tabs v-model="activeTab" class="report-tabs">
|
||||
<el-tab-pane label="综合报表" name="comprehensive">
|
||||
<Comprehensive v-if="activeTab === 'comprehensive'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="日报表" name="day">
|
||||
<DayReport v-if="activeTab === 'day'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="月报表" name="month">
|
||||
<MonthReport v-if="activeTab === 'month'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="年报表" name="year">
|
||||
<YearReport v-if="activeTab === 'year'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="损耗报表" name="loss">
|
||||
<LossReport v-if="activeTab === 'loss'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="产出报表" name="out">
|
||||
<OutReport v-if="activeTab === 'out'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="班报表" name="team">
|
||||
<TeamReport v-if="activeTab === 'team'" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Comprehensive from '@/views/wms/report/tuozhi/comprehensive.vue'
|
||||
import DayReport from '@/views/wms/report/tuozhi/day.vue'
|
||||
import MonthReport from '@/views/wms/report/tuozhi/month.vue'
|
||||
import YearReport from '@/views/wms/report/tuozhi/year.vue'
|
||||
import LossReport from '@/views/wms/report/tuozhi/loss.vue'
|
||||
import OutReport from '@/views/wms/report/tuozhi/out.vue'
|
||||
import TeamReport from '@/views/wms/report/tuozhi/team.vue'
|
||||
|
||||
export default {
|
||||
name: 'TuozhiReport',
|
||||
components: {
|
||||
Comprehensive,
|
||||
DayReport,
|
||||
MonthReport,
|
||||
YearReport,
|
||||
LossReport,
|
||||
OutReport,
|
||||
TeamReport,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 报表页直接复用 wms/report/tuozhi 下的既有报表资源,
|
||||
// 集成页只负责聚合入口,不额外改写报表查询逻辑。
|
||||
activeTab: 'comprehensive',
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.report-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
83
klp-ui/src/views/micro/pages/tuozhi/components/Shipping.vue
Normal file
83
klp-ui/src/views/micro/pages/tuozhi/components/Shipping.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<div class="shipping-container">
|
||||
<el-tabs v-model="activeTab" class="shipping-tabs">
|
||||
<el-tab-pane label="配卷情况" name="waybill">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:showWaybill="true"
|
||||
:showNewExport="true"
|
||||
:querys="waybillQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="发货记录" name="ship">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="shipQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showExportTime="true"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { TUOZHI_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'TuozhiShipping',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 发货板块沿用现有钢卷发运能力,仅将过滤库区限定为脱脂工序链路。
|
||||
activeTab: 'waybill',
|
||||
waybillQuerys: {
|
||||
// 配卷情况需要带上发货绑定信息,便于直接查看配卷结果。
|
||||
dataType: 1,
|
||||
includeBindInfo: true,
|
||||
},
|
||||
shipQuerys: {
|
||||
// 发货记录仅查看已发货数据。
|
||||
dataType: 1,
|
||||
status: 1,
|
||||
},
|
||||
// 发货板块与库存/WIP 保持相同库区口径,避免统计口径不一致。
|
||||
warehouseOptions: TUOZHI_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shipping-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.shipping-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
40
klp-ui/src/views/micro/pages/tuozhi/config.js
Normal file
40
klp-ui/src/views/micro/pages/tuozhi/config.js
Normal file
@@ -0,0 +1,40 @@
|
||||
// 脱脂工序集成页公共配置。
|
||||
// 这里统一维护五个板块共用的逻辑库区,保持库存、WIP、发货、品质口径一致。
|
||||
|
||||
// 脱脂工序主链路逻辑库区:
|
||||
// 1. 脱脂原料库:脱脂工序入口原料
|
||||
// 2. 脱脂成品库:脱脂工序产出成品
|
||||
// 3. 罩式退火原料库:脱脂下游衔接库区
|
||||
export const TUOZHI_WAREHOUSE_OPTIONS = [
|
||||
{ value: '1988150545175736322', label: '脱脂原料库' },
|
||||
{ value: '1988150586938421250', label: '脱脂成品库' },
|
||||
{ value: '1988150648993148929', label: '罩式退火原料库' },
|
||||
]
|
||||
|
||||
// 脱脂工序 WIP 直接复用现有 WMS 工序组件:
|
||||
// - 脱脂工序、脱脂修复工序走 specialSplit 流程
|
||||
// - 脱脂合卷走普通待办流程
|
||||
export const TUOZHI_PROCESSING_TABS = [
|
||||
{
|
||||
title: '脱脂工序',
|
||||
name: 'process',
|
||||
label: '脱脂工序',
|
||||
// 脱脂工序和修复工序都限定在脱脂主链路库区内操作。
|
||||
tabs: TUOZHI_WAREHOUSE_OPTIONS,
|
||||
useSpecialSplit: true,
|
||||
},
|
||||
{
|
||||
title: '合卷',
|
||||
name: 'merge',
|
||||
label: '脱脂合卷',
|
||||
// 合卷沿用待办单模式,不需要传入库区页签。
|
||||
useSpecialSplit: false,
|
||||
},
|
||||
{
|
||||
title: '脱脂修复',
|
||||
name: 'repair',
|
||||
label: '脱脂修复工序',
|
||||
tabs: TUOZHI_WAREHOUSE_OPTIONS,
|
||||
useSpecialSplit: true,
|
||||
},
|
||||
]
|
||||
133
klp-ui/src/views/micro/pages/tuozhi/index.vue
Normal file
133
klp-ui/src/views/micro/pages/tuozhi/index.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div class="tuozhi-container">
|
||||
<div class="tuozhi-sidebar">
|
||||
<el-menu :default-active="activeMenu" class="sidebar-menu" @select="handleMenuSelect">
|
||||
<!-- 脱脂集成页按需求只保留五个核心业务板块 -->
|
||||
<el-menu-item index="inventory">
|
||||
<i class="el-icon-box"></i>
|
||||
<span slot="title">库存</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="processing">
|
||||
<i class="el-icon-s-operation"></i>
|
||||
<span slot="title">WIP</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="report">
|
||||
<i class="el-icon-document"></i>
|
||||
<span slot="title">报表</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="shipping">
|
||||
<i class="el-icon-truck"></i>
|
||||
<span slot="title">发货</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="quality">
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
<span slot="title">品质</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
<div class="tuozhi-content">
|
||||
<component :is="currentComponent" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Inventory from './components/Inventory.vue'
|
||||
import Processing from './components/Processing.vue'
|
||||
import Report from './components/Report.vue'
|
||||
import Shipping from './components/Shipping.vue'
|
||||
import Quality from './components/Quality.vue'
|
||||
|
||||
export default {
|
||||
name: 'TuozhiSystem',
|
||||
components: {
|
||||
Inventory,
|
||||
Processing,
|
||||
Report,
|
||||
Shipping,
|
||||
Quality,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 默认先展示库存板块,与酸轧、镀锌集成入口保持一致。
|
||||
activeMenu: 'inventory',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentComponent() {
|
||||
// 集成页只作为业务导航壳,具体业务能力由各子组件承载。
|
||||
const componentMap = {
|
||||
inventory: 'Inventory',
|
||||
processing: 'Processing',
|
||||
report: 'Report',
|
||||
shipping: 'Shipping',
|
||||
quality: 'Quality',
|
||||
}
|
||||
return componentMap[this.activeMenu]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleMenuSelect(index) {
|
||||
// 左侧菜单切换时,仅替换右侧业务面板,不做额外路由跳转。
|
||||
this.activeMenu = index
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.tuozhi-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: calc(100vh - 84px);
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.tuozhi-sidebar {
|
||||
width: 100px;
|
||||
background-color: #fff;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.sidebar-menu {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
border-right: none;
|
||||
|
||||
::v-deep .el-menu-item {
|
||||
color: #606266;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
background-color: #ecf5ff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background-color: #ecf5ff;
|
||||
color: #409eff;
|
||||
border-right: 3px solid #409eff;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 18px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tuozhi-content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
42
klp-ui/src/views/micro/pages/zinc/components/Inventory.vue
Normal file
42
klp-ui/src/views/micro/pages/zinc/components/Inventory.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="inventory-container">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="querys"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { ZINC_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'ZincInventory',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 镀锌集成库存直接复用钢卷基础查询面板,仅切换逻辑库区范围。
|
||||
querys: {
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
},
|
||||
// 这里使用镀锌主链路库区,避免把技术部/废品库等外围库区混入集成入口。
|
||||
warehouseOptions: ZINC_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.inventory-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
41
klp-ui/src/views/micro/pages/zinc/components/Processing.vue
Normal file
41
klp-ui/src/views/micro/pages/zinc/components/Processing.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="processing-container">
|
||||
<el-tabs v-model="activeTab" type="border-card">
|
||||
<el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.title" :name="tab.name">
|
||||
<DoPage
|
||||
v-if="activeTab === tab.name"
|
||||
:label="tab.label"
|
||||
:tabs="tab.tabs"
|
||||
:useSpecialSplit="tab.useSpecialSplit"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DoPage from '@/views/wms/coil/panels/do.vue'
|
||||
import { ZINC_PROCESSING_TABS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'ZincProcessing',
|
||||
components: {
|
||||
DoPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 镀锌 WIP 复用现有工序待办组件,只切换为镀锌工序标签与对应逻辑库区。
|
||||
activeTab: 'process',
|
||||
// 配置集中定义在 config.js,便于后续同步调整工序名称与库区映射。
|
||||
tabs: ZINC_PROCESSING_TABS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.processing-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
97
klp-ui/src/views/micro/pages/zinc/components/Quality.vue
Normal file
97
klp-ui/src/views/micro/pages/zinc/components/Quality.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="quality-container">
|
||||
<el-tabs v-model="activeTab" class="quality-tabs">
|
||||
<el-tab-pane label="异常钢卷" name="abnormal">
|
||||
<div v-if="activeTab === 'abnormal'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="abnormalQuerys"
|
||||
:labelType="'2'"
|
||||
:hideType="false"
|
||||
:showAbnormal="true"
|
||||
:showControl="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="次品钢卷" name="defect">
|
||||
<div v-if="activeTab === 'defect'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="defectQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="O卷" name="oil">
|
||||
<div v-if="activeTab === 'oil'" class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="oilQuerys"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { ZINC_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'ZincQuality',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 品质页复用现有异常/次品/O 卷查询逻辑,只切换镀锌库区范围。
|
||||
activeTab: 'abnormal',
|
||||
abnormalQuerys: {
|
||||
// 异常钢卷默认按异常信息排序,便于品质人员优先处理。
|
||||
dataType: 1,
|
||||
orderByAbnormal: true,
|
||||
},
|
||||
defectQuerys: {
|
||||
// 次品钢卷使用现有 scrap 口径。
|
||||
dataType: 1,
|
||||
OnlyScrap: true,
|
||||
},
|
||||
oilQuerys: {
|
||||
// O 卷通过质量状态过滤,不额外增加专用接口。
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
qualityStatus: 'O',
|
||||
},
|
||||
// 品质板块的库区范围与镀锌集成其余板块一致,保证筛选口径统一。
|
||||
warehouseOptions: ZINC_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.quality-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.quality-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
69
klp-ui/src/views/micro/pages/zinc/components/Report.vue
Normal file
69
klp-ui/src/views/micro/pages/zinc/components/Report.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="report-container">
|
||||
<el-tabs v-model="activeTab" class="report-tabs">
|
||||
<el-tab-pane label="综合报表" name="comprehensive">
|
||||
<Comprehensive v-if="activeTab === 'comprehensive'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="日报表" name="day">
|
||||
<DayReport v-if="activeTab === 'day'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="月报表" name="month">
|
||||
<MonthReport v-if="activeTab === 'month'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="年报表" name="year">
|
||||
<YearReport v-if="activeTab === 'year'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="损耗报表" name="loss">
|
||||
<LossReport v-if="activeTab === 'loss'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="产出报表" name="out">
|
||||
<OutReport v-if="activeTab === 'out'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="班报表" name="team">
|
||||
<TeamReport v-if="activeTab === 'team'" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Comprehensive from '@/views/wms/report/zinc/comprehensive.vue'
|
||||
import DayReport from '@/views/wms/report/zinc/day.vue'
|
||||
import MonthReport from '@/views/wms/report/zinc/month.vue'
|
||||
import YearReport from '@/views/wms/report/zinc/year.vue'
|
||||
import LossReport from '@/views/wms/report/zinc/loss.vue'
|
||||
import OutReport from '@/views/wms/report/zinc/out.vue'
|
||||
import TeamReport from '@/views/wms/report/zinc/team.vue'
|
||||
|
||||
export default {
|
||||
name: 'ZincReport',
|
||||
components: {
|
||||
Comprehensive,
|
||||
DayReport,
|
||||
MonthReport,
|
||||
YearReport,
|
||||
LossReport,
|
||||
OutReport,
|
||||
TeamReport,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 报表页直接复用 wms/report/zinc 下的既有报表资源,
|
||||
// 集成页只负责聚合入口,不额外改写报表查询逻辑。
|
||||
activeTab: 'comprehensive',
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.report-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
83
klp-ui/src/views/micro/pages/zinc/components/Shipping.vue
Normal file
83
klp-ui/src/views/micro/pages/zinc/components/Shipping.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<div class="shipping-container">
|
||||
<el-tabs v-model="activeTab" class="shipping-tabs">
|
||||
<el-tab-pane label="配卷情况" name="waybill">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:showWaybill="true"
|
||||
:showNewExport="true"
|
||||
:querys="waybillQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="发货记录" name="ship">
|
||||
<div class="tab-content">
|
||||
<BasePage
|
||||
:qrcode="false"
|
||||
:querys="shipQuerys"
|
||||
:showStatus="false"
|
||||
:hideType="false"
|
||||
:useWarehouseIds="true"
|
||||
:warehouseOptions="warehouseOptions"
|
||||
:showControl="false"
|
||||
:showExportTime="true"
|
||||
:showMaterialType="true"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue'
|
||||
import { ZINC_WAREHOUSE_OPTIONS } from '../config'
|
||||
|
||||
export default {
|
||||
name: 'ZincShipping',
|
||||
components: {
|
||||
BasePage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 发货板块沿用现有钢卷发运能力,仅将过滤库区限定为镀锌工序链路。
|
||||
activeTab: 'waybill',
|
||||
waybillQuerys: {
|
||||
// 配卷情况需要带上发货绑定信息,便于直接查看配卷结果。
|
||||
dataType: 1,
|
||||
includeBindInfo: true,
|
||||
},
|
||||
shipQuerys: {
|
||||
// 发货记录仅查看已发货数据。
|
||||
dataType: 1,
|
||||
status: 1,
|
||||
},
|
||||
// 发货板块与库存/WIP 保持相同库区口径,避免统计口径不一致。
|
||||
warehouseOptions: ZINC_WAREHOUSE_OPTIONS,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.shipping-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.shipping-tabs {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
42
klp-ui/src/views/micro/pages/zinc/config.js
Normal file
42
klp-ui/src/views/micro/pages/zinc/config.js
Normal file
@@ -0,0 +1,42 @@
|
||||
// 镀锌工序集成页公共配置。
|
||||
// 这里统一维护五个板块共用的逻辑库区,避免各子页面重复定义后产生偏差。
|
||||
|
||||
// 镀锌工序相关逻辑库区:
|
||||
// 1. 镀锌原料库:镀锌工序入口原料
|
||||
// 2. 镀锌成品库:镀锌工序产出成品
|
||||
// 3. 镀锌纵剪分条原料库:后续分条前的原料库区
|
||||
// 4. 镀锌待打包:镀锌工序产出后待包装库区
|
||||
export const ZINC_WAREHOUSE_OPTIONS = [
|
||||
{ value: '1988150263284953089', label: '镀锌原料库' },
|
||||
{ value: '1988150323162836993', label: '镀锌成品库' },
|
||||
{ value: '1988150487185289217', label: '镀锌纵剪分条原料库' },
|
||||
{ value: '2056545127927787522', label: '镀锌待打包' },
|
||||
]
|
||||
|
||||
// 镀锌工序 WIP 直接复用现有 WMS 工序组件:
|
||||
// - 镀锌工序、镀锌修复工序走 specialSplit 流程
|
||||
// - 镀锌合卷走普通待办流程
|
||||
export const ZINC_PROCESSING_TABS = [
|
||||
{
|
||||
title: '镀锌工序',
|
||||
name: 'process',
|
||||
label: '镀锌工序',
|
||||
// 镀锌工序和修复工序都需要限制在镀锌主链路库区范围内操作。
|
||||
tabs: ZINC_WAREHOUSE_OPTIONS,
|
||||
useSpecialSplit: true,
|
||||
},
|
||||
{
|
||||
title: '合卷',
|
||||
name: 'merge',
|
||||
label: '镀锌合卷',
|
||||
// 合卷沿用待办单模式,不需要传入库区页签。
|
||||
useSpecialSplit: false,
|
||||
},
|
||||
{
|
||||
title: '镀锌修复',
|
||||
name: 'repair',
|
||||
label: '镀锌修复工序',
|
||||
tabs: ZINC_WAREHOUSE_OPTIONS,
|
||||
useSpecialSplit: true,
|
||||
},
|
||||
]
|
||||
@@ -1,5 +1,133 @@
|
||||
<template>
|
||||
<div>
|
||||
镀锌子系统
|
||||
<div class="zinc-container">
|
||||
<div class="zinc-sidebar">
|
||||
<el-menu :default-active="activeMenu" class="sidebar-menu" @select="handleMenuSelect">
|
||||
<!-- 镀锌集成页按需求只保留五个核心业务板块 -->
|
||||
<el-menu-item index="inventory">
|
||||
<i class="el-icon-box"></i>
|
||||
<span slot="title">库存</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="processing">
|
||||
<i class="el-icon-s-operation"></i>
|
||||
<span slot="title">WIP</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="report">
|
||||
<i class="el-icon-document"></i>
|
||||
<span slot="title">报表</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="shipping">
|
||||
<i class="el-icon-truck"></i>
|
||||
<span slot="title">发货</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="quality">
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
<span slot="title">品质</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
<div class="zinc-content">
|
||||
<component :is="currentComponent" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Inventory from './components/Inventory.vue'
|
||||
import Processing from './components/Processing.vue'
|
||||
import Report from './components/Report.vue'
|
||||
import Shipping from './components/Shipping.vue'
|
||||
import Quality from './components/Quality.vue'
|
||||
|
||||
export default {
|
||||
name: 'ZincSystem',
|
||||
components: {
|
||||
Inventory,
|
||||
Processing,
|
||||
Report,
|
||||
Shipping,
|
||||
Quality,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 默认先展示库存板块,与酸轧集成入口保持一致。
|
||||
activeMenu: 'inventory',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentComponent() {
|
||||
// 集成页只作为业务导航壳,具体业务能力由各子组件承载。
|
||||
const componentMap = {
|
||||
inventory: 'Inventory',
|
||||
processing: 'Processing',
|
||||
report: 'Report',
|
||||
shipping: 'Shipping',
|
||||
quality: 'Quality',
|
||||
}
|
||||
return componentMap[this.activeMenu]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleMenuSelect(index) {
|
||||
// 左侧菜单切换时,仅替换右侧业务面板,不做额外路由跳转。
|
||||
this.activeMenu = index
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.zinc-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: calc(100vh - 84px);
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.zinc-sidebar {
|
||||
width: 100px;
|
||||
background-color: #fff;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.sidebar-menu {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
border-right: none;
|
||||
|
||||
::v-deep .el-menu-item {
|
||||
color: #606266;
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
background-color: #ecf5ff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background-color: #ecf5ff;
|
||||
color: #409eff;
|
||||
border-right: 3px solid #409eff;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 18px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.zinc-content {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -334,16 +334,13 @@ export default {
|
||||
|
||||
/** 打印标签 */
|
||||
handlePrintLabel(row) {
|
||||
this.labelRender.data = row;
|
||||
this.labelRender.type = getCoilTagPrintType(row);
|
||||
this.labelRender.data = {
|
||||
...row,
|
||||
updateTime: row.updateTime?.split(' ')[0] || '',
|
||||
};
|
||||
this.$nextTick(() => {
|
||||
const el = this.$refs.labelRender && this.$refs.labelRender.$el;
|
||||
if (el) {
|
||||
el.style.display = 'block';
|
||||
window.print();
|
||||
el.style.display = 'none';
|
||||
}
|
||||
});
|
||||
this.$refs.labelRender.printLabel();
|
||||
})
|
||||
},
|
||||
|
||||
handleExport() {
|
||||
|
||||
Reference in New Issue
Block a user