From ac540b51fc76deec7289498a3cf7569970ffd73d Mon Sep 17 00:00:00 2001
From: rain <1679827795@qq.com>
Date: Mon, 14 Apr 2025 18:50:22 +0800
Subject: [PATCH] 新建工单样式优化
---
src/views/tickets/ticket.vue | 399 +++++++++++++++++++++++++++++++++++---------------------
1 files changed, 249 insertions(+), 150 deletions(-)
diff --git a/src/views/tickets/ticket.vue b/src/views/tickets/ticket.vue
index e57bfd7..0745d79 100644
--- a/src/views/tickets/ticket.vue
+++ b/src/views/tickets/ticket.vue
@@ -57,11 +57,9 @@
<!-- 新建工单对话框 -->
<el-dialog v-model="dialogVisible" title="新建工单" width="70%" :close-on-click-modal="false" @close="resetForm">
- <el-form :model="form" :rules="rules" ref="form" label-width="100px" class="create-ticket-form">
- <!-- 基本信息 -->
+ <el-form :model="form" :rules="rules" ref="form" label-width="90px" class="create-ticket-form">
<div class="form-section">
- <div class="section-title">基本信息</div>
- <el-row :gutter="12">
+ <el-row :gutter="16">
<el-col :span="12">
<el-form-item label="工单名称" prop="name">
<el-input v-model="form.name" placeholder="请输入工单名称"></el-input>
@@ -75,11 +73,11 @@
</el-form-item>
</el-col>
</el-row>
- <el-row :gutter="12">
+
+ <el-row :gutter="16">
<el-col :span="12">
<el-form-item label="所属部门" prop="department">
- <el-select v-model="form.department" placeholder="请选择所属部门" @change="handleDepartmentChange"
- class="full-width">
+ <el-select v-model="form.department" placeholder="请选择所属部门" @change="handleDepartmentChange" class="full-width">
<el-option v-for="dept in departments" :key="dept.value" :label="dept.label" :value="dept.value" />
</el-select>
</el-form-item>
@@ -92,7 +90,8 @@
</el-form-item>
</el-col>
</el-row>
- <el-row :gutter="12">
+
+ <el-row :gutter="16">
<el-col :span="12">
<el-form-item label="关联算法" prop="algorithm">
<el-select v-model="form.algorithm" placeholder="请选择关联算法" class="full-width">
@@ -100,56 +99,53 @@
</el-select>
</el-form-item>
</el-col>
- </el-row>
- </div>
-
- <!-- 修改位置信息部分 -->
- <div class="form-section">
- <div class="section-title">位置信息</div>
- <el-row :gutter="12">
- <el-col :span="24">
- <el-form-item label="地图选址" prop="location">
- <div class="map-select">
- <!-- 替换地图为按钮 -->
- <avue-input-map v-model="form.location" :params="mapParams" @change="handleLocationChange"
- type="button">
- <el-button type="primary" plain>
- <i class="el-icon-map-location"></i> 选择位置
+ <el-col :span="12">
+ <el-form-item label="选择位置" prop="location">
+ <div class="location-wrapper">
+ <avue-input-map v-model="form.location" :params="mapParams" @change="handleLocationChange" type="button">
+ <el-button type="primary" plain class="map-button">
+ <i class="el-icon-map-location"></i> 地图选点
</el-button>
</avue-input-map>
-
- <!-- 添加位置信息显示 -->
- <div v-if="form.location && form.location.length >= 2" class="selected-location">
- <p>已选位置: {{ formatLocation(form.location) }}</p>
- <p>详细地址: {{ form.address || '获取中...' }}</p>
- </div>
+ <div v-if="form.location?.length >= 2" class="location-text">{{ form.address || '获取地址中...' }}</div>
</div>
</el-form-item>
</el-col>
</el-row>
- </div>
- <!-- 工单内容 -->
- <div class="form-section">
- <div class="section-title">工单内容</div>
- <el-form-item label="工单描述" prop="content">
- <el-input type="textarea" v-model="form.content" rows="3" placeholder="请输入工单内容描述" resize="none"></el-input>
- </el-form-item>
- <el-form-item label="附件图片" class="upload-item">
- <el-upload ref="upload" :action="'#'" :auto-upload="false" list-type="picture-card"
- :on-change="handleFileChange" :on-remove="handleUploadRemove" :before-upload="beforeUpload"
- :file-list="form.photos" :limit="1" accept="image/*">
- <i class="el-icon-plus"></i>
- </el-upload>
- <div class="el-upload__tip">支持jpg/png格式图片,最多1张,单张不超过5MB</div>
- </el-form-item>
+ <el-row :gutter="16">
+ <el-col :span="12">
+ <el-form-item label="工单内容" prop="content">
+ <el-input type="textarea" v-model="form.content" :rows="4" placeholder="请输入工单内容描述"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="附件图片" prop="photos" class="upload-wrapper">
+ <el-upload ref="upload"
+ :action="'#'"
+ :auto-upload="false"
+ list-type="picture-card"
+ :on-change="handleFileChange"
+ :on-remove="handleUploadRemove"
+ :before-upload="beforeUpload"
+ :file-list="form.photos"
+ :limit="1"
+ accept="image/*"
+ class="uploader"
+ >
+ <i class="el-icon-plus"></i>
+ </el-upload>
+ <div class="upload-tip">支持jpg/png格式图片,单张不超过5MB</div>
+ </el-form-item>
+ </el-col>
+ </el-row>
</div>
</el-form>
<template #footer>
<div class="dialog-footer">
- <el-button size="small" @click="dialogVisible = false">取 消</el-button>
- <el-button size="small" type="info" @click="saveDraft">存草稿</el-button>
- <el-button size="small" type="primary" @click="submitForm">提 交</el-button>
+ <el-button type="danger" @click="submitForm">确认提交</el-button>
+ <el-button type="primary" plain @click="saveDraft">存草稿</el-button>
+ <el-button @click="dialogVisible = false">取 消</el-button>
</div>
</template>
</el-dialog>
@@ -500,6 +496,27 @@
department: [{ required: true, message: '请选择所属部门', trigger: 'change' }],
handler: [{ required: true, message: '请选择处理人员', trigger: 'change' }],
content: [{ required: true, message: '请输入工单内容', trigger: 'blur' }],
+ algorithm: [{ required: true, message: '请选择关联算法', trigger: 'change' }],
+ location: [{
+ validator: (rule, value, callback) => {
+ if (!value || value.length < 2) {
+ callback(new Error('请选择位置信息'));
+ } else {
+ callback();
+ }
+ },
+ trigger: 'change'
+ }],
+ photos: [{
+ validator: (rule, value, callback) => {
+ if (!this.form.photos || this.form.photos.length === 0) {
+ callback(new Error('请上传工单图片'));
+ } else {
+ callback();
+ }
+ },
+ trigger: 'change'
+ }],
},
departmentUsers: {},
loading: false,
@@ -523,6 +540,7 @@
}, // 新增:派发表单验证规则
stepInfos: [], // 新增:存储步骤信息
fixedStatuses: ["2", "0", "3", "4", "5"], // 固定的五个状态
+ userNameToIdMap: {}, // 新增用户名到ID的映射
};
},
created() {
@@ -703,6 +721,16 @@
label: item.dict_value, // 修改为 label
value: item.dict_key, // 修改为 value
}));
+
+ // 构建用户ID和名称的映射关系
+ this.userNameToIdMap = {};
+ dept_data.forEach(dept => {
+ (dept.user_data || []).forEach(user => {
+ this.userNameToIdMap[user.name] = user.id;
+ });
+ });
+
+ console.log('用户名到ID的映射:', this.userNameToIdMap);
} catch (error) {
console.error('获取下拉框数据失败:', error);
this.$message.error('加载下拉框数据失败');
@@ -796,53 +824,63 @@
},
async submitForm() {
- this.$refs.form.validate(async (valid) => {
- if (valid) {
- if (!this.form.location || this.form.location.length < 2) {
- this.$message.warning('请在地图上选择位置');
- return;
- }
-
- try {
- const submitData = {
- eventName: this.form.name,
- content: this.form.content, // 传递工单内容
- workType: "1",
- longitude: String(this.form.location[0]),
- latitude: String(this.form.location[1]),
- address: this.form.address,
- eventDictKey: this.form.type,
- aiType: this.form.algorithm,
- updateUser: this.form.handler,
- createDept: this.form.department,
- isDraft: 0
- };
-
- // 如果是编辑状态,添加 id
- if (this.form.id) {
- submitData.id = this.form.id;
- }
-
- // 获取文件对象
- let file = null;
- if (this.form.photos && this.form.photos.length > 0) {
- file = this.form.photos[0].raw;
- }
-
- const response = await createTicket(submitData, file);
- if (response.data.code === 0) {
- this.$message.success('工单创建成功');
- this.dialogVisible = false;
- this.fetchTableData();
- } else {
- throw new Error(response.data.msg || '创建失败');
- }
- } catch (error) {
- console.error('提交失败:', error);
- this.$message.error(error.message || '工单创建失败,请稍后重试');
- }
+ try {
+ // 提交时需要完整验证
+ await this.$refs.form.validate();
+
+ // 验证位置信息
+ if (!this.form.location || this.form.location.length < 2) {
+ this.$message.warning('请在地图上选择位置');
+ return;
}
- });
+
+ // 验证图片上传
+ if (!this.form.photos || this.form.photos.length === 0) {
+ this.$message.warning('请上传工单图片');
+ return;
+ }
+
+ const submitData = {
+ eventName: this.form.name,
+ content: this.form.content,
+ workType: "1",
+ longitude: String(this.form.location[0]),
+ latitude: String(this.form.location[1]),
+ address: this.form.address,
+ eventDictKey: this.form.type,
+ aiType: this.form.algorithm,
+ updateUser: this.form.handler,
+ createDept: this.form.department,
+ isDraft: 0
+ };
+
+ if (this.form.id) {
+ submitData.id = this.form.id;
+ }
+
+ // 获取文件对象
+ const file = this.form.photos[0].raw;
+ if (!file) {
+ this.$message.warning('图片文件无效,请重新上传');
+ return;
+ }
+
+ const response = await createTicket(submitData, file);
+ if (response.data.code === 0) {
+ this.$message.success('工单创建成功');
+ this.dialogVisible = false;
+ this.fetchTableData();
+ } else {
+ throw new Error(response.data.msg || '创建失败');
+ }
+ } catch (error) {
+ console.error('提交失败:', error);
+ if (error.message.includes('验证未通过')) {
+ this.$message.warning('请填写完整的工单信息');
+ } else {
+ this.$message.error(error.message || '工单创建失败,请稍后重试');
+ }
+ }
},
async saveDraft() {
@@ -850,7 +888,7 @@
const submitData = {
id: this.form.id,
eventName: this.form.name || undefined,
- content: this.form.content || undefined, // 传递工单内容
+ content: this.form.content || undefined,
workType: "1",
longitude: this.form.location?.[0] ? String(this.form.location[0]) : undefined,
latitude: this.form.location?.[1] ? String(this.form.location[1]) : undefined,
@@ -862,14 +900,10 @@
isDraft: 1
};
- // 确保即使为空字符串也会传入 content
- if (this.form.content !== undefined) {
- submitData.content = this.form.content;
- }
-
- // 如果是编辑状态,添加 id
- if (this.form.id) {
- submitData.id = this.form.id;
+ // 草稿时也至少需要工单名称
+ if (!submitData.eventName) {
+ this.$message.warning('请至少输入工单名称');
+ return;
}
// 过滤掉所有 undefined 的字段
@@ -877,13 +911,12 @@
submitData[key] === undefined && delete submitData[key]
);
- // 获取文件对象
let file = null;
if (this.form.photos && this.form.photos.length > 0) {
file = this.form.photos[0].raw;
}
- const response = await createTicket(submitData, file); // 使用 createTicket 而不是 flowEvent
+ const response = await createTicket(submitData, file);
if (response.data.code === 0) {
this.$message.success('草稿保存成功');
this.dialogVisible = false;
@@ -1322,6 +1355,7 @@
if (this.currentDetail.status !== 3) {
this.$message.warning('只有处理中状态的工单可以提交处理详情');
return;
+
}
try {
@@ -1451,22 +1485,51 @@
// 添加编辑方法
handleEdit(row) {
- // 从原始数据中获取 id 和 dept_id
- const originalDeptId = row.department?.value || row.dept_id;
+ console.log('编辑原始数据:', row);
+
+ // 尝试从row.dept_id或通过部门名称查找对应的部门ID
+ let deptId = row.dept_id; // 优先使用原始数据中的dept_id
+
+ // 如果没有dept_id,则通过部门名称查找
+ if (!deptId) {
+ // 输出所有可用的部门数据用于调试
+ console.log('可用部门列表:', this.departments);
+ console.log('当前部门名称:', row.department);
+
+ const deptInfo = this.departments.find(dept =>
+ dept.label && dept.label.trim() === row.department.trim()
+ );
+ deptId = deptInfo?.value;
+ }
+
+ // 获取工单类型值 - 从types中找到匹配的值
+ const typeValue = this.types.find(t => t.label === row.type)?.value || row.event_dict_key;
+
+ // 获取处理人ID - 使用userNameToIdMap映射
+ const handlerId = this.userNameToIdMap[row.handler] || row.handler;
+
+ console.log('数据映射:', {
+ 部门名称: row.department,
+ 找到的部门ID: deptId,
+ 原始处理人: row.handler,
+ 处理人ID: handlerId,
+ 原始工单类型: row.type,
+ 映射后类型值: typeValue
+ });
this.form = {
- id: row.id, // 保存原始 id
+ id: row.id,
name: row.orderName,
- type: row.event_dict_key, // 使用原始 key 值
- department: originalDeptId,
- handler: row.handler,
- algorithm: row.content,
+ type: typeValue,
+ department: deptId,
+ handler: handlerId, // 使用映射后的处理人ID
+ algorithm: row.aiType,
location: row.location,
address: row.address,
content: row.content,
photos: [],
- content: row.content,
};
+
// 如果有图片,添加到表单中
if (row.photo_url) {
this.form.photos = [{
@@ -1474,9 +1537,9 @@
url: row.photo_url
}];
}
+
this.dialogVisible = true;
},
-
// 添加删除方法
handleDelete(row) {
this.$confirm('确认删除该工单?', '提示', {
@@ -1588,69 +1651,105 @@
}
.create-ticket-form {
- padding: 10px;
+ padding: 20px 10px;
.form-section {
- margin-bottom: 15px;
- background: #f8f9fa;
+ background-color: #fff;
border-radius: 4px;
- padding: 12px;
- .section-title {
- font-size: 14px;
- font-weight: 500;
- color: #303133;
- margin-bottom: 12px;
- padding-left: 8px;
- border-left: 3px solid #409EFF;
- }
+ .el-row {
+ margin-bottom: 16px;
- .el-form-item {
- margin-bottom: 12px;
+ &:last-child {
+ margin-bottom: 0;
+ }
}
}
- .map-select {
- display: flex;
- align-items: center;
- gap: 10px;
+ .location-wrapper {
+ .map-button {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ i {
+ margin-right: 4px;
+ }
+ }
.location-text {
+ margin-top: 8px;
+ padding: 8px 12px;
+ background-color: #f5f7fa;
+ border-radius: 4px;
color: #606266;
font-size: 13px;
+ line-height: 1.4;
}
}
- .upload-item {
- margin-bottom: 0;
- }
+ .upload-wrapper {
+ .uploader {
+ :deep(.el-upload--picture-card) {
+ width: 120px;
+ height: 120px;
+ line-height: 128px;
+ }
- .ticket-upload {
- :deep(.el-upload--picture-card) {
- width: 100px;
- height: 100px;
- line-height: 100px;
- margin: 0 8px 8px 0;
+ :deep(.el-upload-list__item) {
+ width: 120px;
+ height: 120px;
+ }
}
- :deep(.el-upload-list--picture-card .el-upload-list__item) {
- width: 100px;
- height: 100px;
- margin: 0 8px 8px 0;
+ .upload-tip {
+ font-size: 12px;
+ color: #909399;
+ line-height: 1.4;
+ margin-top: 8px;
}
}
- .el-upload__tip {
- font-size: 12px;
- color: #909399;
- line-height: 1.2;
- margin-top: 5px;
+ .el-form-item {
+ margin-bottom: 18px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ :deep(.el-form-item__label) {
+ font-weight: 500;
+ color: #606266;
+ }
+
+ :deep(.el-input__inner) {
+ height: 36px;
+ line-height: 36px;
+ }
+
+ :deep(.el-textarea__inner) {
+ padding: 8px 12px;
}
}
.dialog-footer {
text-align: right;
- padding-top: 10px;
+ padding-top: 16px;
+ border-top: 1px solid #ebeef5;
+
+ .el-button + .el-button {
+ margin-left: 12px;
+ }
+
+ .el-button {
+ padding: 9px 20px;
+
+ &:last-child {
+ margin-left: 12px;
+ }
+ }
}
.map-container {
--
Gitblit v1.9.3