0924
This commit is contained in:
@ -34,7 +34,7 @@ export const delxunjian = (ids) => {
|
|||||||
//查询人员
|
//查询人员
|
||||||
export const xunjianUserlist = (query) => {
|
export const xunjianUserlist = (query) => {
|
||||||
return request({
|
return request({
|
||||||
url: '/ops/constructionUser/list',
|
url: '/system/user/list',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params: query
|
||||||
});
|
});
|
||||||
|
|||||||
@ -605,13 +605,14 @@ const formatDate = (dateString) => {
|
|||||||
const getUsersList = async () => {
|
const getUsersList = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await xunjianUserlist();
|
const response = await xunjianUserlist();
|
||||||
const userRows = response?.data?.rows || response?.rows || [];
|
// 适配新接口格式:检查code为200且rows为数组
|
||||||
|
const userRows = response.code === 200 && response.rows && Array.isArray(response.rows) ? response.rows : [];
|
||||||
|
|
||||||
userList.value = userRows
|
userList.value = userRows
|
||||||
.filter((item) => item && typeof item === 'object')
|
.filter((item) => item && typeof item === 'object')
|
||||||
.map((item, index) => ({
|
.map((item) => ({
|
||||||
label: item.userName || `用户${index + 1}`,
|
label: item.userName || '未知用户',
|
||||||
value: item.id || `id_${index}`
|
value: String(item.userId || '') // 使用userId作为唯一标识
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (userList.value.length === 0) {
|
if (userList.value.length === 0) {
|
||||||
|
|||||||
@ -12,9 +12,6 @@
|
|||||||
<div class="nav-tab active" @click="handleInspection7">运维组织</div>
|
<div class="nav-tab active" @click="handleInspection7">运维组织</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 页面标题 -->
|
|
||||||
<TitleComponent title="运维组织模块" subtitle="实时监控人员状态、车辆状态和班组状态"></TitleComponent>
|
|
||||||
|
|
||||||
<!-- 选项卡 -->
|
<!-- 选项卡 -->
|
||||||
<div class="tabs-wrapper">
|
<div class="tabs-wrapper">
|
||||||
<div style="display: flex; align-items: center; gap: 10px">
|
<div style="display: flex; align-items: center; gap: 10px">
|
||||||
@ -182,7 +179,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue';
|
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import TitleComponent from './TitleComponent.vue';
|
|
||||||
import * as echarts from 'echarts'; // 导入ECharts
|
import * as echarts from 'echarts'; // 导入ECharts
|
||||||
import renwuImage from '@/assets/images/renwu.png';
|
import renwuImage from '@/assets/images/renwu.png';
|
||||||
|
|
||||||
|
|||||||
@ -10,8 +10,6 @@
|
|||||||
<div class="nav-tab" @click="handleInspection6">工单管理</div>
|
<div class="nav-tab" @click="handleInspection6">工单管理</div>
|
||||||
<div class="nav-tab" @click="handleInspection7">运维组织</div>
|
<div class="nav-tab" @click="handleInspection7">运维组织</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 页面标题 -->
|
|
||||||
<TitleComponent title="报修管理模块" subtitle="创建报修任务,跟进报修记录,管理维修进度"></TitleComponent>
|
|
||||||
|
|
||||||
<!-- 选项卡 -->
|
<!-- 选项卡 -->
|
||||||
<div class="tabs-wrapper">
|
<div class="tabs-wrapper">
|
||||||
@ -385,7 +383,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import TitleComponent from './TitleComponent.vue';
|
|
||||||
import { baoxiulist, baoxiuDetail, updatebaoxiu, addbaoxiu } from '@/api/zhinengxunjian/baoxiou/index';
|
import { baoxiulist, baoxiuDetail, updatebaoxiu, addbaoxiu } from '@/api/zhinengxunjian/baoxiou/index';
|
||||||
import { xunjianUserlist } from '@/api/zhinengxunjian/xunjian';
|
import { xunjianUserlist } from '@/api/zhinengxunjian/xunjian';
|
||||||
import { ElMessage, ElLoading } from 'element-plus';
|
import { ElMessage, ElLoading } from 'element-plus';
|
||||||
@ -632,10 +630,10 @@ const getUsersList = async () => {
|
|||||||
const res = await xunjianUserlist();
|
const res = await xunjianUserlist();
|
||||||
// 根据接口返回格式,成功码是200,用户数据在rows数组中
|
// 根据接口返回格式,成功码是200,用户数据在rows数组中
|
||||||
if (res.code === 200 && res.rows && Array.isArray(res.rows)) {
|
if (res.code === 200 && res.rows && Array.isArray(res.rows)) {
|
||||||
// 映射用户数据,将id转换为字符串以避免大整数精度问题
|
// 映射用户数据,使用userId字段作为唯一标识并转换为字符串以避免大整数精度问题
|
||||||
usersList.value = res.rows.map((user) => ({
|
usersList.value = res.rows.map((user) => ({
|
||||||
id: String(user.id),
|
id: String(user.userId || ''),
|
||||||
name: user.userName
|
name: user.userName || '未知用户'
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
usersList.value = [];
|
usersList.value = [];
|
||||||
|
|||||||
@ -12,9 +12,6 @@
|
|||||||
<div class="nav-tab" @click="handleInspection7">运维组织</div>
|
<div class="nav-tab" @click="handleInspection7">运维组织</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 页面标题 -->
|
|
||||||
<TitleComponent title="报修管理模块" subtitle="创建报修任务,跟进报修记录,管理维修进度"></TitleComponent>
|
|
||||||
|
|
||||||
<!-- 选项卡 -->
|
<!-- 选项卡 -->
|
||||||
<div class="tabs-wrapper">
|
<div class="tabs-wrapper">
|
||||||
<div style="display: flex; align-items: center; gap: 10px">
|
<div style="display: flex; align-items: center; gap: 10px">
|
||||||
@ -369,7 +366,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import TitleComponent from './TitleComponent.vue';
|
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { baoxiulist, baoxiuDetail, baoxiuRecord, updatebaoxiu } from '@/api/zhinengxunjian/baoxiou/index';
|
import { baoxiulist, baoxiuDetail, baoxiuRecord, updatebaoxiu } from '@/api/zhinengxunjian/baoxiou/index';
|
||||||
import { xunjianUserlist } from '@/api/zhinengxunjian/xunjian';
|
import { xunjianUserlist } from '@/api/zhinengxunjian/xunjian';
|
||||||
@ -498,10 +494,10 @@ const getUsersList = async () => {
|
|||||||
const res = await xunjianUserlist();
|
const res = await xunjianUserlist();
|
||||||
// 根据接口返回格式,成功码是200,用户数据在rows数组中
|
// 根据接口返回格式,成功码是200,用户数据在rows数组中
|
||||||
if (res.code === 200 && res.rows && Array.isArray(res.rows)) {
|
if (res.code === 200 && res.rows && Array.isArray(res.rows)) {
|
||||||
// 映射用户数据,将id转换为字符串以避免大整数精度问题
|
// 映射用户数据,使用userId字段作为唯一标识并转换为字符串以避免大整数精度问题
|
||||||
usersList.value = res.rows.map((user) => ({
|
usersList.value = res.rows.map((user) => ({
|
||||||
id: String(user.id),
|
id: String(user.userId || ''),
|
||||||
name: user.userName
|
name: user.userName || '未知用户'
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
usersList.value = [];
|
usersList.value = [];
|
||||||
|
|||||||
@ -12,8 +12,6 @@
|
|||||||
<div class="nav-tab active" @click="handleInspection7">运维组织</div>
|
<div class="nav-tab active" @click="handleInspection7">运维组织</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 页面标题 -->
|
|
||||||
<TitleComponent title="运维组织模块" subtitle="实时监控人员状态、车辆状态和班组状态"></TitleComponent>
|
|
||||||
|
|
||||||
<!-- 选项卡 -->
|
<!-- 选项卡 -->
|
||||||
<div class="tabs-wrapper">
|
<div class="tabs-wrapper">
|
||||||
@ -139,7 +137,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import TitleComponent from './TitleComponent.vue';
|
|
||||||
|
|
||||||
// 搜索和筛选条件
|
// 搜索和筛选条件
|
||||||
const searchKeyword = ref('');
|
const searchKeyword = ref('');
|
||||||
|
|||||||
@ -91,27 +91,37 @@
|
|||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<!-- 已接单状态 -->
|
<!-- 已接单状态 -->
|
||||||
<template v-if="scope.row.status === '已接单'">
|
<template v-if="scope.row.status === '已接单'">
|
||||||
<el-button type="text" @click="handleViewDetail(scope.row)" class="action-btn">查看详情</el-button>
|
<el-button type="text" @click="handleFollow(scope.row)" class="action-btn">跟踪</el-button>
|
||||||
<el-button type="text" @click="handleCancel(scope.row)" class="action-btn cancel-btn">删除</el-button>
|
<el-button type="text" @click="handleCancel(scope.row)" class="action-btn cancel-btn">删除</el-button>
|
||||||
<el-button type="text" @click="handleEdit(scope.row)" class="action-btn">编辑</el-button>
|
<el-button type="text" @click="handleViewDetail(scope.row)" class="action-btn">详情</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 已派单状态 -->
|
||||||
|
<template v-else-if="scope.row.status === '已派单'">
|
||||||
|
<el-button type="text" @click="handleSetTrack(scope.row)" class="action-btn">
|
||||||
|
{{ scope.row.point === '1' ? '取消跟踪' : '跟踪' }}
|
||||||
|
</el-button>
|
||||||
|
<el-button type="text" @click="handleViewDetail(scope.row)" class="action-btn">详情</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 待派单状态 -->
|
<!-- 待派单状态 -->
|
||||||
<template v-else-if="scope.row.status === '待派单'">
|
<template v-else-if="scope.row.status === '待派单'">
|
||||||
|
<el-button type="text" @click="handleAssign(scope.row)" class="action-btn">派单</el-button>
|
||||||
<el-button type="text" @click="handleEdit(scope.row)" class="action-btn">编辑</el-button>
|
<el-button type="text" @click="handleEdit(scope.row)" class="action-btn">编辑</el-button>
|
||||||
<el-button type="text" @click="handleViewDetail(scope.row)" class="action-btn">详情</el-button>
|
<el-button type="text" @click="handleViewDetail(scope.row)" class="action-btn">详情</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 执行中状态 -->
|
<!-- 执行中状态 -->
|
||||||
<template v-else-if="scope.row.status === '执行中'">
|
<template v-else-if="scope.row.status === '执行中'">
|
||||||
|
<el-button type="text" @click="handleCommunicate(scope.row)" class="action-btn">沟通</el-button>
|
||||||
<el-button type="text" @click="handleViewProgress(scope.row)" class="action-btn">查看进度</el-button>
|
<el-button type="text" @click="handleViewProgress(scope.row)" class="action-btn">查看进度</el-button>
|
||||||
<el-button type="text" @click="handleViewDetail(scope.row)" class="action-btn">详情</el-button>
|
<el-button type="text" @click="handleViewDetail(scope.row)" class="action-btn">详情</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 已完成状态 -->
|
<!-- 已完成状态 -->
|
||||||
<template v-else-if="scope.row.status === '已完成'">
|
<template v-else-if="scope.row.status === '已完成'">
|
||||||
<el-button type="text" @click="handleViewDetail(scope.row)" class="action-btn">详情</el-button>
|
|
||||||
<el-button type="text" @click="handleArchive(scope.row)" class="action-btn">归档</el-button>
|
<el-button type="text" @click="handleArchive(scope.row)" class="action-btn">归档</el-button>
|
||||||
|
<el-button type="text" @click="handleViewDetail(scope.row)" class="action-btn">详情</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 默认显示 -->
|
<!-- 默认显示 -->
|
||||||
@ -172,7 +182,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="截止时间*" prop="deadline">
|
<el-form-item label="截止时间*" prop="deadline">
|
||||||
<el-date-picker v-model="createForm.deadline" type="date" placeholder="yyyy/mm/日" format="yyyy/MM/dd" value-format="yyyy/MM/dd" />
|
<el-date-picker v-model="createForm.deadline" type="date" placeholder="请选择日期" value-format="YYYY-MM-DD" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -189,11 +199,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="相关设备/系统">
|
<el-form-item label="相关设备/系统">
|
||||||
<el-select v-model="createForm.relatedEquipment" placeholder="请填写相关设备或系统名称" filterable allow-create>
|
<el-input v-model="createForm.relatedEquipment" placeholder="请输入相关设备或系统名称" />
|
||||||
<el-option label="设备A" value="设备A" />
|
|
||||||
<el-option label="设备B" value="设备B" />
|
|
||||||
<el-option label="系统1" value="系统1" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -201,7 +207,10 @@
|
|||||||
<div class="steps-container">
|
<div class="steps-container">
|
||||||
<div class="step-item" v-for="(step, index) in createForm.steps" :key="index">
|
<div class="step-item" v-for="(step, index) in createForm.steps" :key="index">
|
||||||
<div class="step-number">{{ index + 1 }}</div>
|
<div class="step-number">{{ index + 1 }}</div>
|
||||||
<el-input v-model="step.content" placeholder="输入试验步骤" />
|
<el-input v-model="step.content" placeholder="输入试验步骤" style="flex: 1; margin-right: 10px" />
|
||||||
|
<el-button v-if="createForm.steps.length > 1" type="text" class="delete-step-btn" @click="deleteStep(index)" style="color: #f56c6c">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-button type="text" class="add-step-btn" @click="addStep">添加步骤</el-button>
|
<el-button type="text" class="add-step-btn" @click="addStep">添加步骤</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -275,7 +284,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="detail-item">
|
<div class="detail-item">
|
||||||
<span class="detail-label">创建时间:</span>
|
<span class="detail-label">创建时间:</span>
|
||||||
<span class="detail-value">{{ detailData.sendOrderTime ? formatDate(detailData.sendOrderTime) : '-' }}</span>
|
<span class="detail-value">{{ detailData.createTime ? formatDate(detailData.createTime) : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
@ -332,9 +341,7 @@
|
|||||||
v-for="(node, index) in group.items"
|
v-for="(node, index) in group.items"
|
||||||
:key="node.id"
|
:key="node.id"
|
||||||
:title="node.name"
|
:title="node.name"
|
||||||
:description="`目的: ${node.intendedPurpose || '-'}\n预计时间: ${
|
:description="`目的: ${node.intendedPurpose || '-'}`"
|
||||||
node.intendedTime ? formatDate(node.intendedTime) : '-'
|
|
||||||
}\n完成时间: ${node.finishTime ? formatDate(node.finishTime) : '-'}\n备注: ${node.remark || '-'}`"
|
|
||||||
/>
|
/>
|
||||||
</el-steps>
|
</el-steps>
|
||||||
</div>
|
</div>
|
||||||
@ -381,6 +388,25 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 派单弹窗 -->
|
||||||
|
<el-dialog v-model="assignDialogVisible" title="派单" width="400px" :before-close="cancelAssign">
|
||||||
|
<div class="assign-dialog-content">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">选择执行人:</label>
|
||||||
|
<el-select v-model="selectedExecutor" placeholder="请选择执行人" style="width: 100%" :loading="loadingUsers" filterable>
|
||||||
|
<el-option v-for="item in executors" :key="item.userId" :label="item.userName" :value="item.userId" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="cancelAssign">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmAssign" :loading="assignLoading">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -388,8 +414,9 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, reactive } from 'vue';
|
import { ref, computed, reactive } from 'vue';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import { gongdanlist, addgongdan, gongdanDetail, uploadgongdan } from '@/api/zhinengxunjian/gongdan/index';
|
import { gongdanlist, addgongdan, updategongdan, gongdanDetail, uploadgongdan } from '@/api/zhinengxunjian/gongdan/index';
|
||||||
import { addjiedian } from '@/api/zhinengxunjian/jiedian';
|
import { addjiedian } from '@/api/zhinengxunjian/jiedian';
|
||||||
|
import { xunjianUserlist } from '@/api/zhinengxunjian/xunjian';
|
||||||
import ImageUpload from '@/components/ImageUpload/index.vue';
|
import ImageUpload from '@/components/ImageUpload/index.vue';
|
||||||
import { ElMessageBox } from 'element-plus';
|
import { ElMessageBox } from 'element-plus';
|
||||||
|
|
||||||
@ -442,7 +469,7 @@ const fetchWorkOrderList = async () => {
|
|||||||
type: mapCodeToType(item.type),
|
type: mapCodeToType(item.type),
|
||||||
priority: mapCodeToPriority(item.level),
|
priority: mapCodeToPriority(item.level),
|
||||||
creator: item.sendOrderPersonVo?.userName || '',
|
creator: item.sendOrderPersonVo?.userName || '',
|
||||||
createTime: item.sendOrderTime ? formatDate(item.sendOrderTime) : '',
|
createTime: item.createTime ? formatDate(item.createTime) : item.sendOrderTime ? formatDate(item.sendOrderTime) : '',
|
||||||
deadline: item.endTime ? formatDate(item.endTime) : '',
|
deadline: item.endTime ? formatDate(item.endTime) : '',
|
||||||
status: mapCodeToStatus(item.status),
|
status: mapCodeToStatus(item.status),
|
||||||
executor: item.getOrderPersonVo?.userName || '',
|
executor: item.getOrderPersonVo?.userName || '',
|
||||||
@ -530,19 +557,18 @@ const mapCodeToPriority = (code) => {
|
|||||||
return priorityMap[codeStr] || code;
|
return priorityMap[codeStr] || code;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 日期格式化函数
|
// 日期格式化函数 - 支持datetime格式
|
||||||
const formatDate = (dateString) => {
|
const formatDate = (dateString) => {
|
||||||
if (!dateString) return '';
|
if (!dateString) return '';
|
||||||
const date = new Date(dateString);
|
const date = new Date(dateString);
|
||||||
return date
|
const year = date.getFullYear();
|
||||||
.toLocaleString('zh-CN', {
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
year: 'numeric',
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
month: '2-digit',
|
const hours = String(date.getHours()).padStart(2, '0');
|
||||||
day: '2-digit',
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||||
hour: '2-digit',
|
|
||||||
minute: '2-digit'
|
// 返回与datetime选择器value-format一致的格式
|
||||||
})
|
return `${year}/${month}/${day} ${hours}:${minutes}`;
|
||||||
.replace(/\//g, '-');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 初始化加载数据
|
// 初始化加载数据
|
||||||
@ -692,18 +718,252 @@ const handleCancel = (row) => {
|
|||||||
|
|
||||||
const handleCommunicate = (row) => {
|
const handleCommunicate = (row) => {
|
||||||
console.log('沟通:', row);
|
console.log('沟通:', row);
|
||||||
|
// 这里可以实现沟通功能,例如打开沟通弹窗或跳转到沟通页面
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleArchive = (row) => {
|
const handleArchive = (row) => {
|
||||||
console.log('归档:', row);
|
console.log('归档:', row);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 编辑工单
|
// 派单弹窗相关状态
|
||||||
const handleEdit = (row) => {
|
const assignDialogVisible = ref(false);
|
||||||
console.log('编辑工单:', row);
|
const assignLoading = ref(false);
|
||||||
// 实现编辑功能,可能需要打开编辑弹窗并加载工单数据
|
const currentTaskId = ref('');
|
||||||
|
const currentTaskInfo = ref(null); // 存储当前工单的完整信息
|
||||||
|
const selectedExecutor = ref('');
|
||||||
|
const executors = ref([]);
|
||||||
|
const loadingUsers = ref(false);
|
||||||
|
|
||||||
|
// 派单功能
|
||||||
|
const handleAssign = async (row) => {
|
||||||
|
console.log('派单:', row);
|
||||||
|
currentTaskId.value = row.id;
|
||||||
|
currentTaskInfo.value = row; // 保存完整的工单信息
|
||||||
|
selectedExecutor.value = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 调用xunjianUserlist接口获取用户列表
|
||||||
|
loadingUsers.value = true;
|
||||||
|
const res = await xunjianUserlist();
|
||||||
|
if (res && res.code === 200 && res.rows && Array.isArray(res.rows)) {
|
||||||
|
// 过滤有效用户并格式化数据
|
||||||
|
executors.value = res.rows
|
||||||
|
.filter((user) => user.userId && user.userName)
|
||||||
|
.map((user) => ({
|
||||||
|
userId: user.userId.toString(),
|
||||||
|
userName: user.userName
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
ElMessage.error('获取用户列表失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取用户列表异常:', error);
|
||||||
|
ElMessage.error('获取用户列表失败,请稍后重试');
|
||||||
|
} finally {
|
||||||
|
loadingUsers.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开派单弹窗
|
||||||
|
assignDialogVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 确认派单
|
||||||
|
const confirmAssign = async () => {
|
||||||
|
if (!selectedExecutor.value) {
|
||||||
|
ElMessage.warning('请选择执行人');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
assignLoading.value = true;
|
||||||
|
// 调用updategongdan接口来执行派单操作
|
||||||
|
// 从执行人列表中查找选中的执行人信息
|
||||||
|
const selectedExecutorInfo = executors.value.find((item) => item.userId === selectedExecutor.value);
|
||||||
|
|
||||||
|
// 先获取完整的工单详情,确保有所有必要字段(与编辑弹窗一样的方式)
|
||||||
|
const detailResponse = await gongdanDetail(currentTaskId.value);
|
||||||
|
if (detailResponse.code !== 200) {
|
||||||
|
ElMessage.error('获取工单详情失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取完整的工单数据
|
||||||
|
const workOrderDetail = detailResponse.data;
|
||||||
|
|
||||||
|
// 在完整工单数据基础上进行修改(与编辑弹窗一样的方式)
|
||||||
|
const updateData = {
|
||||||
|
...workOrderDetail,
|
||||||
|
// 状态更新为已派单(根据系统状态映射,2表示已派单)
|
||||||
|
status: 2,
|
||||||
|
// 设置执行人ID
|
||||||
|
handler: selectedExecutor.value,
|
||||||
|
// 设置执行人姓名
|
||||||
|
handlerName: selectedExecutorInfo?.userName || '',
|
||||||
|
// 设置派单人ID(根据qiangxiujilu.vue的实现,同时提供getOrderPerson和sendPerson两个字段)
|
||||||
|
getOrderPerson: selectedExecutor.value,
|
||||||
|
sendPerson: selectedExecutor.value,
|
||||||
|
// 设置派单人Vo对象(包含id和userName)
|
||||||
|
getOrderPersonVo: selectedExecutorInfo
|
||||||
|
? {
|
||||||
|
id: selectedExecutor.value,
|
||||||
|
userName: selectedExecutorInfo.userName
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
// 更新时间
|
||||||
|
updateTime: new Date().toISOString(),
|
||||||
|
// 根据用户要求,在派单时设置派单时间
|
||||||
|
sendOrderTime: new Date().toISOString(),
|
||||||
|
// 确保类型字段正确
|
||||||
|
type: workOrderDetail.type || 1
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await updategongdan(updateData);
|
||||||
|
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success('派单成功');
|
||||||
|
assignDialogVisible.value = false;
|
||||||
|
|
||||||
|
// 刷新工单列表以显示更新后的状态
|
||||||
|
fetchWorkOrderList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || '派单失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('派单异常:', error);
|
||||||
|
ElMessage.error('派单失败,请稍后重试');
|
||||||
|
} finally {
|
||||||
|
assignLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 取消派单
|
||||||
|
const cancelAssign = () => {
|
||||||
|
assignDialogVisible.value = false;
|
||||||
|
selectedExecutor.value = '';
|
||||||
|
currentTaskId.value = '';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 跟踪功能 - 已接单状态
|
||||||
|
const handleFollow = (row) => {
|
||||||
|
console.log('跟踪:', row);
|
||||||
|
// 这里可以实现跟踪功能,例如显示工单跟踪记录或打开跟踪记录页面
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置跟踪功能 - 已派单状态
|
||||||
|
const handleSetTrack = async (row) => {
|
||||||
|
try {
|
||||||
|
// 获取当前point值,默认为2(不跟踪)
|
||||||
|
const currentPoint = row.point || '2';
|
||||||
|
// 确定新的point值和操作类型
|
||||||
|
const newPoint = currentPoint === '1' ? '2' : '1';
|
||||||
|
const operationText = currentPoint === '1' ? '取消跟踪' : '设置跟踪';
|
||||||
|
|
||||||
|
// 弹出确认对话框
|
||||||
|
await ElMessageBox.confirm(`确定要${operationText}该工单吗?`, '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取完整的工单详情
|
||||||
|
const detailResponse = await gongdanDetail(row.id);
|
||||||
|
if (detailResponse.code !== 200) {
|
||||||
|
ElMessage.error('获取工单详情失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取完整的工单数据
|
||||||
|
const workOrderDetail = detailResponse.data;
|
||||||
|
|
||||||
|
// 在完整工单数据基础上进行修改
|
||||||
|
const updateData = {
|
||||||
|
...workOrderDetail,
|
||||||
|
// 切换point值:1表示跟踪,2表示不跟踪
|
||||||
|
point: newPoint,
|
||||||
|
// 更新时间
|
||||||
|
updateTime: new Date().toISOString()
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await updategongdan(updateData);
|
||||||
|
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success(`${operationText}成功`);
|
||||||
|
// 刷新工单列表以显示更新后的状态
|
||||||
|
fetchWorkOrderList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || `${operationText}失败`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error === 'cancel') {
|
||||||
|
// 用户取消操作,不做处理
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.error('设置跟踪异常:', error);
|
||||||
|
ElMessage.error('设置跟踪失败,请稍后重试');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编辑工单
|
||||||
|
const handleEdit = async (row) => {
|
||||||
|
console.log('编辑工单:', row);
|
||||||
|
try {
|
||||||
|
// 获取工单详情
|
||||||
|
const detailResponse = await gongdanDetail(row.id);
|
||||||
|
if (detailResponse.code !== 200) {
|
||||||
|
ElMessage.error('获取工单详情失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const workOrderDetail = detailResponse.data;
|
||||||
|
|
||||||
|
// 填充表单数据(与新增工单使用同一套表单)
|
||||||
|
createForm.title = workOrderDetail.title || '';
|
||||||
|
createForm.type = mapCodeToType(workOrderDetail.type) || '维护保养';
|
||||||
|
createForm.priority = mapCodeToPriority(workOrderDetail.level) || '低';
|
||||||
|
createForm.deadline = workOrderDetail.endTime ? formatDate(workOrderDetail.endTime) : '';
|
||||||
|
createForm.description = workOrderDetail.info || '';
|
||||||
|
createForm.location = workOrderDetail.position || '';
|
||||||
|
createForm.relatedEquipment = workOrderDetail.device || '';
|
||||||
|
createForm.file = workOrderDetail.fileId || '';
|
||||||
|
createForm.resultDescription = workOrderDetail.results || '';
|
||||||
|
createForm.needAssignee = !!workOrderDetail.executor;
|
||||||
|
|
||||||
|
// 填充步骤数据:从nodes数组中提取并按code排序
|
||||||
|
if (workOrderDetail.nodes && Array.isArray(workOrderDetail.nodes)) {
|
||||||
|
// 复制nodes数组并按code升序排序(与groupNodesByModule函数保持一致的排序逻辑)
|
||||||
|
const sortedNodes = [...workOrderDetail.nodes].sort((a, b) => (a.code || 0) - (b.code || 0));
|
||||||
|
// 转换为createForm.steps所需的格式
|
||||||
|
createForm.steps = sortedNodes.map((node) => ({
|
||||||
|
content: node.intendedPurpose || ''
|
||||||
|
}));
|
||||||
|
// 确保至少有一个空步骤
|
||||||
|
if (createForm.steps.length === 0) {
|
||||||
|
createForm.steps = [{ content: '' }];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果没有nodes数据,重置为默认的一个空步骤
|
||||||
|
createForm.steps = [{ content: '' }];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 存储当前编辑的工单ID,用于区分是创建还是编辑操作
|
||||||
|
editingWorkOrderId.value = row.id;
|
||||||
|
|
||||||
|
// 保存原始创建时间
|
||||||
|
originalCreateTime.value = workOrderDetail.createTime || '';
|
||||||
|
|
||||||
|
// 打开新增工单的弹窗
|
||||||
|
createDialogVisible.value = true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('打开编辑工单弹窗过程中发生错误:', error);
|
||||||
|
ElMessage.error('打开编辑工单弹窗失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编辑状态下的工单ID
|
||||||
|
const editingWorkOrderId = ref('');
|
||||||
|
|
||||||
|
// 保存原始创建时间(编辑工单时使用)
|
||||||
|
const originalCreateTime = ref('');
|
||||||
|
|
||||||
// 查看工单进度
|
// 查看工单进度
|
||||||
const handleViewProgress = (row) => {
|
const handleViewProgress = (row) => {
|
||||||
console.log('查看工单进度:', row);
|
console.log('查看工单进度:', row);
|
||||||
@ -750,6 +1010,16 @@ const addStep = () => {
|
|||||||
createForm.steps.push({ content: '' });
|
createForm.steps.push({ content: '' });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 删除试验步骤
|
||||||
|
const deleteStep = (index) => {
|
||||||
|
// 确保至少保留一个步骤
|
||||||
|
if (createForm.steps.length <= 1) {
|
||||||
|
ElMessage.warning('至少需要保留一个步骤');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
createForm.steps.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
// 提交创建工单
|
// 提交创建工单
|
||||||
const submitCreate = async () => {
|
const submitCreate = async () => {
|
||||||
// 表单验证
|
// 表单验证
|
||||||
@ -795,23 +1065,17 @@ const submitCreate = async () => {
|
|||||||
|
|
||||||
// 准备工单数据
|
// 准备工单数据
|
||||||
const workOrderData = {
|
const workOrderData = {
|
||||||
createTime: new Date().toISOString(),
|
// 编辑模式下使用原始创建时间,创建模式下使用当前时间
|
||||||
|
createTime: editingWorkOrderId.value && originalCreateTime.value ? originalCreateTime.value : new Date().toISOString(),
|
||||||
updateTime: new Date().toISOString(),
|
updateTime: new Date().toISOString(),
|
||||||
params: {},
|
params: {},
|
||||||
module: 1, //
|
module: 1,
|
||||||
projectId: 1, // 假设项目ID为1
|
projectId: 1,
|
||||||
title: createForm.title,
|
title: createForm.title,
|
||||||
type: mapTypeToCode(createForm.type),
|
type: mapTypeToCode(createForm.type),
|
||||||
level: mapPriorityToCode(createForm.priority),
|
level: mapPriorityToCode(createForm.priority),
|
||||||
// 修复RangeError: 添加日期有效性检查
|
// 采用与shiyanguanli页面相同的日期处理方式
|
||||||
endTime: createForm.deadline
|
endTime: createForm.deadline ? new Date(createForm.deadline).toISOString() : '',
|
||||||
? (() => {
|
|
||||||
const deadlineDate = new Date(createForm.deadline);
|
|
||||||
|
|
||||||
return isNaN(deadlineDate.getTime()) ? new Date().toISOString() : deadlineDate.toISOString();
|
|
||||||
})()
|
|
||||||
: new Date().toISOString(),
|
|
||||||
info: createForm.description,
|
info: createForm.description,
|
||||||
position: createForm.location,
|
position: createForm.location,
|
||||||
device: createForm.relatedEquipment || '',
|
device: createForm.relatedEquipment || '',
|
||||||
@ -820,18 +1084,35 @@ const submitCreate = async () => {
|
|||||||
nodeIds: nodeIds,
|
nodeIds: nodeIds,
|
||||||
results: createForm.resultDescription || '',
|
results: createForm.resultDescription || '',
|
||||||
status: 1, // 待派单 1待派单2已派单3执行中4已完成
|
status: 1, // 待派单 1待派单2已派单3执行中4已完成
|
||||||
sendOrderTime: new Date().toISOString(),
|
sendOrderTime: '', // 根据用户要求,只有在派单并选择人员后才赋值
|
||||||
getOrderTime: '',
|
getOrderTime: '',
|
||||||
finishiOrderTime: '',
|
finishiOrderTime: '',
|
||||||
orderResult: '', // 验收结果1通过2需整改
|
orderResult: '', // 验收结果1通过2需整改
|
||||||
point: ''
|
point: '2', // 默认不跟踪(2表示不跟踪,1表示跟踪)
|
||||||
|
createDept: '',
|
||||||
|
createBy: '',
|
||||||
|
handlerDept: '',
|
||||||
|
handler: '',
|
||||||
|
handlerName: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
// 然后调用addgongdan接口
|
let response;
|
||||||
const gongdanResponse = await addgongdan(workOrderData);
|
// 区分创建和编辑操作
|
||||||
|
if (editingWorkOrderId.value) {
|
||||||
|
// 编辑操作:调用updategongdan接口
|
||||||
|
const updateData = {
|
||||||
|
...workOrderData,
|
||||||
|
id: editingWorkOrderId.value
|
||||||
|
};
|
||||||
|
response = await updategongdan(updateData);
|
||||||
|
} else {
|
||||||
|
// 创建操作:调用addgongdan接口
|
||||||
|
response = await addgongdan(workOrderData);
|
||||||
|
}
|
||||||
|
|
||||||
if (gongdanResponse.code === 200) {
|
if (response.code === 200) {
|
||||||
ElMessage.success('工单创建成功');
|
const successMessage = editingWorkOrderId.value ? '工单编辑成功' : '工单创建成功';
|
||||||
|
ElMessage.success(successMessage);
|
||||||
createDialogVisible.value = false;
|
createDialogVisible.value = false;
|
||||||
|
|
||||||
// 重置表单
|
// 重置表单
|
||||||
@ -843,10 +1124,15 @@ const submitCreate = async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 重置编辑状态
|
||||||
|
editingWorkOrderId.value = '';
|
||||||
|
originalCreateTime.value = '';
|
||||||
|
|
||||||
// 刷新工单列表
|
// 刷新工单列表
|
||||||
fetchWorkOrderList();
|
fetchWorkOrderList();
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error('工单创建失败');
|
const errorMessage = editingWorkOrderId.value ? '工单编辑失败' : '工单创建失败';
|
||||||
|
ElMessage.error(errorMessage);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 增加详细的错误信息日志
|
// 增加详细的错误信息日志
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -771,7 +771,7 @@ const getUsersList = async () => {
|
|||||||
try {
|
try {
|
||||||
const res = await xunjianUserlist();
|
const res = await xunjianUserlist();
|
||||||
if (res.code === 200 && res.rows && Array.isArray(res.rows)) {
|
if (res.code === 200 && res.rows && Array.isArray(res.rows)) {
|
||||||
usersList.value = res.rows.map((user) => ({ id: String(user.id), name: user.userName }));
|
usersList.value = res.rows.map((user) => ({ id: String(user.userId || ''), name: user.userName || '未知用户' }));
|
||||||
} else {
|
} else {
|
||||||
usersList.value = [];
|
usersList.value = [];
|
||||||
ElMessage.error('获取用户列表失败');
|
ElMessage.error('获取用户列表失败');
|
||||||
|
|||||||
@ -14,12 +14,7 @@
|
|||||||
|
|
||||||
<!-- 页面标题和操作区 -->
|
<!-- 页面标题和操作区 -->
|
||||||
<div class="header-section">
|
<div class="header-section">
|
||||||
<TitleComponent title="抢修管理模块" subtitle="处理紧急抢修任务,跟踪抢修进度和记录"></TitleComponent>
|
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<el-button class="filter-btn" @click="showFilter = !showFilter">
|
|
||||||
筛选
|
|
||||||
<i class="el-icon-arrow-down ml-1"></i>
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" class="export-btn" @click="handleExport"> 导出数据 </el-button>
|
<el-button type="primary" class="export-btn" @click="handleExport"> 导出数据 </el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -32,7 +27,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 筛选栏 (默认隐藏) -->
|
<!-- 筛选栏 (默认隐藏) -->
|
||||||
<div class="filter-bar" v-if="showFilter">
|
<div class="filter-bar">
|
||||||
<div class="filter-container">
|
<div class="filter-container">
|
||||||
<div class="filter-item">
|
<div class="filter-item">
|
||||||
<el-select v-model="taskStatus" placeholder="任务状态">
|
<el-select v-model="taskStatus" placeholder="任务状态">
|
||||||
@ -370,7 +365,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import TitleComponent from './TitleComponent.vue';
|
|
||||||
import { qiangxiuDetail, qiangxiuRecord, qiangxiulist, updateqiangxiu } from '@/api/zhinengxunjian/qiangxiu';
|
import { qiangxiuDetail, qiangxiuRecord, qiangxiulist, updateqiangxiu } from '@/api/zhinengxunjian/qiangxiu';
|
||||||
import { xunjianUserlist } from '@/api/zhinengxunjian/xunjian';
|
import { xunjianUserlist } from '@/api/zhinengxunjian/xunjian';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
@ -754,12 +748,12 @@ const handleAssign = async (record) => {
|
|||||||
try {
|
try {
|
||||||
const res = await xunjianUserlist();
|
const res = await xunjianUserlist();
|
||||||
if (res && res.code === 200) {
|
if (res && res.code === 200) {
|
||||||
// 过滤无效数据+统一sysUserId为字符串
|
// 过滤无效数据+统一userId为字符串
|
||||||
executors.value = (res.rows || [])
|
executors.value = (res.rows || [])
|
||||||
.filter((item) => item.sysUserId && item.userName)
|
.filter((item) => item.userId && item.userName)
|
||||||
.map((item) => ({
|
.map((item) => ({
|
||||||
userId: item.sysUserId.toString(), // 关键:使用sysUserId字段
|
userId: item.userId.toString(), // 使用userId字段
|
||||||
userName: item.userName
|
userName: item.userName || '未知用户'
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -1018,22 +1012,6 @@ const handleInspectionManagement2 = () => {
|
|||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-actions {
|
|
||||||
display: flex;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-btn {
|
|
||||||
background-color: #fff;
|
|
||||||
color: #303133;
|
|
||||||
border-color: #dcdfe6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.export-btn {
|
|
||||||
background-color: #165dff;
|
|
||||||
border-color: #165dff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 选项卡样式 */
|
/* 选项卡样式 */
|
||||||
.tabs-wrapper {
|
.tabs-wrapper {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
@ -1087,21 +1065,14 @@ const handleInspectionManagement2 = () => {
|
|||||||
.filter-actions {
|
.filter-actions {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 10px;
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-btn {
|
.search-btn,
|
||||||
background-color: #f2f3f5;
|
.export-btn,
|
||||||
color: #303133;
|
.create-btn {
|
||||||
border-color: #f2f3f5;
|
height: 36px;
|
||||||
transition: all 0.2s ease;
|
border-radius: 4px;
|
||||||
}
|
|
||||||
|
|
||||||
.search-btn:hover {
|
|
||||||
background-color: #e5e6eb;
|
|
||||||
color: #303133;
|
|
||||||
border-color: #e5e6eb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 统计卡片样式 */
|
/* 统计卡片样式 */
|
||||||
|
|||||||
@ -12,9 +12,6 @@
|
|||||||
<div class="nav-tab active" @click="handleInspection7">运维组织</div>
|
<div class="nav-tab active" @click="handleInspection7">运维组织</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 页面标题 -->
|
|
||||||
<TitleComponent title="运维组织模块" subtitle="实时监控人员状态、车辆状态和班组状态"></TitleComponent>
|
|
||||||
|
|
||||||
<!-- 选项卡 -->
|
<!-- 选项卡 -->
|
||||||
<div class="tabs-wrapper">
|
<div class="tabs-wrapper">
|
||||||
<div style="display: flex; align-items: center; gap: 10px">
|
<div style="display: flex; align-items: center; gap: 10px">
|
||||||
@ -133,7 +130,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, onMounted } from 'vue';
|
import { ref, watch, onMounted } from 'vue';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import TitleComponent from './TitleComponent.vue';
|
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
// 激活的选项卡
|
// 激活的选项卡
|
||||||
|
|||||||
@ -424,6 +424,16 @@
|
|||||||
<div class="step-item" v-for="(step, index) in formData.steps" :key="index">
|
<div class="step-item" v-for="(step, index) in formData.steps" :key="index">
|
||||||
<div class="step-number">{{ index + 1 }}</div>
|
<div class="step-number">{{ index + 1 }}</div>
|
||||||
<el-input v-model="step.content" placeholder="输入试验步骤" />
|
<el-input v-model="step.content" placeholder="输入试验步骤" />
|
||||||
|
<el-button
|
||||||
|
v-if="formData.steps.length > 1"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
class="delete-step-btn"
|
||||||
|
@click="deleteStep(index)"
|
||||||
|
style="color: #f56c6c"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-button type="text" size="small" class="add-step-btn" @click="addStep">添加步骤</el-button>
|
<el-button type="text" size="small" class="add-step-btn" @click="addStep">添加步骤</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -579,6 +589,7 @@ import router from '@/router';
|
|||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import { shiyanDetail, shiyanlist, addshiyan, updateshiyan } from '@/api/zhinengxunjian/shiyan/index';
|
import { shiyanDetail, shiyanlist, addshiyan, updateshiyan } from '@/api/zhinengxunjian/shiyan/index';
|
||||||
import { xunjianUserlist } from '@/api/zhinengxunjian/xunjian/index';
|
import { xunjianUserlist } from '@/api/zhinengxunjian/xunjian/index';
|
||||||
|
import { addjiedian } from '@/api/zhinengxunjian/jiedian/index';
|
||||||
// 1. 选项卡状态管理
|
// 1. 选项卡状态管理
|
||||||
const activeTab = ref('plan'); // 默认为"巡检计划"
|
const activeTab = ref('plan'); // 默认为"巡检计划"
|
||||||
const timeRange = ref('month'); // 统计时间范围:月/周/日
|
const timeRange = ref('month'); // 统计时间范围:月/周/日
|
||||||
@ -839,20 +850,14 @@ const userList = ref([]);
|
|||||||
const getUsersList = async () => {
|
const getUsersList = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await xunjianUserlist();
|
const response = await xunjianUserlist();
|
||||||
const userRows =
|
// 适配新接口格式:检查code为200且rows为数组
|
||||||
response?.data?.rows && Array.isArray(response.data.rows)
|
const userRows = response.code === 200 && response.rows && Array.isArray(response.rows) ? response.rows : [];
|
||||||
? response.data.rows
|
|
||||||
: response?.rows && Array.isArray(response.rows)
|
|
||||||
? response.rows
|
|
||||||
: Array.isArray(response)
|
|
||||||
? response
|
|
||||||
: [];
|
|
||||||
|
|
||||||
userList.value = userRows
|
userList.value = userRows
|
||||||
.filter((item) => item && typeof item === 'object')
|
.filter((item) => item && typeof item === 'object')
|
||||||
.map((item, index) => ({
|
.map((item) => ({
|
||||||
label: item.userName || `用户${index + 1}`,
|
label: item.userName || '未知用户',
|
||||||
value: item.id || `id_${index}`
|
value: String(item.userId || '') // 使用userId作为唯一标识
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (userList.value.length === 0) {
|
if (userList.value.length === 0) {
|
||||||
@ -933,8 +938,40 @@ const handleSave = async () => {
|
|||||||
// 编辑模式:调用更新接口
|
// 编辑模式:调用更新接口
|
||||||
response = await updateshiyan(requestData);
|
response = await updateshiyan(requestData);
|
||||||
} else {
|
} else {
|
||||||
|
// 处理步骤数据格式
|
||||||
|
const stepsData = formData.value.steps
|
||||||
|
.filter((step) => step.content.trim())
|
||||||
|
.map((step, index) => ({
|
||||||
|
createTime: new Date().toISOString(),
|
||||||
|
updateTime: new Date().toISOString(),
|
||||||
|
remark: step.content.trim(),
|
||||||
|
status: '1', // 使用数字代码
|
||||||
|
// module值为2(与工单列表的1不同)
|
||||||
|
module: 2,
|
||||||
|
sort: index + 1
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 首先调用addjiedian接口
|
||||||
|
const jiedianResponse = await addjiedian(stepsData);
|
||||||
|
|
||||||
|
if (jiedianResponse.code !== 200) {
|
||||||
|
ElMessage.error('创建步骤失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取返回的ids,实际返回格式中msg字段包含ids字符串
|
||||||
|
let nodeIds = '';
|
||||||
|
if (jiedianResponse.code === 200 && jiedianResponse.msg) {
|
||||||
|
nodeIds = jiedianResponse.msg;
|
||||||
|
} else {
|
||||||
|
ElMessage.warning('未获取到有效的步骤ID');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 新增模式:调用添加接口(删除请求参数中的id,避免后端报错)
|
// 新增模式:调用添加接口(删除请求参数中的id,避免后端报错)
|
||||||
const { id, ...addData } = requestData;
|
const { id, ...addData } = requestData;
|
||||||
|
// 添加nodeIds字段
|
||||||
|
addData.nodeIds = nodeIds;
|
||||||
response = await addshiyan(addData);
|
response = await addshiyan(addData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1041,10 +1078,22 @@ const handleEditRecord = async (row) => {
|
|||||||
const recordDetail = detailResponse.data.rows?.[0] || detailResponse.data;
|
const recordDetail = detailResponse.data.rows?.[0] || detailResponse.data;
|
||||||
// 兼容两种数据结构:可能在rows数组中,也可能直接在data中
|
// 兼容两种数据结构:可能在rows数组中,也可能直接在data中
|
||||||
|
|
||||||
// 3. 处理testStep:将逗号分隔的字符串转换为步骤数组
|
// 3. 处理步骤数据:优先从nodes数组中提取
|
||||||
const steps = [];
|
const steps = [];
|
||||||
if (recordDetail.testStep) {
|
// 如果有nodes数组,优先从nodes中提取步骤数据
|
||||||
// 拆分字符串(例如 "1. 213,2. 321" → ["1. 213", "2. 321"])
|
if (recordDetail.nodes && Array.isArray(recordDetail.nodes)) {
|
||||||
|
// 复制nodes数组并按code升序排序
|
||||||
|
const sortedNodes = [...recordDetail.nodes].sort((a, b) => (a.code || 0) - (b.code || 0));
|
||||||
|
// 转换为所需的格式
|
||||||
|
sortedNodes.forEach((node) => {
|
||||||
|
if (node.intendedPurpose && node.intendedPurpose.trim()) {
|
||||||
|
steps.push({ content: node.intendedPurpose.trim() });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 如果nodes中没有数据,回退到从testStep字符串解析
|
||||||
|
else if (recordDetail.testStep) {
|
||||||
|
// 拆分字符串
|
||||||
const stepItems = recordDetail.testStep.split(',');
|
const stepItems = recordDetail.testStep.split(',');
|
||||||
stepItems.forEach((stepText) => {
|
stepItems.forEach((stepText) => {
|
||||||
// 移除序号前缀(如"1. "),只保留内容
|
// 移除序号前缀(如"1. "),只保留内容
|
||||||
@ -1137,6 +1186,17 @@ const addStep = () => {
|
|||||||
formData.value.steps.push({ content: '' });
|
formData.value.steps.push({ content: '' });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 删除步骤
|
||||||
|
const deleteStep = (index) => {
|
||||||
|
// 确保至少保留一个步骤
|
||||||
|
if (formData.value.steps.length <= 1) {
|
||||||
|
ElMessage.warning('至少需要保留一个步骤');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 从数组中删除指定索引的步骤
|
||||||
|
formData.value.steps.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
// 添加新设备
|
// 添加新设备
|
||||||
const addEquipment = () => {
|
const addEquipment = () => {
|
||||||
if (newEquipment.value.trim()) {
|
if (newEquipment.value.trim()) {
|
||||||
|
|||||||
@ -482,36 +482,13 @@ const getUsersList = async () => {
|
|||||||
try {
|
try {
|
||||||
const response = await xunjianUserlist({});
|
const response = await xunjianUserlist({});
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
// 从任务数据中提取用户信息
|
// 直接从接口返回的用户列表中提取信息
|
||||||
const usersMap = new Map(); // 使用Map确保id唯一
|
const users = response.rows || [];
|
||||||
const tasks = response.rows || [];
|
|
||||||
|
|
||||||
tasks.forEach((task) => {
|
// 将用户数据转换为所需格式:包含id和userName以适配模板和getUserById函数
|
||||||
// 提取personInfo中的用户信息
|
userList.value = users.map((user) => ({
|
||||||
if (task.personInfo && task.personInfo.id && task.personInfo.userName) {
|
id: user.userId, // 用于标识和查找
|
||||||
usersMap.set(task.personInfo.id, {
|
userName: user.userName // 显示名称
|
||||||
id: task.personInfo.id,
|
|
||||||
userName: task.personInfo.userName
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提取testPlan.persons中的用户信息
|
|
||||||
if (task.testPlan && task.testPlan.persons && Array.isArray(task.testPlan.persons)) {
|
|
||||||
task.testPlan.persons.forEach((person) => {
|
|
||||||
if (person.id && person.userName) {
|
|
||||||
usersMap.set(person.id, {
|
|
||||||
id: person.id,
|
|
||||||
userName: person.userName
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 将Map转换为下拉选择器需要的格式:{ label, value }
|
|
||||||
userList.value = Array.from(usersMap.values()).map((user) => ({
|
|
||||||
label: user.userName, // 显示在下拉框中的文本
|
|
||||||
value: user.id // 选中后的值
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 调试信息,确认数据格式正确
|
// 调试信息,确认数据格式正确
|
||||||
|
|||||||
@ -807,21 +807,14 @@ const planList = ref([]);
|
|||||||
const getUsersList = async () => {
|
const getUsersList = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await xunjianUserlist();
|
const response = await xunjianUserlist();
|
||||||
|
// 适配新接口格式:检查code为200且rows为数组
|
||||||
const userRows =
|
const userRows = response.code === 200 && response.rows && Array.isArray(response.rows) ? response.rows : [];
|
||||||
response?.data?.rows && Array.isArray(response.data.rows)
|
|
||||||
? response.data.rows
|
|
||||||
: response?.rows && Array.isArray(response.rows)
|
|
||||||
? response.rows
|
|
||||||
: Array.isArray(response)
|
|
||||||
? response
|
|
||||||
: [];
|
|
||||||
|
|
||||||
userList.value = userRows
|
userList.value = userRows
|
||||||
.filter((item) => item && typeof item === 'object')
|
.filter((item) => item && typeof item === 'object')
|
||||||
.map((item, index) => ({
|
.map((item) => ({
|
||||||
label: item.userName || `用户${index + 1}`,
|
label: item.userName || '未知用户',
|
||||||
value: item.id || `id_${index}`
|
value: String(item.userId || '') // 使用userId作为唯一标识
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (userList.value.length === 0) {
|
if (userList.value.length === 0) {
|
||||||
|
|||||||
@ -12,9 +12,6 @@
|
|||||||
<div class="nav-tab" @click="handleInspection7">运维组织</div>
|
<div class="nav-tab" @click="handleInspection7">运维组织</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 页面标题 -->
|
|
||||||
<TitleComponent title="工单管理模块" subtitle="发起工单任务,跟踪流程记录和执行情况"></TitleComponent>
|
|
||||||
|
|
||||||
<!-- 子选项卡 -->
|
<!-- 子选项卡 -->
|
||||||
<div class="tabs-wrapper">
|
<div class="tabs-wrapper">
|
||||||
<div style="display: flex; align-items: center; gap: 10px">
|
<div style="display: flex; align-items: center; gap: 10px">
|
||||||
@ -220,7 +217,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import TitleComponent from './TitleComponent.vue';
|
import { gongdanlist, gongdanDetail, updategongdan, delgongdan } from '@/api/zhinengxunjian/gongdan/index';
|
||||||
// 导入Element Plus的Steps组件
|
// 导入Element Plus的Steps组件
|
||||||
import { ElSteps, ElStep } from 'element-plus';
|
import { ElSteps, ElStep } from 'element-plus';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user