From 0c5b607e028bd756079cb328dd0914db2c9093f5 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 04 十二月 2025 14:59:55 +0800
Subject: [PATCH] 1.部署修改

---
 src/views/productionManagement/LineManagement/index.vue |  412 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 412 insertions(+), 0 deletions(-)

diff --git a/src/views/productionManagement/LineManagement/index.vue b/src/views/productionManagement/LineManagement/index.vue
new file mode 100644
index 0000000..706d2d2
--- /dev/null
+++ b/src/views/productionManagement/LineManagement/index.vue
@@ -0,0 +1,412 @@
+<template>
+	<div class="app-container line-management">
+		<div class="config-wrap">
+			<div class="left">
+				<div class="header">
+					<div>浜х嚎绠$悊</div>
+					<div>
+						<el-button size="small" type="primary" @click="addLine">鏂板浜х嚎</el-button>
+					</div>
+				</div>
+				<el-tree
+						:data="lineTree"
+						node-key="id"
+						:props="{ label: 'name' }"
+						@node-click="onNodeClick"
+						highlight-current
+						class="tree"
+					>
+						<template #default="{ data }">
+                <span>
+                  <el-tag size="small" type="warning" effect="plain" style="margin-right:4px;">
+                    浜х嚎
+                  </el-tag>
+                  {{ data.name }}
+                </span>
+							<span class="ops">
+                  <el-button link size="small" type="primary" @click.stop="openRenameDialog(data)">閲嶅懡鍚�</el-button>
+                  <el-button link size="small" type="danger" @click.stop="confirmRemoveNode(data)">鍒犻櫎</el-button>
+                </span>
+						</template>
+					</el-tree>
+			</div>
+			<div class="right">
+					<div v-if="currentLine" class="process-config">
+						<div class="title">
+							<span>宸ュ簭绠$悊锛歿{ currentLine.label }}</span>
+						</div>
+						<div class="q-toolbar">
+							<el-button size="small" type="primary" @click="openAddProcessDialog">鏂板宸ュ簭</el-button>
+						</div>
+						<el-table :data="processList" border size="small" v-loading="processLoading">
+						<el-table-column label="宸ュ簭鍚嶇О" prop="name" />
+						<el-table-column label="鎿嶄綔" width="160" align="center">
+							<template #default="scope">
+								<el-button link type="primary" size="small" @click="openEditProcessDialog(scope.row)">缂栬緫</el-button>
+								<el-button link type="danger" size="small" @click="onDeleteProcess(scope.row)">鍒犻櫎</el-button>
+							</template>
+						</el-table-column>
+					</el-table>
+					<div class="pagination-container">
+						<el-pagination
+							v-model:current-page="processQueryParams.current"
+							v-model:page-size="processQueryParams.size"
+							:page-sizes="[10, 20, 50, 100]"
+							:layout="'total, sizes, prev, pager, next, jumper'"
+							:total="total"
+							@size-change="handleProcessSizeChange"
+							@current-change="handleProcessCurrentChange"
+						/>
+					</div>
+					</div>
+					<div v-else class="empty">璇烽�夋嫨宸︿晶浜х嚎杩涜宸ュ簭閰嶇疆</div>
+				</div>
+		</div>
+		<!-- 鏂板浜х嚎寮圭獥 -->
+		<el-dialog v-model="addDialogVisible" :title="addDialogTitle" width="420px">
+			<el-form :model="addForm" :rules="addRules" ref="addFormRef" label-width="80px">
+				<el-form-item label="浜х嚎鍚嶇О" prop="name">
+					<el-input v-model="addForm.name" placeholder="璇疯緭鍏ヤ骇绾垮悕绉�" />
+				</el-form-item>
+			</el-form>
+			<template #footer>
+				<el-button @click="onCancelAdd">鍙� 娑�</el-button>
+				<el-button type="primary" @click="onConfirmAdd" :loading="addLoading">纭� 璁�</el-button>
+			</template>
+		</el-dialog>
+		<!-- 閲嶅懡鍚嶅脊绐� -->
+		<el-dialog v-model="renameDialogVisible" :title="renameDialogTitle" width="420px">
+			<el-form :model="renameForm" :rules="addRules" ref="renameFormRef" label-width="80px">
+				<el-form-item label="浜х嚎鍚嶇О" prop="name">
+					<el-input v-model="renameForm.name" placeholder="璇疯緭鍏ヤ骇绾垮悕绉�" />
+				</el-form-item>
+			</el-form>
+			<template #footer>
+				<el-button @click="onCancelRename">鍙� 娑�</el-button>
+				<el-button type="primary" @click="onConfirmRename" :loading="renameLoading">纭� 璁�</el-button>
+			</template>
+		</el-dialog>
+		
+		<!-- 鏂板/缂栬緫宸ュ簭寮圭獥 -->
+		<el-dialog v-model="addProcessDialogVisible" :title="addProcessDialogTitle" width="420px">
+			<el-form :model="addProcessForm" label-width="80px">
+				<el-form-item label="宸ュ簭鍚嶇О" prop="name">
+					<el-input v-model="addProcessForm.name" placeholder="璇疯緭鍏ュ伐搴忓悕绉�" />
+				</el-form-item>
+			</el-form>
+			<template #footer>
+				<el-button @click="onCancelAddProcess">鍙� 娑�</el-button>
+				<el-button type="primary" :loading="addProcessSaving" @click="onConfirmAddProcess">淇� 瀛�</el-button>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script setup>
+import { ref, reactive, computed, watch, onMounted } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { getDeptPositionTree, addDeptPosition, updateDeptPosition, deleteDeptPosition, laborConfListPage } from '@/api/lavorissce/issue'
+
+// 缁撴瀯锛氫骇绾垮垪琛�
+const lines = reactive([]) // [{id,name,processes:[{id,processName,processCode,standardTime,status}]}]
+
+// 鍔犺浇浜х嚎鍒楄〃
+async function loadLineTree() {
+	try {
+		const res = await getDeptPositionTree()
+		const data = res.data
+		lines.splice(0, lines.length, ...data)
+	} catch (e) {
+		// 闈欓粯澶辫触锛屼繚鐣欐湰鍦扮ず渚嬫暟鎹�
+	}
+}
+
+const lineTree = computed(() => lines)
+
+const currentLine = ref(null)
+// 鍙充晶锛氬綋鍓嶄骇绾跨殑宸ュ簭鍒楄〃
+const processList = ref([])
+const processLoading = ref(false)
+
+// 宸ュ簭鍒嗛〉鍙傛暟
+const processQueryParams = reactive({
+	current: 1,
+	size: 10
+})
+const total = ref(0)
+
+// 鍔犺浇宸ュ簭鍒楄〃
+async function loadProcessList(lineId) {
+	if (!lineId) {
+		if (!currentLine.value) return
+		lineId = currentLine.value.id
+	}
+	
+	try {
+		processLoading.value = true
+		const res = await laborConfListPage({
+			id: lineId,
+			current: processQueryParams.current,
+			size: processQueryParams.size
+		})
+		// 鏂版帴鍙h繑鍥炵殑鏄爲褰㈢粨鏋勶紝鐩存帴浣跨敤杩斿洖鐨勬暟鎹�
+		processList.value = res.data.records.map(it => ({
+			...it,
+			id: it.id,
+			name: it.name
+		}))
+		total.value = res.data.total
+	} finally {
+		processLoading.value = false
+	}
+}
+
+// 宸ュ簭鍒嗛〉浜嬩欢澶勭悊
+function handleProcessSizeChange(val) {
+	processQueryParams.size = val
+	processQueryParams.current = 1
+	loadProcessList()
+}
+
+function handleProcessCurrentChange(val) {
+	processQueryParams.current = val
+	loadProcessList()
+}
+
+// 鏂板宸ュ簭寮圭獥鐘舵�佷笌閫昏緫锛堜緵妯℃澘浣跨敤锛�
+const addProcessDialogVisible = ref(false)
+const addProcessDialogTitle = ref('鏂板宸ュ簭')
+const addProcessSaving = ref(false)
+const addProcessForm = reactive({ id: undefined, name: '' })
+
+function openAddProcessDialog() {
+	if (!currentLine.value) return
+	addProcessDialogTitle.value = '鏂板宸ュ簭'
+	addProcessForm.id = undefined
+	addProcessForm.name = ''
+	addProcessDialogVisible.value = true
+}
+
+function openEditProcessDialog(row) {
+	if (!currentLine.value || !row) return
+	addProcessDialogTitle.value = '缂栬緫宸ュ簭'
+	addProcessForm.id = row.id
+	addProcessForm.name = row.name
+	addProcessDialogVisible.value = true
+}
+
+function onCancelAddProcess() {
+	addProcessDialogVisible.value = false
+}
+
+async function onConfirmAddProcess() {
+	if (!currentLine.value.id) {
+		ElMessage.error('璇峰厛閫夋嫨浜х嚎')
+		return
+	}
+	addProcessSaving.value = true
+	try {
+		if (addProcessForm.id) {
+			// 缂栬緫宸ュ簭
+			await updateDeptPosition({
+				id: addProcessForm.id,
+				name: addProcessForm.name,
+				type: 2 // 宸ュ簭绫诲瀷
+			})
+		} else {
+			// 鏂板宸ュ簭
+			await addDeptPosition({
+				parentId: currentLine.value.id,
+				name: addProcessForm.name,
+				type: 2 // 宸ュ簭绫诲瀷
+			})
+		}
+		
+		// 閲嶆柊鍔犺浇宸ュ簭鍒楄〃
+		await loadProcessList()
+		
+		addProcessDialogVisible.value = false
+		ElMessage.success('淇濆瓨鎴愬姛')
+	} catch (e) {
+		ElMessage.error((e && (e.msg || e.message)) || '淇濆瓨澶辫触')
+	} finally {
+		addProcessSaving.value = false
+	}
+}
+
+async function onDeleteProcess(row) {
+	if (!currentLine.value || !row) return
+	try {
+		await ElMessageBox.confirm('纭畾鍒犻櫎璇ュ伐搴忓悧锛�', '鎻愮ず', { type: 'warning' })
+	} catch {
+		return
+	}
+	try {
+		await deleteDeptPosition([row.id])
+		// 閲嶆柊鍔犺浇宸ュ簭鍒楄〃
+		await loadProcessList()
+		ElMessage.success('鍒犻櫎鎴愬姛')
+	} catch (e) {
+		ElMessage.error((e && (e.msg || e.message)) || '鍒犻櫎澶辫触')
+	}
+}
+
+// 鏂板浜х嚎寮圭獥鐘舵��
+const addDialogVisible = ref(false)
+const addDialogTitle = ref('鏂板浜х嚎')
+const addLoading = ref(false)
+const addFormRef = ref()
+const addForm = reactive({ name: '', type: 1, parentId: undefined })
+const addRules = { name: [{ required: true, message: '璇疯緭鍏ヤ骇绾垮悕绉�', trigger: 'blur' }] }
+
+// 閲嶅懡鍚嶄骇绾垮脊绐楃姸鎬�
+const renameDialogVisible = ref(false)
+const renameLoading = ref(false)
+const renameFormRef = ref()
+const renameForm = reactive({ id: undefined, type: 1, name: '' })
+const renameDialogTitle = ref('閲嶅懡鍚嶄骇绾�')
+
+function newLine() {
+	return {
+		id: Date.now(),
+		label: '鏂颁骇绾�',
+		hrPositionId: undefined,
+		processes: []
+	}
+}
+
+async function addLine() {
+	openAddDialog()
+}
+
+function openAddDialog() {
+	addForm.name = ''
+	addForm.type = 1
+	addForm.parentId = undefined
+	addDialogTitle.value = '鏂板浜х嚎'
+	addDialogVisible.value = true
+}
+
+function onCancelAdd() {
+	addDialogVisible.value = false
+}
+
+async function onConfirmAdd() {
+	addFormRef.value?.validate(async (valid) => {
+		if (!valid) return
+		try {
+			addLoading.value = true
+			const payload = { name: addForm.name, type: addForm.type, parentId: 0 }
+			await addDeptPosition(payload)
+			addDialogVisible.value = false
+			await loadLineTree()
+		} finally {
+			addLoading.value = false
+		}
+	})
+}
+
+function onNodeClick(node) {
+	console.log(node);
+	
+	currentLine.value = node
+		// 閫夋嫨浜х嚎鏃讹紝鍔犺浇宸ュ簭鍒楄〃
+		loadProcessList()
+}
+
+function openRenameDialog(node) {
+	renameForm.id = node.id
+	renameForm.type = 1
+	renameForm.name = node.name
+	renameDialogTitle.value = '閲嶅懡鍚嶄骇绾�'
+	renameDialogVisible.value = true
+}
+
+function onCancelRename() {
+	renameDialogVisible.value = false
+}
+
+async function onConfirmRename() {
+	renameFormRef.value?.validate(async (valid) => {
+		if (!valid) return
+		try {
+			renameLoading.value = true
+			await updateDeptPosition({ id: renameForm.id, name: renameForm.name, type: renameForm.type })
+			renameDialogVisible.value = false
+			await loadLineTree()
+		} finally {
+			renameLoading.value = false
+		}
+	})
+}
+
+async function confirmRemoveNode(node) {
+	const id = node.id
+	// 绠�鍗曠‘璁�
+	try {
+		await deleteDeptPosition([id])
+		await loadLineTree()
+	} catch (e) {
+		// ignore errors
+	}
+}
+
+
+
+onMounted(() => {
+	loadLineTree()
+})
+</script>
+
+<style scoped>
+.labor-issue {
+	display: flex;
+	flex-direction: column;
+	gap: 12px;
+}
+.config-wrap {
+	display: flex;
+	gap: 16px;
+	align-items: stretch;
+}
+.left, .right {
+	background: #fff;
+	border: 1px solid var(--el-border-color, #ebeef5);
+	border-radius: 8px;
+	box-shadow: var(--el-box-shadow-light, 0 2px 12px 0 rgba(0,0,0,.1));
+}
+.left { width: 340px; padding: 12px; }
+.right { flex: 1; padding: 14px; }
+.header {
+	display: flex;
+	align-items: flex-start;
+	margin-bottom: 10px;
+	flex-direction: column;
+}
+.header :deep(.el-button+.el-button) { margin-left: 8px; }
+.tree {
+	max-height: calc(100vh - 300px);
+	overflow: auto;
+	padding: 6px;
+	border-radius: 6px;
+	background: #fafafa;
+}
+.ops { margin-left: 8px; opacity: 0.6; transition: opacity .2s; }
+:deep(.el-tree-node__content):hover .ops { opacity: 1; }
+
+.q-toolbar { margin-bottom: 10px; }
+.empty { color: #999; padding: 48px; text-align: center; }
+
+.summary-wrap { display: flex; flex-direction: column; gap: 16px; }
+.people, .summary {
+	background: #fff;
+	border: 1px solid var(--el-border-color, #ebeef5);
+	border-radius: 8px;
+	padding: 12px;
+	box-shadow: var(--el-box-shadow-light, 0 2px 12px 0 rgba(0,0,0,.06));
+}
+.summary .header {
+	font-weight: 600;
+	margin-bottom: 12px;
+}
+</style>

--
Gitblit v1.9.3