🎈 perf: 处理一些细节问题
This commit is contained in:
@@ -363,3 +363,7 @@ div.pagination-container {
|
|||||||
height: var(--btn-height);
|
height: var(--btn-height);
|
||||||
line-height: var(--btn-height);
|
line-height: var(--btn-height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-tabs__content {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
278
klp-ui/src/components/KLPUI/KLPList/index.vue
Normal file
278
klp-ui/src/components/KLPUI/KLPList/index.vue
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
<template>
|
||||||
|
<div class="klp-list-container">
|
||||||
|
<!-- 列表加载状态 -->
|
||||||
|
<div v-loading="loading" class="list-loading-wrapper">
|
||||||
|
<!-- 列表项渲染 -->
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in listData"
|
||||||
|
:key="item[listKey] || index"
|
||||||
|
class="klp-list-item"
|
||||||
|
:class="{ 'active': isSelected(item) }"
|
||||||
|
@click.stop="handleItemClick(item)"
|
||||||
|
>
|
||||||
|
<!-- 列表标题区域 - 文字溢出省略+Tooltip -->
|
||||||
|
<div class="klp-list-title">
|
||||||
|
<span class="title-label">{{ titleLabel }}:</span>
|
||||||
|
<el-tooltip
|
||||||
|
:content="item[titleField]"
|
||||||
|
placement="top"
|
||||||
|
:disabled="!isContentOverflow(item)"
|
||||||
|
effect="light"
|
||||||
|
>
|
||||||
|
<span class="title-value">{{ item[titleField] }}</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧操作按钮组 -->
|
||||||
|
<div class="klp-list-actions">
|
||||||
|
<slot name="actions" :item="item" :isSelected="isSelected(item)"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 空状态提示 -->
|
||||||
|
<div v-if="listData.length === 0 && !loading" class="klp-list-empty">
|
||||||
|
<el-empty description="暂无数据" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "klp-list",
|
||||||
|
components: {},
|
||||||
|
props: {
|
||||||
|
/** 列表数据源(必传) */
|
||||||
|
listData: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 列表项唯一标识字段(必传,如orderId、id) */
|
||||||
|
listKey: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 列表标题前置标签(如"订单编号:") */
|
||||||
|
titleLabel: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
default: "标题"
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 列表项标题对应的字段名(如orderCode、name) */
|
||||||
|
titleField: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
default: "title"
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 列表加载状态 */
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 标题最大宽度(像素),控制文字溢出 */
|
||||||
|
titleMaxWidth: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: 200
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 内部管理选中状态:存储当前选中项的唯一键值(单选中)
|
||||||
|
selectedKey: null,
|
||||||
|
// 文字溢出检测临时元素(避免重复创建)
|
||||||
|
overflowCheckElements: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 判断当前列表项是否被选中
|
||||||
|
* @param {Object} item - 列表项数据
|
||||||
|
* @returns {Boolean} 选中状态
|
||||||
|
*/
|
||||||
|
isSelected(item) {
|
||||||
|
const itemKey = item[this.listKey];
|
||||||
|
return this.selectedKey === itemKey;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列表项点击事件:切换选中状态(单选中逻辑)
|
||||||
|
* @param {Object} item - 点击的列表项数据
|
||||||
|
*/
|
||||||
|
handleItemClick(item) {
|
||||||
|
const itemKey = item[this.listKey];
|
||||||
|
// 单选中逻辑:点击已选中项取消选中,点击未选中项切换选中(取消其他项)
|
||||||
|
this.selectedKey = this.selectedKey === itemKey ? null : itemKey;
|
||||||
|
|
||||||
|
// 向父组件触发事件:传递当前选中项(null表示无选中)
|
||||||
|
const selectedItem = this.selectedKey ? item : null;
|
||||||
|
this.$emit("item-click", selectedItem, item);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空选中状态(支持父组件通过ref调用)
|
||||||
|
*/
|
||||||
|
clearSelection() {
|
||||||
|
this.selectedKey = null;
|
||||||
|
// 触发清空选中事件
|
||||||
|
this.$emit("selection-cleared");
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主动设置选中项(支持父组件通过ref调用)
|
||||||
|
* @param {String/Number} targetKey - 要选中项的唯一键值
|
||||||
|
*/
|
||||||
|
setSelection(targetKey) {
|
||||||
|
const isExist = this.listData.some(item => item[this.listKey] === targetKey);
|
||||||
|
if (isExist) {
|
||||||
|
this.selectedKey = targetKey;
|
||||||
|
// 触发选中事件
|
||||||
|
const selectedItem = this.listData.find(item => item[this.listKey] === targetKey);
|
||||||
|
this.$emit("item-click", selectedItem);
|
||||||
|
} else {
|
||||||
|
this.selectedKey = null;
|
||||||
|
console.warn(`列表中不存在key为${targetKey}的项`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文字是否溢出(控制Tooltip显示/隐藏)
|
||||||
|
* @param {Object} item - 列表项数据
|
||||||
|
* @returns {Boolean} 是否溢出
|
||||||
|
*/
|
||||||
|
isContentOverflow(item) {
|
||||||
|
const itemKey = item[this.listKey];
|
||||||
|
const content = item[this.titleField] || "";
|
||||||
|
|
||||||
|
// 内容为空时不显示Tooltip
|
||||||
|
if (!content) return false;
|
||||||
|
|
||||||
|
// 创建临时元素测量文字实际宽度(复用元素避免性能问题)
|
||||||
|
if (!this.overflowCheckElements[itemKey]) {
|
||||||
|
const tempEl = document.createElement("span");
|
||||||
|
// 复制title-value的样式(确保测量准确)
|
||||||
|
tempEl.style.cssText = `
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
`;
|
||||||
|
tempEl.textContent = content;
|
||||||
|
document.body.appendChild(tempEl);
|
||||||
|
this.overflowCheckElements[itemKey] = tempEl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 比较文字实际宽度与设定的最大宽度
|
||||||
|
const tempEl = this.overflowCheckElements[itemKey];
|
||||||
|
return tempEl.offsetWidth > this.titleMaxWidth;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
/** 列表数据变化时,重置选中状态和溢出检测元素 */
|
||||||
|
listData: {
|
||||||
|
deep: true,
|
||||||
|
handler() {
|
||||||
|
this.clearSelection();
|
||||||
|
// 清理临时测量元素
|
||||||
|
Object.values(this.overflowCheckElements).forEach(el => {
|
||||||
|
document.body.removeChild(el);
|
||||||
|
});
|
||||||
|
this.overflowCheckElements = {};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 标题最大宽度变化时,强制重绘以重新计算溢出 */
|
||||||
|
titleMaxWidth() {
|
||||||
|
this.$forceUpdate();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 组件销毁时清理临时元素,避免内存泄漏 */
|
||||||
|
beforeDestroy() {
|
||||||
|
Object.values(this.overflowCheckElements).forEach(el => {
|
||||||
|
document.body.removeChild(el);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 列表容器基础样式 */
|
||||||
|
.klp-list-container {
|
||||||
|
max-height: calc(100vh - 220px);
|
||||||
|
overflow-y: auto;
|
||||||
|
padding-right: 8px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载状态容器(避免加载时容器塌陷) */
|
||||||
|
.list-loading-wrapper {
|
||||||
|
min-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 列表项样式 */
|
||||||
|
.klp-list-item {
|
||||||
|
padding: 6px 8px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
border-bottom: 1px solid #e6e6e6;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 列表项选中状态(左侧高亮边框+背景色) */
|
||||||
|
.klp-list-item.active {
|
||||||
|
border-left: 3px solid #409eff;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 列表标题区域(占满中间空间,让操作按钮靠右) */
|
||||||
|
.klp-list-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标题前置标签样式 */
|
||||||
|
.klp-list-title .title-label {
|
||||||
|
color: #606266;
|
||||||
|
margin-right: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
white-space: nowrap; /* 标签不换行 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标题内容样式(溢出省略) */
|
||||||
|
.klp-list-title .title-value {
|
||||||
|
color: #303133;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
white-space: nowrap; /* 禁止换行 */
|
||||||
|
overflow: hidden; /* 超出部分隐藏 */
|
||||||
|
text-overflow: ellipsis; /* 超出部分显示省略号 */
|
||||||
|
max-width: v-bind(titleMaxWidth + "px"); /* 绑定父组件传入的最大宽度 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 操作按钮组(按钮间距控制) */
|
||||||
|
.klp-list-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 空状态样式(居中显示) */
|
||||||
|
.klp-list-empty {
|
||||||
|
padding: 40px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -4,10 +4,36 @@
|
|||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<div>
|
<div>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-input v-model="queryParams.orderCode" placeholder="请输入单据编号" clearable
|
<el-input
|
||||||
@keyup.enter.native="handleQuery" />
|
v-model="queryParams.orderCode"
|
||||||
|
placeholder="请输入单据编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="handleQuery"
|
||||||
|
/>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-tree v-loading="orderListLoading" :data="treeData" :props="defaultProps" @node-click="handleNodeClick" />
|
|
||||||
|
<!-- 使用klp-list组件替换el-tree -->
|
||||||
|
<klp-list
|
||||||
|
v-loading="orderListLoading"
|
||||||
|
:list-data="orderList"
|
||||||
|
list-key="orderId"
|
||||||
|
title-label="订单编号"
|
||||||
|
title-field="orderCode"
|
||||||
|
:title-max-width="180"
|
||||||
|
@item-click="handleItemClick"
|
||||||
|
>
|
||||||
|
<!-- 操作按钮插槽 -->
|
||||||
|
<!-- <template #actions="{ item, isSelected }">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-view"
|
||||||
|
@click.stop="handleViewDetail(item)"
|
||||||
|
title="查看详情"
|
||||||
|
></el-button>
|
||||||
|
</template> -->
|
||||||
|
</klp-list>
|
||||||
|
|
||||||
<pagination
|
<pagination
|
||||||
:page.sync="queryParams.pageNum"
|
:page.sync="queryParams.pageNum"
|
||||||
:limit.sync="queryParams.pageSize"
|
:limit.sync="queryParams.pageSize"
|
||||||
@@ -47,14 +73,15 @@
|
|||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="应收明细" name="receivable">
|
<el-tab-pane label="应收明细" name="receivable">
|
||||||
<el-table v-loading="rightLoading" :data="currentOrder.receivables" empty-text="暂无数据">
|
<el-table v-loading="rightLoading" :data="currentOrder.receivables" empty-text="暂无数据">
|
||||||
<el-table-column label="应收ID" align="center" prop="receivableId" v-if="false" />
|
|
||||||
<el-table-column label="客户" align="center" prop="customerName" />
|
<el-table-column label="客户" align="center" prop="customerName" />
|
||||||
<el-table-column label="订单ID" align="center" prop="orderId" />
|
<el-table-column label="订单ID" align="center" prop="orderId" />
|
||||||
<el-table-column label="到期日" align="center" prop="dueDate" width="180">
|
<el-table-column label="到期日" align="center" prop="dueDate" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.dueDate, '{y}-{m}-{d}') }}</span>
|
<span>{{ parseTime(scope.row.dueDate, '{y}-{m}-{d}') }}</span>
|
||||||
<el-tag v-if="new Date(scope.row.dueDate) < new Date()" type="danger">过期</el-tag>
|
<el-tag v-if="new Date(scope.row.dueDate) < new Date()" type="danger">过期</el-tag>
|
||||||
<el-tag v-else-if="new Date(scope.row.dueDate) > new Date()" type="success">还剩{{ parseInt((new Date(scope.row.dueDate) - new Date()) / (1000 * 60 * 60 * 24)) }}天</el-tag>
|
<el-tag v-else-if="new Date(scope.row.dueDate) > new Date()" type="success">
|
||||||
|
还剩{{ parseInt((new Date(scope.row.dueDate) - new Date()) / (1000 * 60 * 60 * 24)) }}天
|
||||||
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="应收金额" align="center" prop="amount" />
|
<el-table-column label="应收金额" align="center" prop="amount" />
|
||||||
@@ -66,14 +93,15 @@
|
|||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="应付明细" name="payable">
|
<el-tab-pane label="应付明细" name="payable">
|
||||||
<el-table v-loading="rightLoading" :data="currentOrder.payables" empty-text="暂无数据">
|
<el-table v-loading="rightLoading" :data="currentOrder.payables" empty-text="暂无数据">
|
||||||
<el-table-column label="应付ID" align="center" prop="payableId" v-if="false" />
|
|
||||||
<el-table-column label="供应商" align="center" prop="supplierName" />
|
<el-table-column label="供应商" align="center" prop="supplierName" />
|
||||||
<el-table-column label="订单ID" align="center" prop="orderId" />
|
<el-table-column label="订单ID" align="center" prop="orderId" />
|
||||||
<el-table-column label="到期日" align="center" prop="dueDate" width="180">
|
<el-table-column label="到期日" align="center" prop="dueDate" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.dueDate, '{y}-{m}-{d}') }}</span>
|
<span>{{ parseTime(scope.row.dueDate, '{y}-{m}-{d}') }}</span>
|
||||||
<el-tag v-if="new Date(scope.row.dueDate) < new Date()" type="danger">过期</el-tag>
|
<el-tag v-if="new Date(scope.row.dueDate) < new Date()" type="danger">过期</el-tag>
|
||||||
<el-tag v-else-if="new Date(scope.row.dueDate) > new Date()" type="success">还剩{{ parseInt((new Date(scope.row.dueDate) - new Date()) / (1000 * 60 * 60 * 24)) }}天</el-tag>
|
<el-tag v-else-if="new Date(scope.row.dueDate) > new Date()" type="success">
|
||||||
|
还剩{{ parseInt((new Date(scope.row.dueDate) - new Date()) / (1000 * 60 * 60 * 24)) }}天
|
||||||
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="应付金额" align="center" prop="amount" />
|
<el-table-column label="应付金额" align="center" prop="amount" />
|
||||||
@@ -97,7 +125,6 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -108,11 +135,13 @@ import { listPayable } from "@/api/finance/payable";
|
|||||||
import { listFinancialDocument } from "@/api/finance/financialDocument";
|
import { listFinancialDocument } from "@/api/finance/financialDocument";
|
||||||
|
|
||||||
import OrderDetailList from '@/views/wms/order/panels/detail.vue'
|
import OrderDetailList from '@/views/wms/order/panels/detail.vue'
|
||||||
|
import klpList from "@/components/KLPUI/KLPList/index.vue"; // 引入klp-list组件
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Order",
|
name: "Order",
|
||||||
components: {
|
components: {
|
||||||
OrderDetailList
|
OrderDetailList,
|
||||||
|
klpList // 注册klp-list组件
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -124,12 +153,8 @@ export default {
|
|||||||
orderCode: undefined
|
orderCode: undefined
|
||||||
},
|
},
|
||||||
orderListLoading: false,
|
orderListLoading: false,
|
||||||
treeData: [],
|
orderList: [], // 用于klp-list的列表数据
|
||||||
total: 0,
|
total: 0,
|
||||||
defaultProps: {
|
|
||||||
children: 'children',
|
|
||||||
label: 'label'
|
|
||||||
},
|
|
||||||
rightLoading: false,
|
rightLoading: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -144,37 +169,60 @@ export default {
|
|||||||
getList() {
|
getList() {
|
||||||
this.orderListLoading = true;
|
this.orderListLoading = true;
|
||||||
listOrder(this.queryParams).then(response => {
|
listOrder(this.queryParams).then(response => {
|
||||||
this.treeData = response.rows.map(item => ({
|
this.orderList = response.rows; // 直接使用原始数据
|
||||||
label: item.orderCode,
|
|
||||||
value: item
|
|
||||||
}));
|
|
||||||
this.total = response.total;
|
this.total = response.total;
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.orderListLoading = false;
|
this.orderListLoading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleNodeClick(data) {
|
// 处理列表项点击事件
|
||||||
|
handleItemClick(selectedItem) {
|
||||||
|
if (!selectedItem) {
|
||||||
|
this.currentOrder = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.rightLoading) {
|
if (this.rightLoading) {
|
||||||
this.$message.warning('请等待当前订单加载完成');
|
this.$message.warning('请等待当前订单加载完成');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.currentOrder = data.value;
|
|
||||||
this.fetchData(data.value.orderId);
|
this.currentOrder = selectedItem;
|
||||||
|
this.fetchData(selectedItem.orderId);
|
||||||
|
},
|
||||||
|
// 查看详情按钮点击事件
|
||||||
|
handleViewDetail(item) {
|
||||||
|
this.currentOrder = item;
|
||||||
|
this.fetchData(item.orderId);
|
||||||
},
|
},
|
||||||
async fetchData(orderId) {
|
async fetchData(orderId) {
|
||||||
this.rightLoading = true;
|
this.rightLoading = true;
|
||||||
// 需要逐个获取订单明细、应收明细、应付明细、凭证管理
|
try {
|
||||||
const orderDetail = (await listOrderDetail({ orderId, pageSize: 1000 })).rows;
|
// 并行请求提高性能
|
||||||
const receivableDetail = (await listReceivable({ orderId, pageSize: 1000 })).rows;
|
const [
|
||||||
const payableDetail = (await listPayable({ orderId, pageSize: 1000 })).rows;
|
orderDetailRes,
|
||||||
const documentDetail = (await listFinancialDocument({ orderId, pageSize: 1000 })).rows;
|
receivableRes,
|
||||||
this.rightLoading = false;
|
payableRes,
|
||||||
|
documentRes
|
||||||
|
] = await Promise.all([
|
||||||
|
listOrderDetail({ orderId, pageSize: 1000 }),
|
||||||
|
listReceivable({ orderId, pageSize: 1000 }),
|
||||||
|
listPayable({ orderId, pageSize: 1000 }),
|
||||||
|
listFinancialDocument({ orderId, pageSize: 1000 })
|
||||||
|
]);
|
||||||
|
|
||||||
this.currentOrder = {
|
this.currentOrder = {
|
||||||
...this.currentOrder,
|
...this.currentOrder,
|
||||||
details: orderDetail,
|
details: orderDetailRes.rows,
|
||||||
receivables: receivableDetail,
|
receivables: receivableRes.rows,
|
||||||
payables: payableDetail,
|
payables: payableRes.rows,
|
||||||
documents: documentDetail
|
documents: documentRes.rows
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
this.$message.error('数据加载失败,请重试');
|
||||||
|
console.error(error);
|
||||||
|
} finally {
|
||||||
|
this.rightLoading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,14 +39,22 @@
|
|||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
>导出</el-button>
|
>导出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="bomItemList" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" :data="bomItemList" @selection-change="handleSelectionChange">
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column label="属性名称" align="center" prop="attrKey" />
|
<el-table-column label="属性名称" align="center" prop="attrKey">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.attrKey }}</span>
|
||||||
|
<span v-if="scope.row.remark">
|
||||||
|
<el-tooltip :content="scope.row.remark" placement="top">
|
||||||
|
<i class="el-icon-info"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="属性值" align="center" prop="attrValue" />
|
<el-table-column label="属性值" align="center" prop="attrValue" />
|
||||||
<el-table-column label="备注" align="center" prop="remark" />
|
<!-- <el-table-column label="备注" align="center" prop="remark" /> -->
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button
|
<el-button
|
||||||
|
|||||||
@@ -65,8 +65,8 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
<!-- <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
||||||
@pagination="getList" />
|
@pagination="getList" /> -->
|
||||||
|
|
||||||
<!-- 添加或修改订单明细对话框 -->
|
<!-- 添加或修改订单明细对话框 -->
|
||||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
<el-select placeholder="请选择产品规范" @change="handleChangeSpec" style="width: 100%;">
|
<el-select placeholder="请选择产品规范" @change="handleChangeSpec" style="width: 100%;">
|
||||||
<el-option v-for="item in productSpecList" :key="item.groupId" :label="item.groupName" :value="item.groupId" />
|
<el-option v-for="item in productSpecList" :key="item.groupId" :label="item.groupName" :value="item.groupId" />
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<el-button type="primary" @click="handleAddSpec">新增产品规范</el-button>
|
<el-button @click="handleAddSpec" style="width: 100%;">新增产品规范</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
@@ -158,7 +158,7 @@ export default {
|
|||||||
EOrderStatus,
|
EOrderStatus,
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 20,
|
pageSize: 100,
|
||||||
orderId: this.orderId,
|
orderId: this.orderId,
|
||||||
productId: undefined,
|
productId: undefined,
|
||||||
quantity: undefined,
|
quantity: undefined,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<!-- 左右布局容器 -->
|
<!-- 左右布局容器 -->
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<!-- 左侧:自定义简洁订单列表区(占8列) -->
|
<!-- 左侧:使用klp-list组件(占6列) -->
|
||||||
<el-col :span="6" style="display: table-cell;">
|
<el-col :span="6" style="display: table-cell;">
|
||||||
<!-- 搜索表单 - 精简搜索项 -->
|
<!-- 搜索表单 - 精简搜索项 -->
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"
|
||||||
@@ -19,54 +19,33 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 功能按钮区 -->
|
<!-- klp-list组件 -->
|
||||||
<!-- <el-row :gutter="10" class="mb-4">
|
<klp-list
|
||||||
<el-col :span="6">
|
:list-data="orderList"
|
||||||
|
:model-value="selectedIds"
|
||||||
</el-col>
|
title-field="orderCode"
|
||||||
<el-col :span="6">
|
list-key="orderId"
|
||||||
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
|
title-label="订单编号"
|
||||||
class="w-full">批量删除</el-button>
|
:loading="loading"
|
||||||
</el-col>
|
@item-click="handleRowClick"
|
||||||
</el-row> -->
|
>
|
||||||
|
<!-- 自定义操作按钮 -->
|
||||||
<!-- 自定义简洁列表 -->
|
<template #actions="{ item }">
|
||||||
<div class="custom-list-container" v-loading="loading">
|
|
||||||
<!-- 列表项 -->
|
|
||||||
<div v-for="(item, index) in orderList" :key="item.orderId" class="order-item"
|
|
||||||
:class="{ 'active': selectedOrderId === item.orderId }" @click="handleRowClick(item)">
|
|
||||||
<!-- 复选框 -->
|
|
||||||
<!-- <el-checkbox v-model="selectedIds[item.orderId]" @change.stop="handleCheckboxChange(item, $event)"
|
|
||||||
class="checkbox"></el-checkbox> -->
|
|
||||||
<!-- 订单编号 -->
|
|
||||||
<div class="order-code">
|
|
||||||
<span class="label">订单编号:</span>
|
|
||||||
<span class="value">{{ item.orderCode }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 操作按钮组 -->
|
|
||||||
<div class="order-actions">
|
|
||||||
<!-- 预订单确认按钮 -->
|
<!-- 预订单确认按钮 -->
|
||||||
<el-button size="mini" plain title="预订单确认" type="success" icon="el-icon-check" v-if="isPre"
|
<el-button size="mini" plain title="预订单确认" type="success" icon="el-icon-check" v-if="isPre"
|
||||||
@click.stop="handleStartProduction(item)"></el-button>
|
@click.stop="handleStartProduction(item)"></el-button>
|
||||||
|
|
||||||
<!-- 删除按钮 -->
|
<!-- 删除按钮 -->
|
||||||
<el-button size="mini" type="text" style="color: red" icon="el-icon-delete" @click.stop="handleDelete(item)"></el-button>
|
<el-button size="mini" type="text" style="color: red" icon="el-icon-delete" @click.stop="handleDelete(item)"></el-button>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</klp-list>
|
||||||
|
|
||||||
<!-- 空状态 -->
|
|
||||||
<div v-if="orderList.length === 0 && !loading" class="empty-state">
|
|
||||||
<el-empty description="暂无订单数据" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 分页组件 -->
|
<!-- 分页组件 -->
|
||||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
|
||||||
:limit.sync="queryParams.pageSize" @pagination="getList" class="mt-4" />
|
:limit.sync="queryParams.pageSize" @pagination="getList" class="mt-4" />
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<!-- 右侧:详情区(占16列) -->
|
<!-- 右侧:详情区(占18列) -->
|
||||||
<el-col :span="18">
|
<el-col :span="18">
|
||||||
<div>
|
<div>
|
||||||
<!-- 未选中行时显示提示 -->
|
<!-- 未选中行时显示提示 -->
|
||||||
@@ -81,56 +60,45 @@
|
|||||||
<!-- 订单信息Tab -->
|
<!-- 订单信息Tab -->
|
||||||
<el-tab-pane label="订单信息" name="orderInfo">
|
<el-tab-pane label="订单信息" name="orderInfo">
|
||||||
<el-form ref="detailForm" :model="form" :rules="rules" label-width="80px" size="small" class="mt-4">
|
<el-form ref="detailForm" :model="form" :rules="rules" label-width="80px" size="small" class="mt-4">
|
||||||
<!-- <el-row :gutter="20"> -->
|
|
||||||
<!-- <el-col :span="12"> -->
|
|
||||||
<el-form-item label="订单ID" prop="orderId">
|
<el-form-item label="订单ID" prop="orderId">
|
||||||
<el-input style="width: 60%;" v-model="form.orderId" placeholder="无" disabled>
|
<el-input style="width: 60%;" v-model="form.orderId" placeholder="无" disabled>
|
||||||
<el-button style="padding: -1;" slot="append" size="mini" type="text" icon="el-icon-document-copy"
|
<el-button style="padding: -1;" slot="append" size="mini" type="text" icon="el-icon-document-copy"
|
||||||
@click.stop="copyOrderId(form.orderId)"></el-button>
|
@click.stop="copyOrderId(form.orderId)"></el-button>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- </el-col> -->
|
|
||||||
<!-- <el-col :span="12"> -->
|
|
||||||
<el-form-item label="订单编号" prop="orderCode">
|
<el-form-item label="订单编号" prop="orderCode">
|
||||||
<el-input style="width: 60%;" v-model="form.orderCode" placeholder="无" disabled />
|
<el-input style="width: 60%;" v-model="form.orderCode" placeholder="无" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- </el-col> -->
|
|
||||||
<!-- <el-col :span="12"> -->
|
|
||||||
<el-form-item label="客户名称" prop="customerId">
|
<el-form-item label="客户名称" prop="customerId">
|
||||||
<customer-select style="width: 60%;" v-model="form.customerId" />
|
<customer-select style="width: 60%;" v-model="form.customerId" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- </el-col> -->
|
|
||||||
<!-- <el-col :span="12"> -->
|
|
||||||
<el-form-item label="销售经理" prop="salesManager">
|
<el-form-item label="销售经理" prop="salesManager">
|
||||||
<el-input style="width: 60%;" v-model="form.salesManager" placeholder="无" />
|
<el-input style="width: 60%;" v-model="form.salesManager" placeholder="无" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- </el-col> -->
|
|
||||||
<!-- <el-col :span="12"> -->
|
|
||||||
<el-form-item label="含税金额" prop="taxAmount">
|
<el-form-item label="含税金额" prop="taxAmount">
|
||||||
<el-input-number style="width: 60%;" :controls="false" v-model="form.taxAmount" placeholder="0.00" precision="2"
|
<el-input-number style="width: 60%;" :controls="false" v-model="form.taxAmount" placeholder="0.00" precision="2"
|
||||||
:min="0" />
|
:min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- </el-col> -->
|
|
||||||
<!-- <el-col :span="12"> -->
|
|
||||||
<el-form-item label="无税金额" prop="noTaxAmount">
|
<el-form-item label="无税金额" prop="noTaxAmount">
|
||||||
<el-input-number style="width: 60%;" :controls="false" v-model="form.noTaxAmount" placeholder="0.00" precision="2"
|
<el-input-number style="width: 60%;" :controls="false" v-model="form.noTaxAmount" placeholder="0.00" precision="2"
|
||||||
:min="0" />
|
:min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- </el-col> -->
|
|
||||||
<!-- <el-col :span="12" v-if="!isPre"> -->
|
<el-form-item label="订单状态" prop="orderStatus" v-if="!isPre">
|
||||||
<el-form-item label="订单状态" prop="orderStatus">
|
|
||||||
<el-select style="width: 60%;" v-model="form.orderStatus" @change="handleOrderStatusChange" size="mini">
|
<el-select style="width: 60%;" v-model="form.orderStatus" @change="handleOrderStatusChange" size="mini">
|
||||||
<el-option v-for="item in dict.type.order_status" :key="item.value" :label="item.label"
|
<el-option v-for="item in dict.type.order_status" :key="item.value" :label="item.label"
|
||||||
:value="parseInt(item.value)" />
|
:value="parseInt(item.value)" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- </el-col> -->
|
|
||||||
<!-- <el-col :span="24"> -->
|
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input style="width: 60%;" v-model="form.remark" placeholder="无" type="textarea" rows="4" />
|
<el-input style="width: 60%;" v-model="form.remark" placeholder="无" type="textarea" rows="4" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- </el-col> -->
|
|
||||||
<!-- </el-row> -->
|
|
||||||
|
|
||||||
<!-- 更新按钮 -->
|
<!-- 更新按钮 -->
|
||||||
<el-form-item class="text-right">
|
<el-form-item class="text-right">
|
||||||
@@ -203,10 +171,11 @@ import { getOrder, delOrder, addOrder, updateOrder, listByStatus } from "@/api/w
|
|||||||
import OrderDetailPanel from './detail.vue';
|
import OrderDetailPanel from './detail.vue';
|
||||||
import { EOrderStatus } from "@/utils/enums";
|
import { EOrderStatus } from "@/utils/enums";
|
||||||
import CustomerSelect from '@/components/KLPService/CustomerSelect/index.vue';
|
import CustomerSelect from '@/components/KLPService/CustomerSelect/index.vue';
|
||||||
|
import klpList from "@/components/KLPUI/KLPList/index.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Order",
|
name: "Order",
|
||||||
components: { OrderDetailPanel, CustomerSelect },
|
components: { OrderDetailPanel, CustomerSelect, klpList },
|
||||||
dicts: ['order_status'],
|
dicts: ['order_status'],
|
||||||
props: {
|
props: {
|
||||||
isPre: {
|
isPre: {
|
||||||
@@ -227,10 +196,8 @@ export default {
|
|||||||
buttonLoading: false,
|
buttonLoading: false,
|
||||||
// 列表加载遮罩
|
// 列表加载遮罩
|
||||||
loading: true,
|
loading: true,
|
||||||
// 选中的订单ID集合(用于批量操作)
|
// 选中的订单ID集合
|
||||||
selectedIds: {},
|
selectedIds: {},
|
||||||
// 非多个禁用(批量删除用)
|
|
||||||
multiple: true,
|
|
||||||
// 显示搜索条件
|
// 显示搜索条件
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
// 总条数
|
// 总条数
|
||||||
@@ -304,7 +271,6 @@ export default {
|
|||||||
|
|
||||||
// 重置选中状态
|
// 重置选中状态
|
||||||
this.selectedIds = {};
|
this.selectedIds = {};
|
||||||
this.checkMultipleStatus();
|
|
||||||
|
|
||||||
// 如果之前选中的订单不在列表中了,清空选中状态
|
// 如果之前选中的订单不在列表中了,清空选中状态
|
||||||
if (this.selectedOrderId && !this.orderList.some(item => item.orderId === this.selectedOrderId)) {
|
if (this.selectedOrderId && !this.orderList.some(item => item.orderId === this.selectedOrderId)) {
|
||||||
@@ -337,18 +303,6 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 处理复选框变化 */
|
|
||||||
handleCheckboxChange(item, checked) {
|
|
||||||
this.selectedIds[item.orderId] = checked;
|
|
||||||
this.checkMultipleStatus();
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 检查批量操作状态 */
|
|
||||||
checkMultipleStatus() {
|
|
||||||
const selectedCount = Object.values(this.selectedIds).filter(checked => checked).length;
|
|
||||||
this.multiple = selectedCount === 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 订单状态变更 */
|
/** 订单状态变更 */
|
||||||
handleOrderStatusChange() {
|
handleOrderStatusChange() {
|
||||||
updateOrder(this.form).then(response => {
|
updateOrder(this.form).then(response => {
|
||||||
@@ -463,30 +417,13 @@ export default {
|
|||||||
|
|
||||||
/** 删除订单 */
|
/** 删除订单 */
|
||||||
handleDelete(row) {
|
handleDelete(row) {
|
||||||
// 获取要删除的订单ID
|
this.$modal.confirm(`是否确认删除订单"${row.orderCode}"?`).then(() => {
|
||||||
let orderIds;
|
|
||||||
if (row) {
|
|
||||||
// 单条删除
|
|
||||||
orderIds = [row.orderId];
|
|
||||||
} else {
|
|
||||||
// 批量删除
|
|
||||||
orderIds = Object.entries(this.selectedIds)
|
|
||||||
.filter(([id, checked]) => checked)
|
|
||||||
.map(([id]) => id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!orderIds.length) {
|
|
||||||
this.$modal.msgWarning("请选择要删除的订单");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$modal.confirm(`是否确认删除选中的 ${orderIds.length} 个订单?`).then(() => {
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
return delOrder(orderIds);
|
return delOrder([row.orderId]);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.$modal.msgSuccess("删除成功");
|
this.$modal.msgSuccess("删除成功");
|
||||||
// 如果删除的是当前选中的订单,清空详情
|
// 如果删除的是当前选中的订单,清空详情
|
||||||
if (row && this.selectedOrderId === row.orderId) {
|
if (this.selectedOrderId === row.orderId) {
|
||||||
this.selectedOrderId = null;
|
this.selectedOrderId = null;
|
||||||
}
|
}
|
||||||
this.getList();
|
this.getList();
|
||||||
@@ -525,78 +462,6 @@ export default {
|
|||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 自定义列表容器 */
|
|
||||||
.custom-list-container {
|
|
||||||
max-height: calc(100vh - 220px);
|
|
||||||
overflow-y: auto;
|
|
||||||
padding-right: 8px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 列表项样式 */
|
|
||||||
.order-item {
|
|
||||||
padding: 12px 16px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border-bottom: 1px solid #e6e6e6;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 选中状态 */
|
|
||||||
.order-item.active {
|
|
||||||
border-left: 3px solid #409eff;
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 订单编号样式 */
|
|
||||||
.order-code {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-code .label {
|
|
||||||
color: #606266;
|
|
||||||
margin-right: 6px;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-code .value {
|
|
||||||
color: #303133;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 操作按钮组 */
|
|
||||||
.order-actions {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 复选框样式调整 */
|
|
||||||
.checkbox {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 空状态样式 */
|
|
||||||
.empty-state {
|
|
||||||
padding: 40px 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 右侧详情容器 */
|
|
||||||
.detail-container {
|
|
||||||
height: 100%;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 16px;
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
||||||
min-height: calc(100vh - 32px);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 空提示样式 */
|
/* 空提示样式 */
|
||||||
.empty-tip {
|
.empty-tip {
|
||||||
height: 400px;
|
height: 400px;
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
|
||||||
<el-form-item label="采购订单编号" prop="detailCode">
|
|
||||||
<el-input v-model="queryParams.detailCode" placeholder="请输入采购订单编号" clearable
|
|
||||||
@keyup.enter.native="handleQuery" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="原材料" prop="rawMaterialId">
|
<el-form-item label="原材料" prop="rawMaterialId">
|
||||||
<RawMaterialSelect v-model="queryParams.rawMaterialId" placeholder="请选择原材料" can-add />
|
<RawMaterialSelect v-model="queryParams.rawMaterialId" placeholder="请选择原材料" can-add />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -40,10 +36,10 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button>
|
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<!-- <el-col :span="1.5">
|
||||||
<el-button type="info" plain icon="el-icon-plus" size="mini" :disabled="!hasArrivalItems"
|
<el-button type="info" plain icon="el-icon-plus" size="mini" :disabled="!hasArrivalItems"
|
||||||
@click="handleCreateStockIn">创建入库单</el-button>
|
@click="handleCreateStockIn">创建入库单</el-button>
|
||||||
</el-col>
|
</el-col> -->
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
|||||||
@@ -12,15 +12,15 @@
|
|||||||
>
|
>
|
||||||
<!-- 下拉选项:循环制造规范列表 -->
|
<!-- 下拉选项:循环制造规范列表 -->
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in mSpecList"
|
v-for="item in pSpecList"
|
||||||
:key="item.specId"
|
:key="item.groupId"
|
||||||
:label="item.specName"
|
:label="item.groupName"
|
||||||
:value="item.specId"
|
:value="item.groupId"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 无数据提示 -->
|
<!-- 无数据提示 -->
|
||||||
<el-option
|
<el-option
|
||||||
v-if="mSpecList.length === 0 && !loading"
|
v-if="pSpecList.length === 0 && !loading"
|
||||||
value=""
|
value=""
|
||||||
disabled
|
disabled
|
||||||
>
|
>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listManufacturingSpec } from '@/api/work/manufacturingSpec'
|
import { listProductSpecGroup } from '@/api/work/productSpecGroup'
|
||||||
import { debounce } from '@/utils' // 防抖:避免频繁触发接口请求
|
import { debounce } from '@/utils' // 防抖:避免频繁触发接口请求
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -44,7 +44,7 @@ export default {
|
|||||||
// 可选:允许外部自定义搜索参数的字段名(增强组件复用性)
|
// 可选:允许外部自定义搜索参数的字段名(增强组件复用性)
|
||||||
searchKey: {
|
searchKey: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'specName' // 默认为“规范名称”搜索(对应接口的mSpecName参数)
|
default: 'groupName' // 默认为“规范名称”搜索(对应接口的mSpecName参数)
|
||||||
},
|
},
|
||||||
// 可选:每页加载数量(外部可配置)
|
// 可选:每页加载数量(外部可配置)
|
||||||
pageSize: {
|
pageSize: {
|
||||||
@@ -54,7 +54,7 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
mSpecList: [], // 制造规范列表数据
|
pSpecList: [], // 制造规范列表数据
|
||||||
loading: false, // 远程请求加载状态
|
loading: false, // 远程请求加载状态
|
||||||
queryParams: {
|
queryParams: {
|
||||||
// 搜索参数:默认用specName(可通过searchKey自定义)
|
// 搜索参数:默认用specName(可通过searchKey自定义)
|
||||||
@@ -109,14 +109,14 @@ export default {
|
|||||||
// 5. 获取制造规范列表(远程接口请求)
|
// 5. 获取制造规范列表(远程接口请求)
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true // 开始加载:显示加载动画
|
this.loading = true // 开始加载:显示加载动画
|
||||||
listManufacturingSpec(this.queryParams)
|
listProductSpecGroup(this.queryParams)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
// 接口成功:赋值列表数据(兼容res.rows或res.data.rows,避免接口返回格式差异)
|
// 接口成功:赋值列表数据(兼容res.rows或res.data.rows,避免接口返回格式差异)
|
||||||
this.mSpecList = res.rows || res.data?.rows || []
|
this.pSpecList = res.rows || res.data?.rows || []
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
// 接口失败:清空列表,避免旧数据残留
|
// 接口失败:清空列表,避免旧数据残留
|
||||||
this.mSpecList = []
|
this.pSpecList = []
|
||||||
this.$message.error('获取制造规范列表失败,请重试') // 错误提示(优化用户体验)
|
this.$message.error('获取制造规范列表失败,请重试') // 错误提示(优化用户体验)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
@@ -125,9 +125,9 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// 6. 选择变化时触发(返回完整订单项,方便父组件使用)
|
// 6. 选择变化时触发(返回完整订单项,方便父组件使用)
|
||||||
handleSelectChange(mSpecId) {
|
handleSelectChange(pSpecId) {
|
||||||
// 根据选中的ID,找到对应的完整制造规范对象
|
// 根据选中的ID,找到对应的完整制造规范对象
|
||||||
const selectedItem = this.mSpecList.find(item => item.specId === mSpecId)
|
const selectedItem = this.pSpecList.find(item => item.groupId === pSpecId)
|
||||||
// 触发change事件:返回完整项(父组件可通过@change接收)
|
// 触发change事件:返回完整项(父组件可通过@change接收)
|
||||||
this.$emit('change', selectedItem)
|
this.$emit('change', selectedItem)
|
||||||
// 可选:触发input事件后,额外触发change事件(符合常规组件使用习惯)
|
// 可选:触发input事件后,额外触发change事件(符合常规组件使用习惯)
|
||||||
|
|||||||
@@ -53,7 +53,9 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 处理数据,兼容多种字段名,保证任务名唯一
|
// 处理数据,兼容多种字段名,保证任务名唯一
|
||||||
const taskData = this.tasks.map((item, idx) => {
|
|
||||||
|
const taskData = this.tasks
|
||||||
|
.map((item, idx) => {
|
||||||
const name = (item.taskName || item.planName || item.remark || item.productName || item.name || `任务${idx+1}`) + (item.productName ? `-${item.productName}` : '');
|
const name = (item.taskName || item.planName || item.remark || item.productName || item.name || `任务${idx+1}`) + (item.productName ? `-${item.productName}` : '');
|
||||||
const start = item.startDate || item.start_time || item.start || item.start_date;
|
const start = item.startDate || item.start_time || item.start || item.start_date;
|
||||||
const end = item.endDate || item.end_time || item.end || item.end_date;
|
const end = item.endDate || item.end_time || item.end || item.end_date;
|
||||||
@@ -72,7 +74,10 @@ export default {
|
|||||||
startDate: start,
|
startDate: start,
|
||||||
endDate: end
|
endDate: end
|
||||||
};
|
};
|
||||||
});
|
})
|
||||||
|
// 确保三个字段都存在:startDate,endDate,name
|
||||||
|
.filter(item => item.startDate && item.endDate && item.name);
|
||||||
|
|
||||||
// 先全部用 getColor 分配基础色
|
// 先全部用 getColor 分配基础色
|
||||||
taskData.forEach((item, idx) => {
|
taskData.forEach((item, idx) => {
|
||||||
item._color = getColor(item.lineId, item.orderId, idx);
|
item._color = getColor(item.lineId, item.orderId, idx);
|
||||||
|
|||||||
@@ -44,11 +44,18 @@
|
|||||||
|
|
||||||
<el-table v-loading="loading" :data="productSpecList" @selection-change="handleSelectionChange">
|
<el-table v-loading="loading" :data="productSpecList" @selection-change="handleSelectionChange">
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column label="主键" align="center" prop="specId" v-if="false"/>
|
<el-table-column label="规范名称" align="center" prop="specKey">
|
||||||
<el-table-column label="所属产品规范组ID" align="center" prop="groupId" />
|
<template slot-scope="scope">
|
||||||
<el-table-column label="规范名称" align="center" prop="specKey" />
|
<span>{{ scope.row.specKey }}</span>
|
||||||
|
<span v-if="scope.row.remark">
|
||||||
|
<el-tooltip :content="scope.row.remark" placement="top">
|
||||||
|
<i class="el-icon-info"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="规范值" align="center" prop="specValue" />
|
<el-table-column label="规范值" align="center" prop="specValue" />
|
||||||
<el-table-column label="备注" align="center" prop="remark" />
|
<!-- <el-table-column label="备注" align="center" prop="remark" /> -->
|
||||||
<el-table-column label="操作" v-if="!readonly" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" v-if="!readonly" align="center" class-name="small-padding fixed-width">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button
|
<el-button
|
||||||
|
|||||||
@@ -135,8 +135,10 @@ export default {
|
|||||||
this.$refs.detailForm.validate(valid => {
|
this.$refs.detailForm.validate(valid => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
if (this.detailForm.dateRange && this.detailForm.dateRange.length === 2) {
|
if (this.detailForm.dateRange && this.detailForm.dateRange.length === 2) {
|
||||||
this.detailForm.startDate = this.detailForm.dateRange[0].replace(' ', "T") + '.000Z';
|
// const startDate = this.parseTime(this.detailForm.dateRange[0], '{y}-{m}-{d}T{h}:{i}:{s}') + '.000Z';
|
||||||
this.detailForm.endDate = this.detailForm.dateRange[1].replace(' ', "T") + '.000Z';
|
// const endDate = this.parseTime(this.detailForm.dateRange[1], '{y}-{m}-{d}T{h}:{i}:{s}') + '.000Z';
|
||||||
|
this.detailForm.startDate = this.detailForm.dateRange[0];
|
||||||
|
this.detailForm.endDate = this.detailForm.dateRange[1];
|
||||||
} else {
|
} else {
|
||||||
this.detailForm.startDate = '';
|
this.detailForm.startDate = '';
|
||||||
this.detailForm.endDate = '';
|
this.detailForm.endDate = '';
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
<el-select placeholder="请选择产品规范" @change="handleChangeSpec" style="width: 100%;">
|
<el-select placeholder="请选择产品规范" @change="handleChangeSpec" style="width: 100%;">
|
||||||
<el-option v-for="item in productSpecList.filter(item => item.productId != this.form.productId)" :key="item.groupId" :label="item.groupName" :value="item.groupId" />
|
<el-option v-for="item in productSpecList.filter(item => item.productId != this.form.productId)" :key="item.groupId" :label="item.groupName" :value="item.groupId" />
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<el-button type="primary" @click="handleAddSpec">新增产品规范</el-button>
|
<el-button @click="handleAddSpec" style="width: 100%;">新增产品规范</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user