feat: fix build issue
This commit is contained in:
62
plus-ui/src/api/inspection/device/index.ts
Normal file
62
plus-ui/src/api/inspection/device/index.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ArDeviceVO, ArDeviceForm, ArDeviceQuery } from '@/api/inspection/device/types';
|
||||
|
||||
/**
|
||||
* 查询AR设备列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
export const listArDevice = (query?: ArDeviceQuery): AxiosPromise<ArDeviceVO[]> => {
|
||||
return request({
|
||||
url: '/inspection/device/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询AR设备详细
|
||||
* @param id
|
||||
*/
|
||||
export const getArDevice = (id: string | number): AxiosPromise<ArDeviceVO> => {
|
||||
return request({
|
||||
url: '/inspection/device/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增AR设备
|
||||
* @param data
|
||||
*/
|
||||
export const addArDevice = (data: ArDeviceForm) => {
|
||||
return request({
|
||||
url: '/inspection/device',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改AR设备
|
||||
* @param data
|
||||
*/
|
||||
export const updateArDevice = (data: ArDeviceForm) => {
|
||||
return request({
|
||||
url: '/inspection/device',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除AR设备
|
||||
* @param id
|
||||
*/
|
||||
export const delArDevice = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/inspection/device/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
90
plus-ui/src/api/inspection/device/types.ts
Normal file
90
plus-ui/src/api/inspection/device/types.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
export interface ArDeviceVO {
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
deviceName: string;
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
*/
|
||||
deviceNo: string;
|
||||
|
||||
/**
|
||||
* 设备型号
|
||||
*/
|
||||
deviceModel: string;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
status: string;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime: string;
|
||||
}
|
||||
|
||||
export interface ArDeviceForm extends BaseEntity {
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
deviceName?: string;
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
*/
|
||||
deviceNo?: string;
|
||||
|
||||
/**
|
||||
* 设备型号
|
||||
*/
|
||||
deviceModel?: string;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
status?: string;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export interface ArDeviceQuery extends PageQuery {
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
deviceName?: string;
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
*/
|
||||
deviceNo?: string;
|
||||
|
||||
/**
|
||||
* 设备型号
|
||||
*/
|
||||
deviceModel?: string;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
status?: string;
|
||||
}
|
||||
62
plus-ui/src/api/inspection/execution/index.ts
Normal file
62
plus-ui/src/api/inspection/execution/index.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ArExecutionVO, ArExecutionForm, ArExecutionQuery } from '@/api/inspection/execution/types';
|
||||
|
||||
/**
|
||||
* 查询任务执行记录列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
export const listArExecution = (query?: ArExecutionQuery): AxiosPromise<ArExecutionVO[]> => {
|
||||
return request({
|
||||
url: '/inspection/execution/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询任务执行记录详细
|
||||
* @param id
|
||||
*/
|
||||
export const getArExecution = (id: string | number): AxiosPromise<ArExecutionVO> => {
|
||||
return request({
|
||||
url: '/inspection/execution/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增任务执行记录
|
||||
* @param data
|
||||
*/
|
||||
export const addArExecution = (data: ArExecutionForm) => {
|
||||
return request({
|
||||
url: '/inspection/execution',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改任务执行记录
|
||||
* @param data
|
||||
*/
|
||||
export const updateArExecution = (data: ArExecutionForm) => {
|
||||
return request({
|
||||
url: '/inspection/execution',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除任务执行记录
|
||||
* @param id
|
||||
*/
|
||||
export const delArExecution = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/inspection/execution/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
240
plus-ui/src/api/inspection/execution/types.ts
Normal file
240
plus-ui/src/api/inspection/execution/types.ts
Normal file
@@ -0,0 +1,240 @@
|
||||
export interface ArExecutionVO {
|
||||
/**
|
||||
* 执行ID
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 任务模板ID
|
||||
*/
|
||||
taskId: string | number;
|
||||
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
taskName?: string;
|
||||
|
||||
/**
|
||||
* 执行编号
|
||||
*/
|
||||
executionCode: string;
|
||||
|
||||
/**
|
||||
* 区域ID
|
||||
*/
|
||||
regionId: string | number;
|
||||
|
||||
/**
|
||||
* 区域名称
|
||||
*/
|
||||
regionName?: string;
|
||||
|
||||
/**
|
||||
* 使用的AR设备ID
|
||||
*/
|
||||
deviceId: string | number;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
deviceName?: string;
|
||||
|
||||
/**
|
||||
* 操作人ID
|
||||
*/
|
||||
operatorId: string | number;
|
||||
|
||||
/**
|
||||
* 操作人姓名
|
||||
*/
|
||||
operatorName: string;
|
||||
|
||||
/**
|
||||
* 监护人ID
|
||||
*/
|
||||
custodianId: string | number;
|
||||
|
||||
/**
|
||||
* 监护人姓名
|
||||
*/
|
||||
custodianName: string;
|
||||
|
||||
/**
|
||||
* 送电人ID
|
||||
*/
|
||||
senderId: string | number;
|
||||
|
||||
/**
|
||||
* 送电人姓名
|
||||
*/
|
||||
senderName: string;
|
||||
|
||||
/**
|
||||
* 受电人ID
|
||||
*/
|
||||
recipientId: string | number;
|
||||
|
||||
/**
|
||||
* 受电人姓名
|
||||
*/
|
||||
recipientName: string;
|
||||
|
||||
/**
|
||||
* 指挥人ID
|
||||
*/
|
||||
commanderId: string | number;
|
||||
|
||||
/**
|
||||
* 指挥人姓名
|
||||
*/
|
||||
commanderName: string;
|
||||
|
||||
/**
|
||||
* 执行状态(pending待执行 in_progress执行中 completed已完成 cancelled已取消)
|
||||
*/
|
||||
status: string;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
startTime: string;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
endTime: string;
|
||||
|
||||
/**
|
||||
* 总步骤数
|
||||
*/
|
||||
totalSteps: number;
|
||||
|
||||
/**
|
||||
* 已完成步骤数
|
||||
*/
|
||||
completedSteps: number;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime: string;
|
||||
}
|
||||
|
||||
export interface ArExecutionForm extends BaseEntity {
|
||||
/**
|
||||
* 执行ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 任务模板ID
|
||||
*/
|
||||
taskId?: string | number;
|
||||
|
||||
/**
|
||||
* 执行编号
|
||||
*/
|
||||
executionCode?: string;
|
||||
|
||||
/**
|
||||
* 区域ID
|
||||
*/
|
||||
regionId?: string | number;
|
||||
|
||||
/**
|
||||
* 使用的AR设备ID
|
||||
*/
|
||||
deviceId?: string | number;
|
||||
|
||||
/**
|
||||
* 操作人ID
|
||||
*/
|
||||
operatorId?: string | number;
|
||||
|
||||
/**
|
||||
* 操作人姓名
|
||||
*/
|
||||
operatorName?: string;
|
||||
|
||||
/**
|
||||
* 监护人ID
|
||||
*/
|
||||
custodianId?: string | number;
|
||||
|
||||
/**
|
||||
* 监护人姓名
|
||||
*/
|
||||
custodianName?: string;
|
||||
|
||||
/**
|
||||
* 送电人ID
|
||||
*/
|
||||
senderId?: string | number;
|
||||
|
||||
/**
|
||||
* 送电人姓名
|
||||
*/
|
||||
senderName?: string;
|
||||
|
||||
/**
|
||||
* 受电人ID
|
||||
*/
|
||||
recipientId?: string | number;
|
||||
|
||||
/**
|
||||
* 受电人姓名
|
||||
*/
|
||||
recipientName?: string;
|
||||
|
||||
/**
|
||||
* 指挥人ID
|
||||
*/
|
||||
commanderId?: string | number;
|
||||
|
||||
/**
|
||||
* 指挥人姓名
|
||||
*/
|
||||
commanderName?: string;
|
||||
|
||||
/**
|
||||
* 执行状态
|
||||
*/
|
||||
status?: string;
|
||||
}
|
||||
|
||||
export interface ArExecutionQuery extends PageQuery {
|
||||
/**
|
||||
* 任务模板ID
|
||||
*/
|
||||
taskId?: string | number;
|
||||
|
||||
/**
|
||||
* 执行编号
|
||||
*/
|
||||
executionCode?: string;
|
||||
|
||||
/**
|
||||
* 区域ID
|
||||
*/
|
||||
regionId?: string | number;
|
||||
|
||||
/**
|
||||
* 使用的AR设备ID
|
||||
*/
|
||||
deviceId?: string | number;
|
||||
|
||||
/**
|
||||
* 执行状态
|
||||
*/
|
||||
status?: string;
|
||||
|
||||
/**
|
||||
* 开始时间-开始
|
||||
*/
|
||||
startTimeBegin?: string;
|
||||
|
||||
/**
|
||||
* 开始时间-结束
|
||||
*/
|
||||
startTimeEnd?: string;
|
||||
}
|
||||
62
plus-ui/src/api/inspection/point/index.ts
Normal file
62
plus-ui/src/api/inspection/point/index.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ArPointVO, ArPointForm, ArPointQuery } from '@/api/inspection/point/types';
|
||||
|
||||
/**
|
||||
* 查询巡检点位列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
export const listArPoint = (query?: ArPointQuery): AxiosPromise<ArPointVO[]> => {
|
||||
return request({
|
||||
url: '/inspection/point/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询巡检点位详细
|
||||
* @param id
|
||||
*/
|
||||
export const getArPoint = (id: string | number): AxiosPromise<ArPointVO> => {
|
||||
return request({
|
||||
url: '/inspection/point/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增巡检点位
|
||||
* @param data
|
||||
*/
|
||||
export const addArPoint = (data: ArPointForm) => {
|
||||
return request({
|
||||
url: '/inspection/point',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改巡检点位
|
||||
* @param data
|
||||
*/
|
||||
export const updateArPoint = (data: ArPointForm) => {
|
||||
return request({
|
||||
url: '/inspection/point',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除巡检点位
|
||||
* @param id
|
||||
*/
|
||||
export const delArPoint = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/inspection/point/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
90
plus-ui/src/api/inspection/point/types.ts
Normal file
90
plus-ui/src/api/inspection/point/types.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
export interface ArPointVO {
|
||||
/**
|
||||
* 点位ID
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 所属区域ID
|
||||
*/
|
||||
regionId: string | number;
|
||||
|
||||
/**
|
||||
* 所属区域名称
|
||||
*/
|
||||
regionName?: string;
|
||||
|
||||
/**
|
||||
* 点位名称
|
||||
*/
|
||||
pointName: string;
|
||||
|
||||
/**
|
||||
* 点位代码
|
||||
*/
|
||||
pointCode: string;
|
||||
|
||||
/**
|
||||
* 位置数据(JSON格式,包含坐标等)
|
||||
*/
|
||||
positionData: Record<string, any> | string;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime: string;
|
||||
}
|
||||
|
||||
export interface ArPointForm extends BaseEntity {
|
||||
/**
|
||||
* 点位ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 所属区域ID
|
||||
*/
|
||||
regionId?: string | number;
|
||||
|
||||
/**
|
||||
* 点位名称
|
||||
*/
|
||||
pointName?: string;
|
||||
|
||||
/**
|
||||
* 点位代码
|
||||
*/
|
||||
pointCode?: string;
|
||||
|
||||
/**
|
||||
* 位置数据(JSON格式,包含坐标等)
|
||||
*/
|
||||
positionData?: Record<string, any> | string;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export interface ArPointQuery extends PageQuery {
|
||||
/**
|
||||
* 所属区域ID
|
||||
*/
|
||||
regionId?: string | number;
|
||||
|
||||
/**
|
||||
* 点位名称
|
||||
*/
|
||||
pointName?: string;
|
||||
|
||||
/**
|
||||
* 点位代码
|
||||
*/
|
||||
pointCode?: string;
|
||||
}
|
||||
62
plus-ui/src/api/inspection/region/index.ts
Normal file
62
plus-ui/src/api/inspection/region/index.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ArRegionVO, ArRegionForm, ArRegionQuery } from '@/api/inspection/region/types';
|
||||
|
||||
/**
|
||||
* 查询巡检区域列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
export const listArRegion = (query?: ArRegionQuery): AxiosPromise<ArRegionVO[]> => {
|
||||
return request({
|
||||
url: '/inspection/region/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询巡检区域详细
|
||||
* @param id
|
||||
*/
|
||||
export const getArRegion = (id: string | number): AxiosPromise<ArRegionVO> => {
|
||||
return request({
|
||||
url: '/inspection/region/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增巡检区域
|
||||
* @param data
|
||||
*/
|
||||
export const addArRegion = (data: ArRegionForm) => {
|
||||
return request({
|
||||
url: '/inspection/region',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改巡检区域
|
||||
* @param data
|
||||
*/
|
||||
export const updateArRegion = (data: ArRegionForm) => {
|
||||
return request({
|
||||
url: '/inspection/region',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除巡检区域
|
||||
* @param id
|
||||
*/
|
||||
export const delArRegion = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/inspection/region/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
85
plus-ui/src/api/inspection/region/types.ts
Normal file
85
plus-ui/src/api/inspection/region/types.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
export interface ArRegionVO {
|
||||
/**
|
||||
* 区域ID
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 区域名称
|
||||
*/
|
||||
regionName: string;
|
||||
|
||||
/**
|
||||
* 区域代码
|
||||
*/
|
||||
regionCode: string;
|
||||
|
||||
/**
|
||||
* 区域数据(JSON格式)
|
||||
*/
|
||||
regionData: Record<string, any> | string;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
status: string;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime: string;
|
||||
}
|
||||
|
||||
export interface ArRegionForm extends BaseEntity {
|
||||
/**
|
||||
* 区域ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 区域名称
|
||||
*/
|
||||
regionName?: string;
|
||||
|
||||
/**
|
||||
* 区域代码
|
||||
*/
|
||||
regionCode?: string;
|
||||
|
||||
/**
|
||||
* 区域数据(JSON格式)
|
||||
*/
|
||||
regionData?: Record<string, any> | string;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
status?: string;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export interface ArRegionQuery extends PageQuery {
|
||||
/**
|
||||
* 区域名称
|
||||
*/
|
||||
regionName?: string;
|
||||
|
||||
/**
|
||||
* 区域代码
|
||||
*/
|
||||
regionCode?: string;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
status?: string;
|
||||
}
|
||||
74
plus-ui/src/api/inspection/step/index.ts
Normal file
74
plus-ui/src/api/inspection/step/index.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ArStepVO, ArStepForm, ArStepQuery } from '@/api/inspection/step/types';
|
||||
|
||||
/**
|
||||
* 查询巡检步骤列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
export const listArStep = (query?: ArStepQuery): AxiosPromise<ArStepVO[]> => {
|
||||
return request({
|
||||
url: '/inspection/step/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询任务的步骤树形结构
|
||||
* @param taskId
|
||||
* @returns {*}
|
||||
*/
|
||||
export const getArStepTree = (taskId: string | number): AxiosPromise<ArStepVO[]> => {
|
||||
return request({
|
||||
url: '/inspection/step/tree/' + taskId,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询巡检步骤详细
|
||||
* @param id
|
||||
*/
|
||||
export const getArStep = (id: string | number): AxiosPromise<ArStepVO> => {
|
||||
return request({
|
||||
url: '/inspection/step/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增巡检步骤
|
||||
* @param data
|
||||
*/
|
||||
export const addArStep = (data: ArStepForm) => {
|
||||
return request({
|
||||
url: '/inspection/step',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改巡检步骤
|
||||
* @param data
|
||||
*/
|
||||
export const updateArStep = (data: ArStepForm) => {
|
||||
return request({
|
||||
url: '/inspection/step',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除巡检步骤(级联删除子步骤)
|
||||
* @param id
|
||||
*/
|
||||
export const delArStep = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/inspection/step/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
245
plus-ui/src/api/inspection/step/types.ts
Normal file
245
plus-ui/src/api/inspection/step/types.ts
Normal file
@@ -0,0 +1,245 @@
|
||||
export interface ArStepVO {
|
||||
/**
|
||||
* 步骤ID
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 所属任务ID
|
||||
*/
|
||||
taskId: string | number;
|
||||
|
||||
/**
|
||||
* 父步骤ID(0表示根节点)
|
||||
*/
|
||||
parentId: string | number;
|
||||
|
||||
/**
|
||||
* 祖级列表
|
||||
*/
|
||||
ancestors: string;
|
||||
|
||||
/**
|
||||
* 步骤名称
|
||||
*/
|
||||
stepName: string;
|
||||
|
||||
/**
|
||||
* 步骤内容
|
||||
*/
|
||||
stepContent: string;
|
||||
|
||||
/**
|
||||
* 内容语音URL
|
||||
*/
|
||||
contentVoice: string;
|
||||
|
||||
/**
|
||||
* 显示顺序
|
||||
*/
|
||||
orderNum: number;
|
||||
|
||||
/**
|
||||
* 关联点位ID
|
||||
*/
|
||||
pointId: string | number;
|
||||
|
||||
/**
|
||||
* 关联点位名称
|
||||
*/
|
||||
pointName?: string;
|
||||
|
||||
/**
|
||||
* 是否需要语音播报(0否 1是)
|
||||
*/
|
||||
needVoiceRead: string;
|
||||
|
||||
/**
|
||||
* 是否需要复述(0否 1是)
|
||||
*/
|
||||
needVoiceRephrase: string;
|
||||
|
||||
/**
|
||||
* 复述内容
|
||||
*/
|
||||
rephraseContent: string;
|
||||
|
||||
/**
|
||||
* 复述语音URL
|
||||
*/
|
||||
rephraseVoice: string;
|
||||
|
||||
/**
|
||||
* 是否需要语音确认(0否 1是)
|
||||
*/
|
||||
needVoiceConfirm: string;
|
||||
|
||||
/**
|
||||
* 确认内容
|
||||
*/
|
||||
confirmContent: string;
|
||||
|
||||
/**
|
||||
* 确认语音URL
|
||||
*/
|
||||
confirmVoice: string;
|
||||
|
||||
/**
|
||||
* 确认关键词
|
||||
*/
|
||||
confirmWord: string;
|
||||
|
||||
/**
|
||||
* 是否需要AI识别(0否 1是)
|
||||
*/
|
||||
needAi: string;
|
||||
|
||||
/**
|
||||
* AI识别目标名称
|
||||
*/
|
||||
aiTargetName: string;
|
||||
|
||||
/**
|
||||
* AI配置数据(JSON格式)
|
||||
*/
|
||||
aiData: Record<string, any> | string;
|
||||
|
||||
/**
|
||||
* 是否需要操作(0否 1是)
|
||||
*/
|
||||
isOperation: string;
|
||||
|
||||
/**
|
||||
* 是否叶子节点(0否 1是)
|
||||
*/
|
||||
isLeaf: string;
|
||||
|
||||
/**
|
||||
* 子节点列表(用于树形结构)
|
||||
*/
|
||||
children?: ArStepVO[];
|
||||
}
|
||||
|
||||
export interface ArStepForm extends BaseEntity {
|
||||
/**
|
||||
* 步骤ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 所属任务ID
|
||||
*/
|
||||
taskId?: string | number;
|
||||
|
||||
/**
|
||||
* 父步骤ID(0表示根节点)
|
||||
*/
|
||||
parentId?: string | number;
|
||||
|
||||
/**
|
||||
* 步骤名称
|
||||
*/
|
||||
stepName?: string;
|
||||
|
||||
/**
|
||||
* 步骤内容
|
||||
*/
|
||||
stepContent?: string;
|
||||
|
||||
/**
|
||||
* 内容语音URL
|
||||
*/
|
||||
contentVoice?: string;
|
||||
|
||||
/**
|
||||
* 显示顺序
|
||||
*/
|
||||
orderNum?: number;
|
||||
|
||||
/**
|
||||
* 关联点位ID
|
||||
*/
|
||||
pointId?: string | number;
|
||||
|
||||
/**
|
||||
* 是否需要语音播报(0否 1是)
|
||||
*/
|
||||
needVoiceRead?: string;
|
||||
|
||||
/**
|
||||
* 是否需要复述(0否 1是)
|
||||
*/
|
||||
needVoiceRephrase?: string;
|
||||
|
||||
/**
|
||||
* 复述内容
|
||||
*/
|
||||
rephraseContent?: string;
|
||||
|
||||
/**
|
||||
* 复述语音URL
|
||||
*/
|
||||
rephraseVoice?: string;
|
||||
|
||||
/**
|
||||
* 是否需要语音确认(0否 1是)
|
||||
*/
|
||||
needVoiceConfirm?: string;
|
||||
|
||||
/**
|
||||
* 确认内容
|
||||
*/
|
||||
confirmContent?: string;
|
||||
|
||||
/**
|
||||
* 确认语音URL
|
||||
*/
|
||||
confirmVoice?: string;
|
||||
|
||||
/**
|
||||
* 确认关键词
|
||||
*/
|
||||
confirmWord?: string;
|
||||
|
||||
/**
|
||||
* 是否需要AI识别(0否 1是)
|
||||
*/
|
||||
needAi?: string;
|
||||
|
||||
/**
|
||||
* AI识别目标名称
|
||||
*/
|
||||
aiTargetName?: string;
|
||||
|
||||
/**
|
||||
* AI配置数据(JSON格式)
|
||||
*/
|
||||
aiData?: Record<string, any> | string;
|
||||
|
||||
/**
|
||||
* 是否需要操作(0否 1是)
|
||||
*/
|
||||
isOperation?: string;
|
||||
}
|
||||
|
||||
export interface ArStepQuery {
|
||||
/**
|
||||
* 所属任务ID
|
||||
*/
|
||||
taskId?: string | number;
|
||||
|
||||
/**
|
||||
* 父步骤ID
|
||||
*/
|
||||
parentId?: string | number;
|
||||
|
||||
/**
|
||||
* 步骤名称
|
||||
*/
|
||||
stepName?: string;
|
||||
|
||||
/**
|
||||
* 关联点位ID
|
||||
*/
|
||||
pointId?: string | number;
|
||||
}
|
||||
62
plus-ui/src/api/inspection/stepMedia/index.ts
Normal file
62
plus-ui/src/api/inspection/stepMedia/index.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ArStepMediaVO, ArStepMediaForm, ArStepMediaQuery } from '@/api/inspection/stepMedia/types';
|
||||
|
||||
/**
|
||||
* 查询步骤媒体文件列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
export const listArStepMedia = (query?: ArStepMediaQuery): AxiosPromise<ArStepMediaVO[]> => {
|
||||
return request({
|
||||
url: '/inspection/stepMedia/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询步骤媒体文件详细
|
||||
* @param id
|
||||
*/
|
||||
export const getArStepMedia = (id: string | number): AxiosPromise<ArStepMediaVO> => {
|
||||
return request({
|
||||
url: '/inspection/stepMedia/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增步骤媒体文件
|
||||
* @param data
|
||||
*/
|
||||
export const addArStepMedia = (data: ArStepMediaForm) => {
|
||||
return request({
|
||||
url: '/inspection/stepMedia',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改步骤媒体文件
|
||||
* @param data
|
||||
*/
|
||||
export const updateArStepMedia = (data: ArStepMediaForm) => {
|
||||
return request({
|
||||
url: '/inspection/stepMedia',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除步骤媒体文件
|
||||
* @param id
|
||||
*/
|
||||
export const delArStepMedia = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/inspection/stepMedia/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
95
plus-ui/src/api/inspection/stepMedia/types.ts
Normal file
95
plus-ui/src/api/inspection/stepMedia/types.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
export interface ArStepMediaVO {
|
||||
/**
|
||||
* 媒体ID
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 步骤记录ID
|
||||
*/
|
||||
stepRecordId: string | number;
|
||||
|
||||
/**
|
||||
* 媒体类型(image图片 video视频 audio音频)
|
||||
*/
|
||||
mediaType: string;
|
||||
|
||||
/**
|
||||
* 文件URL
|
||||
*/
|
||||
fileUrl: string;
|
||||
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
fileName: string;
|
||||
|
||||
/**
|
||||
* 文件大小(字节)
|
||||
*/
|
||||
fileSize: number;
|
||||
|
||||
/**
|
||||
* 上传时间
|
||||
*/
|
||||
uploadTime: string;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime: string;
|
||||
}
|
||||
|
||||
export interface ArStepMediaForm extends BaseEntity {
|
||||
/**
|
||||
* 媒体ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 步骤记录ID
|
||||
*/
|
||||
stepRecordId?: string | number;
|
||||
|
||||
/**
|
||||
* 媒体类型(image图片 video视频 audio音频)
|
||||
*/
|
||||
mediaType?: string;
|
||||
|
||||
/**
|
||||
* 文件URL
|
||||
*/
|
||||
fileUrl?: string;
|
||||
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
fileName?: string;
|
||||
|
||||
/**
|
||||
* 文件大小(字节)
|
||||
*/
|
||||
fileSize?: number;
|
||||
}
|
||||
|
||||
export interface ArStepMediaQuery extends PageQuery {
|
||||
/**
|
||||
* 步骤记录ID
|
||||
*/
|
||||
stepRecordId?: string | number;
|
||||
|
||||
/**
|
||||
* 媒体类型
|
||||
*/
|
||||
mediaType?: string;
|
||||
|
||||
/**
|
||||
* 上传时间-开始
|
||||
*/
|
||||
uploadTimeBegin?: string;
|
||||
|
||||
/**
|
||||
* 上传时间-结束
|
||||
*/
|
||||
uploadTimeEnd?: string;
|
||||
}
|
||||
62
plus-ui/src/api/inspection/stepRecord/index.ts
Normal file
62
plus-ui/src/api/inspection/stepRecord/index.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ArStepRecordVO, ArStepRecordForm, ArStepRecordQuery } from '@/api/inspection/stepRecord/types';
|
||||
|
||||
/**
|
||||
* 查询步骤执行记录列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
export const listArStepRecord = (query?: ArStepRecordQuery): AxiosPromise<ArStepRecordVO[]> => {
|
||||
return request({
|
||||
url: '/inspection/stepRecord/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询步骤执行记录详细
|
||||
* @param id
|
||||
*/
|
||||
export const getArStepRecord = (id: string | number): AxiosPromise<ArStepRecordVO> => {
|
||||
return request({
|
||||
url: '/inspection/stepRecord/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增步骤执行记录
|
||||
* @param data
|
||||
*/
|
||||
export const addArStepRecord = (data: ArStepRecordForm) => {
|
||||
return request({
|
||||
url: '/inspection/stepRecord',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改步骤执行记录
|
||||
* @param data
|
||||
*/
|
||||
export const updateArStepRecord = (data: ArStepRecordForm) => {
|
||||
return request({
|
||||
url: '/inspection/stepRecord',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除步骤执行记录
|
||||
* @param id
|
||||
*/
|
||||
export const delArStepRecord = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/inspection/stepRecord/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
155
plus-ui/src/api/inspection/stepRecord/types.ts
Normal file
155
plus-ui/src/api/inspection/stepRecord/types.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
export interface ArStepRecordVO {
|
||||
/**
|
||||
* 记录ID
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 任务执行ID
|
||||
*/
|
||||
executionId: string | number;
|
||||
|
||||
/**
|
||||
* 执行编号
|
||||
*/
|
||||
executionCode?: string;
|
||||
|
||||
/**
|
||||
* 步骤ID
|
||||
*/
|
||||
stepId: string | number;
|
||||
|
||||
/**
|
||||
* 步骤名称
|
||||
*/
|
||||
stepName?: string;
|
||||
|
||||
/**
|
||||
* 状态(pending待执行 completed已完成 skipped已跳过)
|
||||
*/
|
||||
status: string;
|
||||
|
||||
/**
|
||||
* 是否完成(0否 1是)
|
||||
*/
|
||||
isDone: string;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
startTime: string;
|
||||
|
||||
/**
|
||||
* 完成时间
|
||||
*/
|
||||
completionTime: string;
|
||||
|
||||
/**
|
||||
* 耗时(秒)
|
||||
*/
|
||||
duration: number;
|
||||
|
||||
/**
|
||||
* 文本反馈
|
||||
*/
|
||||
textFeedback: string;
|
||||
|
||||
/**
|
||||
* 语音识别文本
|
||||
*/
|
||||
voiceText: string;
|
||||
|
||||
/**
|
||||
* AI识别结果(JSON格式)
|
||||
*/
|
||||
aiResult: Record<string, any> | string;
|
||||
|
||||
/**
|
||||
* 执行人ID
|
||||
*/
|
||||
executorId: string | number;
|
||||
|
||||
/**
|
||||
* 执行人姓名
|
||||
*/
|
||||
executorName: string;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime: string;
|
||||
}
|
||||
|
||||
export interface ArStepRecordForm extends BaseEntity {
|
||||
/**
|
||||
* 记录ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 任务执行ID
|
||||
*/
|
||||
executionId?: string | number;
|
||||
|
||||
/**
|
||||
* 步骤ID
|
||||
*/
|
||||
stepId?: string | number;
|
||||
|
||||
/**
|
||||
* 状态(pending待执行 completed已完成 skipped已跳过)
|
||||
*/
|
||||
status?: string;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
startTime?: string;
|
||||
|
||||
/**
|
||||
* 文本反馈
|
||||
*/
|
||||
textFeedback?: string;
|
||||
|
||||
/**
|
||||
* 语音识别文本
|
||||
*/
|
||||
voiceText?: string;
|
||||
|
||||
/**
|
||||
* AI识别结果(JSON格式)
|
||||
*/
|
||||
aiResult?: Record<string, any> | string;
|
||||
|
||||
/**
|
||||
* 执行人ID
|
||||
*/
|
||||
executorId?: string | number;
|
||||
|
||||
/**
|
||||
* 执行人姓名
|
||||
*/
|
||||
executorName?: string;
|
||||
}
|
||||
|
||||
export interface ArStepRecordQuery extends PageQuery {
|
||||
/**
|
||||
* 任务执行ID
|
||||
*/
|
||||
executionId?: string | number;
|
||||
|
||||
/**
|
||||
* 步骤ID
|
||||
*/
|
||||
stepId?: string | number;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
status?: string;
|
||||
|
||||
/**
|
||||
* 执行人ID
|
||||
*/
|
||||
executorId?: string | number;
|
||||
}
|
||||
62
plus-ui/src/api/inspection/task/index.ts
Normal file
62
plus-ui/src/api/inspection/task/index.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ArTaskVO, ArTaskForm, ArTaskQuery } from '@/api/inspection/task/types';
|
||||
|
||||
/**
|
||||
* 查询巡检任务模板列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
export const listArTask = (query?: ArTaskQuery): AxiosPromise<ArTaskVO[]> => {
|
||||
return request({
|
||||
url: '/inspection/task/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询巡检任务模板详细
|
||||
* @param id
|
||||
*/
|
||||
export const getArTask = (id: string | number): AxiosPromise<ArTaskVO> => {
|
||||
return request({
|
||||
url: '/inspection/task/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增巡检任务模板
|
||||
* @param data
|
||||
*/
|
||||
export const addArTask = (data: ArTaskForm) => {
|
||||
return request({
|
||||
url: '/inspection/task',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改巡检任务模板
|
||||
* @param data
|
||||
*/
|
||||
export const updateArTask = (data: ArTaskForm) => {
|
||||
return request({
|
||||
url: '/inspection/task',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除巡检任务模板
|
||||
* @param id
|
||||
*/
|
||||
export const delArTask = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/inspection/task/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
110
plus-ui/src/api/inspection/task/types.ts
Normal file
110
plus-ui/src/api/inspection/task/types.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
export interface ArTaskVO {
|
||||
/**
|
||||
* 任务ID
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
taskName: string;
|
||||
|
||||
/**
|
||||
* 任务代码
|
||||
*/
|
||||
taskCode: string;
|
||||
|
||||
/**
|
||||
* 关联区域ID
|
||||
*/
|
||||
regionId: string | number;
|
||||
|
||||
/**
|
||||
* 关联区域名称
|
||||
*/
|
||||
regionName?: string;
|
||||
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
taskType: string;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
status: string;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime: string;
|
||||
}
|
||||
|
||||
export interface ArTaskForm extends BaseEntity {
|
||||
/**
|
||||
* 任务ID
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
taskName?: string;
|
||||
|
||||
/**
|
||||
* 任务代码
|
||||
*/
|
||||
taskCode?: string;
|
||||
|
||||
/**
|
||||
* 关联区域ID
|
||||
*/
|
||||
regionId?: string | number;
|
||||
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
taskType?: string;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
status?: string;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export interface ArTaskQuery extends PageQuery {
|
||||
/**
|
||||
* 任务名称
|
||||
*/
|
||||
taskName?: string;
|
||||
|
||||
/**
|
||||
* 任务代码
|
||||
*/
|
||||
taskCode?: string;
|
||||
|
||||
/**
|
||||
* 关联区域ID
|
||||
*/
|
||||
regionId?: string | number;
|
||||
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
taskType?: string;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
status?: string;
|
||||
}
|
||||
@@ -93,7 +93,91 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||
|
||||
// 动态路由,基于用户权限动态去加载
|
||||
export const dynamicRoutes: RouteRecordRaw[] = [
|
||||
|
||||
{
|
||||
path: '/inspection',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
name: 'Inspection',
|
||||
alwaysShow: true,
|
||||
meta: {
|
||||
title: 'AR巡检',
|
||||
icon: 'guide'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'device',
|
||||
component: () => import('@/views/inspection/device/index.vue'),
|
||||
name: 'ArDevice',
|
||||
meta: {
|
||||
title: '设备管理',
|
||||
icon: 'monitor'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'region',
|
||||
component: () => import('@/views/inspection/region/index.vue'),
|
||||
name: 'ArRegion',
|
||||
meta: {
|
||||
title: '区域管理',
|
||||
icon: 'location'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'point',
|
||||
component: () => import('@/views/inspection/point/index.vue'),
|
||||
name: 'ArPoint',
|
||||
meta: {
|
||||
title: '点位管理',
|
||||
icon: 'position'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'task',
|
||||
component: () => import('@/views/inspection/task/index.vue'),
|
||||
name: 'ArTask',
|
||||
meta: {
|
||||
title: '任务模板',
|
||||
icon: 'list'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'step',
|
||||
component: () => import('@/views/inspection/step/index.vue'),
|
||||
name: 'ArStep',
|
||||
meta: {
|
||||
title: '巡检步骤',
|
||||
icon: 'tree'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'stepMedia',
|
||||
component: () => import('@/views/inspection/stepMedia/index.vue'),
|
||||
name: 'ArStepMedia',
|
||||
meta: {
|
||||
title: '步骤媒体',
|
||||
icon: 'picture'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'execution',
|
||||
component: () => import('@/views/inspection/execution/index.vue'),
|
||||
name: 'ArExecution',
|
||||
meta: {
|
||||
title: '执行记录',
|
||||
icon: 'documentation'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'stepRecord',
|
||||
component: () => import('@/views/inspection/stepRecord/index.vue'),
|
||||
name: 'ArStepRecord',
|
||||
meta: {
|
||||
title: '步骤记录',
|
||||
icon: 'edit'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
258
plus-ui/src/views/inspection/device/index.vue
Normal file
258
plus-ui/src/views/inspection/device/index.vue
Normal file
@@ -0,0 +1,258 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="设备名称" prop="deviceName">
|
||||
<el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备编号" prop="deviceNo">
|
||||
<el-input v-model="queryParams.deviceNo" placeholder="请输入设备编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备型号" prop="deviceModel">
|
||||
<el-input v-model="queryParams.deviceModel" placeholder="请输入设备型号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
|
||||
<el-option label="正常" value="0" />
|
||||
<el-option label="停用" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:device:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:device:edit']" type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:device:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:device:export']" type="warning" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="deviceList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="设备ID" align="center" prop="id" width="80" />
|
||||
<el-table-column label="设备名称" align="center" prop="deviceName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="设备编号" align="center" prop="deviceNo" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="设备型号" align="center" prop="deviceModel" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status === '0'" type="success">正常</el-tag>
|
||||
<el-tag v-else type="danger">停用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" align="center" width="180" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button v-hasPermi="['inspection:device:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button v-hasPermi="['inspection:device:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改AR设备对话框 -->
|
||||
<el-dialog v-model="dialog.visible" :title="dialog.title" width="600px" append-to-body>
|
||||
<el-form ref="deviceFormRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="设备名称" prop="deviceName">
|
||||
<el-input v-model="form.deviceName" placeholder="请输入设备名称" maxlength="100" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备编号" prop="deviceNo">
|
||||
<el-input v-model="form.deviceNo" placeholder="请输入设备编号" maxlength="50" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备型号" prop="deviceModel">
|
||||
<el-input v-model="form.deviceModel" placeholder="请输入设备型号" maxlength="100" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio value="0">正常</el-radio>
|
||||
<el-radio value="1">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" maxlength="500" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ArDevice" lang="ts">
|
||||
import { listArDevice, getArDevice, delArDevice, addArDevice, updateArDevice } from '@/api/inspection/device';
|
||||
import { ArDeviceVO, ArDeviceQuery, ArDeviceForm } from '@/api/inspection/device/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const deviceList = ref<ArDeviceVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const deviceFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ArDeviceForm = {
|
||||
id: undefined,
|
||||
deviceName: undefined,
|
||||
deviceNo: undefined,
|
||||
deviceModel: undefined,
|
||||
status: '0',
|
||||
remark: undefined
|
||||
};
|
||||
|
||||
const data = reactive<PageData<ArDeviceForm, ArDeviceQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
deviceName: undefined,
|
||||
deviceNo: undefined,
|
||||
deviceModel: undefined,
|
||||
status: undefined
|
||||
},
|
||||
rules: {
|
||||
deviceName: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }],
|
||||
deviceNo: [{ required: true, message: '设备编号不能为空', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询AR设备列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listArDevice(queryParams.value);
|
||||
deviceList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
deviceFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ArDeviceVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加AR设备';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ArDeviceVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getArDevice(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改AR设备';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
deviceFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateArDevice(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addArDevice(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess(form.value.id ? '修改成功' : '新增成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ArDeviceVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除AR设备编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delArDevice(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'inspection/device/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`ar_device_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
376
plus-ui/src/views/inspection/execution/index.vue
Normal file
376
plus-ui/src/views/inspection/execution/index.vue
Normal file
@@ -0,0 +1,376 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="执行编号" prop="executionCode">
|
||||
<el-input v-model="queryParams.executionCode" placeholder="请输入执行编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="任务模板" prop="taskId">
|
||||
<el-select v-model="queryParams.taskId" placeholder="请选择任务模板" clearable filterable>
|
||||
<el-option v-for="task in taskOptions" :key="task.id" :label="task.taskName" :value="task.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="区域" prop="regionId">
|
||||
<el-select v-model="queryParams.regionId" placeholder="请选择区域" clearable filterable>
|
||||
<el-option v-for="region in regionOptions" :key="region.id" :label="region.regionName" :value="region.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备" prop="deviceId">
|
||||
<el-select v-model="queryParams.deviceId" placeholder="请选择设备" clearable filterable>
|
||||
<el-option v-for="device in deviceOptions" :key="device.id" :label="device.deviceName" :value="device.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
|
||||
<el-option label="待执行" value="pending" />
|
||||
<el-option label="执行中" value="in_progress" />
|
||||
<el-option label="已完成" value="completed" />
|
||||
<el-option label="已取消" value="cancelled" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:execution:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:execution:edit']" type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:execution:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:execution:export']" type="warning" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="executionList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="执行编号" align="center" prop="executionCode" :show-overflow-tooltip="true" width="180" />
|
||||
<el-table-column label="任务名称" align="center" prop="taskName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="区域" align="center" prop="regionName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="设备" align="center" prop="deviceName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="操作人" align="center" prop="operatorName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="状态" align="center" prop="status" width="90">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status === 'pending'" type="info">待执行</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === 'in_progress'" type="warning">执行中</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === 'completed'" type="success">已完成</el-tag>
|
||||
<el-tag v-else type="danger">已取消</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="进度" align="center" width="120">
|
||||
<template #default="scope">
|
||||
<el-progress :percentage="calculateProgress(scope.row)" :color="getProgressColor(scope.row.status)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开始时间" align="center" prop="startTime" width="180" />
|
||||
<el-table-column label="操作" align="center" width="180" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button v-hasPermi="['inspection:execution:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button v-hasPermi="['inspection:execution:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改任务执行记录对话框 -->
|
||||
<el-dialog v-model="dialog.visible" :title="dialog.title" width="800px" append-to-body>
|
||||
<el-form ref="executionFormRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="任务模板" prop="taskId">
|
||||
<el-select v-model="form.taskId" placeholder="请选择任务模板" filterable style="width: 100%">
|
||||
<el-option v-for="task in taskOptions" :key="task.id" :label="task.taskName" :value="task.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="区域" prop="regionId">
|
||||
<el-select v-model="form.regionId" placeholder="请选择区域" filterable style="width: 100%">
|
||||
<el-option v-for="region in regionOptions" :key="region.id" :label="region.regionName" :value="region.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="使用设备" prop="deviceId">
|
||||
<el-select v-model="form.deviceId" placeholder="请选择使用设备" clearable filterable style="width: 100%">
|
||||
<el-option v-for="device in deviceOptions" :key="device.id" :label="device.deviceName" :value="device.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="执行状态" prop="status">
|
||||
<el-select v-model="form.status" placeholder="请选择状态" style="width: 100%">
|
||||
<el-option label="待执行" value="pending" />
|
||||
<el-option label="执行中" value="in_progress" />
|
||||
<el-option label="已完成" value="completed" />
|
||||
<el-option label="已取消" value="cancelled" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider content-position="left">执行角色</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="操作人" prop="operatorName">
|
||||
<el-input v-model="form.operatorName" placeholder="请输入操作人姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="监护人" prop="custodianName">
|
||||
<el-input v-model="form.custodianName" placeholder="请输入监护人姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="送电人" prop="senderName">
|
||||
<el-input v-model="form.senderName" placeholder="请输入送电人姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="受电人" prop="recipientName">
|
||||
<el-input v-model="form.recipientName" placeholder="请输入受电人姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="指挥人" prop="commanderName">
|
||||
<el-input v-model="form.commanderName" placeholder="请输入指挥人姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ArExecution" lang="ts">
|
||||
import { listArExecution, getArExecution, delArExecution, addArExecution, updateArExecution } from '@/api/inspection/execution';
|
||||
import { ArExecutionVO, ArExecutionQuery, ArExecutionForm } from '@/api/inspection/execution/types';
|
||||
import { listArTask } from '@/api/inspection/task';
|
||||
import { ArTaskVO } from '@/api/inspection/task/types';
|
||||
import { listArRegion } from '@/api/inspection/region';
|
||||
import { ArRegionVO } from '@/api/inspection/region/types';
|
||||
import { listArDevice } from '@/api/inspection/device';
|
||||
import { ArDeviceVO } from '@/api/inspection/device/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const executionList = ref<ArExecutionVO[]>([]);
|
||||
const taskOptions = ref<ArTaskVO[]>([]);
|
||||
const regionOptions = ref<ArRegionVO[]>([]);
|
||||
const deviceOptions = ref<ArDeviceVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const executionFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ArExecutionForm = {
|
||||
id: undefined,
|
||||
taskId: undefined,
|
||||
executionCode: undefined,
|
||||
regionId: undefined,
|
||||
deviceId: undefined,
|
||||
operatorId: undefined,
|
||||
operatorName: undefined,
|
||||
custodianId: undefined,
|
||||
custodianName: undefined,
|
||||
senderId: undefined,
|
||||
senderName: undefined,
|
||||
recipientId: undefined,
|
||||
recipientName: undefined,
|
||||
commanderId: undefined,
|
||||
commanderName: undefined,
|
||||
status: 'pending'
|
||||
};
|
||||
|
||||
const data = reactive<PageData<ArExecutionForm, ArExecutionQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
taskId: undefined,
|
||||
executionCode: undefined,
|
||||
regionId: undefined,
|
||||
deviceId: undefined,
|
||||
status: undefined,
|
||||
startTimeBegin: undefined,
|
||||
startTimeEnd: undefined
|
||||
},
|
||||
rules: {
|
||||
taskId: [{ required: true, message: '任务模板不能为空', trigger: 'change' }],
|
||||
regionId: [{ required: true, message: '区域不能为空', trigger: 'change' }],
|
||||
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 计算进度百分比 */
|
||||
const calculateProgress = (row: ArExecutionVO) => {
|
||||
if (!row.totalSteps || row.totalSteps === 0) return 0;
|
||||
return Math.round((row.completedSteps / row.totalSteps) * 100);
|
||||
};
|
||||
|
||||
/** 获取进度条颜色 */
|
||||
const getProgressColor = (status: string) => {
|
||||
if (status === 'completed') return '#67c23a';
|
||||
if (status === 'in_progress') return '#e6a23c';
|
||||
if (status === 'cancelled') return '#f56c6c';
|
||||
return '#909399';
|
||||
};
|
||||
|
||||
/** 查询选项数据 */
|
||||
const getOptions = async () => {
|
||||
const [taskRes, regionRes, deviceRes] = await Promise.all([
|
||||
listArTask({ pageNum: 1, pageSize: 1000, status: '0' }),
|
||||
listArRegion({ pageNum: 1, pageSize: 1000, status: '0' }),
|
||||
listArDevice({ pageNum: 1, pageSize: 1000, status: '0' })
|
||||
]);
|
||||
taskOptions.value = taskRes.rows;
|
||||
regionOptions.value = regionRes.rows;
|
||||
deviceOptions.value = deviceRes.rows;
|
||||
};
|
||||
|
||||
/** 查询任务执行记录列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listArExecution(queryParams.value);
|
||||
executionList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
executionFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ArExecutionVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加任务执行记录';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ArExecutionVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getArExecution(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改任务执行记录';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
executionFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateArExecution(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addArExecution(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess(form.value.id ? '修改成功' : '新增成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ArExecutionVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除任务执行记录编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delArExecution(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'inspection/execution/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`ar_execution_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getOptions();
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
297
plus-ui/src/views/inspection/point/index.vue
Normal file
297
plus-ui/src/views/inspection/point/index.vue
Normal file
@@ -0,0 +1,297 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="所属区域" prop="regionId">
|
||||
<el-select v-model="queryParams.regionId" placeholder="请选择所属区域" clearable filterable>
|
||||
<el-option v-for="region in regionOptions" :key="region.id" :label="region.regionName" :value="region.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="点位名称" prop="pointName">
|
||||
<el-input v-model="queryParams.pointName" placeholder="请输入点位名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="点位代码" prop="pointCode">
|
||||
<el-input v-model="queryParams.pointCode" placeholder="请输入点位代码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:point:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:point:edit']" type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:point:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:point:export']" type="warning" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="pointList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="点位ID" align="center" prop="id" width="80" />
|
||||
<el-table-column label="所属区域" align="center" prop="regionName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="点位名称" align="center" prop="pointName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="点位代码" align="center" prop="pointCode" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" align="center" width="180" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button v-hasPermi="['inspection:point:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button v-hasPermi="['inspection:point:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改巡检点位对话框 -->
|
||||
<el-dialog v-model="dialog.visible" :title="dialog.title" width="700px" append-to-body>
|
||||
<el-form ref="pointFormRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属区域" prop="regionId">
|
||||
<el-select v-model="form.regionId" placeholder="请选择所属区域" filterable>
|
||||
<el-option v-for="region in regionOptions" :key="region.id" :label="region.regionName" :value="region.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="点位代码" prop="pointCode">
|
||||
<el-input v-model="form.pointCode" placeholder="请输入点位代码" maxlength="50" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="点位名称" prop="pointName">
|
||||
<el-input v-model="form.pointName" placeholder="请输入点位名称" maxlength="100" />
|
||||
</el-form-item>
|
||||
<el-form-item label="位置数据" prop="positionData">
|
||||
<el-input
|
||||
v-model="positionDataStr"
|
||||
type="textarea"
|
||||
:rows="8"
|
||||
placeholder='请输入位置数据JSON格式,例如: {"x": 10.5, "y": 20.3, "z": 1.5, "rotation": {"x": 0, "y": 90, "z": 0}}'
|
||||
/>
|
||||
<div v-if="jsonError" class="el-form-item__error">{{ jsonError }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" maxlength="500" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ArPoint" lang="ts">
|
||||
import { listArPoint, getArPoint, delArPoint, addArPoint, updateArPoint } from '@/api/inspection/point';
|
||||
import { ArPointVO, ArPointQuery, ArPointForm } from '@/api/inspection/point/types';
|
||||
import { listArRegion } from '@/api/inspection/region';
|
||||
import { ArRegionVO } from '@/api/inspection/region/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const pointList = ref<ArPointVO[]>([]);
|
||||
const regionOptions = ref<ArRegionVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const positionDataStr = ref('');
|
||||
const jsonError = ref('');
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const pointFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ArPointForm = {
|
||||
id: undefined,
|
||||
regionId: undefined,
|
||||
pointName: undefined,
|
||||
pointCode: undefined,
|
||||
positionData: undefined,
|
||||
remark: undefined
|
||||
};
|
||||
|
||||
const data = reactive<PageData<ArPointForm, ArPointQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
regionId: undefined,
|
||||
pointName: undefined,
|
||||
pointCode: undefined
|
||||
},
|
||||
rules: {
|
||||
regionId: [{ required: true, message: '所属区域不能为空', trigger: 'change' }],
|
||||
pointName: [{ required: true, message: '点位名称不能为空', trigger: 'blur' }],
|
||||
pointCode: [{ required: true, message: '点位代码不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询区域选项 */
|
||||
const getRegionOptions = async () => {
|
||||
const res = await listArRegion({ pageNum: 1, pageSize: 1000, status: '0' });
|
||||
regionOptions.value = res.rows;
|
||||
};
|
||||
|
||||
/** 验证并解析JSON */
|
||||
const parsePositionData = () => {
|
||||
jsonError.value = '';
|
||||
if (!positionDataStr.value || positionDataStr.value.trim() === '') {
|
||||
form.value.positionData = undefined;
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
form.value.positionData = JSON.parse(positionDataStr.value);
|
||||
return true;
|
||||
} catch (e) {
|
||||
jsonError.value = 'JSON格式不正确';
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 查询巡检点位列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listArPoint(queryParams.value);
|
||||
pointList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
positionDataStr.value = '';
|
||||
jsonError.value = '';
|
||||
pointFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ArPointVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加巡检点位';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ArPointVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getArPoint(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
// 格式化JSON显示
|
||||
if (form.value.positionData) {
|
||||
positionDataStr.value = JSON.stringify(form.value.positionData, null, 2);
|
||||
}
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改巡检点位';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
pointFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
// 验证JSON格式
|
||||
if (!parsePositionData()) {
|
||||
return;
|
||||
}
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateArPoint(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addArPoint(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess(form.value.id ? '修改成功' : '新增成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ArPointVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除巡检点位编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delArPoint(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'inspection/point/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`ar_point_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getRegionOptions();
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
298
plus-ui/src/views/inspection/region/index.vue
Normal file
298
plus-ui/src/views/inspection/region/index.vue
Normal file
@@ -0,0 +1,298 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="区域名称" prop="regionName">
|
||||
<el-input v-model="queryParams.regionName" placeholder="请输入区域名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="区域代码" prop="regionCode">
|
||||
<el-input v-model="queryParams.regionCode" placeholder="请输入区域代码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
|
||||
<el-option label="正常" value="0" />
|
||||
<el-option label="停用" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:region:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:region:edit']" type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:region:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:region:export']" type="warning" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="regionList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="区域ID" align="center" prop="id" width="80" />
|
||||
<el-table-column label="区域名称" align="center" prop="regionName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="区域代码" align="center" prop="regionCode" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status === '0'" type="success">正常</el-tag>
|
||||
<el-tag v-else type="danger">停用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" align="center" width="180" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button v-hasPermi="['inspection:region:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button v-hasPermi="['inspection:region:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改巡检区域对话框 -->
|
||||
<el-dialog v-model="dialog.visible" :title="dialog.title" width="700px" append-to-body>
|
||||
<el-form ref="regionFormRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="区域名称" prop="regionName">
|
||||
<el-input v-model="form.regionName" placeholder="请输入区域名称" maxlength="100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="区域代码" prop="regionCode">
|
||||
<el-input v-model="form.regionCode" placeholder="请输入区域代码" maxlength="50" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio value="0">正常</el-radio>
|
||||
<el-radio value="1">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="区域数据" prop="regionData">
|
||||
<el-input
|
||||
v-model="regionDataStr"
|
||||
type="textarea"
|
||||
:rows="6"
|
||||
placeholder='请输入区域数据JSON格式,例如: {"area": 1000, "building": "主楼", "floor": 3}'
|
||||
/>
|
||||
<div v-if="jsonError" class="el-form-item__error">{{ jsonError }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" maxlength="500" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ArRegion" lang="ts">
|
||||
import { listArRegion, getArRegion, delArRegion, addArRegion, updateArRegion } from '@/api/inspection/region';
|
||||
import { ArRegionVO, ArRegionQuery, ArRegionForm } from '@/api/inspection/region/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const regionList = ref<ArRegionVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const regionDataStr = ref('');
|
||||
const jsonError = ref('');
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const regionFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ArRegionForm = {
|
||||
id: undefined,
|
||||
regionName: undefined,
|
||||
regionCode: undefined,
|
||||
regionData: undefined,
|
||||
status: '0',
|
||||
remark: undefined
|
||||
};
|
||||
|
||||
const data = reactive<PageData<ArRegionForm, ArRegionQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
regionName: undefined,
|
||||
regionCode: undefined,
|
||||
status: undefined
|
||||
},
|
||||
rules: {
|
||||
regionName: [{ required: true, message: '区域名称不能为空', trigger: 'blur' }],
|
||||
regionCode: [{ required: true, message: '区域代码不能为空', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 验证并解析JSON */
|
||||
const parseRegionData = () => {
|
||||
jsonError.value = '';
|
||||
if (!regionDataStr.value || regionDataStr.value.trim() === '') {
|
||||
form.value.regionData = undefined;
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
form.value.regionData = JSON.parse(regionDataStr.value);
|
||||
return true;
|
||||
} catch (e) {
|
||||
jsonError.value = 'JSON格式不正确';
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 查询巡检区域列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listArRegion(queryParams.value);
|
||||
regionList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
regionDataStr.value = '';
|
||||
jsonError.value = '';
|
||||
regionFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ArRegionVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加巡检区域';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ArRegionVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getArRegion(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
// 格式化JSON显示
|
||||
if (form.value.regionData) {
|
||||
regionDataStr.value = JSON.stringify(form.value.regionData, null, 2);
|
||||
}
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改巡检区域';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
regionFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
// 验证JSON格式
|
||||
if (!parseRegionData()) {
|
||||
return;
|
||||
}
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateArRegion(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addArRegion(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess(form.value.id ? '修改成功' : '新增成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ArRegionVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除巡检区域编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delArRegion(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'inspection/region/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`ar_region_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
485
plus-ui/src/views/inspection/step/index.vue
Normal file
485
plus-ui/src/views/inspection/step/index.vue
Normal file
@@ -0,0 +1,485 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<!-- 任务信息展示 -->
|
||||
<el-card v-if="currentTaskId" shadow="hover" class="mb-[10px]">
|
||||
<div class="flex items-center">
|
||||
<el-tag type="primary" size="large">当前任务: {{ currentTaskName || '未指定任务' }}</el-tag>
|
||||
<el-button v-if="route.query.taskId" link type="primary" icon="Back" @click="handleBack" class="ml-4">返回任务列表</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item v-if="!currentTaskId" label="所属任务" prop="taskId">
|
||||
<el-select v-model="queryParams.taskId" placeholder="请选择所属任务" clearable filterable @change="handleTaskChange">
|
||||
<el-option v-for="task in taskOptions" :key="task.id" :label="task.taskName" :value="task.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="步骤名称" prop="stepName">
|
||||
<el-input v-model="queryParams.stepName" placeholder="请输入步骤名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:step:add']" type="primary" plain icon="Plus" :disabled="!queryParams.taskId" @click="handleAdd()">新增根步骤</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table
|
||||
ref="stepTableRef"
|
||||
v-loading="loading"
|
||||
:data="stepList"
|
||||
row-key="id"
|
||||
border
|
||||
:default-expand-all="isExpandAll"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<el-table-column label="步骤名称" align="left" prop="stepName" :show-overflow-tooltip="true" width="250" />
|
||||
<el-table-column label="步骤内容" align="left" prop="stepContent" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="关联点位" align="center" prop="pointName" :show-overflow-tooltip="true" width="150" />
|
||||
<el-table-column label="排序" align="center" prop="orderNum" width="80" />
|
||||
<el-table-column label="语音播报" align="center" prop="needVoiceRead" width="90">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.needVoiceRead === '1'" type="success" size="small">是</el-tag>
|
||||
<el-tag v-else type="info" size="small">否</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="AI识别" align="center" prop="needAi" width="80">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.needAi === '1'" type="warning" size="small">是</el-tag>
|
||||
<el-tag v-else type="info" size="small">否</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="需要操作" align="center" prop="isOperation" width="90">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.isOperation === '1'" type="danger" size="small">是</el-tag>
|
||||
<el-tag v-else type="info" size="small">否</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="230" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="新增子步骤" placement="top">
|
||||
<el-button v-hasPermi="['inspection:step:add']" link type="primary" icon="Plus" @click="handleAdd(scope.row)" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button v-hasPermi="['inspection:step:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button v-hasPermi="['inspection:step:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改巡检步骤对话框 -->
|
||||
<el-dialog v-model="dialog.visible" :title="dialog.title" width="900px" append-to-body>
|
||||
<el-form ref="stepFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<!-- 基本信息 -->
|
||||
<el-divider content-position="left">基本信息</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属任务" prop="taskId">
|
||||
<el-select v-model="form.taskId" placeholder="请选择所属任务" disabled style="width: 100%">
|
||||
<el-option v-for="task in taskOptions" :key="task.id" :label="task.taskName" :value="task.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="父步骤" prop="parentId">
|
||||
<el-tree-select
|
||||
v-model="form.parentId"
|
||||
:data="stepTreeOptions"
|
||||
:props="{ value: 'id', label: 'stepName', children: 'children' } as any"
|
||||
value-key="id"
|
||||
placeholder="请选择父步骤(0为根节点)"
|
||||
check-strictly
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<el-form-item label="步骤名称" prop="stepName">
|
||||
<el-input v-model="form.stepName" placeholder="请输入步骤名称" maxlength="100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="排序号" prop="orderNum">
|
||||
<el-input-number v-model="form.orderNum" :min="0" :max="9999" controls-position="right" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="步骤内容" prop="stepContent">
|
||||
<el-input v-model="form.stepContent" type="textarea" :rows="3" placeholder="请输入步骤内容" />
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="关联点位" prop="pointId">
|
||||
<el-select v-model="form.pointId" placeholder="请选择关联点位" clearable filterable style="width: 100%">
|
||||
<el-option v-for="point in pointOptions" :key="point.id" :label="point.pointName" :value="point.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="内容语音URL" prop="contentVoice">
|
||||
<el-input v-model="form.contentVoice" placeholder="请输入内容语音URL" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 语音配置 -->
|
||||
<el-divider content-position="left">语音配置</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="语音播报" prop="needVoiceRead">
|
||||
<el-switch v-model="form.needVoiceRead" active-value="1" inactive-value="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="需要复述" prop="needVoiceRephrase">
|
||||
<el-switch v-model="form.needVoiceRephrase" active-value="1" inactive-value="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="语音确认" prop="needVoiceConfirm">
|
||||
<el-switch v-model="form.needVoiceConfirm" active-value="1" inactive-value="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="form.needVoiceRephrase === '1'" :gutter="20">
|
||||
<el-col :span="16">
|
||||
<el-form-item label="复述内容" prop="rephraseContent">
|
||||
<el-input v-model="form.rephraseContent" placeholder="请输入复述内容" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="复述语音URL" prop="rephraseVoice">
|
||||
<el-input v-model="form.rephraseVoice" placeholder="语音URL" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="form.needVoiceConfirm === '1'" :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="确认内容" prop="confirmContent">
|
||||
<el-input v-model="form.confirmContent" placeholder="请输入确认内容" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="确认关键词" prop="confirmWord">
|
||||
<el-input v-model="form.confirmWord" placeholder="关键词" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="确认语音URL" prop="confirmVoice">
|
||||
<el-input v-model="form.confirmVoice" placeholder="语音URL" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- AI配置 -->
|
||||
<el-divider content-position="left">AI配置</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="需要AI识别" prop="needAi">
|
||||
<el-switch v-model="form.needAi" active-value="1" inactive-value="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="需要操作" prop="isOperation">
|
||||
<el-switch v-model="form.isOperation" active-value="1" inactive-value="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="form.needAi === '1'" :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="AI目标名称" prop="aiTargetName">
|
||||
<el-input v-model="form.aiTargetName" placeholder="请输入AI识别目标名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item v-if="form.needAi === '1'" label="AI配置数据" prop="aiData">
|
||||
<el-input
|
||||
v-model="aiDataStr"
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
placeholder='请输入AI配置JSON格式,例如: {"modelName": "yolov8", "confidence": 0.8, "classes": ["红灯", "绿灯"]}'
|
||||
/>
|
||||
<div v-if="jsonError" class="el-form-item__error">{{ jsonError }}</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ArStep" lang="ts">
|
||||
import { listArStep, getArStep, delArStep, addArStep, updateArStep, getArStepTree } from '@/api/inspection/step';
|
||||
import { ArStepVO, ArStepQuery, ArStepForm } from '@/api/inspection/step/types';
|
||||
import { listArTask } from '@/api/inspection/task';
|
||||
import { ArTaskVO } from '@/api/inspection/task/types';
|
||||
import { listArPoint } from '@/api/inspection/point';
|
||||
import { ArPointVO } from '@/api/inspection/point/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const stepList = ref<ArStepVO[]>([]);
|
||||
const taskOptions = ref<ArTaskVO[]>([]);
|
||||
const pointOptions = ref<ArPointVO[]>([]);
|
||||
const stepTreeOptions = ref<any[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const showSearch = ref(true);
|
||||
const isExpandAll = ref(true);
|
||||
const loading = ref(false);
|
||||
const currentTaskId = ref<string | number | undefined>(undefined);
|
||||
const currentTaskName = ref<string | undefined>(undefined);
|
||||
const aiDataStr = ref('');
|
||||
const jsonError = ref('');
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const stepFormRef = ref<ElFormInstance>();
|
||||
const stepTableRef = ref<ElTableInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ArStepForm = {
|
||||
id: undefined,
|
||||
taskId: undefined,
|
||||
parentId: 0,
|
||||
stepName: undefined,
|
||||
stepContent: undefined,
|
||||
contentVoice: undefined,
|
||||
orderNum: 0,
|
||||
pointId: undefined,
|
||||
needVoiceRead: '0',
|
||||
needVoiceRephrase: '0',
|
||||
rephraseContent: undefined,
|
||||
rephraseVoice: undefined,
|
||||
needVoiceConfirm: '0',
|
||||
confirmContent: undefined,
|
||||
confirmVoice: undefined,
|
||||
confirmWord: undefined,
|
||||
needAi: '0',
|
||||
aiTargetName: undefined,
|
||||
aiData: undefined,
|
||||
isOperation: '0'
|
||||
};
|
||||
|
||||
const data = reactive<PageData<ArStepForm, ArStepQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
taskId: undefined,
|
||||
parentId: undefined,
|
||||
stepName: undefined,
|
||||
pointId: undefined
|
||||
},
|
||||
rules: {
|
||||
taskId: [{ required: true, message: '所属任务不能为空', trigger: 'change' }],
|
||||
stepName: [{ required: true, message: '步骤名称不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 从路由参数初始化任务ID */
|
||||
onMounted(() => {
|
||||
if (route.query.taskId) {
|
||||
currentTaskId.value = route.query.taskId as string;
|
||||
currentTaskName.value = route.query.taskName as string;
|
||||
queryParams.value.taskId = currentTaskId.value;
|
||||
}
|
||||
getTaskOptions();
|
||||
getPointOptions();
|
||||
if (queryParams.value.taskId) {
|
||||
getList();
|
||||
}
|
||||
});
|
||||
|
||||
/** 返回任务列表 */
|
||||
const handleBack = () => {
|
||||
router.back();
|
||||
};
|
||||
|
||||
/** 查询任务选项 */
|
||||
const getTaskOptions = async () => {
|
||||
const res = await listArTask({ pageNum: 1, pageSize: 1000, status: '0' });
|
||||
taskOptions.value = res.rows;
|
||||
};
|
||||
|
||||
/** 查询点位选项 */
|
||||
const getPointOptions = async () => {
|
||||
const res = await listArPoint({ pageNum: 1, pageSize: 1000 });
|
||||
pointOptions.value = res.rows;
|
||||
};
|
||||
|
||||
/** 查询步骤下拉树结构 */
|
||||
const getStepTreeselect = async () => {
|
||||
if (!queryParams.value.taskId) {
|
||||
stepTreeOptions.value = [];
|
||||
return;
|
||||
}
|
||||
const res = await getArStepTree(queryParams.value.taskId);
|
||||
stepTreeOptions.value = [];
|
||||
const data: any = { id: 0, stepName: '根节点', children: [] };
|
||||
data.children = res.data || [];
|
||||
stepTreeOptions.value.push(data);
|
||||
};
|
||||
|
||||
/** 验证并解析JSON */
|
||||
const parseAiData = () => {
|
||||
jsonError.value = '';
|
||||
if (!aiDataStr.value || aiDataStr.value.trim() === '') {
|
||||
form.value.aiData = undefined;
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
form.value.aiData = JSON.parse(aiDataStr.value);
|
||||
return true;
|
||||
} catch (e) {
|
||||
jsonError.value = 'JSON格式不正确';
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 查询巡检步骤树形列表 */
|
||||
const getList = async () => {
|
||||
if (!queryParams.value.taskId) {
|
||||
proxy?.$modal.msgWarning('请先选择任务');
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
const res = await getArStepTree(queryParams.value.taskId);
|
||||
stepList.value = res.data || [];
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 任务改变事件 */
|
||||
const handleTaskChange = () => {
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
aiDataStr.value = '';
|
||||
jsonError.value = '';
|
||||
stepFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = async (row?: ArStepVO) => {
|
||||
reset();
|
||||
await getStepTreeselect();
|
||||
form.value.taskId = queryParams.value.taskId;
|
||||
if (row && row.id) {
|
||||
form.value.parentId = row.id;
|
||||
} else {
|
||||
form.value.parentId = 0;
|
||||
}
|
||||
dialog.visible = true;
|
||||
dialog.title = row ? '添加子步骤' : '添加根步骤';
|
||||
};
|
||||
|
||||
/** 展开/折叠操作 */
|
||||
const handleToggleExpandAll = () => {
|
||||
isExpandAll.value = !isExpandAll.value;
|
||||
toggleExpandAll(stepList.value, isExpandAll.value);
|
||||
};
|
||||
|
||||
/** 展开/折叠操作 */
|
||||
const toggleExpandAll = (data: ArStepVO[], status: boolean) => {
|
||||
data.forEach((item) => {
|
||||
stepTableRef.value?.toggleRowExpansion(item, status);
|
||||
if (item.children && item.children.length > 0) toggleExpandAll(item.children, status);
|
||||
});
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row: ArStepVO) => {
|
||||
reset();
|
||||
await getStepTreeselect();
|
||||
const res = await getArStep(row.id);
|
||||
Object.assign(form.value, res.data);
|
||||
// 格式化JSON显示
|
||||
if (form.value.aiData) {
|
||||
aiDataStr.value = JSON.stringify(form.value.aiData, null, 2);
|
||||
}
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改巡检步骤';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
stepFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
// 验证JSON格式
|
||||
if (form.value.needAi === '1' && !parseAiData()) {
|
||||
return;
|
||||
}
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateArStep(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addArStep(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row: ArStepVO) => {
|
||||
await proxy?.$modal.confirm('是否确认删除步骤"' + row.stepName + '"?注意:将级联删除所有子步骤!');
|
||||
loading.value = true;
|
||||
await delArStep(row.id).finally(() => (loading.value = false));
|
||||
await getList();
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
};
|
||||
</script>
|
||||
272
plus-ui/src/views/inspection/stepMedia/index.vue
Normal file
272
plus-ui/src/views/inspection/stepMedia/index.vue
Normal file
@@ -0,0 +1,272 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="步骤记录" prop="stepRecordId">
|
||||
<el-input v-model="queryParams.stepRecordId" placeholder="请输入步骤记录ID" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="媒体类型" prop="mediaType">
|
||||
<el-select v-model="queryParams.mediaType" placeholder="请选择媒体类型" clearable>
|
||||
<el-option label="图片" value="image" />
|
||||
<el-option label="视频" value="video" />
|
||||
<el-option label="音频" value="audio" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:stepMedia:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:stepMedia:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:stepMedia:export']" type="warning" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="stepMediaList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="预览" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-image
|
||||
v-if="scope.row.mediaType === 'image'"
|
||||
:src="scope.row.fileUrl"
|
||||
:preview-src-list="[scope.row.fileUrl]"
|
||||
fit="cover"
|
||||
style="width: 60px; height: 60px"
|
||||
/>
|
||||
<el-icon v-else-if="scope.row.mediaType === 'video'" :size="40" color="#409eff">
|
||||
<VideoPlay />
|
||||
</el-icon>
|
||||
<el-icon v-else :size="40" color="#67c23a">
|
||||
<Microphone />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="文件名称" align="center" prop="fileName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="媒体类型" align="center" prop="mediaType" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.mediaType === 'image'" type="success">图片</el-tag>
|
||||
<el-tag v-else-if="scope.row.mediaType === 'video'" type="primary">视频</el-tag>
|
||||
<el-tag v-else type="warning">音频</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="文件大小" align="center" prop="fileSize" width="120">
|
||||
<template #default="scope">{{ formatFileSize(scope.row.fileSize) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上传时间" align="center" prop="uploadTime" width="180" />
|
||||
<el-table-column label="操作" align="center" width="180" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="下载" placement="top">
|
||||
<el-button link type="primary" icon="Download" @click="handleDownload(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button v-hasPermi="['inspection:stepMedia:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 添加步骤媒体文件对话框 -->
|
||||
<el-dialog v-model="dialog.visible" :title="dialog.title" width="600px" append-to-body>
|
||||
<el-form ref="stepMediaFormRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="步骤记录ID" prop="stepRecordId">
|
||||
<el-input v-model="form.stepRecordId" placeholder="请输入步骤记录ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="媒体类型" prop="mediaType">
|
||||
<el-radio-group v-model="form.mediaType">
|
||||
<el-radio value="image">图片</el-radio>
|
||||
<el-radio value="video">视频</el-radio>
|
||||
<el-radio value="audio">音频</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="文件URL" prop="fileUrl">
|
||||
<el-input v-model="form.fileUrl" placeholder="请输入文件URL" />
|
||||
</el-form-item>
|
||||
<el-form-item label="文件名称" prop="fileName">
|
||||
<el-input v-model="form.fileName" placeholder="请输入文件名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="文件大小" prop="fileSize">
|
||||
<el-input-number v-model="form.fileSize" :min="0" controls-position="right" style="width: 100%" />
|
||||
<span class="ml-2 text-gray-500">字节</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ArStepMedia" lang="ts">
|
||||
import { VideoPlay, Microphone } from '@element-plus/icons-vue';
|
||||
import { listArStepMedia, getArStepMedia, delArStepMedia, addArStepMedia } from '@/api/inspection/stepMedia';
|
||||
import { ArStepMediaVO, ArStepMediaQuery, ArStepMediaForm } from '@/api/inspection/stepMedia/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const stepMediaList = ref<ArStepMediaVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const stepMediaFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ArStepMediaForm = {
|
||||
id: undefined,
|
||||
stepRecordId: undefined,
|
||||
mediaType: 'image',
|
||||
fileUrl: undefined,
|
||||
fileName: undefined,
|
||||
fileSize: undefined
|
||||
};
|
||||
|
||||
const data = reactive<PageData<ArStepMediaForm, ArStepMediaQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
stepRecordId: undefined,
|
||||
mediaType: undefined,
|
||||
uploadTimeBegin: undefined,
|
||||
uploadTimeEnd: undefined
|
||||
},
|
||||
rules: {
|
||||
stepRecordId: [{ required: true, message: '步骤记录ID不能为空', trigger: 'blur' }],
|
||||
mediaType: [{ required: true, message: '媒体类型不能为空', trigger: 'change' }],
|
||||
fileUrl: [{ required: true, message: '文件URL不能为空', trigger: 'blur' }],
|
||||
fileName: [{ required: true, message: '文件名称不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 格式化文件大小 */
|
||||
const formatFileSize = (size: number) => {
|
||||
if (!size) return '-';
|
||||
if (size < 1024) return size + ' B';
|
||||
if (size < 1024 * 1024) return (size / 1024).toFixed(2) + ' KB';
|
||||
if (size < 1024 * 1024 * 1024) return (size / (1024 * 1024)).toFixed(2) + ' MB';
|
||||
return (size / (1024 * 1024 * 1024)).toFixed(2) + ' GB';
|
||||
};
|
||||
|
||||
/** 查询步骤媒体文件列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listArStepMedia(queryParams.value);
|
||||
stepMediaList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
stepMediaFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ArStepMediaVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加步骤媒体文件';
|
||||
};
|
||||
|
||||
/** 下载文件 */
|
||||
const handleDownload = (row: ArStepMediaVO) => {
|
||||
window.open(row.fileUrl, '_blank');
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
stepMediaFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
await addArStepMedia(form.value).finally(() => (buttonLoading.value = false));
|
||||
proxy?.$modal.msgSuccess('新增成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ArStepMediaVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除步骤媒体文件编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delArStepMedia(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'inspection/stepMedia/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`ar_step_media_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
326
plus-ui/src/views/inspection/stepRecord/index.vue
Normal file
326
plus-ui/src/views/inspection/stepRecord/index.vue
Normal file
@@ -0,0 +1,326 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="任务执行" prop="executionId">
|
||||
<el-select v-model="queryParams.executionId" placeholder="请选择任务执行" clearable filterable>
|
||||
<el-option v-for="execution in executionOptions" :key="execution.id" :label="execution.executionCode" :value="execution.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
|
||||
<el-option label="待执行" value="pending" />
|
||||
<el-option label="已完成" value="completed" />
|
||||
<el-option label="已跳过" value="skipped" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:stepRecord:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:stepRecord:edit']" type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:stepRecord:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:stepRecord:export']" type="warning" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="stepRecordList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="执行编号" align="center" prop="executionCode" :show-overflow-tooltip="true" width="180" />
|
||||
<el-table-column label="步骤名称" align="center" prop="stepName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="执行人" align="center" prop="executorName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="状态" align="center" prop="status" width="90">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status === 'pending'" type="info">待执行</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === 'completed'" type="success">已完成</el-tag>
|
||||
<el-tag v-else type="warning">已跳过</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="耗时(秒)" align="center" prop="duration" width="100" />
|
||||
<el-table-column label="开始时间" align="center" prop="startTime" width="180" />
|
||||
<el-table-column label="完成时间" align="center" prop="completionTime" width="180" />
|
||||
<el-table-column label="操作" align="center" width="180" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button v-hasPermi="['inspection:stepRecord:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button v-hasPermi="['inspection:stepRecord:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改步骤执行记录对话框 -->
|
||||
<el-dialog v-model="dialog.visible" :title="dialog.title" width="700px" append-to-body>
|
||||
<el-form ref="stepRecordFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="任务执行" prop="executionId">
|
||||
<el-select v-model="form.executionId" placeholder="请选择任务执行" filterable style="width: 100%">
|
||||
<el-option v-for="execution in executionOptions" :key="execution.id" :label="execution.executionCode" :value="execution.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="步骤" prop="stepId">
|
||||
<el-select v-model="form.stepId" placeholder="请选择步骤" filterable style="width: 100%">
|
||||
<el-option v-for="step in stepOptions" :key="step.id" :label="step.stepName" :value="step.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="form.status" placeholder="请选择状态" style="width: 100%">
|
||||
<el-option label="待执行" value="pending" />
|
||||
<el-option label="已完成" value="completed" />
|
||||
<el-option label="已跳过" value="skipped" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="执行人" prop="executorName">
|
||||
<el-input v-model="form.executorName" placeholder="请输入执行人姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="文本反馈" prop="textFeedback">
|
||||
<el-input v-model="form.textFeedback" type="textarea" :rows="3" placeholder="请输入文本反馈" />
|
||||
</el-form-item>
|
||||
<el-form-item label="语音识别文本" prop="voiceText">
|
||||
<el-input v-model="form.voiceText" type="textarea" :rows="2" placeholder="请输入语音识别文本" />
|
||||
</el-form-item>
|
||||
<el-form-item label="AI识别结果" prop="aiResult">
|
||||
<el-input v-model="aiResultStr" type="textarea" :rows="4" placeholder='请输入AI识别结果JSON格式' />
|
||||
<div v-if="jsonError" class="el-form-item__error">{{ jsonError }}</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ArStepRecord" lang="ts">
|
||||
import { listArStepRecord, getArStepRecord, delArStepRecord, addArStepRecord, updateArStepRecord } from '@/api/inspection/stepRecord';
|
||||
import { ArStepRecordVO, ArStepRecordQuery, ArStepRecordForm } from '@/api/inspection/stepRecord/types';
|
||||
import { listArExecution } from '@/api/inspection/execution';
|
||||
import { ArExecutionVO } from '@/api/inspection/execution/types';
|
||||
import { listArStep } from '@/api/inspection/step';
|
||||
import { ArStepVO } from '@/api/inspection/step/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const stepRecordList = ref<ArStepRecordVO[]>([]);
|
||||
const executionOptions = ref<ArExecutionVO[]>([]);
|
||||
const stepOptions = ref<ArStepVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const aiResultStr = ref('');
|
||||
const jsonError = ref('');
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const stepRecordFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ArStepRecordForm = {
|
||||
id: undefined,
|
||||
executionId: undefined,
|
||||
stepId: undefined,
|
||||
status: 'pending',
|
||||
textFeedback: undefined,
|
||||
voiceText: undefined,
|
||||
aiResult: undefined,
|
||||
executorId: undefined,
|
||||
executorName: undefined
|
||||
};
|
||||
|
||||
const data = reactive<PageData<ArStepRecordForm, ArStepRecordQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
executionId: undefined,
|
||||
stepId: undefined,
|
||||
status: undefined,
|
||||
executorId: undefined
|
||||
},
|
||||
rules: {
|
||||
executionId: [{ required: true, message: '任务执行不能为空', trigger: 'change' }],
|
||||
stepId: [{ required: true, message: '步骤不能为空', trigger: 'change' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 验证并解析JSON */
|
||||
const parseAiResult = () => {
|
||||
jsonError.value = '';
|
||||
if (!aiResultStr.value || aiResultStr.value.trim() === '') {
|
||||
form.value.aiResult = undefined;
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
form.value.aiResult = JSON.parse(aiResultStr.value);
|
||||
return true;
|
||||
} catch (e) {
|
||||
jsonError.value = 'JSON格式不正确';
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 查询选项数据 */
|
||||
const getOptions = async () => {
|
||||
const [executionRes, stepRes] = await Promise.all([
|
||||
listArExecution({ pageNum: 1, pageSize: 1000 }),
|
||||
listArStep({ pageNum: 1, pageSize: 1000 })
|
||||
]);
|
||||
executionOptions.value = executionRes.rows;
|
||||
stepOptions.value = stepRes.rows;
|
||||
};
|
||||
|
||||
/** 查询步骤执行记录列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listArStepRecord(queryParams.value);
|
||||
stepRecordList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
aiResultStr.value = '';
|
||||
jsonError.value = '';
|
||||
stepRecordFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ArStepRecordVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加步骤执行记录';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ArStepRecordVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getArStepRecord(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
if (form.value.aiResult) {
|
||||
aiResultStr.value = JSON.stringify(form.value.aiResult, null, 2);
|
||||
}
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改步骤执行记录';
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
stepRecordFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
if (!parseAiResult()) {
|
||||
return;
|
||||
}
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateArStepRecord(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addArStepRecord(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess(form.value.id ? '修改成功' : '新增成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ArStepRecordVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除步骤执行记录编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delArStepRecord(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'inspection/stepRecord/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`ar_step_record_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getOptions();
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
297
plus-ui/src/views/inspection/task/index.vue
Normal file
297
plus-ui/src/views/inspection/task/index.vue
Normal file
@@ -0,0 +1,297 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="任务名称" prop="taskName">
|
||||
<el-input v-model="queryParams.taskName" placeholder="请输入任务名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="任务代码" prop="taskCode">
|
||||
<el-input v-model="queryParams.taskCode" placeholder="请输入任务代码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="关联区域" prop="regionId">
|
||||
<el-select v-model="queryParams.regionId" placeholder="请选择关联区域" clearable filterable>
|
||||
<el-option v-for="region in regionOptions" :key="region.id" :label="region.regionName" :value="region.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="任务类型" prop="taskType">
|
||||
<el-input v-model="queryParams.taskType" placeholder="请输入任务类型" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
|
||||
<el-option label="正常" value="0" />
|
||||
<el-option label="停用" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:task:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:task:edit']" type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:task:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['inspection:task:export']" type="warning" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="taskList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="任务ID" align="center" prop="id" width="80" />
|
||||
<el-table-column label="任务名称" align="center" prop="taskName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="任务代码" align="center" prop="taskCode" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="关联区域" align="center" prop="regionName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="任务类型" align="center" prop="taskType" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status === '0'" type="success">正常</el-tag>
|
||||
<el-tag v-else type="danger">停用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" align="center" width="250" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="管理步骤" placement="top">
|
||||
<el-button v-hasPermi="['inspection:step:list']" link type="primary" icon="List" @click="handleManageSteps(scope.row)">步骤</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button v-hasPermi="['inspection:task:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button v-hasPermi="['inspection:task:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改巡检任务模板对话框 -->
|
||||
<el-dialog v-model="dialog.visible" :title="dialog.title" width="600px" append-to-body>
|
||||
<el-form ref="taskFormRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="任务名称" prop="taskName">
|
||||
<el-input v-model="form.taskName" placeholder="请输入任务名称" maxlength="100" />
|
||||
</el-form-item>
|
||||
<el-form-item label="任务代码" prop="taskCode">
|
||||
<el-input v-model="form.taskCode" placeholder="请输入任务代码" maxlength="50" />
|
||||
</el-form-item>
|
||||
<el-form-item label="关联区域" prop="regionId">
|
||||
<el-select v-model="form.regionId" placeholder="请选择关联区域" filterable style="width: 100%">
|
||||
<el-option v-for="region in regionOptions" :key="region.id" :label="region.regionName" :value="region.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="任务类型" prop="taskType">
|
||||
<el-input v-model="form.taskType" placeholder="请输入任务类型" maxlength="50" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio value="0">正常</el-radio>
|
||||
<el-radio value="1">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" maxlength="500" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ArTask" lang="ts">
|
||||
import { listArTask, getArTask, delArTask, addArTask, updateArTask } from '@/api/inspection/task';
|
||||
import { ArTaskVO, ArTaskQuery, ArTaskForm } from '@/api/inspection/task/types';
|
||||
import { listArRegion } from '@/api/inspection/region';
|
||||
import { ArRegionVO } from '@/api/inspection/region/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const router = useRouter();
|
||||
|
||||
const taskList = ref<ArTaskVO[]>([]);
|
||||
const regionOptions = ref<ArRegionVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const taskFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ArTaskForm = {
|
||||
id: undefined,
|
||||
taskName: undefined,
|
||||
taskCode: undefined,
|
||||
regionId: undefined,
|
||||
taskType: undefined,
|
||||
status: '0',
|
||||
remark: undefined
|
||||
};
|
||||
|
||||
const data = reactive<PageData<ArTaskForm, ArTaskQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
taskName: undefined,
|
||||
taskCode: undefined,
|
||||
regionId: undefined,
|
||||
taskType: undefined,
|
||||
status: undefined
|
||||
},
|
||||
rules: {
|
||||
taskName: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
|
||||
taskCode: [{ required: true, message: '任务代码不能为空', trigger: 'blur' }],
|
||||
regionId: [{ required: true, message: '关联区域不能为空', trigger: 'change' }],
|
||||
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询区域选项 */
|
||||
const getRegionOptions = async () => {
|
||||
const res = await listArRegion({ pageNum: 1, pageSize: 1000, status: '0' });
|
||||
regionOptions.value = res.rows;
|
||||
};
|
||||
|
||||
/** 查询巡检任务模板列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listArTask(queryParams.value);
|
||||
taskList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
taskFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ArTaskVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加巡检任务模板';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ArTaskVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getArTask(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改巡检任务模板';
|
||||
};
|
||||
|
||||
/** 管理步骤按钮操作 */
|
||||
const handleManageSteps = (row: ArTaskVO) => {
|
||||
router.push({
|
||||
path: '/inspection/step',
|
||||
query: {
|
||||
taskId: row.id,
|
||||
taskName: row.taskName
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
taskFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateArTask(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addArTask(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess(form.value.id ? '修改成功' : '新增成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ArTaskVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除巡检任务模板编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
|
||||
await delArTask(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'inspection/task/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`ar_task_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getRegionOptions();
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user