From e3fc89bb84fc32e0048cbd53ee96e26f01a8881f Mon Sep 17 00:00:00 2001
From: ZN <zhang_12370@163.com>
Date: 星期一, 09 三月 2026 13:14:35 +0800
Subject: [PATCH] feat(项目类型): 优化项目类型对话框的附件上传和步骤排序功能
---
src/views/projectManagement/projectType/components/ProjectTypeDialog.vue | 161 ++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 122 insertions(+), 39 deletions(-)
diff --git a/src/views/projectManagement/projectType/components/ProjectTypeDialog.vue b/src/views/projectManagement/projectType/components/ProjectTypeDialog.vue
index 6e3df3c..d73f464 100644
--- a/src/views/projectManagement/projectType/components/ProjectTypeDialog.vue
+++ b/src/views/projectManagement/projectType/components/ProjectTypeDialog.vue
@@ -32,10 +32,13 @@
<div class="info-item">
<span class="item-label">闄勪欢</span>
<el-upload
- action="#"
- :auto-upload="false"
- :show-file-list="false"
- @change="handleFileChange"
+ :action="uploadUrl"
+ :headers="uploadHeaders"
+ :on-success="handleUploadSuccess"
+ :on-remove="handleRemove"
+ :file-list="form.attachmentList"
+ name="files"
+ multiple
>
<el-button type="primary">涓婁紶闄勪欢</el-button>
</el-upload>
@@ -43,11 +46,20 @@
</div>
<!-- 姝ラ閰嶇疆琛ㄦ牸 -->
+ <p class="top-tip">璇锋寜鐓ч『搴忛厤缃」鐩樁娈碉紝鎷栨嫿<b>姝ラ</b>鎺掑簭鍗冲彲</p>
<div class="step-table-container">
- <el-table :data="form.savePlanNodeList" border style="width: 100%">
- <el-table-column label="姝ラ" width="80" align="center">
+ <el-table
+ :data="form.savePlanNodeList"
+ border
+ style="width: 100%"
+ row-key="id"
+ class="drag-table"
+ >
+ <el-table-column label="姝ラ" width="80" align="center" class-name="drag-handle">
<template #default="scope">
- {{ scope.$index + 1 }}
+ <div class="step-index" style="cursor: move;">
+ {{ scope.$index + 1 }}
+ </div>
</template>
</el-table-column>
@@ -118,28 +130,6 @@
<el-input v-model="scope.row.workContent" placeholder="璇疯緭鍏�" />
</template>
</el-table-column>
-
- <el-table-column label="鎿嶄綔" width="180" align="center">
- <template #default="scope">
- <el-button
- link
- type="primary"
- :disabled="scope.$index === 0"
- @click="moveStep(scope.$index, -1)"
- >涓婄Щ</el-button>
- <el-button
- link
- type="primary"
- :disabled="scope.$index === form.savePlanNodeList.length - 1"
- @click="moveStep(scope.$index, 1)"
- >涓嬬Щ</el-button>
- <el-button
- link
- type="danger"
- @click="removeStep(scope.$index)"
- >鍒犻櫎</el-button>
- </template>
- </el-table-column>
</el-table>
<div class="add-row-btn" @click="addStep">
@@ -158,10 +148,12 @@
</template>
<script setup>
-import { ref, watch, onMounted } from 'vue';
+import { ref, watch, onMounted, nextTick } from 'vue';
import { Plus, QuestionFilled } from '@element-plus/icons-vue';
import { userListNoPageByTenantId } from '@/api/system/user';
import { ElMessage } from 'element-plus';
+import { getToken } from '@/utils/auth';
+import Sortable from 'sortablejs';
const props = defineProps({
modelValue: Boolean,
@@ -174,12 +166,17 @@
const visible = ref(false);
const formRef = ref(null);
const userOptions = ref([]);
+const uploadHeaders = { Authorization: "Bearer " + getToken() };
+// 涓婁紶鍦板潃
+const uploadUrl = import.meta.env.VITE_APP_BASE_API + "/basic/customer-follow/upload";
+let sortable = null;
const form = ref({
id: undefined,
name: '',
description: '',
attachmentIds: [],
+ attachmentList: [],
savePlanNodeList: []
});
@@ -192,21 +189,70 @@
visible.value = val;
if (val) {
if (props.data) {
- // 缂栬緫妯″紡
- form.value = JSON.parse(JSON.stringify(props.data));
- if (!form.value.savePlanNodeList || form.value.savePlanNodeList.length === 0) {
+ // 缂栬緫妯″紡 - 鍥炴樉鏁版嵁
+ form.value = {
+ id: props.data.id,
+ name: props.data.name,
+ description: props.data.description,
+ attachmentIds: [],
+ attachmentList: props.data.attachmentList || [],
+ savePlanNodeList: []
+ };
+
+ // 鍥炴樉闄勪欢ID
+ if (form.value.attachmentList && form.value.attachmentList.length > 0) {
+ form.value.attachmentIds = form.value.attachmentList.map(item => item.id);
+ }
+
+ // 鍥炴樉姝ラ鑺傜偣
+ if (props.data.planNodeList && props.data.planNodeList.length > 0) {
+ form.value.savePlanNodeList = props.data.planNodeList.map(node => ({
+ id: node.id,
+ projectManagementPlanId: node.projectManagementPlanId,
+ sort: node.sort,
+ name: node.name,
+ leaderId: node.leaderId,
+ leaderName: node.leaderName,
+ estimatedDuration: node.estimatedDuration,
+ hourlyRate: node.hourlyRate,
+ workContent: node.workContent
+ }));
+ } else {
form.value.savePlanNodeList = [createDefaultNode()];
}
} else {
// 鏂板妯″紡
resetForm();
}
+ // 鍒濆鍖栨嫋鎷�
+ nextTick(() => {
+ initSortable();
+ });
}
});
watch(visible, (val) => {
emit('update:modelValue', val);
});
+
+/** 鍒濆鍖栨嫋鎷� */
+function initSortable() {
+ const el = document.querySelector('.drag-table .el-table__body-wrapper tbody');
+ if (!el) return;
+
+ if (sortable) {
+ sortable.destroy();
+ }
+
+ sortable = Sortable.create(el, {
+ handle: '.drag-handle',
+ animation: 150,
+ onEnd: ({ newIndex, oldIndex }) => {
+ const targetRow = form.value.savePlanNodeList.splice(oldIndex, 1)[0];
+ form.value.savePlanNodeList.splice(newIndex, 0, targetRow);
+ }
+ });
+}
/** 鍒涘缓榛樿鑺傜偣瀵硅薄 */
function createDefaultNode() {
@@ -227,6 +273,7 @@
name: '',
description: '',
attachmentIds: [],
+ attachmentList: [],
savePlanNodeList: [createDefaultNode()]
};
if (formRef.value) {
@@ -254,12 +301,38 @@
}
}
-/** 澶勭悊鏂囦欢鍙樺寲 */
-function handleFileChange(file) {
- // 杩欓噷瀹炵幇鏂囦欢涓婁紶閫昏緫锛岃幏鍙� attachmentId
- ElMessage.info('姝e湪涓婁紶: ' + file.name);
- // 妯℃嫙涓婁紶鎴愬姛
- // form.value.attachmentIds.push(newId);
+/** 澶勭悊鏂囦欢涓婁紶鎴愬姛 */
+function handleUploadSuccess(response, file, fileList) {
+ if (response.code === 200) {
+ ElMessage.success('涓婁紶鎴愬姛');
+ // 鍋囪鍚庣杩斿洖鐨勬暟鎹粨鏋勪腑鍖呭惈鏂囦欢ID鍜孶RL绛変俊鎭�
+ // 杩欓噷闇�瑕佹牴鎹疄闄呮帴鍙h繑鍥炵粨鏋勮繘琛岃皟鏁�
+ // 閫氬父 response.data 鍖呭惈鏂囦欢淇℃伅
+ const newFile = response.data;
+ if (newFile && newFile.id) {
+ form.value.attachmentIds.push(newFile.id);
+ form.value.attachmentList.push({
+ name: file.name,
+ url: newFile.url,
+ id: newFile.id
+ });
+ }
+ } else {
+ ElMessage.error(response.msg || '涓婁紶澶辫触');
+ }
+}
+
+/** 澶勭悊鏂囦欢绉婚櫎 */
+function handleRemove(file) {
+ const index = form.value.attachmentList.findIndex(item => item.name === file.name);
+ if (index !== -1) {
+ const fileId = form.value.attachmentList[index].id;
+ form.value.attachmentList.splice(index, 1);
+ const idIndex = form.value.attachmentIds.indexOf(fileId);
+ if (idIndex !== -1) {
+ form.value.attachmentIds.splice(idIndex, 1);
+ }
+ }
}
/** 娣诲姞姝ラ */
@@ -294,6 +367,10 @@
try {
const valid = await formRef.value.validate();
if (valid) {
+ // 鎻愪氦鍓嶈嚜鍔ㄥ~鍏� sort 瀛楁锛屾寜褰撳墠鏁扮粍椤哄簭鎺掑簭
+ form.value.savePlanNodeList.forEach((node, index) => {
+ node.sort = index;
+ });
emit('submit', form.value);
}
} catch (error) {
@@ -382,4 +459,10 @@
gap: 15px;
padding-top: 10px;
}
+.top-tip {
+
+ font-size: 14px;
+ color: #606266;
+ margin:0 0 10px 10px;
+}
</style>
--
Gitblit v1.9.3