From cd9ee0b4268c6b0ccdaf75115aea4680ce40cb83 Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期三, 27 五月 2026 13:38:20 +0800
Subject: [PATCH] Merge branch 'dev_天津_君歌化工' of http://114.132.189.42:9002/r/product-inventory-management into dev_天津_君歌化工
---
src/views/productionManagement/productionProcess/index.vue | 11
src/api/collaborativeApproval/approvalManagement.js | 48 -
src/assets/styles/sidebar.scss | 331 +++++----
src/views/productionManagement/processRoute/processRouteItem/index.vue | 28
src/assets/styles/element-ui.scss | 224 +++---
src/views/collaborativeApproval/approvalProcess/index.vue | 9
src/views/salesManagement/salesLedger/index.vue | 65 -
src/views/salesManagement/salesQuotation/index.vue | 196 -----
src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue | 138 ---
src/views/productionManagement/productionProcess/Edit.vue | 195 +----
src/views/collaborativeApproval/approvalManagement/index.vue | 113 +-
src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue | 40 -
src/views/procurementManagement/procurementLedger/index.vue | 85 --
src/views/productionManagement/productionOrder/New.vue | 4
src/views/productionManagement/processRoute/New.vue | 76 --
src/layout/components/Sidebar/index.vue | 45 +
vite.config.js | 4
src/views/productionManagement/processRoute/Edit.vue | 204 +++--
src/layout/components/Sidebar/SidebarItem.vue | 2
src/views/productionManagement/productionProcess/New.vue | 137 ---
20 files changed, 631 insertions(+), 1,324 deletions(-)
diff --git a/src/api/collaborativeApproval/approvalManagement.js b/src/api/collaborativeApproval/approvalManagement.js
index 25059c4..c2ce4c7 100644
--- a/src/api/collaborativeApproval/approvalManagement.js
+++ b/src/api/collaborativeApproval/approvalManagement.js
@@ -1,53 +1,19 @@
// 瀹℃壒绠$悊閰嶇疆
import request from "@/utils/request";
-// 鏌ヨ瀹℃壒閰嶇疆鍒楄〃
-export function getApprovalConfigList(approveType) {
+// 鏌ヨ瀹℃壒娴佺▼閰嶇疆鑺傜偣鍒楄〃
+export function getApproveProcessConfigNodeList(type) {
return request({
- url: '/approvalConfig/list',
+ url: '/approveProcessConfigNode/list',
method: 'get',
- params: { approveType },
+ params: { type },
})
}
-// 鏌ヨ瀹℃壒閰嶇疆璇︽儏
-export function getApprovalConfigDetail(id) {
+// 鏂板瀹℃壒娴佺▼閰嶇疆鑺傜偣
+export function addApproveProcessConfigNode(data) {
return request({
- url: '/approvalConfig/get/' + id,
- method: 'get',
- })
-}
-
-// 鏂板瀹℃壒閰嶇疆
-export function addApprovalConfig(data) {
- return request({
- url: '/approvalConfig/add',
- method: 'post',
- data: data,
- })
-}
-
-// 淇敼瀹℃壒閰嶇疆
-export function updateApprovalConfig(data) {
- return request({
- url: '/approvalConfig/update',
- method: 'post',
- data: data,
- })
-}
-
-// 鍒犻櫎瀹℃壒閰嶇疆
-export function deleteApprovalConfig(id) {
- return request({
- url: '/approvalConfig/delete/' + id,
- method: 'delete',
- })
-}
-
-// 鎵归噺淇濆瓨瀹℃壒閰嶇疆
-export function batchSaveApprovalConfig(data) {
- return request({
- url: '/approvalConfig/batchSave',
+ url: '/approveProcessConfigNode/add',
method: 'post',
data: data,
})
diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss
index f296f9d..0c4dcd8 100644
--- a/src/assets/styles/element-ui.scss
+++ b/src/assets/styles/element-ui.scss
@@ -1,52 +1,52 @@
-// cover some element-ui styles
-
-.el-breadcrumb__inner,
-.el-breadcrumb__inner a {
- font-weight: 400 !important;
-}
-
-.el-upload {
- input[type="file"] {
- display: none !important;
- }
-}
-
-.el-upload__input {
- display: none;
-}
-
-.cell {
- .el-tag {
- margin-right: 0px;
- }
-}
-
-.small-padding {
- .cell {
- padding-left: 5px;
- padding-right: 5px;
- }
-}
-
-.fixed-width {
- .el-button--mini {
- padding: 7px 10px;
- width: 60px;
- }
-}
-
-.status-col {
- .cell {
- padding: 0 10px;
- text-align: center;
-
- .el-tag {
- margin-right: 0px;
- }
- }
-}
-
-// to fixed https://github.com/ElemeFE/element/issues/2461
+// cover some element-ui styles
+
+.el-breadcrumb__inner,
+.el-breadcrumb__inner a {
+ font-weight: 400 !important;
+}
+
+.el-upload {
+ input[type="file"] {
+ display: none !important;
+ }
+}
+
+.el-upload__input {
+ display: none;
+}
+
+.cell {
+ .el-tag {
+ margin-right: 0px;
+ }
+}
+
+.small-padding {
+ .cell {
+ padding-left: 5px;
+ padding-right: 5px;
+ }
+}
+
+.fixed-width {
+ .el-button--mini {
+ padding: 7px 10px;
+ width: 60px;
+ }
+}
+
+.status-col {
+ .cell {
+ padding: 0 10px;
+ text-align: center;
+
+ .el-tag {
+ margin-right: 0px;
+ }
+ }
+}
+
+// to fixed https://github.com/ElemeFE/element/issues/2461
.el-dialog {
transform: none;
left: 0;
@@ -98,64 +98,86 @@
.el-message-box__content {
padding: 24px 24px 0;
}
-.el-message-box__container {
- justify-content: center;
-}
-.el-message-box__btns {
- text-align: center;
- padding: 16px;
- display: flex;
- flex-direction: row-reverse;
- justify-content: center;
- align-items: center;
- .el-button--primary {
- margin-right: 12px;
- }
-}
+.el-message-box__container {
+ justify-content: center;
+}
+.el-message-box__btns {
+ text-align: center;
+ padding: 16px;
+ display: flex;
+ flex-direction: row-reverse;
+ justify-content: center;
+ align-items: center;
+ .el-button--primary {
+ margin-right: 12px;
+ }
+}
.el-table__expanded-cell {
padding: 0 !important;
.el-table__header-wrapper {
background-color: var(--surface-soft) !important;
}
}
-
-// refine element ui upload
-.upload-container {
- .el-upload {
- width: 100%;
-
- .el-upload-dragger {
- width: 100%;
- height: 200px;
- }
- }
-}
-
-// dropdown
-.el-dropdown-menu {
- a {
- display: block;
- }
-}
-
-// fix date-picker ui bug in filter-item
-.el-range-editor.el-input__inner {
- display: inline-flex !important;
-}
-
-// to fix el-date-picker css style
-.el-range-separator {
- box-sizing: content-box;
-}
-
-.el-menu--collapse
- > div
- > .el-submenu
- > .el-submenu__title
- .el-submenu__icon-arrow {
- display: none;
-}
-
+
+// refine element ui upload
+.upload-container {
+ .el-upload {
+ width: 100%;
+
+ .el-upload-dragger {
+ width: 100%;
+ height: 200px;
+ }
+ }
+}
+
+// dropdown
+.el-dropdown-menu {
+ a {
+ display: block;
+ }
+}
+
+// fix date-picker ui bug in filter-item
+.el-range-editor.el-input__inner {
+ display: inline-flex !important;
+}
+
+// to fix el-date-picker css style
+.el-range-separator {
+ box-sizing: content-box;
+}
+
+.el-menu--collapse
+ > div
+ > .el-sub-menu
+ > .el-sub-menu__title
+ .el-sub-menu__icon-arrow {
+ display: none;
+}
+
+/* 纭繚鑿滃崟绠ご濮嬬粓鏄剧ず - 浣跨敤 flex 甯冨眬 */
+.el-sub-menu__title {
+ display: flex !important;
+ align-items: center !important;
+ line-height: normal !important;
+}
+
+.el-sub-menu__title .el-sub-menu__icon-arrow {
+ position: static !important;
+ display: inline-flex !important;
+ visibility: visible !important;
+ width: auto !important;
+ height: auto !important;
+ overflow: visible !important;
+ margin-left: auto !important;
+ align-self: center !important;
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+ transform: none !important;
+ top: auto !important;
+}
+
.el-dropdown .el-dropdown-link {
color: var(--el-color-primary) !important;
}
diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss
index be7b7a7..ff49a33 100644
--- a/src/assets/styles/sidebar.scss
+++ b/src/assets/styles/sidebar.scss
@@ -1,70 +1,69 @@
-#app {
- .main-container {
- min-height: 100%;
- transition: margin-left 0.28s;
- margin-left: $base-sidebar-width;
- position: relative;
- background: transparent;
- }
-
- .sidebarHide {
- margin-left: 0 !important;
- }
-
- .sidebar-container {
- transition: width 0.28s;
- width: $base-sidebar-width !important;
- height: 100%;
- position: fixed;
- font-size: 0px;
- top: 0;
- bottom: 0;
- left: 0;
- z-index: 1001;
- overflow: hidden;
- padding: 12px 0 16px 16px;
- background: transparent;
- box-shadow: none;
-
- // reset element-ui css
- .horizontal-collapse-transition {
- transition: 0s width ease-in-out, 0s padding-left ease-in-out,
- 0s padding-right ease-in-out;
- }
-
- .scrollbar-wrapper {
- overflow-x: hidden !important;
- }
-
- .el-scrollbar__bar.is-vertical {
- right: 0px;
- }
-
- .el-scrollbar {
- height: 100%;
- }
-
- &.has-logo {
- .el-scrollbar {
- height: calc(100% - 72px);
- margin-top: 10px;
- }
- }
-
- .is-horizontal {
- display: none;
- }
-
- a {
- display: inline-block;
- width: 100%;
- overflow: hidden;
- }
-
- .svg-icon {
- margin-right: 16px;
- }
-
+#app {
+ .main-container {
+ min-height: 100%;
+ transition: margin-left 0.28s;
+ margin-left: $base-sidebar-width;
+ position: relative;
+ background: transparent;
+ }
+
+ .sidebarHide {
+ margin-left: 0 !important;
+ }
+
+ .sidebar-container {
+ transition: width 0.28s;
+ width: $base-sidebar-width !important;
+ height: 100%;
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1001;
+ overflow: hidden;
+ padding: 12px 0 16px 16px;
+ background: transparent;
+ box-shadow: none;
+
+ // reset element-ui css
+ .horizontal-collapse-transition {
+ transition: 0s width ease-in-out, 0s padding-left ease-in-out,
+ 0s padding-right ease-in-out;
+ }
+
+ .scrollbar-wrapper {
+ overflow-x: hidden !important;
+ }
+
+ .el-scrollbar__bar.is-vertical {
+ right: 0px;
+ }
+
+ .el-scrollbar {
+ height: 100%;
+ }
+
+ &.has-logo {
+ .el-scrollbar {
+ height: calc(100% - 72px);
+ margin-top: 10px;
+ }
+ }
+
+ .is-horizontal {
+ display: none;
+ }
+
+ a {
+ display: inline-block;
+ width: 100%;
+ overflow: hidden;
+ }
+
+ .svg-icon {
+ margin-right: 16px;
+ }
+
.el-menu {
border: none;
height: 100%;
@@ -75,18 +74,18 @@
backdrop-filter: blur(18px);
box-shadow: var(--shadow-sm);
}
-
- .el-menu-item,
- .menu-title {
- overflow: hidden !important;
- text-overflow: ellipsis !important;
- white-space: nowrap !important;
- }
-
- .el-menu-item .el-menu-tooltip__trigger {
- display: inline-block !important;
- }
-
+
+ .el-menu-item,
+ .menu-title {
+ overflow: hidden !important;
+ text-overflow: ellipsis !important;
+ white-space: nowrap !important;
+ }
+
+ .el-menu-item .el-menu-tooltip__trigger {
+ display: inline-block !important;
+ }
+
// menu hover
.submenu-title-noDropdown,
.el-sub-menu__title {
@@ -95,17 +94,33 @@
border-radius: 14px;
}
}
- & .theme-light .is-active > .el-sub-menu__title {
- color: var(--current-color) !important;
- }
-
+
+ // 鎵�鏈夊瓙鑿滃崟鏍囬锛屼娇鐢� flex 甯冨眬璁╃澶村拰鏂囧瓧鍦ㄤ竴鎺�
+ .el-sub-menu__title {
+ padding-right: 10px !important;
+ display: flex !important;
+ align-items: center !important;
+ line-height: normal !important;
+ }
+
+ // 椤剁骇瀛愯彍鍗曟爣棰�
+ & > .el-menu > .el-sub-menu > .el-sub-menu__title {
+ padding-right: 10px !important;
+ display: flex !important;
+ align-items: center !important;
+ line-height: normal !important;
+ }
+ & .theme-light .is-active > .el-sub-menu__title {
+ color: var(--current-color) !important;
+ }
+
& .nest-menu .el-sub-menu > .el-sub-menu__title,
& .el-sub-menu .el-menu-item {
min-width: 0 !important;
margin: 0 12px 6px;
width: calc(100% - 24px);
padding-left: 8px !important;
- padding-right: 8px !important;
+ padding-right: 24px !important;
box-sizing: border-box;
&:hover {
@@ -116,7 +131,7 @@
border-radius: 14px;
}
}
-
+
& .theme-light .nest-menu .el-sub-menu > .el-sub-menu__title,
& .theme-light .el-sub-menu .el-menu-item {
//background-color: transparent;
@@ -127,7 +142,7 @@
}
}
}
-
+
.hideSidebar {
.sidebar-container {
width: 68px !important;
@@ -138,7 +153,7 @@
.main-container {
margin-left: 84px;
}
-
+
.submenu-title-noDropdown {
padding: 0 !important;
position: relative;
@@ -225,60 +240,56 @@
width: 0;
overflow: hidden;
visibility: hidden;
- display: inline-block;
- }
- & > i {
- height: 0;
- width: 0;
- overflow: hidden;
- visibility: hidden;
- display: inline-block;
+ display: inline-block;
+ }
+ & > i.el-sub-menu__icon-arrow {
+ display: none;
}
}
}
}
}
-
- .el-menu--collapse .el-menu .el-sub-menu {
- min-width: $base-sidebar-width !important;
- }
-
- // mobile responsive
- .mobile {
- .main-container {
- margin-left: 0px;
- }
-
- .sidebar-container {
- transition: transform 0.28s;
- width: $base-sidebar-width !important;
- }
-
- &.hideSidebar {
- .sidebar-container {
- pointer-events: none;
- transition-duration: 0.3s;
- transform: translate3d(-$base-sidebar-width, 0, 0);
- }
- }
- }
-
- .withoutAnimation {
- .main-container,
- .sidebar-container {
- transition: none;
- }
- }
-}
-
-// when menu collapsed
-.el-menu--vertical {
- & > .el-menu {
- .svg-icon {
- margin-right: 16px;
- }
- }
-
+
+ .el-menu--collapse .el-menu .el-sub-menu {
+ min-width: $base-sidebar-width !important;
+ }
+
+ // mobile responsive
+ .mobile {
+ .main-container {
+ margin-left: 0px;
+ }
+
+ .sidebar-container {
+ transition: transform 0.28s;
+ width: $base-sidebar-width !important;
+ }
+
+ &.hideSidebar {
+ .sidebar-container {
+ pointer-events: none;
+ transition-duration: 0.3s;
+ transform: translate3d(-$base-sidebar-width, 0, 0);
+ }
+ }
+ }
+
+ .withoutAnimation {
+ .main-container,
+ .sidebar-container {
+ transition: none;
+ }
+ }
+}
+
+// when menu collapsed
+.el-menu--vertical {
+ & > .el-menu {
+ .svg-icon {
+ margin-right: 16px;
+ }
+ }
+
.nest-menu .el-sub-menu > .el-sub-menu__title,
.el-menu-item {
min-width: 0 !important;
@@ -297,27 +308,27 @@
border-radius: 14px;
}
}
-
- // the scroll bar appears when the sub-menu is too long
- > .el-menu--popup {
- max-height: 100vh;
- overflow-y: auto;
- padding: 8px;
- border-radius: 18px;
- border: 1px solid var(--surface-border);
- box-shadow: var(--shadow-md);
-
- &::-webkit-scrollbar-track-piece {
- background: #dfe7e1;
- }
-
- &::-webkit-scrollbar {
- width: 6px;
- }
-
- &::-webkit-scrollbar-thumb {
- background: #9aa79e;
- border-radius: 20px;
- }
- }
-}
+
+ // the scroll bar appears when the sub-menu is too long
+ > .el-menu--popup {
+ max-height: 100vh;
+ overflow-y: auto;
+ padding: 8px;
+ border-radius: 18px;
+ border: 1px solid var(--surface-border);
+ box-shadow: var(--shadow-md);
+
+ &::-webkit-scrollbar-track-piece {
+ background: #dfe7e1;
+ }
+
+ &::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #9aa79e;
+ border-radius: 20px;
+ }
+ }
+}
diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue
index f395d95..955a8d4 100644
--- a/src/layout/components/Sidebar/SidebarItem.vue
+++ b/src/layout/components/Sidebar/SidebarItem.vue
@@ -9,7 +9,7 @@
</app-link>
</template>
- <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported>
+ <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)">
<template v-if="item.meta" #title>
<svg-icon :icon-class="item.meta && item.meta.icon" />
<span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
index 83d3026..fd73024 100644
--- a/src/layout/components/Sidebar/index.vue
+++ b/src/layout/components/Sidebar/index.vue
@@ -99,6 +99,10 @@
.el-sub-menu__title {
color: v-bind(getMenuTextColor);
+ padding-right: 10px !important;
+ display: flex !important;
+ align-items: center !important;
+ line-height: normal !important;
}
:deep(.el-sub-menu.is-active > .el-sub-menu__title) {
@@ -111,8 +115,10 @@
padding-left: 10px !important;
padding-right: 10px !important;
box-sizing: border-box;
- overflow: hidden;
background-clip: padding-box;
+ display: flex !important;
+ align-items: center !important;
+ line-height: normal !important;
}
:deep(.el-menu-item.is-active) {
@@ -137,6 +143,43 @@
:deep(.el-menu-item:hover) {
border-radius: 14px;
}
+
+ /* 纭繚瀛愯彍鍗曠澶存樉绀� - 浣跨敤 flex 甯冨眬璁╃澶村拰鏂囧瓧鍦ㄤ竴鎺� */
+ :deep(.el-sub-menu .el-sub-menu__title) {
+ display: flex !important;
+ align-items: center !important;
+ justify-content: flex-start !important;
+ line-height: normal !important;
+ }
+
+ :deep(.el-sub-menu .el-sub-menu__title .el-sub-menu__icon-arrow) {
+ position: static !important;
+ display: inline-flex !important;
+ visibility: visible !important;
+ width: auto !important;
+ height: auto !important;
+ overflow: visible !important;
+ margin-left: auto !important;
+ margin-right: 0 !important;
+ order: 999 !important;
+ align-self: center !important;
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+ transform: none !important;
+ top: auto !important;
+ }
+
+ /* 纭繚涓�绾ц彍鍗曠澶存樉绀� */
+ :deep(> .el-menu > .el-sub-menu > .el-sub-menu__title .el-sub-menu__icon-arrow) {
+ display: inline-flex !important;
+ visibility: visible !important;
+ }
+
+ /* 纭繚浜岀骇鑿滃崟绠ご鏄剧ず */
+ :deep(.nest-menu .el-sub-menu > .el-sub-menu__title .el-sub-menu__icon-arrow) {
+ display: inline-flex !important;
+ visibility: visible !important;
+ }
}
}
</style>
diff --git a/src/views/collaborativeApproval/approvalManagement/index.vue b/src/views/collaborativeApproval/approvalManagement/index.vue
index 1eb20c8..aaf3a43 100644
--- a/src/views/collaborativeApproval/approvalManagement/index.vue
+++ b/src/views/collaborativeApproval/approvalManagement/index.vue
@@ -186,8 +186,10 @@
import {
Plus, ArrowLeft, Delete, Check, RefreshLeft, Setting,
Suitcase, Calendar, Location, Money, ShoppingCart, DocumentChecked,
- Van, ArrowRight, User, InfoFilled
+ Van, ArrowRight, User, InfoFilled, Sell
} from '@element-plus/icons-vue';
+import { getApproveProcessConfigNodeList, addApproveProcessConfigNode } from '@/api/collaborativeApproval/approvalManagement';
+import { userListNoPage } from '@/api/system/user';
// 褰撳墠閫変腑鐨勬爣绛鹃〉
const activeTab = ref('1');
@@ -201,6 +203,7 @@
{ value: '5', label: '閲囪喘瀹℃壒', icon: 'ShoppingCart', color: '#909399' },
{ value: '6', label: '鎶ヤ环瀹℃壒', icon: 'DocumentChecked', color: '#9B59B6' },
{ value: '7', label: '鍙戣揣瀹℃壒', icon: 'Van', color: '#1ABC9C' },
+ { value: '10', label: '閿�鍞鎵�', icon: 'Sell', color: '#FF6B6B' },
];
// 瀹℃壒绫诲瀷鍚嶇О鏄犲皠
@@ -212,6 +215,7 @@
5: '閲囪喘瀹℃壒',
6: '鎶ヤ环瀹℃壒',
7: '鍙戣揣瀹℃壒',
+ 10: '閿�鍞鎵�',
};
// 瀹℃壒绫诲瀷鍥炬爣鏄犲皠
@@ -223,6 +227,7 @@
5: 'ShoppingCart',
6: 'DocumentChecked',
7: 'Van',
+ 10: 'Sell',
};
// 瀹℃壒绫诲瀷棰滆壊鏄犲皠
@@ -234,6 +239,7 @@
5: '#909399',
6: '#9B59B6',
7: '#1ABC9C',
+ 10: '#FF6B6B',
};
// 澶村儚棰滆壊姹�
@@ -271,44 +277,8 @@
return texts[index] || `绗�${index + 1}绾;
};
-// 鑾峰彇瀹℃壒浜烘暟閲�
-const getApproverCount = (typeValue) => {
- const type = Number(typeValue);
- const data = mockConfigData[type] || [];
- return data.length;
-};
-
-// 妯℃嫙鐢ㄦ埛鍒楄〃鏁版嵁
-const userList = ref([
- { userId: 1, nickName: '寮犱笁' },
- { userId: 2, nickName: '鏉庡洓' },
- { userId: 3, nickName: '鐜嬩簲' },
- { userId: 4, nickName: '璧靛叚' },
- { userId: 5, nickName: '瀛欎竷' },
- { userId: 6, nickName: '鍛ㄥ叓' },
- { userId: 7, nickName: '鍚翠節' },
- { userId: 8, nickName: '閮戝崄' },
-]);
-
-// 妯℃嫙瀹℃壒閰嶇疆鏁版嵁瀛樺偍锛堟寜瀹℃壒绫诲瀷鍒嗙被锛�
-const mockConfigData = {
- 1: [
- { id: 1, approveType: 1, approverId: 1, approverName: '寮犱笁', sortOrder: 1 },
- { id: 2, approveType: 1, approverId: 2, approverName: '鏉庡洓', sortOrder: 2 },
- ],
- 2: [
- { id: 3, approveType: 2, approverId: 3, approverName: '鐜嬩簲', sortOrder: 1 },
- ],
- 3: [],
- 4: [
- { id: 4, approveType: 4, approverId: 1, approverName: '寮犱笁', sortOrder: 1 },
- { id: 5, approveType: 4, approverId: 3, approverName: '鐜嬩簲', sortOrder: 2 },
- { id: 6, approveType: 4, approverId: 5, approverName: '瀛欎竷', sortOrder: 3 },
- ],
- 5: [],
- 6: [],
- 7: [],
-};
+// 瀹℃壒浜哄垪琛紙鐪熷疄鎺ュ彛锛�
+const userList = ref([]);
// 瀹℃壒浜哄垪琛�
const approverList = ref([]);
@@ -326,14 +296,40 @@
};
// 鍔犺浇瀹℃壒閰嶇疆鏁版嵁锛堟ā鎷燂級
-const loadData = () => {
+const loadData = async () => {
loading.value = true;
- setTimeout(() => {
- const data = mockConfigData[currentApproveType.value] || [];
- approverList.value = data.sort((a, b) => a.sortOrder - b.sortOrder);
+ try {
+ const res = await getApproveProcessConfigNodeList(currentApproveType.value);
+ const source = Array.isArray(res?.data)
+ ? res.data
+ : Array.isArray(res?.rows)
+ ? res.rows
+ : Array.isArray(res?.data?.records)
+ ? res.data.records
+ : [];
+ const data = source.map((item, index) => ({
+ ...item,
+ sortOrder: item.nodeOrder ?? item.sortOrder ?? index + 1,
+ }));
+ approverList.value = data.sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0));
originalList.value = JSON.parse(JSON.stringify(approverList.value));
+ } catch (error) {
+ approverList.value = [];
+ originalList.value = [];
+ ElMessage.error('鍔犺浇瀹℃壒閰嶇疆澶辫触');
+ } finally {
loading.value = false;
- }, 300);
+ }
+};
+
+const loadUserList = async () => {
+ try {
+ const res = await userListNoPage();
+ userList.value = Array.isArray(res?.data) ? res.data : [];
+ } catch (error) {
+ userList.value = [];
+ ElMessage.error('鍔犺浇浜哄憳鍒楄〃澶辫触');
+ }
};
// 瀹℃壒浜洪�夋嫨鍙樺寲
@@ -393,8 +389,8 @@
approverList.value[index + 1].sortOrder = index + 2;
};
-// 淇濆瓨閰嶇疆锛堟ā鎷燂級
-const handleSave = () => {
+// 淇濆瓨閰嶇疆
+const handleSave = async () => {
if (approverList.value.length === 0) {
ElMessage.warning('璇疯嚦灏戦厤缃竴涓鎵逛汉');
return;
@@ -414,17 +410,21 @@
}
saveLoading.value = true;
- setTimeout(() => {
- mockConfigData[currentApproveType.value] = approverList.value.map((item, index) => ({
- ...item,
- id: item.id || Date.now() + index,
- sortOrder: index + 1,
+ try {
+ const payload = approverList.value.map((item, index) => ({
+ approveType: currentApproveType.value,
+ nodeOrder: index + 1,
+ approverId: item.approverId,
+ approverName: item.approverName,
}));
- originalList.value = JSON.parse(JSON.stringify(mockConfigData[currentApproveType.value]));
- approverList.value = JSON.parse(JSON.stringify(originalList.value));
+ await addApproveProcessConfigNode(payload);
ElMessage.success('淇濆瓨鎴愬姛');
+ await loadData();
+ } catch (error) {
+ ElMessage.error('淇濆瓨澶辫触');
+ } finally {
saveLoading.value = false;
- }, 500);
+ }
};
// 閲嶇疆
@@ -445,8 +445,9 @@
.catch(() => {});
};
-onMounted(() => {
- loadData();
+onMounted(async () => {
+ await loadUserList();
+ await loadData();
});
</script>
diff --git a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue b/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
index 20a4ee6..1269621 100644
--- a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
+++ b/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
@@ -39,39 +39,6 @@
</el-form-item>
</el-col>
</el-row>
- <!-- 瀹℃壒浜洪�夋嫨锛堝姩鎬佽妭鐐癸級 -->
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鐢宠浜猴細" prop="approveUser">
- <el-select
- v-model="form.approveUser"
- placeholder="閫夋嫨浜哄憳"
- disabled
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐢宠鏃ユ湡锛�" prop="approveTime">
- <el-date-picker
- v-model="form.approveTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- disabled
- />
- </el-form-item>
- </el-col>
- </el-row>
</el-form>
<!-- 鎶ヤ环瀹℃壒锛氬睍绀烘姤浠疯鎯咃紙澶嶇敤閿�鍞姤浠�"鏌ョ湅璇︽儏瀵硅瘽妗�"鍐呭缁撴瀯锛� -->
@@ -228,7 +195,6 @@
updateApproveNode
} from "@/api/collaborativeApproval/approvalProcess.js";
import useUserStore from "@/store/modules/user.js";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
import { WarningFilled, Edit, Check, MoreFilled } from '@element-plus/icons-vue'
import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
import { getPurchaseByCode } from "@/api/procurementManagement/procurementLedger.js";
@@ -248,7 +214,6 @@
const formRef = ref(null);
const userStore = useUserStore()
const productOptions = ref([]);
-const userList = ref([])
const quotationLoading = ref(false)
const currentQuotation = ref({})
const purchaseLoading = ref(false)
@@ -258,9 +223,7 @@
const data = reactive({
form: {
- approveTime: "",
approveId: "",
- approveUser: "",
approveDeptId: "",
approveReason: "",
checkResult: "",
@@ -295,9 +258,6 @@
dialogFormVisible.value = true;
currentQuotation.value = {}
currentPurchase.value = {}
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
form.value = {...row}
// 绔嬪嵆娓呴櫎琛ㄥ崟楠岃瘉鐘舵�侊紙鍥犱负瀛楁鏄痙isabled鐨勶紝涓嶉渶瑕侀獙璇侊級
nextTick(() => {
diff --git a/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue b/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
index 998fa33..8328ee6 100644
--- a/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
+++ b/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
@@ -97,82 +97,7 @@
</el-form-item>
</el-col>
</el-row>
- <!-- 瀹℃壒浜洪�夋嫨锛堝姩鎬佽妭鐐癸級 -->
- <el-row>
- <el-col :span="24">
- <el-form-item>
- <template #label>
- <span>瀹℃壒浜洪�夋嫨锛�</span>
- <el-button type="primary" @click="addApproverNode" style="margin-left: 8px;">鏂板鑺傜偣</el-button>
- </template>
- <div style="display: flex; align-items: flex-end; flex-wrap: wrap;">
- <div
- v-for="(node, index) in approverNodes"
- :key="node.id"
- style="margin-right: 30px; text-align: center; margin-bottom: 10px;"
- >
- <div>
- <span>瀹℃壒浜�</span>
- 鈫�
- </div>
- <el-select
- v-model="node.userId"
- placeholder="閫夋嫨浜哄憳"
- style="width: 120px; margin-bottom: 8px;"
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- <div>
- <el-button
- type="danger"
- size="small"
- @click="removeApproverNode(index)"
- v-if="approverNodes.length > 1"
- >鍒犻櫎</el-button>
- </div>
- </div>
- </div>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="30">
- <el-col :span="12">
- <el-form-item label="鐢宠浜猴細" prop="approveUser">
- <el-select
- v-model="form.approveUser"
- placeholder="閫夋嫨浜哄憳"
- filterable
- default-first-option
- :reserve-keyword="false"
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="鐢宠鏃ユ湡锛�" prop="approveTime">
- <el-date-picker
- v-model="form.approveTime"
- type="date"
- placeholder="璇烽�夋嫨鏃ユ湡"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- </el-col>
- </el-row>
+
<el-row :gutter="30">
<el-col :span="24">
<el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
@@ -211,13 +136,10 @@
import {
delLedgerFile,
} from "@/api/salesManagement/salesLedger.js";
-import {userListNoPageByTenantId} from "@/api/system/user.js";
import { getToken } from "@/utils/auth";
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
import useUserStore from "@/store/modules/user";
-import { getCurrentDate } from "@/utils/index.js";
-import log from "@/views/monitor/job/log.vue";
const userStore = useUserStore();
const dialogFormVisible = ref(false);
@@ -231,24 +153,19 @@
});
const data = reactive({
form: {
- approveTime: "",
approveId: "",
- approveUser: "",
- approveDeptId: "",
+ approveDeptId: "",
approveDeptName: "",
approveReason: "",
checkResult: "",
tempFileIds: [],
- approverList: [], // 鏂板瀛楁锛屽瓨鍌ㄦ墍鏈夎妭鐐圭殑瀹℃壒浜篿d
startDate: "", // 璇峰亣寮�濮嬫椂闂�
endDate: "", // 璇峰亣缁撴潫鏃堕棿
price: null, // 鎶ラ攢閲戦
location: "" // 鍑哄樊鍦扮偣
},
rules: {
- approveTime: [{ required: false, message: "璇疯緭鍏�", trigger: "change" },],
approveId: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
- approveUser: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
approveDeptName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
approveReason: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
checkResult: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
@@ -268,18 +185,7 @@
}
})
-// 瀹℃壒浜鸿妭鐐圭浉鍏�
-const approverNodes = ref([
- { id: 1, userId: null }
-])
-let nextApproverId = 2
-const userList = ref([])
-function addApproverNode() {
- approverNodes.value.push({ id: nextApproverId++, userId: null })
-}
-function removeApproverNode(index) {
- approverNodes.value.splice(index, 1)
-}
+
// 澶勭悊閮ㄩ棬閫夋嫨鍙樺寲
const handleDeptChange = (deptId) => {
if (deptId) {
@@ -295,39 +201,19 @@
const openDialog = (type, row) => {
operationType.value = type;
dialogFormVisible.value = true;
- userListNoPageByTenantId().then((res) => {
- userList.value = res.data;
- });
- form.value = {}
- approverNodes.value = [
- { id: 1, userId: null }
- ]
- form.value.approveUser = userStore.id;
- form.value.approveTime = getCurrentDate();
-
+ form.value = {}
+
// 鑾峰彇褰撳墠鐢ㄦ埛淇℃伅骞惰缃儴闂↖D
form.value.approveDeptId = userStore.currentDeptId
-
+
// 鍔犺浇閮ㄩ棬閫夐」锛屽苟鍦ㄥ姞杞藉畬鎴愬悗璁剧疆閮ㄩ棬鍚嶇О
getProductOptions();
if (operationType.value === 'edit') {
fileList.value = row.commonFileList
form.value.tempFileIds = fileList.value.map(file => file.id)
- currentApproveStatus.value = row.approveStatus
+ currentApproveStatus.value = row.approveStatus
approveProcessGetInfo({id: row.approveId,approveReason: '1'}).then(res => {
- form.value = {...res.data}
- // 鍙嶆樉瀹℃壒浜�
- if (res.data && res.data.approveUserIds) {
- const userIds = res.data.approveUserIds.split(',')
- approverNodes.value = userIds.map((userId, idx) => ({
- id: idx + 1,
- userId: parseInt(userId.trim())
- }))
- nextApproverId = userIds.length + 1
- } else {
- approverNodes.value = [{ id: 1, userId: null }]
- nextApproverId = 2
- }
+ form.value = {...res.data}
})
}
}
@@ -362,15 +248,7 @@
}
// 鎻愪氦浜у搧琛ㄥ崟
const submitForm = () => {
- // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
- form.value.approveUserIds = approverNodes.value.map(node => node.userId).join(',')
form.value.approveType = props.approveType
- // 瀹℃壒浜哄繀濉牎楠�
- const hasEmptyApprover = approverNodes.value.some(node => !node.userId)
- if (hasEmptyApprover) {
- proxy.$modal.msgError("璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒")
- return
- }
// 褰� approveType 涓� 2 鏃讹紝鏍¢獙璇峰亣鏃堕棿
if (props.approveType == 2) {
if (!form.value.startDate) {
diff --git a/src/views/collaborativeApproval/approvalProcess/index.vue b/src/views/collaborativeApproval/approvalProcess/index.vue
index dba6bc1..deaf6db 100644
--- a/src/views/collaborativeApproval/approvalProcess/index.vue
+++ b/src/views/collaborativeApproval/approvalProcess/index.vue
@@ -70,7 +70,7 @@
<el-button
type="primary"
@click="openForm('add')"
- v-if="currentApproveType !== 5 && currentApproveType !== 6 && currentApproveType !== 7"
+ v-if="currentApproveType !== 5 && currentApproveType !== 6 && currentApproveType !== 7 && currentApproveType !== 10"
class="action-btn primary"
>
<el-icon><Plus /></el-icon>
@@ -84,7 +84,7 @@
type="danger"
plain
@click="handleDelete"
- v-if="currentApproveType !== 5 && currentApproveType !== 6 && currentApproveType !== 7"
+ v-if="currentApproveType !== 5 && currentApproveType !== 6 && currentApproveType !== 7 && currentApproveType !== 10"
class="action-btn danger"
>
<el-icon><Delete /></el-icon>
@@ -159,6 +159,7 @@
{ value: '5', label: '閲囪喘瀹℃壒', icon: 'ShoppingCart', color: '#909399' },
{ value: '6', label: '鎶ヤ环瀹℃壒', icon: 'DocumentChecked', color: '#9B59B6' },
{ value: '7', label: '鍙戣揣瀹℃壒', icon: 'Van', color: '#1ABC9C' },
+ { value: '10', label: '閿�鍞鎵�', icon: 'Sell', color: '#FF6B6B' },
];
// 褰撳墠瀹℃壒绫诲瀷淇℃伅
@@ -207,6 +208,7 @@
const isReimburseType = currentApproveType.value === 4; // 鎶ラ攢绠$悊
const isQuotationType = currentApproveType.value === 6; // 鎶ヤ环瀹℃壒
const isPurchaseType = currentApproveType.value === 5; // 閲囪喘瀹℃壒
+ const isSalesType = currentApproveType.value === 10; // 閿�鍞鎵�
// 鍩虹鍒楅厤缃�
const baseColumns = [
@@ -305,6 +307,7 @@
currentApproveType.value === 5 ||
currentApproveType.value === 6 ||
currentApproveType.value === 7 ||
+ currentApproveType.value === 10 ||
row.approveStatus == 2 ||
row.approveStatus == 1 ||
row.approveStatus == 4
@@ -405,6 +408,7 @@
5: "/approveProcess/exportFive",
6: "/approveProcess/exportSix",
7: "/approveProcess/exportSeven",
+ 10: "/approveProcess/exportTen",
}
const url = urlMap[type] || urlMap[0]
const nameMap = {
@@ -416,6 +420,7 @@
5: "閲囪喘鐢宠瀹℃壒琛�",
6: "鎶ヤ环瀹℃壒琛�",
7: "鍙戣揣瀹℃壒琛�",
+ 10: "閿�鍞鎵硅〃",
}
const fileName = nameMap[type] || nameMap[0]
proxy.download(url, {}, `${fileName}.xlsx`)
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 8a293fc..8e06d8b 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -298,50 +298,6 @@
</el-form-item>
</el-col>
</el-row>
- <el-row :gutter="30">
- <el-col :span="24">
- <el-form-item>
- <template #label>
- <div style="display: flex; align-items: center; justify-content: space-between; width: 100%;">
- <span>瀹℃壒浜洪�夋嫨锛�</span>
- <el-button type="primary" size="small" @click="addApproverNode" icon="Plus">鏂板鑺傜偣</el-button>
- </div>
- </template>
- <div class="approver-nodes-container">
- <div
- v-for="(node, index) in approverNodes"
- :key="node.id"
- class="approver-node-item"
- >
- <div class="approver-node-header">
- <span class="approver-node-label">瀹℃壒鑺傜偣 {{ index + 1 }}</span>
- <el-button
- v-if="approverNodes.length > 1"
- type="danger"
- size="small"
- text
- @click="removeApproverNode(index)"
- icon="Delete"
- >鍒犻櫎</el-button>
- </div>
- <el-select
- v-model="node.userId"
- placeholder="璇烽�夋嫨瀹℃壒浜�"
- filterable
- style="width: 100%;"
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- </div>
- </div>
- </el-form-item>
- </el-col>
- </el-row>
<el-row>
<el-form-item label="浜у搧淇℃伅锛�"
prop="entryDate">
@@ -760,16 +716,6 @@
const userStore = useUserStore();
- // 瀹℃壒浜鸿妭鐐癸紙浠块攢鍞彴璐﹀彂璐у鎵逛汉锛�
- const approverNodes = ref([{ id: 1, userId: null }]);
- let nextApproverId = 2;
- const addApproverNode = () => {
- approverNodes.value.push({ id: nextApproverId++, userId: null });
- };
- const removeApproverNode = (index) => {
- approverNodes.value.splice(index, 1);
- };
-
// 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
const approvalStatusText = {
1: "寰呭鏍�",
@@ -1121,19 +1067,12 @@
}
try {
- // 鑾峰彇瀹℃壒浜篒D瀛楃涓�
- const approveUserIds = approverNodes.value
- .filter(node => node.userId)
- .map(node => node.userId)
- .join(",");
-
let params = {
productData: proxy.HaveJson(productData.value),
supplierId: form.value.supplierId,
paymentMethod: form.value.paymentMethod,
recorderId: form.value.recorderId,
projectName: form.value.projectName,
- approveUserIds: approveUserIds,
templateName: templateName.value.trim(),
};
console.log("template params ===>", params, "currentTemplateId:", currentTemplateId.value);
@@ -1284,9 +1223,6 @@
templateName.value = "";
filterInputValue.value = "";
isTemplateNameDuplicate.value = false;
- // 閲嶇疆瀹℃壒浜鸿妭鐐癸紙榛樿涓�涓┖鑺傜偣锛�
- approverNodes.value = [{ id: 1, userId: null }];
- nextApproverId = 2;
try {
// 骞惰鍔犺浇鍩虹鏁版嵁
const [userRes, salesRes, supplierRes] = await Promise.all([
@@ -1325,15 +1261,6 @@
form.value = { ...purchaseRes };
productData.value = purchaseRes.productData || [];
fileList.value = purchaseRes.salesLedgerFiles || [];
- // 濡傛灉缂栬緫鏃舵湁瀹℃壒浜猴紝瑙f瀽瀹℃壒浜篒D瀛楃涓插苟璁剧疆鍒拌妭鐐逛腑
- if (purchaseRes.approveUserIds) {
- const approverIds = purchaseRes.approveUserIds.split(",");
- approverNodes.value = approverIds.map((id, index) => ({
- id: index + 1,
- userId: Number(id)
- }));
- nextApproverId = approverIds.length + 1;
- }
} catch (error) {
console.error("鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:", error);
proxy.$modal.msgError("鍔犺浇鏁版嵁澶辫触");
@@ -1402,14 +1329,6 @@
const submitForm = () => {
proxy.$refs["formRef"].validate(valid => {
if (valid) {
- // 瀹℃壒浜哄繀濉牎楠岋紙鎵�鏈夎妭鐐归兘瑕侀�変汉锛�
- const hasEmptyApprover = approverNodes.value.some(node => !node.userId);
- if (hasEmptyApprover) {
- proxy.$modal.msgError("璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒");
- return;
- }
- const approveUserIds = approverNodes.value.map(node => node.userId).join(",");
-
if (productData.value.length > 0) {
// 鏂板鏃讹紝闇�瑕佷粠姣忎釜浜у搧瀵硅薄涓垹闄� id 瀛楁
let processedProductData = productData.value;
@@ -1430,7 +1349,6 @@
}
form.value.tempFileIds = tempFileIds;
form.value.type = 2;
- form.value.approveUserIds = approveUserIds;
// 濡傛灉salesLedgerId涓虹┖锛屽垯涓嶄紶閫抯alesContractNo
if (!form.value.salesLedgerId) {
@@ -1454,9 +1372,6 @@
// 鍏抽棴寮规
const closeDia = () => {
proxy.resetForm("formRef");
- // 閲嶇疆瀹℃壒浜鸿妭鐐癸紙榛樿涓�涓┖鑺傜偣锛�
- approverNodes.value = [{ id: 1, userId: null }];
- nextApproverId = 2;
dialogFormVisible.value = false;
};
// 鎵撳紑浜у搧寮规
diff --git a/src/views/productionManagement/processRoute/Edit.vue b/src/views/productionManagement/processRoute/Edit.vue
index 0c0fe0f..f84719b 100644
--- a/src/views/productionManagement/processRoute/Edit.vue
+++ b/src/views/productionManagement/processRoute/Edit.vue
@@ -3,7 +3,7 @@
<el-dialog
v-model="isShow"
title="缂栬緫宸ヨ壓璺嚎"
- width="400"
+ width="800"
@close="closeModal"
>
<el-form label-width="140px" :model="formState" label-position="top" ref="formRef">
@@ -25,35 +25,54 @@
</el-button>
</el-form-item>
- <el-form-item
- label="BOM"
- prop="bomId"
- :rules="[
- {
- required: true,
- message: '璇烽�夋嫨BOM',
- trigger: 'change',
- }
- ]"
- >
- <el-select
- v-model="formState.bomId"
- placeholder="璇烽�夋嫨BOM"
- clearable
- :disabled="!formState.productModelId || bomOptions.length === 0"
- style="width: 100%"
- >
- <el-option
- v-for="item in bomOptions"
- :key="item.id"
- :label="item.bomNo || `BOM-${item.id}`"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
-
<el-form-item label="澶囨敞" prop="description">
<el-input v-model="formState.description" type="textarea" />
+ </el-form-item>
+
+ <!-- 宸ュ簭閰嶇疆 -->
+ <el-form-item label="宸ュ簭閰嶇疆" required>
+ <el-table :data="formState.processRouteItemList" border size="small" style="width: 100%">
+ <el-table-column label="閮ㄤ欢" min-width="200">
+ <template #default="{ row }">
+ <el-select
+ v-model="row.processId"
+ placeholder="璇烽�夋嫨閮ㄤ欢"
+ clearable
+ filterable
+ style="width: 100%"
+ >
+ <el-option
+ v-for="process in processOptions"
+ :key="process.id"
+ :label="formatProcessOptionLabel(process)"
+ :value="process.id"
+ />
+ </el-select>
+ </template>
+ </el-table-column>
+ <el-table-column label="璐ㄦ" width="80" align="center">
+ <template #default="{ row }">
+ <el-switch v-model="row.isQuality" :active-value="true" inactive-value="false"/>
+ </template>
+ </el-table-column>
+ <el-table-column label="澶囨敞" min-width="150">
+ <template #default="{ row }">
+ <el-input v-model="row.remark" placeholder="璇疯緭鍏ュ娉�" size="small"/>
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="60" align="center">
+ <template #default="{ $index }">
+ <el-button type="danger" link size="small" @click="removeProcessItem($index)">
+ <el-icon><Delete /></el-icon>
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ <div style="margin-top: 8px;">
+ <el-button type="primary" link size="small" @click="addProcessItem">
+ <el-icon><Plus /></el-icon> 娣诲姞宸ュ簭
+ </el-button>
+ </div>
</el-form-item>
</el-form>
@@ -76,7 +95,7 @@
<script setup>
import {ref, computed, getCurrentInstance, onMounted, nextTick, watch} from "vue";
import {update} from "@/api/productionManagement/processRoute.js";
-import {getByModel} from "@/api/productionManagement/productBom.js";
+import {processList} from "@/api/productionManagement/productionProcess.js";
import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
const props = defineProps({
@@ -99,8 +118,8 @@
productModelId: undefined,
productName: "",
productModelName: "",
- bomId: undefined,
description: '',
+ processRouteItemList: [],
});
const isShow = computed({
@@ -113,9 +132,49 @@
});
const showProductSelectDialog = ref(false);
-const bomOptions = ref([]);
+const processOptions = ref([]);
let { proxy } = getCurrentInstance()
+
+// 鑾峰彇宸ュ簭鍒楄〃
+const getProcessOptions = async () => {
+ try {
+ const res = await processList();
+ processOptions.value = res.data || [];
+ } catch (error) {
+ console.error("鑾峰彇宸ュ簭鍒楄〃澶辫触", error);
+ processOptions.value = [];
+ }
+};
+
+// 鏍煎紡鍖栧伐搴忛�夐」鏍囩
+const formatProcessOptionLabel = (process) => {
+ if (!process) return '';
+ const typeMap = {
+ 1: '鍔犲伐',
+ 2: '鍒澘鍐疯姱鍒朵綔',
+ 3: '绠¤矾缁勫',
+ 4: '缃愪綋杩炴帴鍙婅皟璇�',
+ 5: '娴嬭瘯鎵撳帇',
+ 6: '鍏朵粬',
+ };
+ const typeText = typeMap[process.type] || '';
+ return `${process.name} ${process.no ? '(' + process.no + ')' : ''} ${typeText ? '[' + typeText + ']' : ''}`;
+};
+
+// 娣诲姞宸ュ簭
+const addProcessItem = () => {
+ formState.value.processRouteItemList.push({
+ processId: undefined,
+ isQuality: false,
+ remark: '',
+ });
+};
+
+// 绉婚櫎宸ュ簭
+const removeProcessItem = (index) => {
+ formState.value.processRouteItemList.splice(index, 1);
+};
const closeModal = () => {
isShow.value = false;
@@ -131,90 +190,42 @@
productName: props.record.productName || "",
// 娉ㄦ剰锛歳ecord涓殑瀛楁鏄痬odel锛岄渶瑕佹槧灏勫埌productModelName
productModelName: props.record.model || props.record.productModelName || "",
- bomId: props.record.bomId,
description: props.record.description || '',
+ processRouteItemList: props.record.processRouteItemList || [],
};
- // 濡傛灉鏈変骇鍝佸瀷鍙稩D锛屽姞杞紹OM鍒楄〃
- if (props.record.productModelId) {
- loadBomList(props.record.productModelId);
- }
}
}
-
-// 鍔犺浇BOM鍒楄〃
-const loadBomList = async (productModelId) => {
- if (!productModelId) {
- bomOptions.value = [];
- return;
- }
- try {
- const res = await getByModel(productModelId);
- // 澶勭悊杩斿洖鐨凚OM鏁版嵁锛氬彲鑳芥槸鏁扮粍銆佸璞℃垨鍖呭惈data瀛楁
- let bomList = [];
- if (Array.isArray(res)) {
- bomList = res;
- } else if (res && res.data) {
- bomList = Array.isArray(res.data) ? res.data : [res.data];
- } else if (res && typeof res === 'object') {
- bomList = [res];
- }
- bomOptions.value = bomList;
- } catch (error) {
- console.error("鍔犺浇BOM鍒楄〃澶辫触锛�", error);
- bomOptions.value = [];
- }
-};
// 浜у搧閫夋嫨澶勭悊
const handleProductSelect = async (products) => {
if (products && products.length > 0) {
const product = products[0];
- // 鍏堟煡璇OM鍒楄〃锛堝繀閫夛級
- try {
- const res = await getByModel(product.id);
- // 澶勭悊杩斿洖鐨凚OM鏁版嵁锛氬彲鑳芥槸鏁扮粍銆佸璞℃垨鍖呭惈data瀛楁
- let bomList = [];
- if (Array.isArray(res)) {
- bomList = res;
- } else if (res && res.data) {
- bomList = Array.isArray(res.data) ? res.data : [res.data];
- } else if (res && typeof res === 'object') {
- bomList = [res];
- }
-
- if (bomList.length > 0) {
- formState.value.productModelId = product.id;
- formState.value.productName = product.productName;
- formState.value.productModelName = product.model;
- // 濡傛灉褰撳墠閫夋嫨鐨凚OM涓嶅湪鏂板垪琛ㄤ腑锛屽垯閲嶇疆BOM閫夋嫨
- const currentBomExists = bomList.some(bom => bom.id === formState.value.bomId);
- if (!currentBomExists) {
- formState.value.bomId = undefined;
- }
- bomOptions.value = bomList;
- showProductSelectDialog.value = false;
- // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
- proxy.$refs["formRef"]?.validateField('productModelId');
- } else {
- proxy.$modal.msgError("璇ヤ骇鍝佹病鏈塀OM锛岃鍏堝垱寤築OM");
- }
- } catch (error) {
- // 濡傛灉鎺ュ彛杩斿洖404鎴栧叾浠栭敊璇紝璇存槑娌℃湁BOM
- proxy.$modal.msgError("璇ヤ骇鍝佹病鏈塀OM锛岃鍏堝垱寤築OM");
- }
+ formState.value.productModelId = product.id;
+ formState.value.productName = product.productName;
+ formState.value.productModelName = product.model;
+ showProductSelectDialog.value = false;
+ // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+ proxy.$refs["formRef"]?.validateField('productModelId');
}
};
const handleSubmit = () => {
proxy.$refs["formRef"].validate(valid => {
if (valid) {
- // 楠岃瘉鏄惁閫夋嫨浜嗕骇鍝佸拰BOM
+ // 楠岃瘉鏄惁閫夋嫨浜嗕骇鍝�
if (!formState.value.productModelId) {
proxy.$modal.msgError("璇烽�夋嫨浜у搧");
return;
}
- if (!formState.value.bomId) {
- proxy.$modal.msgError("璇烽�夋嫨BOM");
+ // 楠岃瘉鏄惁閰嶇疆浜嗗伐搴�
+ if (!formState.value.processRouteItemList || formState.value.processRouteItemList.length === 0) {
+ proxy.$modal.msgError("璇疯嚦灏戦厤缃竴涓伐搴�");
+ return;
+ }
+ // 楠岃瘉鎵�鏈夊伐搴忔槸鍚﹂�夋嫨浜嗛儴浠�
+ const invalidItem = formState.value.processRouteItemList.find(item => !item.processId);
+ if (invalidItem) {
+ proxy.$modal.msgError("璇烽�夋嫨鎵�鏈夊伐搴忕殑閮ㄤ欢");
return;
}
update(formState.value).then(res => {
@@ -245,6 +256,7 @@
}, { immediate: true });
onMounted(() => {
+ getProcessOptions();
if (props.visible && props.record) {
setFormData();
}
diff --git a/src/views/productionManagement/processRoute/New.vue b/src/views/productionManagement/processRoute/New.vue
index 62c6873..f9893a1 100644
--- a/src/views/productionManagement/processRoute/New.vue
+++ b/src/views/productionManagement/processRoute/New.vue
@@ -25,33 +25,6 @@
</el-button>
</el-form-item>
- <el-form-item
- label="BOM"
- prop="bomId"
- :rules="[
- {
- required: true,
- message: '璇烽�夋嫨BOM',
- trigger: 'change',
- }
- ]"
- >
- <el-select
- v-model="formState.bomId"
- placeholder="璇烽�夋嫨BOM"
- clearable
- :disabled="!formState.productModelId || bomOptions.length === 0"
- style="width: 100%"
- >
- <el-option
- v-for="item in bomOptions"
- :key="item.id"
- :label="item.bomNo || `BOM-${item.id}`"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
-
<el-form-item label="澶囨敞" prop="description">
<el-input v-model="formState.description" type="textarea" />
</el-form-item>
@@ -76,7 +49,6 @@
<script setup>
import {ref, computed, getCurrentInstance} from "vue";
import {add} from "@/api/productionManagement/processRoute.js";
-import {getByModel} from "@/api/productionManagement/productBom.js";
import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
const props = defineProps({
@@ -94,7 +66,6 @@
productModelId: undefined,
productName: "",
productModelName: "",
- bomId: undefined,
description: '',
});
@@ -108,7 +79,6 @@
});
const showProductSelectDialog = ref(false);
-const bomOptions = ref([]);
let { proxy } = getCurrentInstance()
@@ -119,10 +89,8 @@
productModelId: undefined,
productName: "",
productModelName: "",
- bomId: undefined,
description: '',
};
- bomOptions.value = [];
isShow.value = false;
};
@@ -130,48 +98,21 @@
const handleProductSelect = async (products) => {
if (products && products.length > 0) {
const product = products[0];
- // 鍏堟煡璇OM鍒楄〃锛堝繀閫夛級
- try {
- const res = await getByModel(product.id);
- // 澶勭悊杩斿洖鐨凚OM鏁版嵁锛氬彲鑳芥槸鏁扮粍銆佸璞℃垨鍖呭惈data瀛楁
- let bomList = [];
- if (Array.isArray(res)) {
- bomList = res;
- } else if (res && res.data) {
- bomList = Array.isArray(res.data) ? res.data : [res.data];
- } else if (res && typeof res === 'object') {
- bomList = [res];
- }
-
- if (bomList.length > 0) {
- formState.value.productModelId = product.id;
- formState.value.productName = product.productName;
- formState.value.productModelName = product.model;
- formState.value.bomId = undefined; // 閲嶇疆BOM閫夋嫨
- bomOptions.value = bomList;
- showProductSelectDialog.value = false;
- // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
- proxy.$refs["formRef"]?.validateField('productModelId');
- } else {
- proxy.$modal.msgError("璇ヤ骇鍝佹病鏈塀OM锛岃鍏堝垱寤築OM");
- }
- } catch (error) {
- // 濡傛灉鎺ュ彛杩斿洖404鎴栧叾浠栭敊璇紝璇存槑娌℃湁BOM
- proxy.$modal.msgError("璇ヤ骇鍝佹病鏈塀OM锛岃鍏堝垱寤築OM");
- }
+ formState.value.productModelId = product.id;
+ formState.value.productName = product.productName;
+ formState.value.productModelName = product.model;
+ showProductSelectDialog.value = false;
+ // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+ proxy.$refs["formRef"]?.validateField('productModelId');
}
};
const handleSubmit = () => {
proxy.$refs["formRef"].validate(valid => {
if (valid) {
- // 楠岃瘉鏄惁閫夋嫨浜嗕骇鍝佸拰BOM
+ // 楠岃瘉鏄惁閫夋嫨浜嗕骇鍝�
if (!formState.value.productModelId) {
proxy.$modal.msgError("璇烽�夋嫨浜у搧");
- return;
- }
- if (!formState.value.bomId) {
- proxy.$modal.msgError("璇烽�夋嫨BOM");
return;
}
add(formState.value).then(res => {
@@ -185,10 +126,11 @@
})
};
-
defineExpose({
closeModal,
handleSubmit,
isShow,
});
</script>
+
+
diff --git a/src/views/productionManagement/processRoute/processRouteItem/index.vue b/src/views/productionManagement/processRoute/processRouteItem/index.vue
index c2c24b4..398403a 100644
--- a/src/views/productionManagement/processRoute/processRouteItem/index.vue
+++ b/src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -50,7 +50,7 @@
<!-- 琛ㄦ牸瑙嗗浘 -->
<div v-if="viewMode === 'table'" class="section-header">
- <div class="section-title">浜у搧閮ㄤ欢鍒楄〃</div>
+ <div class="section-title">宸ュ簭鍒楄〃</div>
<div class="section-actions">
<el-button
icon="Grid"
@@ -74,14 +74,9 @@
class="lims-table"
>
<el-table-column align="center" label="搴忓彿" width="60" type="index" />
- <el-table-column label="浜у搧鍚嶇О" prop="name" min-width="140" show-overflow-tooltip>
+ <el-table-column label="閮ㄤ欢鍚嶇О" prop="name" min-width="140" show-overflow-tooltip>
<template #default="scope">
{{ getProcessField(scope.row, 'name') }}
- </template>
- </el-table-column>
- <el-table-column label="浜у搧瑙勬牸" prop="productModel" min-width="120" show-overflow-tooltip>
- <template #default="scope">
- {{ getProcessField(scope.row, 'productModel') }}
</template>
</el-table-column>
<el-table-column label="閮ㄤ欢缂栧彿" prop="no" width="120" show-overflow-tooltip>
@@ -92,6 +87,16 @@
<el-table-column label="閮ㄤ欢绫诲瀷" prop="typeText" width="120" show-overflow-tooltip>
<template #default="scope">
{{ getProcessTypeText(getProcessRaw(scope.row)?.type) || '-' }}
+ </template>
+ </el-table-column>
+ <el-table-column label="浜у搧鍚嶇О" prop="productName" min-width="140" show-overflow-tooltip>
+ <template #default="scope">
+ {{ scope.row.productName || getProcessField(scope.row, 'productName') }}
+ </template>
+ </el-table-column>
+ <el-table-column label="浜у搧瑙勬牸" prop="productModel" min-width="120" show-overflow-tooltip>
+ <template #default="scope">
+ {{ scope.row.model || getProcessField(scope.row, 'productModel') }}
</template>
</el-table-column>
<el-table-column label="璁″垝宸ユ椂(灏忔椂)" prop="salaryQuota" width="130" align="center">
@@ -130,7 +135,7 @@
<!-- 鍗$墖瑙嗗浘 -->
<template v-else>
<div class="section-header">
- <div class="section-title">宸ヨ壓璺嚎椤圭洰鍒楄〃</div>
+ <div class="section-title">宸ュ簭鍒楄〃</div>
<div class="section-actions">
<el-button
icon="Menu"
@@ -162,7 +167,8 @@
<!-- 涓庡伐搴忎富琛ㄤ竴鑷寸殑绠�瑕佷俊鎭� -->
<div class="card-content">
<div class="product-info">
- <div class="product-name">{{ getProcessField(item, 'productModel') }}</div>
+ <div class="product-name">{{ item.productName || getProcessField(item, 'productName') }}</div>
+ <div class="product-model">{{ item.model || getProcessField(item, 'productModel') }}</div>
<div v-if="getProcessRaw(item)?.no" class="product-model">缂栧彿 {{ getProcessRaw(item)?.no }}</div>
<div v-if="getProcessTypeText(getProcessRaw(item)?.type)" class="product-model">
{{ getProcessTypeText(getProcessRaw(item)?.type) }}
@@ -184,7 +190,7 @@
<!-- 鏂板/缂栬緫寮圭獥锛堝竷灞�銆佸瓧娈典笌宸ュ簭/閮ㄤ欢椤� New銆丒dit 涓�鑷达紱鎻愪氦鍙傛暟浠嶄负鍘熸帴鍙e瓧娈碉級 -->
<el-dialog
v-model="dialogVisible"
- :title="operationType === 'add' ? '鏂板宸ヨ壓璺嚎椤圭洰' : '缂栬緫宸ヨ壓璺嚎椤圭洰'"
+ :title="operationType === 'add' ? '鏂板宸ュ簭' : '缂栬緫宸ュ簭'"
width="760"
@close="closeDialog"
>
@@ -322,7 +328,7 @@
const submitLoading = ref(false);
const cardsContainer = ref(null);
const tableRef = ref(null);
-const viewMode = ref('table'); // table | card
+const viewMode = ref('card'); // table | card
const routeInfo = ref({
processRouteCode: '',
productName: '',
diff --git a/src/views/productionManagement/productionOrder/New.vue b/src/views/productionManagement/productionOrder/New.vue
index c6b1a2c..656d017 100644
--- a/src/views/productionManagement/productionOrder/New.vue
+++ b/src/views/productionManagement/productionOrder/New.vue
@@ -37,7 +37,7 @@
<el-input v-model="formState.unit" disabled />
</el-form-item>
- <!-- <el-form-item label="宸ヨ壓璺嚎">
+ <el-form-item label="宸ヨ壓璺嚎">
<el-select v-model="formState.routeId"
placeholder="璇烽�夋嫨宸ヨ壓璺嚎"
style="width: 100%;"
@@ -47,7 +47,7 @@
:label="`${item.processRouteCode || ''}`"
:value="item.id" />
</el-select>
- </el-form-item> -->
+ </el-form-item>
<el-form-item
label="闇�姹傛暟閲�"
diff --git a/src/views/productionManagement/productionProcess/Edit.vue b/src/views/productionManagement/productionProcess/Edit.vue
index b3ccddc..38a6665 100644
--- a/src/views/productionManagement/productionProcess/Edit.vue
+++ b/src/views/productionManagement/productionProcess/Edit.vue
@@ -10,53 +10,21 @@
<el-row :gutter="16">
<el-col :span="12">
<el-form-item
- label="浜у搧鍚嶇О锛�"
- prop="productId"
+ label="閮ㄤ欢鍚嶇О"
+ prop="name"
:rules="[
{
required: true,
- message: '璇烽�夋嫨浜у搧鍚嶇О',
- },
- ]">
- <el-tree-select
- v-model="formState.productId"
- placeholder="璇烽�夋嫨浜у搧鍚嶇О"
- clearable
- filterable
- check-strictly
- :data="productCategoryOptions"
- :render-after-expand="false"
- style="width: 100%"
- @change="handleProductChange"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item
- label="浜у搧瑙勬牸锛�"
- prop="productModelId"
- :rules="[
- {
- required: true,
- message: '璇烽�夋嫨浜у搧瑙勬牸',
- },
- ]">
- <el-select v-model="formState.productModelId"
- placeholder="璇烽�夋嫨浜у搧瑙勬牸"
- clearable
- filterable
- :disabled="!formState.productId"
- style="width: 100%">
- <el-option v-for="item in modelOptions"
- :key="item.id"
- :label="item.model"
- :value="item.id" />
- </el-select>
+ message: '璇疯緭鍏ラ儴浠跺悕绉�',
+ }
+ ]"
+ >
+ <el-input v-model="formState.name" placeholder="璇疯緭鍏ラ儴浠跺悕绉�" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="閮ㄤ欢缂栧彿" prop="no">
- <el-input v-model="formState.no" />
+ <el-input v-model="formState.no" placeholder="璇疯緭鍏ラ儴浠剁紪鍙�" />
</el-form-item>
</el-col>
<el-col :span="12">
@@ -111,6 +79,25 @@
</el-form-item>
</el-col>
<el-col :span="12">
+ <el-form-item label="璁″垝鎵ц浜哄憳" prop="executorId">
+ <el-select
+ v-model="formState.executorId"
+ placeholder="璇烽�夋嫨璁″垝鎵ц浜哄憳"
+ clearable
+ filterable
+ style="width: 100%"
+ @change="handleExecutorChange"
+ >
+ <el-option
+ v-for="item in plannerOptions"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
<el-form-item label="鏄惁璐ㄦ" prop="isQuality">
<el-switch v-model="formState.isQuality" :active-value="true" inactive-value="false"/>
</el-form-item>
@@ -135,7 +122,6 @@
<script setup>
import { ref, computed, getCurrentInstance, watch, onMounted } from "vue";
import {update} from "@/api/productionManagement/productionProcess.js";
-import { modelListPage, productTreeList } from "@/api/basicData/product";
import { userListNoPageByTenantId } from "@/api/system/user.js";
const props = defineProps({
@@ -156,18 +142,16 @@
const formState = ref({
id: props.record.id,
name: props.record.name,
- productId: props.record.productId,
- productModelId: props.record.productModelId,
type: props.record.type,
no: props.record.no,
remark: props.record.remark,
salaryQuota: props.record.salaryQuota,
plannerId: props.record.plannerId,
plannerName: props.record.plannerName,
+ executorId: props.record.executorId,
+ executorName: props.record.executorName,
isQuality: props.record.isQuality,
});
-const productCategoryOptions = ref([]);
-const modelOptions = ref([]);
const plannerOptions = ref([]);
const isShow = computed({
@@ -185,14 +169,14 @@
formState.value = {
id: newRecord.id,
name: newRecord.name || '',
- productId: newRecord.productId,
- productModelId: getRecordProductModelId(newRecord),
- no: newRecord.no || '',
type: newRecord.type,
+ no: newRecord.no || '',
remark: newRecord.remark || '',
salaryQuota: newRecord.salaryQuota || '',
plannerId: newRecord.plannerId,
plannerName: newRecord.plannerName || '',
+ executorId: newRecord.executorId,
+ executorName: newRecord.executorName || '',
isQuality: props.record.isQuality,
};
}
@@ -204,17 +188,16 @@
formState.value = {
id: props.record.id,
name: props.record.name || '',
- productId: props.record.productId,
- productModelId: getRecordProductModelId(props.record),
- no: props.record.no || '',
type: props.record.type,
+ no: props.record.no || '',
remark: props.record.remark || '',
salaryQuota: props.record.salaryQuota || '',
plannerId: props.record.plannerId,
plannerName: props.record.plannerName || '',
+ executorId: props.record.executorId,
+ executorName: props.record.executorName || '',
isQuality: props.record.isQuality,
};
- getModelOptions(formState.value.productId);
}
});
@@ -231,105 +214,6 @@
return;
}
callback();
-};
-
-const convertProductTree = list => {
- return (list || []).map(item => {
- const children = convertProductTree(item.children || item.childList || []);
- return {
- ...item,
- value: item.id,
- label: item.name || item.label,
- children,
- disabled: children.length > 0,
- };
- });
-};
-
-const findNodeById = (nodes, targetId) => {
- for (const node of nodes || []) {
- if (String(node.value) === String(targetId)) {
- return node;
- }
- if (node.children && node.children.length > 0) {
- const found = findNodeById(node.children, targetId);
- if (found) return found;
- }
- }
- return null;
-};
-
-const findNodeIdByLabel = (nodes, targetLabel) => {
- for (const node of nodes || []) {
- if (node.label === targetLabel) {
- return node.value;
- }
- if (node.children && node.children.length > 0) {
- const found = findNodeIdByLabel(node.children, targetLabel);
- if (found !== null && found !== undefined) return found;
- }
- }
- return undefined;
-};
-
-function findModelIdByName(models, modelName) {
- if (!modelName) {
- return undefined;
- }
- const matched = (models || []).find(item => String(item.model) === String(modelName));
- return matched?.id;
-}
-
-function getRecordProductModelId(record) {
- if (!record) {
- return undefined;
- }
- return record.productModelId ?? record.modelId ?? record.specificationModelId ?? undefined;
-}
-
-function syncProductModelIdFromModelName() {
- if (formState.value.productModelId || modelOptions.value.length === 0) {
- return;
- }
- const modelName = props.record?.productModel || props.record?.model || props.record?.specificationModel || "";
- const matchedId = findModelIdByName(modelOptions.value, modelName);
- if (matchedId !== undefined) {
- formState.value.productModelId = matchedId;
- }
-}
-
-const getProductCategoryOptions = async () => {
- try {
- const res = await productTreeList();
- const list = Array.isArray(res) ? res : res?.data || [];
- productCategoryOptions.value = convertProductTree(list);
- if (!formState.value.productId && formState.value.name) {
- formState.value.productId = findNodeIdByLabel(productCategoryOptions.value, formState.value.name);
- }
- await getModelOptions(formState.value.productId);
- syncProductModelIdFromModelName();
- } catch (e) {
- productCategoryOptions.value = [];
- }
-};
-
-const getModelOptions = async productId => {
- if (!productId) {
- modelOptions.value = [];
- return;
- }
- try {
- const res = await modelListPage({
- id: productId,
- current: 1,
- size: 999,
- });
- const records = res?.records || res?.data?.records || [];
- modelOptions.value = records;
- syncProductModelIdFromModelName();
- } catch (e) {
- modelOptions.value = [];
- }
};
const getPlannerOptions = async () => {
@@ -350,11 +234,9 @@
formState.value.plannerName = selectedUser?.nickName || '';
};
-const handleProductChange = async value => {
- const selectedNode = findNodeById(productCategoryOptions.value, value);
- formState.value.name = selectedNode?.label || '';
- formState.value.productModelId = undefined;
- await getModelOptions(value);
+const handleExecutorChange = value => {
+ const selectedUser = plannerOptions.value.find(item => String(item.userId) === String(value));
+ formState.value.executorName = selectedUser?.nickName || '';
};
const closeModal = () => {
@@ -376,7 +258,6 @@
};
onMounted(() => {
- getProductCategoryOptions();
getPlannerOptions();
});
diff --git a/src/views/productionManagement/productionProcess/New.vue b/src/views/productionManagement/productionProcess/New.vue
index 250e229..8b57f23 100644
--- a/src/views/productionManagement/productionProcess/New.vue
+++ b/src/views/productionManagement/productionProcess/New.vue
@@ -10,53 +10,21 @@
<el-row :gutter="16">
<el-col :span="12">
<el-form-item
- label="浜у搧鍚嶇О锛�"
- prop="productId"
+ label="閮ㄤ欢鍚嶇О"
+ prop="name"
:rules="[
{
required: true,
- message: '璇烽�夋嫨浜у搧鍚嶇О',
- },
- ]">
- <el-tree-select
- v-model="formState.productId"
- placeholder="璇烽�夋嫨浜у搧鍚嶇О"
- clearable
- filterable
- check-strictly
- :data="productCategoryOptions"
- :render-after-expand="false"
- style="width: 100%"
- @change="handleProductChange"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item
- label="浜у搧瑙勬牸锛�"
- prop="productModelId"
- :rules="[
- {
- required: true,
- message: '璇烽�夋嫨浜у搧瑙勬牸',
- },
- ]">
- <el-select v-model="formState.productModelId"
- placeholder="璇烽�夋嫨浜у搧瑙勬牸"
- clearable
- filterable
- :disabled="!formState.productId"
- style="width: 100%">
- <el-option v-for="item in modelOptions"
- :key="item.id"
- :label="item.model"
- :value="item.id" />
- </el-select>
+ message: '璇疯緭鍏ラ儴浠跺悕绉�',
+ }
+ ]"
+ >
+ <el-input v-model="formState.name" placeholder="璇疯緭鍏ラ儴浠跺悕绉�" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="閮ㄤ欢缂栧彿" prop="no">
- <el-input v-model="formState.no" />
+ <el-input v-model="formState.no" placeholder="璇疯緭鍏ラ儴浠剁紪鍙�" />
</el-form-item>
</el-col>
<el-col :span="12">
@@ -113,6 +81,25 @@
</el-form-item>
</el-col>
<el-col :span="12">
+ <el-form-item label="璁″垝鎵ц浜哄憳" prop="executorId">
+ <el-select
+ v-model="formState.executorId"
+ placeholder="璇烽�夋嫨璁″垝鎵ц浜哄憳"
+ clearable
+ filterable
+ style="width: 100%"
+ @change="handleExecutorChange"
+ >
+ <el-option
+ v-for="item in plannerOptions"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
<el-form-item label="鏄惁璐ㄦ" prop="isQuality">
<el-switch v-model="formState.isQuality" :active-value="true" inactive-value="false"/>
</el-form-item>
@@ -137,7 +124,6 @@
<script setup>
import { ref, computed, getCurrentInstance, onMounted } from "vue";
import {add} from "@/api/productionManagement/productionProcess.js";
-import { modelListPage, productTreeList } from "@/api/basicData/product";
import { userListNoPageByTenantId } from "@/api/system/user.js";
const props = defineProps({
@@ -152,17 +138,15 @@
// 鍝嶅簲寮忔暟鎹紙鏇夸唬閫夐」寮忕殑 data锛�
const formState = ref({
name: '',
- productId: undefined,
- productModelId: undefined,
type: undefined,
remark: '',
salaryQuota: '',
plannerId: undefined,
plannerName: '',
+ executorId: undefined,
+ executorName: '',
isQuality: false,
});
-const productCategoryOptions = ref([]);
-const modelOptions = ref([]);
const plannerOptions = ref([]);
const isShow = computed({
@@ -189,60 +173,6 @@
callback();
};
-const convertProductTree = list => {
- return (list || []).map(item => {
- const children = convertProductTree(item.children || item.childList || []);
- return {
- ...item,
- value: item.id,
- label: item.name || item.label,
- children,
- disabled: children.length > 0,
- };
- });
-};
-
-const findNodeById = (nodes, targetId) => {
- for (const node of nodes || []) {
- if (String(node.value) === String(targetId)) {
- return node;
- }
- if (node.children && node.children.length > 0) {
- const found = findNodeById(node.children, targetId);
- if (found) return found;
- }
- }
- return null;
-};
-
-const getProductCategoryOptions = async () => {
- try {
- const res = await productTreeList();
- const list = Array.isArray(res) ? res : res?.data || [];
- productCategoryOptions.value = convertProductTree(list);
- } catch (e) {
- productCategoryOptions.value = [];
- }
-};
-
-const getModelOptions = async productId => {
- if (!productId) {
- modelOptions.value = [];
- return;
- }
- try {
- const res = await modelListPage({
- id: productId,
- current: 1,
- size: 999,
- });
- const records = res?.records || res?.data?.records || [];
- modelOptions.value = records;
- } catch (e) {
- modelOptions.value = [];
- }
-};
-
const getPlannerOptions = async () => {
try {
const res = await userListNoPageByTenantId();
@@ -257,11 +187,9 @@
formState.value.plannerName = selectedUser?.nickName || '';
};
-const handleProductChange = async value => {
- const selectedNode = findNodeById(productCategoryOptions.value, value);
- formState.value.name = selectedNode?.label || '';
- formState.value.productModelId = undefined;
- await getModelOptions(value);
+const handleExecutorChange = value => {
+ const selectedUser = plannerOptions.value.find(item => String(item.userId) === String(value));
+ formState.value.executorName = selectedUser?.nickName || '';
};
const closeModal = () => {
@@ -283,7 +211,6 @@
};
onMounted(() => {
- getProductCategoryOptions();
getPlannerOptions();
});
diff --git a/src/views/productionManagement/productionProcess/index.vue b/src/views/productionManagement/productionProcess/index.vue
index 92530e5..e4347e3 100644
--- a/src/views/productionManagement/productionProcess/index.vue
+++ b/src/views/productionManagement/productionProcess/index.vue
@@ -115,14 +115,9 @@
});
const { searchForm } = toRefs(data);
const tableColumn = ref([
-
{
- label: "浜у搧鍚嶇О",
+ label: "閮ㄤ欢鍚嶇О",
prop: "name",
- },
- {
- label: "浜у搧瑙勬牸",
- prop: "productModel",
},
{
label: "閮ㄤ欢缂栧彿",
@@ -141,6 +136,10 @@
prop: "plannerName",
},
{
+ label: "璁″垝鎵ц浜哄憳",
+ prop: "executorName",
+ },
+ {
label: "鏄惁璐ㄦ",
prop: "isQuality",
formatData: (params) => {
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index fa191a0..930b0e8 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -595,50 +595,6 @@
</el-form-item>
</el-col>
</el-row>
-
- <!-- 瀹℃壒浜洪�夋嫨锛堜豢鍗忓悓瀹℃壒閲岀殑瀹℃壒浜鸿妭鐐归�夋嫨锛� -->
- <el-row>
- <el-col :span="24">
- <el-form-item>
- <template #label>
- <span>瀹℃壒浜洪�夋嫨锛�</span>
- <el-button type="primary" @click="addApproverNode" style="margin-left: 8px;">鏂板鑺傜偣</el-button>
- </template>
- <div style="display: flex; align-items: flex-end; flex-wrap: wrap;">
- <div
- v-for="(node, index) in approverNodes"
- :key="node.id"
- style="margin-right: 20px; text-align: center; margin-bottom: 10px;"
- >
- <div>
- <span>瀹℃壒浜�</span>
- 鈫�
- </div>
- <el-select
- v-model="node.userId"
- placeholder="閫夋嫨浜哄憳"
- filterable
- style="width: 140px; margin-bottom: 8px;"
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- <div>
- <el-button
- type="danger"
- @click="removeApproverNode(index)"
- v-if="approverNodes.length > 1"
- >鍒犻櫎</el-button>
- </div>
- </div>
- </div>
- </el-form-item>
- </el-col>
- </el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
@@ -809,16 +765,6 @@
},
});
const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
-
-// 鍙戣揣瀹℃壒浜鸿妭鐐癸紙浠垮崗鍚屽鎵� infoFormDia.vue锛�
-const approverNodes = ref([{ id: 1, userId: null }]);
-let nextApproverId = 2;
-const addApproverNode = () => {
- approverNodes.value.push({ id: nextApproverId++, userId: null });
-};
-const removeApproverNode = (index) => {
- approverNodes.value.splice(index, 1);
-};
// 瀵煎叆鐩稿叧
const importUploadRef = ref(null);
@@ -2115,9 +2061,6 @@
deliveryForm.value = {
type: "璐ц溅",
};
- // 閲嶇疆瀹℃壒浜鸿妭鐐癸紙榛樿涓�涓┖鑺傜偣锛�
- approverNodes.value = [{ id: 1, userId: null }];
- nextApproverId = 2;
deliveryFormVisible.value = true;
};
@@ -2125,13 +2068,6 @@
const submitDelivery = () => {
proxy.$refs["deliveryFormRef"].validate((valid) => {
if (valid) {
- // 瀹℃壒浜哄繀濉牎楠岋紙鎵�鏈夎妭鐐归兘瑕侀�変汉锛�
- const hasEmptyApprover = approverNodes.value.some(node => !node.userId);
- if (hasEmptyApprover) {
- proxy.$modal.msgError("璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒");
- return;
- }
- const approveUserIds = approverNodes.value.map(node => node.userId).join(",");
// 淇濆瓨褰撳墠灞曞紑鐨勮ID锛屼互渚垮彂璐у悗閲嶆柊鍔犺浇瀛愯〃鏍兼暟鎹�
const currentExpandedKeys = [...expandedRowKeys.value];
const salesLedgerId = currentDeliveryRow.value.salesLedgerId;
@@ -2139,7 +2075,6 @@
salesLedgerId: salesLedgerId,
salesLedgerProductId: currentDeliveryRow.value.id,
type: deliveryForm.value.type,
- approveUserIds,
})
.then(() => {
proxy.$modal.msgSuccess("鍙戣揣鎴愬姛");
diff --git a/src/views/salesManagement/salesQuotation/index.vue b/src/views/salesManagement/salesQuotation/index.vue
index 2a094a8..be59964 100644
--- a/src/views/salesManagement/salesQuotation/index.vue
+++ b/src/views/salesManagement/salesQuotation/index.vue
@@ -173,69 +173,6 @@
</div>
</el-card>
- <!-- 瀹℃壒浜轰俊鎭� -->
- <el-card class="form-card" shadow="hover">
- <template #header>
- <div class="card-header-wrapper">
- <el-icon class="card-icon">
- <UserFilled/>
- </el-icon>
- <span class="card-title">瀹℃壒浜洪�夋嫨</span>
- <el-button type="primary" size="small" @click="addApproverNode" class="header-btn">
- <el-icon>
- <Plus/>
- </el-icon>
- 鏂板鑺傜偣
- </el-button>
- </div>
- </template>
- <div class="form-content">
- <el-row>
- <el-col :span="24">
- <el-form-item>
- <div class="approver-nodes-container">
- <div
- v-for="(node, index) in approverNodes"
- :key="node.id"
- class="approver-node-item"
- >
- <div class="approver-node-label">
- <span class="node-step">{{ index + 1 }}</span>
- <span class="node-text">瀹℃壒浜�</span>
- <el-icon class="arrow-icon">
- <ArrowRight/>
- </el-icon>
- </div>
- <el-select
- v-model="node.userId"
- placeholder="閫夋嫨浜哄憳"
- class="approver-select"
- clearable
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- <el-button
- type="danger"
- size="small"
- :icon="Delete"
- @click="removeApproverNode(index)"
- v-if="approverNodes.length > 1"
- class="remove-btn"
- >鍒犻櫎
- </el-button>
- </div>
- </div>
- </el-form-item>
- </el-col>
- </el-row>
- </div>
- </el-card>
-
<!-- 浜у搧淇℃伅 -->
<el-card class="form-card" shadow="hover">
<template #header>
@@ -345,68 +282,6 @@
<FormDialog v-model="importDialogVisible" title="瀵煎叆鎶ヤ环鍗�" width="85%" :close-on-click-modal="false"
@close="importDialogVisible = false" @confirm="handleImportSubmit"
@cancel="importDialogVisible = false">
- <!-- 瀹℃壒浜轰俊鎭� -->
- <el-card class="form-card" shadow="hover">
- <template #header>
- <div class="card-header-wrapper">
- <el-icon class="card-icon">
- <UserFilled/>
- </el-icon>
- <span class="card-title">瀹℃壒浜洪�夋嫨</span>
- <el-button type="primary" size="small" @click="addImportApproverNode" class="header-btn">
- <el-icon>
- <Plus/>
- </el-icon>
- 鏂板鑺傜偣
- </el-button>
- </div>
- </template>
- <div class="form-content">
- <el-row>
- <el-col :span="24">
- <el-form-item>
- <div class="approver-nodes-container">
- <div
- v-for="(node, index) in importApproverNodes"
- :key="node.id"
- class="approver-node-item"
- >
- <div class="approver-node-label">
- <span class="node-step">{{ index + 1 }}</span>
- <span class="node-text">瀹℃壒浜�</span>
- <el-icon class="arrow-icon">
- <ArrowRight/>
- </el-icon>
- </div>
- <el-select
- v-model="node.userId"
- placeholder="閫夋嫨浜哄憳"
- class="approver-select"
- clearable
- >
- <el-option
- v-for="user in userList"
- :key="user.userId"
- :label="user.nickName"
- :value="user.userId"
- />
- </el-select>
- <el-button
- type="danger"
- size="small"
- :icon="Delete"
- @click="removeImportApproverNode(index)"
- v-if="importApproverNodes.length > 1"
- class="remove-btn"
- >鍒犻櫎
- </el-button>
- </div>
- </div>
- </el-form-item>
- </el-col>
- </el-row>
- </div>
- </el-card>
<el-card class="form-card" shadow="hover">
<template #header>
<div class="card-header-wrapper">
@@ -546,10 +421,6 @@
const importDialogVisible = ref(false)
const viewDialogVisible = ref(false)
const importFileList = ref([])
-const importApproverNodes = ref([
- {id: 1, userId: null}
-])
-let nextImportApproverId = 2
const fileUpload = ref(null)
@@ -599,36 +470,11 @@
const userList = ref([]);
const customerOption = ref([]);
-// 瀹℃壒浜鸿妭鐐圭浉鍏�
-const approverNodes = ref([
- {id: 1, userId: null}
-])
-let nextApproverId = 2
-
const isEdit = ref(false)
const showDetail = ref(false)
const editId = ref(null)
const currentQuotation = ref({})
const formRef = ref()
-
-// 娣诲姞瀹℃壒浜鸿妭鐐�
-function addApproverNode() {
- approverNodes.value.push({id: nextApproverId++, userId: null})
-}
-
-// 鍒犻櫎瀹℃壒浜鸿妭鐐�
-function removeApproverNode(index) {
- approverNodes.value.splice(index, 1)
-}
-
-// 瀵煎叆寮圭獥瀹℃壒浜鸿妭鐐圭浉鍏�
-function addImportApproverNode() {
- importApproverNodes.value.push({id: nextImportApproverId++, userId: null})
-}
-
-function removeImportApproverNode(index) {
- importApproverNodes.value.splice(index, 1)
-}
function triggerRemoveImportFile(file) {
const index = importFileList.value.indexOf(file)
@@ -643,12 +489,6 @@
return
}
- const hasEmptyApprover = importApproverNodes.value.some(node => !node.userId)
- if (hasEmptyApprover) {
- ElMessage.error('璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒')
- return
- }
-
const selectedFile = importFileList.value[0]
const rawFile = selectedFile?.raw || selectedFile
if (!validateImportFile(rawFile)) {
@@ -657,10 +497,6 @@
const formData = new FormData()
formData.append('file', rawFile)
-
- // 瀹℃牳浜� IDs锛屼互閫楀彿鍒嗗壊
- const approveUserIds = importApproverNodes.value.map(node => node.userId).join(',')
- formData.append('approveUserIdsJson', approveUserIds)
loading.value = true
try {
@@ -767,10 +603,6 @@
const handleImport = async () => {
importFileList.value = []
- // 鉁� 娓呯┖鈥滃鍏ョ敤鈥濈殑瀹℃壒浜�
- importApproverNodes.value = [{id: 1, userId: null}]
- nextImportApproverId = 2
-
let userLists = await userListNoPage();
importDialogVisible.value = true
@@ -785,9 +617,6 @@
dialogTitle.value = '鏂板鎶ヤ环'
isEdit.value = false
resetForm()
- // 閲嶇疆瀹℃壒浜鸿妭鐐�
- approverNodes.value = [{id: 1, userId: null}]
- nextApproverId = 2
dialogVisible.value = true
let userLists = await userListNoPage();
// 鍙鍒堕渶瑕佺殑瀛楁锛岄伩鍏嶅皢缁勪欢寮曠敤鏀惧叆鍝嶅簲寮忓璞�
@@ -992,19 +821,6 @@
form.discountAmount = row.discountAmount || 0
form.totalAmount = row.totalAmount || 0
- // 鍙嶆樉瀹℃壒浜�
- if (row.approveUserIds) {
- const userIds = row.approveUserIds.split(',')
- approverNodes.value = userIds.map((userId, idx) => ({
- id: idx + 1,
- userId: parseInt(userId.trim())
- }))
- nextApproverId = userIds.length + 1
- } else {
- approverNodes.value = [{id: 1, userId: null}]
- nextApproverId = 2
- }
-
// 鍔犺浇鐢ㄦ埛鍒楄〃
let userLists = await userListNoPage();
userList.value = (userLists.data || []).map(item => ({
@@ -1103,16 +919,6 @@
return
}
- // 瀹℃壒浜哄繀濉牎楠�
- const hasEmptyApprover = approverNodes.value.some(node => !node.userId)
- if (hasEmptyApprover) {
- ElMessage.error('璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒')
- return
- }
-
- // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
- form.approveUserIds = approverNodes.value.map(node => node.userId).join(',')
-
// 璁$畻鎵�鏈変骇鍝佺殑鍗曚环鎬诲拰
form.totalAmount = form.products.reduce((sum, product) => {
const price = Number(product.unitPrice) || 0
@@ -1177,8 +983,6 @@
validDate: item.validDate || '',
paymentMethod: item.paymentMethod || '',
status: item.status || '鑽夌',
- // 瀹℃壒浜猴紙鐢ㄤ簬缂栬緫鏃跺弽鏄撅級
- approveUserIds: item.approveUserIds || '',
remark: item.remark || '',
products: item.products ? item.products.map(product => ({
productId: product.productId || '',
diff --git a/vite.config.js b/vite.config.js
index dc687a8..c01dd12 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -8,11 +8,11 @@
const { VITE_APP_ENV } = env;
const baseUrl =
env.VITE_APP_ENV === "development"
- ? "http://1.15.17.182:9003"
+ ? "http://localhost:7003"
: env.VITE_BASE_API;
const javaUrl =
env.VITE_APP_ENV === "development"
- ? "http://1.15.17.182:9002"
+ ? "http://1.15.17.182:9048"
: env.VITE_JAVA_API;
return {
define:{
--
Gitblit v1.9.3