合并
This commit is contained in:
		| @ -11,3 +11,34 @@ export const keyIndex = () => { | ||||
|     method: 'get' | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 每个项目的出勤人数 | ||||
|  */ | ||||
|  | ||||
| export const projectAttendanceCount = () => { | ||||
|   return request({ | ||||
|     url: '/enterprise/big/screen/projectAttendanceCount', | ||||
|     method: 'get' | ||||
|   }); | ||||
| }; | ||||
| /** | ||||
|  * 人数统计 | ||||
|  */ | ||||
|  | ||||
| export const peopleCount = () => { | ||||
|   return request({ | ||||
|     url: '/enterprise/big/screen/peopleCount', | ||||
|     method: 'get' | ||||
|   }); | ||||
| }; | ||||
| /** | ||||
|  * 出勤人数统计 | ||||
|  */ | ||||
|  | ||||
| export const allAttendanceCount = () => { | ||||
|   return request({ | ||||
|     url: '/enterprise/big/screen/allAttendanceCount', | ||||
|     method: 'get' | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| @ -106,6 +106,6 @@ export const getFootNote = (data) => { | ||||
|   return request({ | ||||
|     url: 'gps/equipmentSon/getList', | ||||
|     method: 'get', | ||||
|     data: data | ||||
|     params: data | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| @ -122,6 +122,11 @@ export interface EquipmentQuery extends PageQuery { | ||||
|    */ | ||||
|   type?: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 展示用户/设备数据:1=用户数据,0=设备数据 | ||||
|    */ | ||||
|   gpsType?: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 用户id | ||||
|    */ | ||||
|  | ||||
| @ -53,7 +53,6 @@ export interface MaterialReceiveVO { | ||||
|    * 备注 | ||||
|    */ | ||||
|   remark: string; | ||||
|  | ||||
| } | ||||
|  | ||||
| export interface MaterialReceiveForm extends BaseEntity { | ||||
| @ -156,11 +155,13 @@ export interface MaterialReceiveForm extends BaseEntity { | ||||
|    * 备注 | ||||
|    */ | ||||
|   remark?: string; | ||||
|  | ||||
|   /** | ||||
|    * 附件 | ||||
|    */ | ||||
|   attachmentId?: string | number; | ||||
| } | ||||
|  | ||||
| export interface MaterialReceiveQuery extends PageQuery { | ||||
|  | ||||
|   /** | ||||
|    * 项目id | ||||
|    */ | ||||
| @ -201,11 +202,8 @@ export interface MaterialReceiveQuery extends PageQuery { | ||||
|    */ | ||||
|   supplierUnit?: string; | ||||
|  | ||||
|     /** | ||||
|      * 日期范围参数 | ||||
|      */ | ||||
|     params?: any; | ||||
|   /** | ||||
|    * 日期范围参数 | ||||
|    */ | ||||
|   params?: any; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										72
									
								
								src/api/mechanical/mechanicalrewriting/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/api/mechanical/mechanicalrewriting/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | ||||
| import request from '@/utils/request'; | ||||
| import { AxiosPromise } from 'axios'; | ||||
| import { MechanicalrewritingVO, MechanicalrewritingForm, MechanicalrewritingQuery } from '@/api/mechanical/mechanicalrewriting/types'; | ||||
|  | ||||
| /** | ||||
|  * 查询机械台账列表 | ||||
|  * @param query | ||||
|  * @returns {*} | ||||
|  */ | ||||
|  | ||||
| export const listMechanicalrewriting = (query?: MechanicalrewritingQuery): AxiosPromise<MechanicalrewritingVO[]> => { | ||||
|   return request({ | ||||
|     url: '/mechanical/mechanicalrewriting/list', | ||||
|     method: 'get', | ||||
|     params: query | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 查询机械台账详细 | ||||
|  * @param id | ||||
|  */ | ||||
| export const getMechanicalrewriting = (id: string | number): AxiosPromise<MechanicalrewritingVO> => { | ||||
|   return request({ | ||||
|     url: '/mechanical/mechanicalrewriting/' + id, | ||||
|     method: 'get' | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 新增机械台账 | ||||
|  * @param data | ||||
|  */ | ||||
| export const addMechanicalrewriting = (data: MechanicalrewritingForm) => { | ||||
|   return request({ | ||||
|     url: '/mechanical/mechanicalrewriting', | ||||
|     method: 'post', | ||||
|     data: data | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 修改机械台账 | ||||
|  * @param data | ||||
|  */ | ||||
| export const updateMechanicalrewriting = (data: MechanicalrewritingForm) => { | ||||
|   return request({ | ||||
|     url: '/mechanical/mechanicalrewriting', | ||||
|     method: 'put', | ||||
|     data: data | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 删除机械台账 | ||||
|  * @param id | ||||
|  */ | ||||
| export const delMechanicalrewriting = (id: string | number | Array<string | number>) => { | ||||
|   return request({ | ||||
|     url: '/mechanical/mechanicalrewriting/' + id, | ||||
|     method: 'delete' | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| //获取类型 | ||||
| export const getType = (query?: any) => { | ||||
|   return request({ | ||||
|     url: '/mechanical/mechanicaltype/getTree', | ||||
|     method: 'get', | ||||
|     params: query | ||||
|   }); | ||||
| }; | ||||
							
								
								
									
										306
									
								
								src/api/mechanical/mechanicalrewriting/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										306
									
								
								src/api/mechanical/mechanicalrewriting/types.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,306 @@ | ||||
| export interface MechanicalrewritingVO { | ||||
|   /** | ||||
|    * 自增ID | ||||
|    */ | ||||
|   id: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 项目ID | ||||
|    */ | ||||
|   projectId: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 班组名称 | ||||
|    */ | ||||
|   teamName: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备名称 | ||||
|    */ | ||||
|   devicename: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备类型 | ||||
|    */ | ||||
|   deviceType: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备编号 | ||||
|    */ | ||||
|   deviceNumber: string; | ||||
|  | ||||
|   /** | ||||
|    * 入场日期 | ||||
|    */ | ||||
|   entryTime: string; | ||||
|  | ||||
|   /** | ||||
|    * 规格型号 | ||||
|    */ | ||||
|   specification: string; | ||||
|  | ||||
|   /** | ||||
|    * 生产能力 | ||||
|    */ | ||||
|   production: string; | ||||
|  | ||||
|   /** | ||||
|    * 车牌号码 | ||||
|    */ | ||||
|   plateNumber: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备管理员 | ||||
|    */ | ||||
|   deviceKeeper: string; | ||||
|  | ||||
|   /** | ||||
|    * 车辆行驶证 | ||||
|    */ | ||||
|   drivingLicence: string; | ||||
|  | ||||
|   /** | ||||
|    * 新旧程度 | ||||
|    */ | ||||
|   degree: string; | ||||
|  | ||||
|   /** | ||||
|    * 车辆容量 | ||||
|    */ | ||||
|   vehicleCapacity: string; | ||||
|  | ||||
|   /** | ||||
|    * 车辆净重 | ||||
|    */ | ||||
|   suttle: string; | ||||
|  | ||||
|   /** | ||||
|    * 铭牌 | ||||
|    */ | ||||
|   nameplate: string; | ||||
|  | ||||
|   /** | ||||
|    * 合格证书 | ||||
|    */ | ||||
|   qualification: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备照片 | ||||
|    */ | ||||
|   equipmentPhoto: string; | ||||
|  | ||||
|   /** | ||||
|    * 检验报告 | ||||
|    */ | ||||
|   verificationReport: string; | ||||
|  | ||||
|   /** | ||||
|    * 备注 | ||||
|    */ | ||||
|   remark: string; | ||||
|  | ||||
| } | ||||
|  | ||||
| export interface MechanicalrewritingForm extends BaseEntity { | ||||
|   /** | ||||
|    * 自增ID | ||||
|    */ | ||||
|   id?: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 项目ID | ||||
|    */ | ||||
|   projectId?: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 班组名称 | ||||
|    */ | ||||
|   teamName?: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备名称 | ||||
|    */ | ||||
|   devicename?: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备类型 | ||||
|    */ | ||||
|   deviceType?: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备编号 | ||||
|    */ | ||||
|   deviceNumber?: string; | ||||
|  | ||||
|   /** | ||||
|    * 入场日期 | ||||
|    */ | ||||
|   entryTime?: string; | ||||
|  | ||||
|   /** | ||||
|    * 规格型号 | ||||
|    */ | ||||
|   specification?: string; | ||||
|  | ||||
|   /** | ||||
|    * 生产能力 | ||||
|    */ | ||||
|   production?: string; | ||||
|  | ||||
|   /** | ||||
|    * 车牌号码 | ||||
|    */ | ||||
|   plateNumber?: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备管理员 | ||||
|    */ | ||||
|   deviceKeeper?: string; | ||||
|  | ||||
|   /** | ||||
|    * 车辆行驶证 | ||||
|    */ | ||||
|   drivingLicence?: string; | ||||
|  | ||||
|   /** | ||||
|    * 新旧程度 | ||||
|    */ | ||||
|   degree?: string; | ||||
|  | ||||
|   /** | ||||
|    * 车辆容量 | ||||
|    */ | ||||
|   vehicleCapacity?: string; | ||||
|  | ||||
|   /** | ||||
|    * 车辆净重 | ||||
|    */ | ||||
|   suttle?: string; | ||||
|  | ||||
|   /** | ||||
|    * 铭牌 | ||||
|    */ | ||||
|   nameplate?: string; | ||||
|  | ||||
|   /** | ||||
|    * 合格证书 | ||||
|    */ | ||||
|   qualification?: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备照片 | ||||
|    */ | ||||
|   equipmentPhoto?: string; | ||||
|  | ||||
|   /** | ||||
|    * 检验报告 | ||||
|    */ | ||||
|   verificationReport?: string; | ||||
|  | ||||
|   /** | ||||
|    * 备注 | ||||
|    */ | ||||
|   remark?: string; | ||||
|  | ||||
| } | ||||
|  | ||||
| export interface MechanicalrewritingQuery extends PageQuery { | ||||
|  | ||||
|   /** | ||||
|    * 项目ID | ||||
|    */ | ||||
|   projectId?: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 班组名称 | ||||
|    */ | ||||
|   teamName?: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备名称 | ||||
|    */ | ||||
|   devicename?: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备类型 | ||||
|    */ | ||||
|   deviceType?: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备编号 | ||||
|    */ | ||||
|   deviceNumber?: string; | ||||
|  | ||||
|   /** | ||||
|    * 入场日期 | ||||
|    */ | ||||
|   entryTime?: string; | ||||
|  | ||||
|   /** | ||||
|    * 规格型号 | ||||
|    */ | ||||
|   specification?: string; | ||||
|  | ||||
|   /** | ||||
|    * 生产能力 | ||||
|    */ | ||||
|   production?: string; | ||||
|  | ||||
|   /** | ||||
|    * 车牌号码 | ||||
|    */ | ||||
|   plateNumber?: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备管理员 | ||||
|    */ | ||||
|   deviceKeeper?: string; | ||||
|  | ||||
|   /** | ||||
|    * 车辆行驶证 | ||||
|    */ | ||||
|   drivingLicence?: string; | ||||
|  | ||||
|   /** | ||||
|    * 新旧程度 | ||||
|    */ | ||||
|   degree?: string; | ||||
|  | ||||
|   /** | ||||
|    * 车辆容量 | ||||
|    */ | ||||
|   vehicleCapacity?: string; | ||||
|  | ||||
|   /** | ||||
|    * 车辆净重 | ||||
|    */ | ||||
|   suttle?: string; | ||||
|  | ||||
|   /** | ||||
|    * 铭牌 | ||||
|    */ | ||||
|   nameplate?: string; | ||||
|  | ||||
|   /** | ||||
|    * 合格证书 | ||||
|    */ | ||||
|   qualification?: string; | ||||
|  | ||||
|   /** | ||||
|    * 设备照片 | ||||
|    */ | ||||
|   equipmentPhoto?: string; | ||||
|  | ||||
|   /** | ||||
|    * 检验报告 | ||||
|    */ | ||||
|   verificationReport?: string; | ||||
|  | ||||
|     /** | ||||
|      * 日期范围参数 | ||||
|      */ | ||||
|     params?: any; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										63
									
								
								src/api/mechanical/mechanicaltype/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/api/mechanical/mechanicaltype/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| import request from '@/utils/request'; | ||||
| import { AxiosPromise } from 'axios'; | ||||
| import { MechanicaltypeVO, MechanicaltypeForm, MechanicaltypeQuery } from '@/api/mechanical/mechanicaltype/types'; | ||||
|  | ||||
| /** | ||||
|  * 查询设备类型列表 | ||||
|  * @param query | ||||
|  * @returns {*} | ||||
|  */ | ||||
|  | ||||
| export const listMechanicaltype = (query?: MechanicaltypeQuery): AxiosPromise<MechanicaltypeVO[]> => { | ||||
|   return request({ | ||||
|     url: '/mechanical/mechanicaltype/list', | ||||
|     method: 'get', | ||||
|     params: query | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 查询设备类型详细 | ||||
|  * @param id | ||||
|  */ | ||||
| export const getMechanicaltype = (id: string | number): AxiosPromise<MechanicaltypeVO> => { | ||||
|   return request({ | ||||
|     url: '/mechanical/mechanicaltype/' + id, | ||||
|     method: 'get' | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 新增设备类型 | ||||
|  * @param data | ||||
|  */ | ||||
| export const addMechanicaltype = (data: MechanicaltypeForm) => { | ||||
|   return request({ | ||||
|     url: '/mechanical/mechanicaltype', | ||||
|     method: 'post', | ||||
|     data: data | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 修改设备类型 | ||||
|  * @param data | ||||
|  */ | ||||
| export const updateMechanicaltype = (data: MechanicaltypeForm) => { | ||||
|   return request({ | ||||
|     url: '/mechanical/mechanicaltype', | ||||
|     method: 'put', | ||||
|     data: data | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 删除设备类型 | ||||
|  * @param id | ||||
|  */ | ||||
| export const delMechanicaltype = (id: string | number | Array<string | number>) => { | ||||
|   return request({ | ||||
|     url: '/mechanical/mechanicaltype/' + id, | ||||
|     method: 'delete' | ||||
|   }); | ||||
| }; | ||||
							
								
								
									
										129
									
								
								src/api/mechanical/mechanicaltype/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								src/api/mechanical/mechanicaltype/types.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | ||||
| export interface MechanicaltypeVO { | ||||
|   /** | ||||
|    * 自增ID | ||||
|    */ | ||||
|   id: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 编码 | ||||
|    */ | ||||
|   code: string; | ||||
|  | ||||
|   /** | ||||
|    * 父编码 | ||||
|    */ | ||||
|   pcode: string; | ||||
|  | ||||
|   /** | ||||
|    * 大 | ||||
|    */ | ||||
|   largeclass: string; | ||||
|  | ||||
|   /** | ||||
|    * 中 | ||||
|    */ | ||||
|   middleclass: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 子类 | ||||
|    */ | ||||
|   subclass: string; | ||||
|  | ||||
|   /** | ||||
|    * 备注 | ||||
|    */ | ||||
|   remark: string; | ||||
|  | ||||
|   /** | ||||
|    * 全名 | ||||
|    */ | ||||
|   fullName: string; | ||||
|   /** | ||||
|    * 类型 | ||||
|    */ | ||||
|   deviceType?: string; | ||||
| } | ||||
|  | ||||
| export interface MechanicaltypeForm extends BaseEntity { | ||||
|   /** | ||||
|    * 自增ID | ||||
|    */ | ||||
|   id?: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 编码 | ||||
|    */ | ||||
|   code?: string; | ||||
|  | ||||
|   /** | ||||
|    * 父编码 | ||||
|    */ | ||||
|   pcode?: string; | ||||
|  | ||||
|   /** | ||||
|    * 大 | ||||
|    */ | ||||
|   largeclass?: string; | ||||
|  | ||||
|   /** | ||||
|    * 中 | ||||
|    */ | ||||
|   middleclass?: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 子类 | ||||
|    */ | ||||
|   subclass?: string; | ||||
|  | ||||
|   /** | ||||
|    * 备注 | ||||
|    */ | ||||
|   remark?: string; | ||||
|  | ||||
|   /** | ||||
|    * 全名 | ||||
|    */ | ||||
|   fullName?: string; | ||||
|  | ||||
|   /** | ||||
|    * 类型 | ||||
|    */ | ||||
|   deviceType?: string; | ||||
| } | ||||
|  | ||||
| export interface MechanicaltypeQuery extends PageQuery { | ||||
|   /** | ||||
|    * 编码 | ||||
|    */ | ||||
|   code?: string; | ||||
|  | ||||
|   /** | ||||
|    * 父编码 | ||||
|    */ | ||||
|   pcode?: string; | ||||
|  | ||||
|   /** | ||||
|    * 大 | ||||
|    */ | ||||
|   largeclass?: string; | ||||
|  | ||||
|   /** | ||||
|    * 中 | ||||
|    */ | ||||
|   middleclass?: string | number; | ||||
|  | ||||
|   /** | ||||
|    * 子类 | ||||
|    */ | ||||
|   subclass?: string; | ||||
|  | ||||
|   /** | ||||
|    * 全名 | ||||
|    */ | ||||
|   fullName?: string; | ||||
|  | ||||
|   /** | ||||
|    * 日期范围参数 | ||||
|    */ | ||||
|   params?: any; | ||||
| } | ||||
| @ -23,7 +23,7 @@ export const projectProgress = (query?: any): any => { | ||||
|  | ||||
| export const outpuProgress = (query?: any): any => { | ||||
|   return request({ | ||||
|     url: '/enterprise/big/screen/projectOutputValueComparison', | ||||
|     url: '/enterprise/big/screen/projectProgressCapacity', | ||||
|     method: 'get', | ||||
|     params: query | ||||
|   }); | ||||
|  | ||||
| @ -31,6 +31,7 @@ export interface FlowTaskVO { | ||||
|   version?: string; | ||||
|   applyNode?: boolean; | ||||
|   buttonList?: buttonList[]; | ||||
|   projectName?: string; | ||||
| } | ||||
|  | ||||
| export interface buttonList { | ||||
|  | ||||
| @ -12,7 +12,8 @@ export default { | ||||
|         businessId: routerJumpVo.businessId, | ||||
|         type: routerJumpVo.type, | ||||
|         planMonth: routerJumpVo.planMonth, | ||||
|         taskId: routerJumpVo.taskId | ||||
|         taskId: routerJumpVo.taskId, | ||||
|         projectName: routerJumpVo.projectName | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
| @ -4,6 +4,7 @@ export interface RouterJumpVo { | ||||
|   type: string; | ||||
|   formCustom: string; | ||||
|   formPath: string; | ||||
|   projectName?: string; | ||||
| } | ||||
|  | ||||
| export interface StartProcessBo { | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								src/assets/images/man.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/assets/images/man.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 26 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/images/map.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/assets/images/map.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 360 KiB | 
| @ -46,6 +46,7 @@ import { OssVO } from '@/api/system/oss/types'; | ||||
| import { propTypes } from '@/utils/propTypes'; | ||||
| import { globalHeaders } from '@/utils/request'; | ||||
| import { compressAccurately } from 'image-conversion'; | ||||
| import { bool } from 'vue-types'; | ||||
|  | ||||
| const props = defineProps({ | ||||
|   modelValue: { | ||||
| @ -81,7 +82,7 @@ const props = defineProps({ | ||||
|   compressTargetSize: propTypes.number.def(300), | ||||
|   idCardType: { | ||||
|     type: String, | ||||
|     default: false | ||||
|     default: '' | ||||
|   } | ||||
| }); | ||||
|  | ||||
|  | ||||
| @ -1,15 +1,18 @@ | ||||
| <template> | ||||
|   <div style="display: flex; justify-content: space-between"> | ||||
|     <div> | ||||
|       <el-button v-if="submitButtonShow" :loading="props.buttonLoading" type="info" @click="submitForm('draft')">暂存</el-button> | ||||
|       <el-button v-if="submitButtonShow" :loading="props.buttonLoading" type="primary" @click="submitForm('submit')">提 交</el-button> | ||||
|       <el-button v-if="approvalButtonShow" :loading="props.buttonLoading" type="primary" @click="approvalVerifyOpen">审批</el-button> | ||||
|       <el-button v-if="props.id && props.status !== 'draft'" type="primary" @click="handleApprovalRecord">流程进度</el-button> | ||||
|       <slot /> | ||||
|     </div> | ||||
|     <div> | ||||
|       <el-button style="float: right" @click="goBack()">返回</el-button> | ||||
|   <div> | ||||
|     <div style="display: flex; justify-content: space-between"> | ||||
|       <div> | ||||
|         <el-button v-if="submitButtonShow" :loading="props.buttonLoading" type="info" @click="submitForm('draft')">暂存</el-button> | ||||
|         <el-button v-if="submitButtonShow" :loading="props.buttonLoading" type="primary" @click="submitForm('submit')">提 交</el-button> | ||||
|         <el-button v-if="approvalButtonShow" :loading="props.buttonLoading" type="primary" @click="approvalVerifyOpen">审批</el-button> | ||||
|         <el-button v-if="props.id && props.status !== 'draft'" type="primary" @click="handleApprovalRecord">流程进度</el-button> | ||||
|         <slot /> | ||||
|       </div> | ||||
|       <div> | ||||
|         <el-button style="float: right" @click="goBack()">返回</el-button> | ||||
|       </div> | ||||
|     </div> | ||||
|     <h3 v-if="props.projectName" class="text-lg font-semibold text-gray-800">项目名称:{{ props.projectName }}</h3> | ||||
|   </div> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| @ -22,7 +25,8 @@ const props = defineProps({ | ||||
|   status: propTypes.string.def(''), | ||||
|   pageType: propTypes.string.def(''), | ||||
|   buttonLoading: propTypes.bool.def(false), | ||||
|   id: propTypes.string.def('') || propTypes.number.def() | ||||
|   id: propTypes.string.def('') || propTypes.number.def(), | ||||
|   projectName: propTypes.string.def('') | ||||
| }); | ||||
| const emits = defineEmits(['submitForm', 'approvalVerifyOpen', 'handleApprovalRecord']); | ||||
| //暂存,提交 | ||||
|  | ||||
| @ -167,7 +167,7 @@ const reset = () => { | ||||
|   form.value = { ...initFormData }; | ||||
|   leaveFormRef.value?.resetFields(); | ||||
| }; | ||||
|  | ||||
| const projectId = ref(''); | ||||
| /** 获取详情 */ | ||||
| const getInfo = () => { | ||||
|   loading.value = true; | ||||
| @ -175,6 +175,7 @@ const getInfo = () => { | ||||
|   nextTick(async () => { | ||||
|     const res = await getVersionDetail(routeParams.value.id); | ||||
|     console.log(res); | ||||
|     projectId.value = res.data.projectId; | ||||
|     Object.assign(form.value, res.data); | ||||
|     loading.value = false; | ||||
|     buttonLoading.value = false; | ||||
| @ -186,7 +187,7 @@ const sheets = ref([]); | ||||
| const getSheetName = async () => { | ||||
|   try { | ||||
|     const params = { | ||||
|       projectId: currentProject.value?.id, | ||||
|       projectId: projectId.value, | ||||
|       versions: form.value.versions | ||||
|     }; | ||||
|     const res = await sheetList(params); | ||||
| @ -208,7 +209,7 @@ const tableData = ref([]); | ||||
| //获取列表 | ||||
| const getListTable = async () => { | ||||
|   const res = await getTreeLimit({ | ||||
|     projectId: currentProject.value?.id, | ||||
|     projectId: projectId.value, | ||||
|     versions: form.value.versions, | ||||
|     sheet: form.value.sheet, | ||||
|     type: '0' | ||||
|  | ||||
| @ -66,7 +66,7 @@ | ||||
|             {{ scope.row.children.length > 0 ? '' : scope.row.quantity }} | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column prop="remark" label="单价" align="center"> | ||||
|         <el-table-column prop="remark" label="单价" align="center" width="200px"> | ||||
|           <template #default="scope"> | ||||
|             <el-input-number | ||||
|               :disabled="versionObj.status != 'draft'" | ||||
| @ -81,6 +81,7 @@ | ||||
|               :precision="4" | ||||
|               :controls="false" | ||||
|               v-if="scope.row.quantity && scope.row.quantity != 0" | ||||
|               width="200px" | ||||
|             /> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -30,7 +30,7 @@ | ||||
|               {{ proxy.formatPrice(scope.row.price) }} | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column prop="plannedBiddingTime" align="center"> | ||||
|           <el-table-column prop="plannedBiddingTime" align="center" width="250px"> | ||||
|             <template #header> <span style="color: red">*</span>计划招标时间 </template> | ||||
|             <template #default="scope"> | ||||
|               <el-date-picker | ||||
| @ -39,6 +39,7 @@ | ||||
|                 value-format="YYYY-MM-DD" | ||||
|                 placeholder="选择时间" | ||||
|                 :disabled="scope.row.status == 0" | ||||
|                 style="width: 200px" | ||||
|               /> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
| @ -126,7 +127,7 @@ | ||||
|             <el-table-column prop="unit" label="单位" /> | ||||
|             <!-- <el-table-column prop="quantity" label="数量" /> --> | ||||
|             <el-table-column prop="quantity" label="计划量" align="center" /> | ||||
|             <el-table-column prop="selectNum" label="设计量" align="center"> | ||||
|             <el-table-column prop="selectNum" label="设计量" align="center" width="200px"> | ||||
|               <template #default="scope"> | ||||
|                 <el-input-number | ||||
|                   :model-value="scope.row.selectNum" | ||||
| @ -141,6 +142,7 @@ | ||||
|                   :controls="false" | ||||
|                   :max="Math.floor(scope.row.quantity)" | ||||
|                   v-if="scope.row.quantity && scope.row.quantity != 0 && scope.row.unitPrice" | ||||
|                   width="150px" | ||||
|                 /> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
| @ -5,7 +5,7 @@ | ||||
|         <el-form :model="queryForm" :inline="true"> | ||||
|           <el-form-item label="版本号" prop="versions"> | ||||
|             <el-select v-model="queryForm.versions" placeholder="选择版本号" @change="changeVersions"> | ||||
|               <el-option v-for="item in options" :key="item.versions" :label="item.versions" :value="item.versions" /> | ||||
|               <el-option v-for="item in options" :key="item.versions" :label="item.versionsName" :value="item.versions" /> | ||||
|             </el-select> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="表名" prop="sheet"> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.versions" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
| @ -162,7 +163,7 @@ const reset = () => { | ||||
|   form.value = { ...initFormData }; | ||||
|   leaveFormRef.value?.resetFields(); | ||||
| }; | ||||
|  | ||||
| const projectId = ref(''); | ||||
| /** 获取详情 */ | ||||
| const getInfo = () => { | ||||
|   loading.value = true; | ||||
| @ -170,6 +171,7 @@ const getInfo = () => { | ||||
|   nextTick(async () => { | ||||
|     const res = await getVersionDetails(routeParams.value.id); | ||||
|     console.log(res); | ||||
|     projectId.value = res.data.projectId; | ||||
|     Object.assign(form.value, res.data); | ||||
|     loading.value = false; | ||||
|     buttonLoading.value = false; | ||||
| @ -181,7 +183,7 @@ const sheets = ref([]); | ||||
| const getSheetName = async () => { | ||||
|   try { | ||||
|     const params = { | ||||
|       projectId: currentProject.value?.id, | ||||
|       projectId: projectId.value, | ||||
|       versions: form.value.versions | ||||
|     }; | ||||
|     const res = await sheetList(params); | ||||
| @ -201,7 +203,7 @@ const changeSheet = () => { | ||||
| //获取列表 | ||||
| const getListTable = async () => { | ||||
|   const res = await listBillofquantitiesLimitList({ | ||||
|     projectId: currentProject.value?.id, | ||||
|     projectId: projectId.value, | ||||
|     versions: form.value.versions, | ||||
|     sheet: form.value.sheet | ||||
|   }); | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|  | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|  | ||||
|  | ||||
| @ -1,30 +1,31 @@ | ||||
| <template> | ||||
|     <el-row> | ||||
|         <el-col> | ||||
|             <div style="color: rgba(0, 30, 59, 1);;font-family: 'Alibaba-PuHuiTi-Bold';margin: 10px 0 0 0;" | ||||
|                 :style="{ fontSize: fontLevelMap[props.fontLevel] }"> | ||||
|                 {{ props.title }} | ||||
|             </div> | ||||
|         </el-col> | ||||
|         <el-col> | ||||
|             <p style="color: rgba(154, 154, 154, 1);font-size: 14px;"> | ||||
|                 {{ props.subtitle }} | ||||
|             </p> | ||||
|         </el-col> | ||||
|  | ||||
|     </el-row> | ||||
|   <el-row> | ||||
|     <el-col> | ||||
|       <div | ||||
|         style="color: rgba(0, 30, 59, 1); font-family: 'Alibaba-PuHuiTi-Bold'; margin: 10px 0 0 0" | ||||
|         :style="{ fontSize: fontLevelMap[props.fontLevel] }" | ||||
|       > | ||||
|         {{ props.title }} | ||||
|       </div> | ||||
|     </el-col> | ||||
|     <el-col> | ||||
|       <p style="color: rgba(154, 154, 154, 1); font-size: 14px"> | ||||
|         {{ props.subtitle }} | ||||
|       </p> | ||||
|     </el-col> | ||||
|   </el-row> | ||||
| </template> | ||||
| <script setup> | ||||
| const props = defineProps({ | ||||
|     title: String, | ||||
|     subtitle: String, | ||||
|     fontLevel: { | ||||
|         type: Number, | ||||
|         default: 1 | ||||
|     } | ||||
| }) | ||||
|   title: String, | ||||
|   subtitle: String, | ||||
|   fontLevel: { | ||||
|     type: Number, | ||||
|     default: 1 | ||||
|   } | ||||
| }); | ||||
| const fontLevelMap = { | ||||
|     1: "24px", | ||||
|     2: "18px" | ||||
| } | ||||
| </script> | ||||
|   1: '24px', | ||||
|   2: '18px' | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -7,7 +7,7 @@ | ||||
|           <el-form :model="state.queryForm" :inline="true"> | ||||
|             <el-form-item label="版本号" prop="versions"> | ||||
|               <el-select v-model="state.queryForm.versions" placeholder="选择版本号" @change="handleChangeVersion"> | ||||
|                 <el-option v-for="item in state.options" :key="item.versions" :label="item.versions" :value="item.versions" /> | ||||
|                 <el-option v-for="item in state.options" :key="item.versions" :label="item.versionsName" :value="item.versions" /> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="表名" prop="sheet"> | ||||
| @ -48,7 +48,7 @@ | ||||
|           <el-form :model="state.queryForm" :inline="true"> | ||||
|             <el-form-item label="版本号" prop="versions"> | ||||
|               <el-select v-model="state.queryForm.versions" placeholder="选择版本号" @change="handleChangeVersion"> | ||||
|                 <el-option v-for="item in state.options" :key="item.versions" :label="item.versions" :value="item.versions" /> | ||||
|                 <el-option v-for="item in state.options" :key="item.versions" :label="item.versionsName" :value="item.versions" /> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
|             <el-form-item> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.versions" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.versions" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.versions" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.versions" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.design" | ||||
|           :status="form.auditStatus" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|  | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|  | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|  | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.auditStatus" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
| @ -205,7 +206,7 @@ const approvalVerifyOpen = async () => { | ||||
|   // 图纸评审验证 判断是否需要设计验证 | ||||
|   if (form.value.isWindow) { | ||||
|     console.log(routeParams.value.businessId); | ||||
|      | ||||
|  | ||||
|     submitVerifyRef.value.openDialog(routeParams.value.taskId, true, routeParams.value.businessId); | ||||
|   } else { | ||||
|     submitVerifyRef.value.openDialog(routeParams.value.taskId); | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.auditStatus" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
							
								
								
									
										756
									
								
								src/views/dhr_demo/InspectionManagement.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										756
									
								
								src/views/dhr_demo/InspectionManagement.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,756 @@ | ||||
| <template> | ||||
|   <div> | ||||
|     <div class="operation-inspection"> | ||||
|       <div class="navigation-tabs"> | ||||
|         <div class="nav-tab" @click="handleInspection1">待办事项</div> | ||||
|         <div class="nav-tab active" @click="handleInspection2">巡检管理</div> | ||||
|         <div class="nav-tab">试验管理</div> | ||||
|         <div class="nav-tab">报修管理</div> | ||||
|         <div class="nav-tab">抢修管理</div> | ||||
|         <div class="nav-tab">工单管理</div> | ||||
|       </div> | ||||
|       <TitleComponent title="运维巡检管理" subtitle="制定巡检计划,安排巡检任务,跟进巡检记录"></TitleComponent> | ||||
|  | ||||
|       <!-- 选项卡和按钮组合 --> | ||||
|       <div class="tabs-wrapper"> | ||||
|         <div style="display: flex; align-items: center; gap: 10px"> | ||||
|           <el-button type="primary" @click="handleInspectionManagement1">巡检计划</el-button> | ||||
|           <el-button type="primary" @click="handleInspectionManagement2">巡检任务</el-button> | ||||
|           <el-button type="primary" @click="handleInspectionManagement3">巡检记录</el-button> | ||||
|         </div> | ||||
|       </div> | ||||
|       <!-- 筛选栏 --> | ||||
|       <div class="filter-bar"> | ||||
|         <div class="filter-item"> | ||||
|           <el-select v-model="planType" placeholder="计划类型" clearable> | ||||
|             <el-option label="全部类型" value="all"></el-option> | ||||
|             <el-option label="每日巡检" value="daily"></el-option> | ||||
|             <el-option label="每周巡检" value="weekly"></el-option> | ||||
|             <el-option label="每月巡检" value="monthly"></el-option> | ||||
|             <el-option label="每季度巡检" value="quarterly"></el-option> | ||||
|           </el-select> | ||||
|         </div> | ||||
|         <div class="filter-item"> | ||||
|           <el-select v-model="status" placeholder="全部状态" clearable> | ||||
|             <el-option label="全部状态" value="all"></el-option> | ||||
|             <el-option label="启用中" value="enabled"></el-option> | ||||
|             <el-option label="已停用" value="disabled"></el-option> | ||||
|           </el-select> | ||||
|         </div> | ||||
|         <div class="filter-item"> | ||||
|           <el-select v-model="inspectionObject" placeholder="巡检对象" clearable> | ||||
|             <el-option label="全部对象" value="all"></el-option> | ||||
|             <el-option label="服务器" value="server"></el-option> | ||||
|             <el-option label="网络设备" value="network"></el-option> | ||||
|             <el-option label="应用系统" value="application"></el-option> | ||||
|             <el-option label="基础设施" value="infrastructure"></el-option> | ||||
|           </el-select> | ||||
|         </div> | ||||
|         <div class="filter-actions"> | ||||
|           <el-button type="primary" class="search-btn">搜索</el-button> | ||||
|           <el-button type="primary" icon="el-icon-plus" class="create-btn" @click="handleCreate">手动创建计划</el-button> | ||||
|         </div> | ||||
|       </div> | ||||
|       <!-- 表格 --> | ||||
|       <div class="table-wrapper"> | ||||
|         <el-table :data="pagedTableData" stripe style="width: 100%" highlight-current-row class="custom-table"> | ||||
|           <el-table-column align="center" prop="name" label="计划名称" style="width: 14.2%"></el-table-column> | ||||
|           <el-table-column align="center" prop="type" label="类型" style="width: 14.2%"></el-table-column> | ||||
|           <el-table-column align="center" prop="object" label="巡检对象" style="width: 14.2%"></el-table-column> | ||||
|           <el-table-column align="center" prop="frequency" label="频率" style="width: 14.2%"></el-table-column> | ||||
|           <el-table-column align="center" prop="status" label="状态" style="width: 14.2%"> | ||||
|             <template #default="scope"> | ||||
|               <el-tag :type="scope.row.status === 'enabled' ? 'success' : 'info'" class="status-tag"> | ||||
|                 {{ scope.row.status === 'enabled' ? '启用中' : '已停用' }} | ||||
|               </el-tag> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column align="center" prop="responsible" label="负责人" style="width: 14.2%"></el-table-column> | ||||
|           <el-table-column align="center" label="操作" style="width: 14.2%" fixed="right"> | ||||
|             <template #default="scope"> | ||||
|               <el-button type="text" @click="handleEdit(scope.row)" size="small" class="action-btn">编辑</el-button> | ||||
|               <el-button type="text" @click="handleDetail(scope.row)" size="small" class="action-btn">详情</el-button> | ||||
|               <el-button | ||||
|                 type="text" | ||||
|                 :disabled="scope.row.status === 'disabled'" | ||||
|                 @click="handleEnable(scope.row)" | ||||
|                 size="small" | ||||
|                 class="action-btn" | ||||
|                 :class="{ 'text-success': scope.row.status === 'disabled' }" | ||||
|               > | ||||
|                 {{ scope.row.status === 'enabled' ? '停用' : '启用' }} | ||||
|               </el-button> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </el-table> | ||||
|       </div> | ||||
|       <!-- 分页区域 --> | ||||
|       <div class="pagination-section"> | ||||
|         <div class="pagination-info"> | ||||
|           显示第{{ (currentPage - 1) * pageSize + 1 }}到{{ Math.min(currentPage * pageSize, total) }}条,共有{{ total }}条记录 | ||||
|         </div> | ||||
|         <div class="pagination-controls"> | ||||
|           <el-pagination | ||||
|             @size-change="handleSizeChange" | ||||
|             @current-change="handleCurrentChange" | ||||
|             :current-page="currentPage" | ||||
|             :page-sizes="[10, 20, 30, 40]" | ||||
|             :page-size="pageSize" | ||||
|             layout="total, sizes, prev, pager, next, jumper" | ||||
|             :total="total" | ||||
|             background | ||||
|           > | ||||
|           </el-pagination> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 创建计划弹窗 --> | ||||
|     <el-dialog v-model="dialogVisible" title="新建巡检计划" width="700px" class="create-plan-dialog" center :show-close="true"> | ||||
|       <el-form :model="createForm" :rules="createFormRules" ref="createFormRef" label-width="150px" class="custom-form"> | ||||
|         <el-form-item label="计划名称*" prop="planName" class="form-item-large"> | ||||
|           <el-input v-model="createForm.planName" placeholder="请输入计划名称" class="custom-input" /> | ||||
|         </el-form-item> | ||||
|  | ||||
|         <div class="form-row"> | ||||
|           <el-form-item label="计划类型*" prop="planType" class="form-item-half"> | ||||
|             <el-select v-model="createForm.planType" placeholder="请选择计划类型" class="custom-select"> | ||||
|               <el-option label="每日巡检" value="daily" /> | ||||
|               <el-option label="每周巡检" value="weekly" /> | ||||
|               <el-option label="每月巡检" value="monthly" /> | ||||
|               <el-option label="每季度巡检" value="quarterly" /> | ||||
|             </el-select> | ||||
|           </el-form-item> | ||||
|  | ||||
|           <el-form-item label="巡检对象类型*" prop="objectType" class="form-item-half"> | ||||
|             <el-select v-model="createForm.objectType" placeholder="请选择对象类型" class="custom-select"> | ||||
|               <el-option label="服务器" value="server" /> | ||||
|               <el-option label="网络设备" value="network" /> | ||||
|               <el-option label="应用系统" value="application" /> | ||||
|               <el-option label="基础设施" value="infrastructure" /> | ||||
|             </el-select> | ||||
|           </el-form-item> | ||||
|         </div> | ||||
|  | ||||
|         <div class="form-row"> | ||||
|           <el-form-item label="开始日期*" prop="startDate" class="form-item-half"> | ||||
|             <el-date-picker | ||||
|               v-model="createForm.startDate" | ||||
|               type="date" | ||||
|               placeholder="选择日期" | ||||
|               format="YYYY-MM-DD" | ||||
|               value-format="YYYY-MM-DD" | ||||
|               class="custom-date-picker" | ||||
|             /> | ||||
|           </el-form-item> | ||||
|  | ||||
|           <el-form-item label="结束日期*" prop="endDate" class="form-item-half"> | ||||
|             <el-date-picker | ||||
|               v-model="createForm.endDate" | ||||
|               type="date" | ||||
|               placeholder="选择日期" | ||||
|               format="YYYY-MM-DD" | ||||
|               value-format="YYYY-MM-DD" | ||||
|               class="custom-date-picker" | ||||
|             /> | ||||
|           </el-form-item> | ||||
|         </div> | ||||
|         <el-form-item label="巡检频率*" class="form-item-large"> | ||||
|           <div style="display: flex; align-items: center; gap: 20px"> | ||||
|             <el-radio-group v-model="createForm.frequencyType" class="frequency-radio-group"> | ||||
|               <el-radio label="daily">每天</el-radio> | ||||
|               <el-radio label="weekly">每周</el-radio> | ||||
|               <el-radio label="monthly">每月</el-radio> | ||||
|             </el-radio-group> | ||||
|  | ||||
|             <!-- 每周选择框 - 变小并排在单选框后面 --> | ||||
|             <el-select | ||||
|               v-if="createForm.frequencyType === 'weekly'" | ||||
|               v-model="createForm.weekday" | ||||
|               placeholder="选择周几" | ||||
|               class="custom-select-small" | ||||
|               style="width: 100px" | ||||
|             > | ||||
|               <el-option label="周一" value="1" /> | ||||
|               <el-option label="周二" value="2" /> | ||||
|               <el-option label="周三" value="3" /> | ||||
|               <el-option label="周四" value="4" /> | ||||
|               <el-option label="周五" value="5" /> | ||||
|               <el-option label="周六" value="6" /> | ||||
|               <el-option label="周日" value="0" /> | ||||
|             </el-select> | ||||
|  | ||||
|             <!-- 每月选择框 - 变小并排在单选框后面 --> | ||||
|             <el-select | ||||
|               v-if="createForm.frequencyType === 'monthly'" | ||||
|               v-model="createForm.monthday" | ||||
|               placeholder="选择几号" | ||||
|               class="custom-select-small" | ||||
|               style="width: 100px" | ||||
|             > | ||||
|               <template v-for="day in 31" :key="day"> | ||||
|                 <el-option :label="day + '号'" :value="day" /> | ||||
|               </template> | ||||
|             </el-select> | ||||
|           </div> | ||||
|         </el-form-item> | ||||
|  | ||||
|         <div class="form-row" s> | ||||
|           <el-form-item label="计划开始时间*" prop="startTime" class="form-item-half"> | ||||
|             <el-time-picker v-model="createForm.startTime" placeholder="选择时间" format="HH:mm" value-format="HH:mm" class="custom-time-picker" /> | ||||
|           </el-form-item> | ||||
|  | ||||
|           <el-form-item label="预计时长(分钟)" class="form-item-half"> | ||||
|             <el-input v-model.number="createForm.estimatedDuration" class="custom-input" /> | ||||
|           </el-form-item> | ||||
|         </div> | ||||
|  | ||||
|         <el-form-item label="负责人*" prop="responsiblePerson" class="form-item-large"> | ||||
|           <el-select v-model="createForm.responsiblePerson" placeholder="请选择负责人" class="custom-select"> | ||||
|             <el-option label="张明" value="zhangming" /> | ||||
|             <el-option label="李华" value="lihua" /> | ||||
|             <el-option label="王强" value="wangqiang" /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|  | ||||
|         <el-form-item label="巡检项*" class="form-item-large"> | ||||
|           <el-checkbox-group v-model="createForm.inspectionItems" style="border: 0.1 solid black; padding: 5px"> | ||||
|             <el-checkbox label="CPU使用率检查" /> | ||||
|             <el-checkbox label="内存使用情况" /> | ||||
|             <el-checkbox label="磁盘空间检查" /> | ||||
|             <el-checkbox label="网络连接状态" /> | ||||
|             <el-checkbox label="系统日志检查" /> | ||||
|           </el-checkbox-group> | ||||
|         </el-form-item> | ||||
|  | ||||
|         <el-form-item label="备注说明" prop="remarks" class="form-item-large"> | ||||
|           <el-input v-model="createForm.remarks" type="textarea" placeholder="请输入备注" rows="3" class="custom-textarea" /> | ||||
|         </el-form-item> | ||||
|       </el-form> | ||||
|  | ||||
|       <template #footer> | ||||
|         <span class="dialog-footer"> | ||||
|           <el-button @click="cancelCreatePlan">取消</el-button> | ||||
|           <el-button type="primary" @click="submitCreatePlan">新增任务</el-button> | ||||
|         </span> | ||||
|       </template> | ||||
|     </el-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup> | ||||
| // 表单引用 | ||||
| const createFormRef = ref(null); | ||||
| import { ref, computed, reactive } from 'vue'; | ||||
| import router from '@/router'; | ||||
| import TitleComponent from '@/views/demo/components/TitleComponent.vue'; | ||||
|  | ||||
| // 激活的选项卡 | ||||
| const activeTab = ref('plan'); | ||||
| // 计划类型 | ||||
| const planType = ref('all'); | ||||
| // 状态 | ||||
| const status = ref('all'); | ||||
| // 巡检对象 | ||||
| const inspectionObject = ref('all'); | ||||
| // 原始表格数据 | ||||
| const rawTableData = ref([ | ||||
|   { | ||||
|     name: '生产服务器每日巡检 2025-05-14', | ||||
|     type: '每日巡检', | ||||
|     object: '服务器', | ||||
|     frequency: '每天8:30', | ||||
|     status: 'enabled', | ||||
|     responsible: '张明' | ||||
|   }, | ||||
|   { | ||||
|     name: '网络设备安全巡检 2025-04-15', | ||||
|     type: '每周巡检', | ||||
|     object: '网络设备', | ||||
|     frequency: '每天10:30', | ||||
|     status: 'enabled', | ||||
|     responsible: '张明' | ||||
|   }, | ||||
|   { | ||||
|     name: '数据库性能巡检 2025-03-03', | ||||
|     type: '每月巡检', | ||||
|     object: '应用系统', | ||||
|     frequency: '每月1日14:00', | ||||
|     status: 'disabled', | ||||
|     responsible: '张明' | ||||
|   }, | ||||
|   { | ||||
|     name: '机房环境季度检查', | ||||
|     type: '每季度巡检', | ||||
|     object: '基础设备', | ||||
|     frequency: '每季度第一个月5号', | ||||
|     status: 'enabled', | ||||
|     responsible: '张明' | ||||
|   }, | ||||
|   { | ||||
|     name: '生产服务器每日巡检 2025-05-14', | ||||
|     type: '每日巡检', | ||||
|     object: '服务器', | ||||
|     frequency: '每天8:30', | ||||
|     status: 'enabled', | ||||
|     responsible: '张明' | ||||
|   }, | ||||
|   { | ||||
|     name: '生产服务器每日巡检 2025-05-14', | ||||
|     type: '每日巡检', | ||||
|     object: '服务器', | ||||
|     frequency: '每天8:30', | ||||
|     status: 'enabled', | ||||
|     responsible: '张明' | ||||
|   }, | ||||
|   { | ||||
|     name: '生产服务器每日巡检 2025-05-14', | ||||
|     type: '每日巡检', | ||||
|     object: '服务器', | ||||
|     frequency: '每天8:30', | ||||
|     status: 'enabled', | ||||
|     responsible: '张明' | ||||
|   }, | ||||
|   { | ||||
|     name: '生产服务器每日巡检 2025-05-14', | ||||
|     type: '每日巡检', | ||||
|     object: '服务器', | ||||
|     frequency: '每天8:30', | ||||
|     status: 'enabled', | ||||
|     responsible: '张明' | ||||
|   }, | ||||
|   { | ||||
|     name: '生产服务器每日巡检 2025-05-14', | ||||
|     type: '每日巡检', | ||||
|     object: '服务器', | ||||
|     frequency: '每天8:30', | ||||
|     status: 'enabled', | ||||
|     responsible: '张明' | ||||
|   }, | ||||
|   { | ||||
|     name: '生产服务器每日巡检 2025-05-14', | ||||
|     type: '每日巡检', | ||||
|     object: '服务器', | ||||
|     frequency: '每天8:30', | ||||
|     status: 'enabled', | ||||
|     responsible: '张明' | ||||
|   }, | ||||
|   { | ||||
|     name: '生产服务器每日巡检 2025-05-14', | ||||
|     type: '每日巡检', | ||||
|     object: '服务器', | ||||
|     frequency: '每天8:30', | ||||
|     status: 'enabled', | ||||
|     responsible: '张明' | ||||
|   }, | ||||
|   // 增加更多数据用于测试分页 | ||||
|   { | ||||
|     name: '应用系统安全检查', | ||||
|     type: '每周巡检', | ||||
|     object: '应用系统', | ||||
|     frequency: '每周五16:00', | ||||
|     status: 'enabled', | ||||
|     responsible: '李华' | ||||
|   }, | ||||
|   { | ||||
|     name: '网络带宽监控', | ||||
|     type: '每日巡检', | ||||
|     object: '网络设备', | ||||
|     frequency: '每天12:00', | ||||
|     status: 'enabled', | ||||
|     responsible: '王强' | ||||
|   } | ||||
| ]); | ||||
| // 当前页码 | ||||
| const currentPage = ref(1); | ||||
| // 每页条数 - 与分页控件默认值保持一致 | ||||
| const pageSize = ref(10); | ||||
| // 总条数 - 从原始数据计算得出 | ||||
| const total = ref(rawTableData.value.length); | ||||
|  | ||||
| // 计算属性:根据当前页码和每页条数获取分页后的数据 | ||||
| const pagedTableData = computed(() => { | ||||
|   const startIndex = (currentPage.value - 1) * pageSize.value; | ||||
|   const endIndex = startIndex + pageSize.value; | ||||
|   return rawTableData.value.slice(startIndex, endIndex); | ||||
| }); | ||||
|  | ||||
| // 每页条数改变 | ||||
| const handleSizeChange = (val) => { | ||||
|   pageSize.value = val; | ||||
|   currentPage.value = 1; // 重置到第一页 | ||||
| }; | ||||
|  | ||||
| // 当前页码改变 | ||||
| const handleCurrentChange = (val) => { | ||||
|   currentPage.value = val; | ||||
| }; | ||||
|  | ||||
| // 编辑 | ||||
| const handleEdit = (row) => { | ||||
|   console.log('编辑', row); | ||||
| }; | ||||
|  | ||||
| // 详情 | ||||
| const handleDetail = (row) => { | ||||
|   console.log('详情', row); | ||||
| }; | ||||
|  | ||||
| // 启用/停用 | ||||
| const handleEnable = (row) => { | ||||
|   row.status = row.status === 'enabled' ? 'disabled' : 'enabled'; | ||||
| }; | ||||
|  | ||||
| // 选项卡切换 | ||||
| const handleTabChange = (newTab, oldTab) => { | ||||
|   // 可以在这里添加选项卡切换时的逻辑 | ||||
|   console.log('选项卡切换:', newTab, oldTab); | ||||
|   return true; | ||||
| }; | ||||
|  | ||||
| // 创建计划弹窗相关 | ||||
| const dialogVisible = ref(false); | ||||
| const createForm = reactive({ | ||||
|   planName: '', | ||||
|   planType: '', | ||||
|   objectType: '', | ||||
|   startDate: '', | ||||
|   endDate: '', | ||||
|   frequencyType: 'daily', | ||||
|   frequencyValue: '', | ||||
|   weekday: '', // 存储周几 | ||||
|   monthday: '', // 存储几号 | ||||
|   startTime: '', | ||||
|   estimatedDuration: 60, | ||||
|   responsiblePerson: '', | ||||
|   inspectionItems: [], | ||||
|   remarks: '' | ||||
| }); | ||||
|  | ||||
| // 创建计划表单验证规则 | ||||
| const createFormRules = computed(() => ({ | ||||
|   planName: [{ required: true, message: '请输入计划名称', trigger: 'blur' }], | ||||
|   planType: [{ required: true, message: '请选择计划类型', trigger: 'change' }], | ||||
|   objectType: [{ required: true, message: '请选择对象类型', trigger: 'change' }], | ||||
|   startDate: [{ required: true, message: '请选择开始日期', trigger: 'change' }], | ||||
|   endDate: [{ required: true, message: '请选择结束日期', trigger: 'change' }], | ||||
|   startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }], | ||||
|   responsiblePerson: [{ required: true, message: '请选择负责人', trigger: 'change' }], | ||||
|   weekday: createForm.frequencyType === 'weekly' ? [{ required: true, message: '请选择周几', trigger: 'change' }] : [], | ||||
|   monthday: createForm.frequencyType === 'monthly' ? [{ required: true, message: '请选择几号', trigger: 'change' }] : [] | ||||
| })); | ||||
|  | ||||
| // 打开创建计划弹窗 | ||||
| const handleCreate = () => { | ||||
|   dialogVisible.value = true; | ||||
| }; | ||||
|  | ||||
| // 提交创建计划 | ||||
| const submitCreatePlan = () => { | ||||
|   console.log('提交创建计划:', createForm); | ||||
|   // 这里可以添加实际的创建计划逻辑 | ||||
|   dialogVisible.value = false; | ||||
|   // 重置表单 | ||||
|   Object.keys(createForm).forEach((key) => { | ||||
|     if (Array.isArray(createForm[key])) { | ||||
|       createForm[key] = []; | ||||
|     } else if (key === 'estimatedDuration') { | ||||
|       createForm[key] = 60; | ||||
|     } else if (key === 'frequencyType') { | ||||
|       createForm[key] = 'daily'; | ||||
|     } else { | ||||
|       createForm[key] = ''; | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| // 取消创建计划 | ||||
| const cancelCreatePlan = () => { | ||||
|   dialogVisible.value = false; | ||||
|   // 重置表单 | ||||
|   Object.keys(createForm).forEach((key) => { | ||||
|     if (Array.isArray(createForm[key])) { | ||||
|       createForm[key] = []; | ||||
|     } else if (key === 'estimatedDuration') { | ||||
|       createForm[key] = 60; | ||||
|     } else if (key === 'frequencyType') { | ||||
|       createForm[key] = 'daily'; | ||||
|     } else { | ||||
|       createForm[key] = ''; | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
| const handleInspection1 = () => { | ||||
|   router.push('/rili/rili'); | ||||
| }; | ||||
| const handleInspection2 = () => { | ||||
|   router.push('/rili/InspectionManagement'); | ||||
| }; | ||||
| const handleInspectionManagement1 = () => { | ||||
|   router.push('/rili/InspectionManagement'); | ||||
| }; | ||||
|  | ||||
| const handleInspectionManagement2 = () => { | ||||
|   router.push('/rili/xunjianrenwu'); | ||||
| }; | ||||
| const handleInspectionManagement3 = () => { | ||||
|   router.push('/rili/xunjianjihua'); | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| /* 样式保持不变 */ | ||||
| .operation-inspection { | ||||
|   padding: 20px; | ||||
|   background-color: #f5f7fa; | ||||
|   min-height: 100vh; | ||||
| } | ||||
|  | ||||
| /* 标题区域样式 */ | ||||
| .title-section { | ||||
|   background-color: #fff; | ||||
|   padding: 20px; | ||||
|   border-radius: 8px; | ||||
|   margin-bottom: 16px; | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); | ||||
| } | ||||
|  | ||||
| .page-title { | ||||
|   font-size: 24px; | ||||
|   font-weight: 600; | ||||
|   color: #303133; | ||||
|   margin: 0 0 8px 0; | ||||
| } | ||||
|  | ||||
| .page-subtitle { | ||||
|   font-size: 14px; | ||||
|   color: #909399; | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| /* 选项卡样式 */ | ||||
| .tabs-wrapper { | ||||
|   background-color: #fff; | ||||
|   padding: 20px; | ||||
|   border-radius: 8px; | ||||
|   margin-bottom: 16px; | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); | ||||
| } | ||||
|  | ||||
| .custom-tabs { | ||||
|   border-bottom: none; | ||||
|   padding-top: 20px; | ||||
| } | ||||
|  | ||||
| .custom-tabs .el-tabs__header { | ||||
|   margin: 0 -20px 0 -20px; | ||||
|   padding: 0 20px; | ||||
|   border-bottom: 1px solid #e4e7ed; | ||||
| } | ||||
|  | ||||
| .custom-tabs .el-tabs__nav-wrap::after { | ||||
|   height: 0; | ||||
| } | ||||
|  | ||||
| .custom-tabs .el-tabs__item { | ||||
|   font-size: 14px; | ||||
|   color: #606266; | ||||
|   padding: 12px 20px; | ||||
|   margin-right: 20px; | ||||
|   border-bottom: 2px solid transparent; | ||||
| } | ||||
|  | ||||
| .custom-tabs .el-tabs__item.is-active { | ||||
|   color: #409eff; | ||||
|   border-bottom-color: #409eff; | ||||
| } | ||||
|  | ||||
| .custom-tabs .el-tabs__item:hover { | ||||
|   color: #409eff; | ||||
| } | ||||
|  | ||||
| /* 筛选栏样式 */ | ||||
| .filter-bar { | ||||
|   background-color: #fff; | ||||
|   padding: 20px; | ||||
|   border-radius: 8px; | ||||
|   margin-bottom: 16px; | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   flex-wrap: wrap; | ||||
|   gap: 16px; | ||||
| } | ||||
|  | ||||
| .filter-item { | ||||
|   flex-shrink: 0; | ||||
| } | ||||
|  | ||||
| .filter-bar .el-select { | ||||
|   width: 150px; | ||||
|   height: 36px; | ||||
| } | ||||
|  | ||||
| .filter-actions { | ||||
|   margin-left: auto; | ||||
|   display: flex; | ||||
|   gap: 10px; | ||||
| } | ||||
|  | ||||
| .search-btn, | ||||
| .create-btn { | ||||
|   height: 36px; | ||||
|   border-radius: 4px; | ||||
| } | ||||
|  | ||||
| /* 表格样式 */ | ||||
| .table-wrapper { | ||||
|   background-color: #fff; | ||||
|   padding: 20px; | ||||
|   border-radius: 8px; | ||||
|   margin-bottom: 16px; | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); | ||||
| } | ||||
|  | ||||
| .custom-table { | ||||
|   border: 1px solid #ebeef5; | ||||
|   border-radius: 4px; | ||||
|   overflow: hidden; | ||||
| } | ||||
|  | ||||
| .custom-table th { | ||||
|   background-color: #fafafa; | ||||
|   font-weight: 500; | ||||
|   color: #606266; | ||||
|   text-align: left; | ||||
|   padding: 12px 16px; | ||||
|   border-bottom: 1px solid #ebeef5; | ||||
| } | ||||
|  | ||||
| .custom-table td { | ||||
|   padding: 12px 16px; | ||||
|   border-bottom: 1px solid #ebeef5; | ||||
|   color: #303133; | ||||
| } | ||||
|  | ||||
| .custom-table tr:hover { | ||||
|   background-color: #f5f7fa; | ||||
| } | ||||
|  | ||||
| .custom-table tr.current-row { | ||||
|   background-color: #ecf5ff; | ||||
| } | ||||
|  | ||||
| .status-tag { | ||||
|   padding: 4px 8px; | ||||
|   font-size: 12px; | ||||
|   border-radius: 4px; | ||||
| } | ||||
|  | ||||
| .action-btn { | ||||
|   color: #409eff; | ||||
|   font-size: 12px; | ||||
|   padding: 4px 8px; | ||||
| } | ||||
|  | ||||
| .action-btn:hover { | ||||
|   color: #66b1ff; | ||||
|   background-color: #ecf5ff; | ||||
| } | ||||
|  | ||||
| /* 分页区域样式 */ | ||||
| .pagination-section { | ||||
|   background-color: #fff; | ||||
|   padding: 16px 20px; | ||||
|   border-radius: 8px; | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .pagination-info { | ||||
|   font-size: 14px; | ||||
|   color: #606266; | ||||
| } | ||||
|  | ||||
| .pagination-controls .el-pagination { | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| .pagination-controls .el-pagination__sizes { | ||||
|   margin-right: 20px; | ||||
| } | ||||
|  | ||||
| .pagination-controls .el-pagination button { | ||||
|   min-width: 32px; | ||||
|   height: 32px; | ||||
|   line-height: 32px; | ||||
|   border-radius: 4px; | ||||
| } | ||||
|  | ||||
| .pagination-controls .el-pagination .el-pager li { | ||||
|   min-width: 32px; | ||||
|   height: 32px; | ||||
|   line-height: 32px; | ||||
|   border-radius: 4px; | ||||
| } | ||||
|  | ||||
| .pagination-controls .el-pagination .el-pager li.active { | ||||
|   background-color: #409eff; | ||||
|   color: #fff; | ||||
| } | ||||
| /* 导航栏样式 */ | ||||
| .navigation-tabs { | ||||
|   display: flex; | ||||
|   margin-bottom: 20px; | ||||
|   background-color: #fff; | ||||
|   border-radius: 4px; | ||||
|   box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08); | ||||
|   padding: 2px; | ||||
| } | ||||
|  | ||||
| .nav-tab { | ||||
|   padding: 12px 24px; | ||||
|   cursor: pointer; | ||||
|   transition: all 0.3s ease; | ||||
|   border-radius: 4px; | ||||
|   font-size: 14px; | ||||
|   color: #606266; | ||||
|   border-right: 1px solid #f0f0f0; | ||||
|   flex: 1; | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| .nav-tab:last-child { | ||||
|   border-right: none; | ||||
| } | ||||
|  | ||||
| .nav-tab:hover { | ||||
|   color: #409eff; | ||||
|   background-color: #ecf5ff; | ||||
| } | ||||
|  | ||||
| .nav-tab.active { | ||||
|   background-color: #409eff; | ||||
|   color: #fff; | ||||
|   box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3); | ||||
| } | ||||
|  | ||||
| .nav-tab { | ||||
|   cursor: pointer; | ||||
|   user-select: none; | ||||
| } | ||||
| /* 响应式设计 */ | ||||
| @media (max-width: 1200px) { | ||||
|   .filter-bar { | ||||
|     flex-direction: column; | ||||
|     align-items: stretch; | ||||
|   } | ||||
|  | ||||
|   .filter-actions { | ||||
|     margin-left: 0; | ||||
|     justify-content: flex-end; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										700
									
								
								src/views/dhr_demo/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										700
									
								
								src/views/dhr_demo/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,700 @@ | ||||
| <template> | ||||
|   <div class="container"> | ||||
|     <!-- 导航栏 --> | ||||
|     <div class="navigation-tabs"> | ||||
|       <div class="nav-tab active" @click="handleInspection1">待办事项</div> | ||||
|       <div class="nav-tab" @click="handleInspection2">巡检管理</div> | ||||
|       <div class="nav-tab">试验管理</div> | ||||
|       <div class="nav-tab">报修管理</div> | ||||
|       <div class="nav-tab">抢修管理</div> | ||||
|       <div class="nav-tab">工单管理</div> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 标题栏 --> | ||||
|     <div class="header"> | ||||
|       <TitleComponent title="运维待办事项" subtitle="管理每日、每周等的运维工作任务"></TitleComponent> | ||||
|     </div> | ||||
|  | ||||
|     <div class="main-content"> | ||||
|       <!-- 左侧日历区域 --> | ||||
|       <div class="calendar-container"> | ||||
|         <div class="calendar-header"> | ||||
|           <div class="calendar-title">待办月视图</div> | ||||
|           <div class="calendar-controls"> | ||||
|             <!-- 年份月份选择 --> | ||||
|             <el-select v-model="selectedYear" placeholder="选择年份" size="small" style="width: 80px; margin-right: 5px"> | ||||
|               <el-option v-for="year in years" :key="year" :label="year.toString()" :value="year"></el-option> | ||||
|             </el-select> | ||||
|             <el-select v-model="selectedMonth" placeholder="选择月份" size="small" style="width: 80px; margin-right: 10px"> | ||||
|               <el-option v-for="month in 12" :key="month" :label="month.toString()" :value="month"></el-option> | ||||
|             </el-select> | ||||
|             <!-- 月份切换按钮 --> | ||||
|             <el-button type="text" icon="el-icon-arrow-left" @click="decreaseMonth"></el-button> | ||||
|             <el-button type="text" icon="el-icon-arrow-right" @click="increaseMonth"></el-button> | ||||
|             <el-button type="primary" size="small">添加</el-button> | ||||
|             <el-button type="primary" size="small" @click="goToToday">今日</el-button> | ||||
|             <el-button type="text" icon="el-icon-plus"></el-button> | ||||
|           </div> | ||||
|         </div> | ||||
|         <!-- 使用 Element Plus 的日历组件 --> | ||||
|         <el-calendar v-model="currentDate"> | ||||
|           <template #date-cell="{ date, data }"> | ||||
|             <div class="custom-date-cell" :class="getCellClass(data.day)"> | ||||
|               <div class="date-day">{{ data.day.split('-').slice(2).join('-') }}</div> | ||||
|               <div class="date-events"> | ||||
|                 <div v-for="event in getDayEvents(data.day)" :key="event.id" class="event-item" :class="'event-' + event.type"> | ||||
|                   <div class="event-title">{{ event.title }}</div> | ||||
|                   <div class="event-description">{{ event.description }}</div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|           </template> | ||||
|         </el-calendar> | ||||
|       </div> | ||||
|  | ||||
|       <!-- 右侧表单区域 --> | ||||
|       <div class="form-container"> | ||||
|         <div class="form-header"> | ||||
|           <h2>今日待办</h2> | ||||
|           <el-button type="primary" size="small" icon="el-icon-plus" @click="openAddTaskDialog">添加</el-button> | ||||
|         </div> | ||||
|  | ||||
|         <!-- 待办事项列表 --> | ||||
|         <div class="todo-list"> | ||||
|           <!-- 待办项1 - 常规维护 --> | ||||
|           <div class="todo-item"> | ||||
|             <div class="todo-color-indicator normal"></div> | ||||
|             <el-checkbox class="todo-checkbox"></el-checkbox> | ||||
|             <div class="todo-content"> | ||||
|               <div class="todo-main"> | ||||
|                 <div class="todo-title">服务器例行检查</div> | ||||
|                 <div class="todo-time">09:00-10:00 AM</div> | ||||
|               </div> | ||||
|               <div class="todo-description">检查所有生产服务器的CPU、内存、磁盘使用率,确保正常运行</div> | ||||
|             </div> | ||||
|           </div> | ||||
|  | ||||
|           <!-- 待办项2 - 重要 --> | ||||
|           <div class="todo-item important"> | ||||
|             <div class="todo-color-indicator important"></div> | ||||
|             <el-checkbox class="todo-checkbox"></el-checkbox> | ||||
|             <div class="todo-content"> | ||||
|               <div class="todo-main"> | ||||
|                 <div class="todo-title">数据库备份</div> | ||||
|                 <div class="todo-time">14:00-15:00 PM</div> | ||||
|               </div> | ||||
|               <div class="todo-description">主要数据库全备份,并验证备份文件完整性</div> | ||||
|             </div> | ||||
|             <div class="todo-actions"> | ||||
|               <el-button type="text" icon="el-icon-edit"></el-button> | ||||
|               <el-button type="text" icon="el-icon-delete"></el-button> | ||||
|             </div> | ||||
|           </div> | ||||
|  | ||||
|           <!-- 待办项3 - 紧急 --> | ||||
|           <div class="todo-item"> | ||||
|             <div class="todo-color-indicator urgent"></div> | ||||
|             <el-checkbox class="todo-checkbox"></el-checkbox> | ||||
|             <div class="todo-content"> | ||||
|               <div class="todo-main"> | ||||
|                 <div class="todo-title">网络设备固件更新</div> | ||||
|                 <div class="todo-time">18:00-20:00 PM</div> | ||||
|               </div> | ||||
|               <div class="todo-description">更新核心交换机和防火墙固件,需安排在业务低峰期</div> | ||||
|             </div> | ||||
|           </div> | ||||
|  | ||||
|           <!-- 待办项4 - 常规维护 --> | ||||
|           <div class="todo-item"> | ||||
|             <div class="todo-color-indicator normal"></div> | ||||
|             <el-checkbox class="todo-checkbox"></el-checkbox> | ||||
|             <div class="todo-content"> | ||||
|               <div class="todo-main"> | ||||
|                 <div class="todo-title">服务器例行检查</div> | ||||
|                 <div class="todo-time">08:00-09:00 AM</div> | ||||
|               </div> | ||||
|               <div class="todo-description">检查所有生产服务器的CPU、内存、磁盘使用率,确保正常运行</div> | ||||
|             </div> | ||||
|           </div> | ||||
|  | ||||
|           <!-- 待办项5 - 常规维护 --> | ||||
|           <div class="todo-item"> | ||||
|             <div class="todo-color-indicator normal"></div> | ||||
|             <el-checkbox class="todo-checkbox"></el-checkbox> | ||||
|             <div class="todo-content"> | ||||
|               <div class="todo-main"> | ||||
|                 <div class="todo-title">服务器例行检查</div> | ||||
|                 <div class="todo-time">06:00-07:00 AM</div> | ||||
|               </div> | ||||
|               <div class="todo-description">检查所有生产服务器的CPU、内存、磁盘使用率,确保正常运行</div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|         <!-- 状态图例 - 标签形式 --> | ||||
|         <div class="status-legend"> | ||||
|           <span class="status-tag normal">常规维护</span> | ||||
|           <span class="status-tag important">重要</span> | ||||
|           <span class="status-tag urgent">紧急</span> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <el-dialog v-model="dialogVisible" title="新增任务" width="480px" class="custom-dialog" :before-close="closeDialog"> | ||||
|       <el-form :model="taskForm" label-width="80px" class="task-form"> | ||||
|         <el-form-item label="任务名称" prop="name"> | ||||
|           <el-input v-model="taskForm.name" placeholder="输入任务名称" class="form-input"></el-input> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="任务描述" prop="description"> | ||||
|           <el-input v-model="taskForm.description" placeholder="输入任务描述" class="form-input"></el-input> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="时间" prop="timeRange"> | ||||
|           <el-date-picker | ||||
|             v-model="taskForm.timeRange" | ||||
|             type="datetimerange" | ||||
|             start-placeholder="开始时间" | ||||
|             end-placeholder="结束时间" | ||||
|             class="form-input" | ||||
|             style="width: 100%" | ||||
|           /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="优先级" prop="priority"> | ||||
|           <el-select v-model="taskForm.priority" placeholder="选择优先级" class="form-input"> | ||||
|             <el-option label="常规项" value="常规项"></el-option> | ||||
|             <el-option label="重要" value="重要"></el-option> | ||||
|             <el-option label="紧急" value="紧急"></el-option> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="任务类型" prop="taskType"> | ||||
|           <el-select v-model="taskForm.taskType" placeholder="选择任务类型" class="form-input"> | ||||
|             <el-option label="常规维护" value="常规维护"></el-option> | ||||
|             <el-option label="安全巡检" value="安全巡检"></el-option> | ||||
|             <el-option label="系统升级" value="系统升级"></el-option> | ||||
|             <el-option label="数据备份" value="数据备份"></el-option> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|       </el-form> | ||||
|       <template #footer> | ||||
|         <el-button @click="closeDialog">取消</el-button> | ||||
|         <el-button type="primary" @click="saveTask">保存任务</el-button> | ||||
|       </template> | ||||
|     </el-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup> | ||||
| import { ref, computed, watch } from 'vue'; | ||||
| import router from '@/router'; | ||||
| import TitleComponent from '../demo/components/TitleComponent.vue'; | ||||
|  | ||||
| // 生成年份选项,生成2020-2029年的年份范围 | ||||
| const targetYear = 2025; | ||||
| const years = ref(Array.from({ length: 10 }, (_, index) => 2020 + index)); | ||||
| const selectedYear = ref(targetYear); | ||||
| const selectedMonth = ref(9); | ||||
|  | ||||
| // 默认显示2025年9月 | ||||
| const currentDate = ref(new Date(targetYear, 8, 1)); | ||||
|  | ||||
| // 减少月份 | ||||
| const decreaseMonth = () => { | ||||
|   const date = new Date(currentDate.value); | ||||
|   date.setMonth(date.getMonth() - 1); | ||||
|   currentDate.value = date; | ||||
|   updateYearAndMonth(); | ||||
| }; | ||||
|  | ||||
| // 增加月份 | ||||
| const increaseMonth = () => { | ||||
|   const date = new Date(currentDate.value); | ||||
|   date.setMonth(date.getMonth() + 1); | ||||
|   currentDate.value = date; | ||||
|   updateYearAndMonth(); | ||||
| }; | ||||
|  | ||||
| // 回到今天 | ||||
| const goToToday = () => { | ||||
|   currentDate.value = new Date(); | ||||
|   updateYearAndMonth(); | ||||
| }; | ||||
|  | ||||
| // 日历事件数据 - 2025年9月的随机事件 | ||||
| const calendarEvents = ref([ | ||||
|   // 服务维护事件 | ||||
|   { id: 1, date: '2025-09-11', title: '服务维护', description: '维护公司内部服务器', type: 'service' }, | ||||
|   { id: 2, date: '2025-09-28', title: '服务维护', description: '先所有旧服务器部署新内存', type: 'service' }, | ||||
|  | ||||
|   // 数据库管理事件 | ||||
|   { id: 3, date: '2025-09-21', title: '数据库管理', description: '定期执行数据库优化', type: 'database' }, | ||||
|   { id: 4, date: '2025-09-30', title: '数据库管理', description: '大型数据库备份策略', type: 'database' }, | ||||
|  | ||||
|   // 网络维护事件 | ||||
|   { id: 5, date: '2025-09-05', title: '网络维护', description: '网络设备例行检查', type: 'network' }, | ||||
|   { id: 6, date: '2025-09-15', title: '网络维护', description: '更新网络安全策略', type: 'network' }, | ||||
|  | ||||
|   // 系统升级事件 | ||||
|   { id: 7, date: '2025-09-18', title: '系统升级', description: '核心系统版本升级', type: 'upgrade' }, | ||||
|   { id: 8, date: '2025-09-25', title: '系统升级', description: '应用服务升级部署', type: 'upgrade' } | ||||
| ]); | ||||
|  | ||||
| // 获取指定日期的事件 | ||||
| const getDayEvents = (dateStr) => { | ||||
|   return calendarEvents.value.filter((event) => event.date === dateStr); | ||||
| }; | ||||
|  | ||||
| // 根据事件类型获取单元格样式 | ||||
| const getCellClass = (date) => { | ||||
|   const events = getDayEvents(date); | ||||
|   if (events.length > 0) { | ||||
|     const eventType = events[0].type; | ||||
|     return `date-cell-${eventType}`; | ||||
|   } | ||||
|   return ''; | ||||
| }; | ||||
|  | ||||
| // 更新年份和月份选择器的值 | ||||
| const updateYearAndMonth = () => { | ||||
|   selectedYear.value = currentDate.value.getFullYear(); | ||||
|   selectedMonth.value = currentDate.value.getMonth() + 1; | ||||
| }; | ||||
|  | ||||
| // 监听年份和月份变化,更新日历显示 | ||||
| watch([selectedYear, selectedMonth], ([newYear, newMonth]) => { | ||||
|   const date = new Date(currentDate.value); | ||||
|   date.setFullYear(newYear); | ||||
|   date.setMonth(newMonth - 1); | ||||
|   currentDate.value = date; | ||||
| }); | ||||
|  | ||||
| // 初始化年份和月份选择器 | ||||
| updateYearAndMonth(); | ||||
|  | ||||
| // 弹窗相关状态管理 | ||||
| const dialogVisible = ref(false); | ||||
| const taskForm = ref({ | ||||
|   name: '', | ||||
|   description: '', | ||||
|   timeRange: '', | ||||
|   priority: '常规项', | ||||
|   taskType: '常规维护' | ||||
| }); | ||||
|  | ||||
| // 打开添加任务弹窗 | ||||
| const openAddTaskDialog = () => { | ||||
|   dialogVisible.value = true; | ||||
| }; | ||||
|  | ||||
| // 关闭弹窗 | ||||
| const closeDialog = () => { | ||||
|   dialogVisible.value = false; | ||||
| }; | ||||
|  | ||||
| // 保存任务 | ||||
| const saveTask = () => { | ||||
|   // 这里可以添加表单验证和保存逻辑 | ||||
|   console.log('保存任务:', taskForm.value); | ||||
|   // 重置表单 | ||||
|   taskForm.value = { | ||||
|     name: '', | ||||
|     description: '', | ||||
|     timeRange: '', | ||||
|     priority: '常规项', | ||||
|     taskType: '常规维护' | ||||
|   }; | ||||
|   // 关闭弹窗 | ||||
|   closeDialog(); | ||||
| }; | ||||
|  | ||||
| const handleInspection1 = () => { | ||||
|   router.push('/rili/rili'); | ||||
| }; | ||||
| const handleInspection2 = () => { | ||||
|   router.push('/rili/InspectionManagement'); | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .container { | ||||
|   padding: 20px; | ||||
|   background-color: #f5f7fa; | ||||
|   min-height: 100vh; | ||||
| } | ||||
|  | ||||
| /* 导航栏样式 */ | ||||
| .navigation-tabs { | ||||
|   display: flex; | ||||
|   margin-bottom: 20px; | ||||
|   background-color: #fff; | ||||
|   border-radius: 4px; | ||||
|   box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08); | ||||
|   padding: 2px; | ||||
| } | ||||
|  | ||||
| .nav-tab { | ||||
|   padding: 12px 24px; | ||||
|   cursor: pointer; | ||||
|   transition: all 0.3s ease; | ||||
|   border-radius: 4px; | ||||
|   font-size: 14px; | ||||
|   color: #606266; | ||||
|   border-right: 1px solid #f0f0f0; | ||||
|   flex: 1; | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| .nav-tab:last-child { | ||||
|   border-right: none; | ||||
| } | ||||
|  | ||||
| .nav-tab:hover { | ||||
|   color: #409eff; | ||||
|   background-color: #ecf5ff; | ||||
| } | ||||
|  | ||||
| .nav-tab.active { | ||||
|   background-color: #409eff; | ||||
|   color: #fff; | ||||
|   box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3); | ||||
| } | ||||
|  | ||||
| .nav-tab { | ||||
|   cursor: pointer; | ||||
|   user-select: none; | ||||
| } | ||||
|  | ||||
| .header { | ||||
|   margin-bottom: 20px; | ||||
| } | ||||
|  | ||||
| .header h1 { | ||||
|   font-size: 24px; | ||||
|   font-weight: 600; | ||||
|   color: #303133; | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| .header p { | ||||
|   font-size: 14px; | ||||
|   color: #606266; | ||||
|   margin: 5px 0 0 0; | ||||
| } | ||||
|  | ||||
| .main-content { | ||||
|   display: flex; | ||||
|   gap: 20px; | ||||
| } | ||||
|  | ||||
| /* 日历区域样式 */ | ||||
| .calendar-container { | ||||
|   flex: 1; | ||||
|   background-color: #fff; | ||||
|   border-radius: 4px; | ||||
|   padding: 20px; | ||||
|   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); | ||||
| } | ||||
|  | ||||
| /* 自定义弹窗样式 */ | ||||
| .custom-dialog { | ||||
|   border-radius: 8px; | ||||
|   overflow: hidden; | ||||
| } | ||||
|  | ||||
| .custom-dialog .el-dialog__header { | ||||
|   background-color: #f5f7fa; | ||||
|   border-bottom: 1px solid #e4e7ed; | ||||
|   padding: 15px 20px; | ||||
| } | ||||
|  | ||||
| .custom-dialog .el-dialog__title { | ||||
|   font-size: 16px; | ||||
|   color: #303133; | ||||
| } | ||||
|  | ||||
| .custom-dialog .el-dialog__body { | ||||
|   padding: 20px; | ||||
| } | ||||
|  | ||||
| /* 确保所有输入框长度相等 */ | ||||
| .task-form .form-input { | ||||
|   height: 30px; | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| /* 时间选择器样式调整 */ | ||||
| .task-form .el-date-editor { | ||||
|   width: 100%; | ||||
|   height: 30px; | ||||
| } | ||||
|  | ||||
| .calendar-header { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   margin-bottom: 20px; | ||||
| } | ||||
|  | ||||
| .calendar-title { | ||||
|   font-size: 16px; | ||||
|   font-weight: 600; | ||||
|   color: #303133; | ||||
| } | ||||
|  | ||||
| .calendar-controls { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   gap: 10px; | ||||
| } | ||||
|  | ||||
| .el-select { | ||||
|   margin-right: 5px; | ||||
| } | ||||
|  | ||||
| /* 表单区域样式 */ | ||||
| .form-container { | ||||
|   width: 400px; | ||||
|   background-color: #fff; | ||||
|   border-radius: 4px; | ||||
|   padding: 20px; | ||||
|   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); | ||||
| } | ||||
|  | ||||
| .form-header { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   margin-bottom: 20px; | ||||
|   padding-bottom: 10px; | ||||
|   border-bottom: 1px solid #f0f0f0; | ||||
| } | ||||
|  | ||||
| .form-header h2 { | ||||
|   font-size: 16px; | ||||
|   font-weight: 600; | ||||
|   color: #303133; | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| .todo-list { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 10px; | ||||
|   margin-bottom: 20px; | ||||
|   max-height: 400px; | ||||
|   overflow-y: auto; | ||||
| } | ||||
|  | ||||
| .todo-item { | ||||
|   display: flex; | ||||
|   align-items: flex-start; | ||||
|   gap: 10px; | ||||
|   padding: 12px 12px 12px 20px; | ||||
|   background-color: #fafafa; | ||||
|   border-radius: 4px; | ||||
|   position: relative; | ||||
|   transition: all 0.3s ease; | ||||
| } | ||||
|  | ||||
| /* 重要任务的背景色 */ | ||||
| .todo-item.important { | ||||
|   background-color: #e6f7ff; | ||||
| } | ||||
|  | ||||
| .todo-checkbox { | ||||
|   margin-top: 2px; | ||||
|   flex-shrink: 0; | ||||
| } | ||||
|  | ||||
| .todo-content { | ||||
|   flex: 1; | ||||
| } | ||||
|  | ||||
| .todo-main { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   margin-bottom: 4px; | ||||
| } | ||||
|  | ||||
| .todo-title { | ||||
|   font-size: 14px; | ||||
|   font-weight: 500; | ||||
|   color: #303133; | ||||
| } | ||||
|  | ||||
| .todo-time { | ||||
|   font-size: 12px; | ||||
|   color: #909399; | ||||
| } | ||||
|  | ||||
| .todo-description { | ||||
|   font-size: 12px; | ||||
|   color: #606266; | ||||
|   line-height: 1.4; | ||||
| } | ||||
|  | ||||
| .todo-actions { | ||||
|   position: absolute; | ||||
|   right: 10px; | ||||
|   bottom: 10px; | ||||
|   display: flex; | ||||
|   gap: 5px; | ||||
| } | ||||
|  | ||||
| .todo-actions .el-button { | ||||
|   padding: 4px 8px; | ||||
|   min-width: auto; | ||||
| } | ||||
|  | ||||
| /* 状态图例 - 标签形式 */ | ||||
| .status-legend { | ||||
|   display: flex; | ||||
|   gap: 10px; | ||||
|   padding-top: 15px; | ||||
|   border-top: 1px solid #ebeef5; | ||||
| } | ||||
|  | ||||
| .status-tag { | ||||
|   display: inline-block; | ||||
|   padding: 4px 12px; | ||||
|   border-radius: 16px; | ||||
|   font-size: 12px; | ||||
|   color: #fff; | ||||
| } | ||||
|  | ||||
| .status-tag.normal { | ||||
|   background-color: #52c41a; | ||||
| } | ||||
|  | ||||
| .status-tag.important { | ||||
|   background-color: #faad14; | ||||
| } | ||||
|  | ||||
| .status-tag.urgent { | ||||
|   background-color: #ff4d4f; | ||||
| } | ||||
|  | ||||
| .todo-color-indicator { | ||||
|   width: 8px; | ||||
|   height: 100%; | ||||
|   border-radius: 0 4px 4px 0; | ||||
|   position: absolute; | ||||
|   left: 0; | ||||
|   top: 0; | ||||
|   flex-shrink: 0; | ||||
| } | ||||
|  | ||||
| .todo-color-indicator.normal { | ||||
|   background-color: #52c41a; | ||||
| } | ||||
|  | ||||
| .todo-color-indicator.important { | ||||
|   background-color: #faad14; | ||||
| } | ||||
|  | ||||
| .todo-color-indicator.urgent { | ||||
|   background-color: #ff4d4f; | ||||
| } | ||||
|  | ||||
| /* 自定义日历单元格样式 */ | ||||
| .custom-date-cell { | ||||
|   padding: 5px; | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| /* 系统升级事件样式 */ | ||||
| .event-upgrade { | ||||
|   background-color: #fff1f0; | ||||
|   color: #f5222d; | ||||
| } | ||||
|  | ||||
| /* 日期单元格背景色 - 按事件类型 */ | ||||
| .date-cell-service { | ||||
|   background-color: #e6f7ff; | ||||
| } | ||||
|  | ||||
| .date-cell-database { | ||||
|   background-color: #f0f9ff; | ||||
| } | ||||
|  | ||||
| .date-cell-network { | ||||
|   background-color: #fffbe6; | ||||
| } | ||||
|  | ||||
| .date-cell-upgrade { | ||||
|   background-color: #fff1f0; | ||||
| } | ||||
|  | ||||
| /* 日历样式优化 */ | ||||
| .el-calendar { | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| .el-calendar-table { | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| .el-calendar-table td { | ||||
|   padding: 2px; | ||||
|   vertical-align: top; | ||||
| } | ||||
|  | ||||
| .el-calendar-day { | ||||
|   height: 120px; | ||||
|   border-radius: 4px; | ||||
|   overflow: hidden; | ||||
| } | ||||
|  | ||||
| .date-day { | ||||
|   font-weight: bold; | ||||
|   margin-bottom: 5px; | ||||
| } | ||||
|  | ||||
| .date-events { | ||||
|   flex: 1; | ||||
|   overflow: hidden; | ||||
| } | ||||
|  | ||||
| .event-item { | ||||
|   padding: 3px; | ||||
|   margin-bottom: 2px; | ||||
|   border-radius: 3px; | ||||
|   font-size: 12px; | ||||
| } | ||||
|  | ||||
| .event-title { | ||||
|   font-weight: bold; | ||||
|   white-space: nowrap; | ||||
|   overflow: hidden; | ||||
|   text-overflow: ellipsis; | ||||
| } | ||||
|  | ||||
| .event-description { | ||||
|   font-size: 11px; | ||||
|   white-space: nowrap; | ||||
|   overflow: hidden; | ||||
|   text-overflow: ellipsis; | ||||
| } | ||||
|  | ||||
| /* 服务维护事件样式 */ | ||||
| .event-service { | ||||
|   background-color: #e6f7ff; | ||||
|   color: #1890ff; | ||||
| } | ||||
|  | ||||
| /* 数据库管理事件样式 */ | ||||
| .event-database { | ||||
|   background-color: #f0f9ff; | ||||
|   color: #36cfc9; | ||||
| } | ||||
|  | ||||
| /* 网络维护事件样式 */ | ||||
| .event-network { | ||||
|   background-color: #fffbe6; | ||||
|   color: #faad14; | ||||
| } | ||||
|  | ||||
| /* 系统升级事件样式 */ | ||||
| .event-upgrade { | ||||
|   background-color: #fff1f0; | ||||
|   color: #f5222d; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										672
									
								
								src/views/dhr_demo/xunjianjihua.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										672
									
								
								src/views/dhr_demo/xunjianjihua.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,672 @@ | ||||
| <template> | ||||
|   <div class="operation-inspection"> | ||||
|     <div class="navigation-tabs"> | ||||
|       <div class="nav-tab" @click="handleInspection1">待办事项</div> | ||||
|       <div class="nav-tab active" @click="handleInspection2">巡检管理</div> | ||||
|       <div class="nav-tab">试验管理</div> | ||||
|       <div class="nav-tab">报修管理</div> | ||||
|       <div class="nav-tab">抢修管理</div> | ||||
|       <div class="nav-tab">工单管理</div> | ||||
|     </div> | ||||
|     <div style="display: flex; align-items: center; gap: 1200px"> | ||||
|       <TitleComponent title="运维巡检管理" subtitle="制定巡检计划,安排巡检任务,跟进巡检记录"></TitleComponent> | ||||
|       <div style="display: flex; align-items: center; gap: 10px"> | ||||
|         <el-button type="primary" class="export-btn">筛选</el-button> | ||||
|         <el-button type="primary" class="create-btn">导入数据</el-button> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 选项卡和按钮组合 --> | ||||
|     <div class="tabs-wrapper"> | ||||
|       <div style="display: flex; align-items: center; gap: 10px"> | ||||
|         <el-button type="primary" @click="handleInspectionManagement1">巡检计划</el-button> | ||||
|         <el-button type="primary" @click="handleInspectionManagement2">巡检任务</el-button> | ||||
|         <el-button type="primary" @click="handleInspectionManagement3">巡检记录</el-button> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 筛选栏 --> | ||||
|     <div class="filter-bar"> | ||||
|       <div class="filter-item"> | ||||
|         <el-select v-model="filterStatus" placeholder="状态" clearable> | ||||
|           <el-option label="全部状态" value="all"></el-option> | ||||
|           <el-option label="正常" value="normal"></el-option> | ||||
|           <el-option label="需关注" value="attention"></el-option> | ||||
|           <el-option label="有问题" value="problem"></el-option> | ||||
|         </el-select> | ||||
|       </div> | ||||
|       <div class="filter-item"> | ||||
|         <el-select v-model="filterType" placeholder="巡检类型" clearable> | ||||
|           <el-option label="全部类型" value="all"></el-option> | ||||
|           <el-option label="数据库" value="database"></el-option> | ||||
|           <el-option label="服务器" value="server"></el-option> | ||||
|           <el-option label="网络设备" value="network"></el-option> | ||||
|         </el-select> | ||||
|       </div> | ||||
|       <div class="filter-item"> | ||||
|         <el-date-picker | ||||
|           v-model="dateRange" | ||||
|           type="daterange" | ||||
|           range-separator="至" | ||||
|           start-placeholder="开始日期" | ||||
|           end-placeholder="结束日期" | ||||
|           value-format="YYYY-MM-DD" | ||||
|         ></el-date-picker> | ||||
|       </div> | ||||
|       <div class="filter-actions"> | ||||
|         <el-button type="primary" class="search-btn">搜索</el-button> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 主内容区 --> | ||||
|     <div class="grid grid-cols-1 lg:grid-cols-3 gap-6" style="grid-auto-rows: 1fr"> | ||||
|       <!-- 左侧和中间内容区 --> | ||||
|       <div class="lg:col-span-2 space-y-6"> | ||||
|         <!-- 巡检记录与报告卡片 --> | ||||
|         <div class="content-card"> | ||||
|           <div class="card-header"> | ||||
|             <h2 class="card-title">巡检记录与报告</h2> | ||||
|             <div class="flex space-x-2"> | ||||
|               <button | ||||
|                 class="px-3 py-1 text-sm rounded-md hover:bg-gray-200 transition" | ||||
|                 :class="{ 'bg-gray-100 text-gray-700': timeRange === 'month', 'bg-white text-gray-500': timeRange !== 'month' }" | ||||
|                 @click="handleTimeRangeChange('month')" | ||||
|               > | ||||
|                 月 | ||||
|               </button> | ||||
|               <button | ||||
|                 class="px-3 py-1 text-sm rounded-md hover:bg-gray-100 transition" | ||||
|                 :class="{ 'bg-gray-100 text-gray-700': timeRange === 'week', 'bg-white text-gray-500': timeRange !== 'week' }" | ||||
|                 @click="handleTimeRangeChange('week')" | ||||
|               > | ||||
|                 周 | ||||
|               </button> | ||||
|               <button | ||||
|                 class="px-3 py-1 text-sm rounded-md hover:bg-gray-100 transition" | ||||
|                 :class="{ 'bg-gray-100 text-gray-700': timeRange === 'day', 'bg-white text-gray-500': timeRange !== 'day' }" | ||||
|                 @click="handleTimeRangeChange('day')" | ||||
|               > | ||||
|                 日 | ||||
|               </button> | ||||
|             </div> | ||||
|           </div> | ||||
|  | ||||
|           <!-- 数据卡片 --> | ||||
|           <div class="card-body"> | ||||
|             <div class="grid grid-cols-2 md:grid-cols-4 gap-4"> | ||||
|               <div class="stat-card"> | ||||
|                 <p class="stat-label">本月完成巡检</p> | ||||
|                 <p class="stat-value">42</p> | ||||
|               </div> | ||||
|               <div class="stat-card"> | ||||
|                 <p class="stat-label">发现问题数</p> | ||||
|                 <p class="stat-value">7</p> | ||||
|               </div> | ||||
|               <div class="stat-card"> | ||||
|                 <p class="stat-label">已解决问题</p> | ||||
|                 <p class="stat-value">5</p> | ||||
|               </div> | ||||
|               <div class="stat-card"> | ||||
|                 <p class="stat-label">平均完成时间</p> | ||||
|                 <p class="stat-value">45分钟</p> | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
|             <div class="divider"></div> | ||||
|  | ||||
|             <!-- 图表区域 --> | ||||
|             <div class="grid grid-cols-1 md:grid-cols-3 gap-6 py-4"> | ||||
|               <!-- 饼图 - 本月巡检完成情况 --> | ||||
|               <div class="md:col-span-1"> | ||||
|                 <p class="chart-title">本月完成巡检</p> | ||||
|                 <div class="relative w-32 h-32 mx-auto"> | ||||
|                   <!-- 饼图使用SVG绘制 - 显示本月巡检完成情况 --> | ||||
|                   <svg class="w-full h-full" viewBox="0 0 100 100"> | ||||
|                     <!-- 背景圆环 --> | ||||
|                     <circle cx="50" cy="50" r="45" fill="none" stroke="#f3f4f6" stroke-width="10" /> | ||||
|                     <!-- 已完成部分 (72%) --> | ||||
|                     <circle | ||||
|                       cx="50" | ||||
|                       cy="50" | ||||
|                       r="45" | ||||
|                       fill="none" | ||||
|                       stroke="#10b981" | ||||
|                       stroke-width="10" | ||||
|                       stroke-dasharray="282.74" | ||||
|                       stroke-dashoffset="113.1" | ||||
|                       transform="rotate(-90 50 50)" | ||||
|                     /> | ||||
|                     <!-- 未完成部分 (28%) --> | ||||
|                     <circle | ||||
|                       cx="50" | ||||
|                       cy="50" | ||||
|                       r="45" | ||||
|                       fill="none" | ||||
|                       stroke="#f97316" | ||||
|                       stroke-width="10" | ||||
|                       stroke-dasharray="113.1" | ||||
|                       stroke-dashoffset="0" | ||||
|                       transform="rotate(-90 50 50)" | ||||
|                     /> | ||||
|                   </svg> | ||||
|                   <!-- 饼图中心显示 --> | ||||
|                   <div class="absolute inset-0 flex flex-col items-center justify-center"> | ||||
|                     <p class="text-sm text-gray-500">已解决问题</p> | ||||
|                     <p class="text-lg font-bold text-gray-800">72%</p> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <!-- 饼图图例 --> | ||||
|                 <div class="mt-3 flex justify-center space-x-4"> | ||||
|                   <div class="flex items-center"> | ||||
|                     <div class="w-3 h-3 rounded-full bg-green-500 mr-1"></div> | ||||
|                     <span class="text-xs text-gray-600">已解决</span> | ||||
|                   </div> | ||||
|                   <div class="flex items-center"> | ||||
|                     <div class="w-3 h-3 rounded-full bg-orange-500 mr-1"></div> | ||||
|                     <span class="text-xs text-gray-600">未解决</span> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|  | ||||
|               <!-- 进度条 --> | ||||
|               <div class="md:col-span-2 flex flex-col justify-center"> | ||||
|                 <div class="space-y-4"> | ||||
|                   <div> | ||||
|                     <div class="flex justify-between text-sm mb-1"> | ||||
|                       <span class="text-gray-600">完成率</span> | ||||
|                       <span class="font-medium text-gray-800">68%</span> | ||||
|                     </div> | ||||
|                     <div class="w-full bg-gray-200 rounded-full h-2"> | ||||
|                       <div class="bg-red-500 h-2 rounded-full" style="width: 68%"></div> | ||||
|                     </div> | ||||
|                   </div> | ||||
|                   <div> | ||||
|                     <div class="flex justify-between text-sm mb-1"> | ||||
|                       <span class="text-gray-600">解决率</span> | ||||
|                       <span class="font-medium text-gray-800">72%</span> | ||||
|                     </div> | ||||
|                     <div class="w-full bg-gray-200 rounded-full h-2"> | ||||
|                       <div class="bg-green-500 h-2 rounded-full" style="width: 72%"></div> | ||||
|                     </div> | ||||
|                   </div> | ||||
|                   <div> | ||||
|                     <div class="flex justify-between text-sm mb-1"> | ||||
|                       <span class="text-gray-600">及时率</span> | ||||
|                       <span class="font-medium text-gray-800">60%</span> | ||||
|                     </div> | ||||
|                     <div class="w-full bg-gray-200 rounded-full h-2"> | ||||
|                       <div class="bg-gray-500 h-2 rounded-full" style="width: 60%"></div> | ||||
|                     </div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
|             <div class="divider"></div> | ||||
|  | ||||
|             <!-- 发现问题种类 --> | ||||
|             <div class="py-4"> | ||||
|               <h3 class="section-title">发现问题种类</h3> | ||||
|               <div class="space-y-4"> | ||||
|                 <div> | ||||
|                   <div class="flex justify-between text-sm mb-1"> | ||||
|                     <span class="text-gray-600">温度异常率</span> | ||||
|                     <span class="text-gray-500">85%</span> | ||||
|                   </div> | ||||
|                   <div class="w-full bg-gray-200 rounded-full h-2"> | ||||
|                     <div class="bg-blue-500 h-2 rounded-full" style="width: 85%"></div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div> | ||||
|                   <div class="flex justify-between text-sm mb-1"> | ||||
|                     <span class="text-gray-600">内存使用率</span> | ||||
|                     <span class="text-gray-500">62%</span> | ||||
|                   </div> | ||||
|                   <div class="w-full bg-gray-200 rounded-full h-2"> | ||||
|                     <div class="bg-blue-500 h-2 rounded-full" style="width: 62%"></div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div> | ||||
|                   <div class="flex justify-between text-sm mb-1"> | ||||
|                     <span class="text-gray-600">CPU负载</span> | ||||
|                     <span class="text-gray-500">45%</span> | ||||
|                   </div> | ||||
|                   <div class="w-full bg-gray-200 rounded-full h-2"> | ||||
|                     <div class="bg-blue-500 h-2 rounded-full" style="width: 45%"></div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div> | ||||
|                   <div class="flex justify-between text-sm mb-1"> | ||||
|                     <span class="text-gray-600">响应时间</span> | ||||
|                     <span class="text-gray-500">30%</span> | ||||
|                   </div> | ||||
|                   <div class="w-full bg-gray-200 rounded-full h-2"> | ||||
|                     <div class="bg-blue-500 h-2 rounded-full" style="width: 30%"></div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div> | ||||
|                   <div class="flex justify-between text-sm mb-1"> | ||||
|                     <span class="text-gray-600">磁盘空间状态</span> | ||||
|                     <span class="text-gray-500">15%</span> | ||||
|                   </div> | ||||
|                   <div class="w-full bg-gray-200 rounded-full h-2"> | ||||
|                     <div class="bg-blue-500 h-2 rounded-full" style="width: 15%"></div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <!-- 右侧最近巡检结果 --> | ||||
|       <div class="lg:col-span-1" style="display: flex; flex-direction: column; height: 100%"> | ||||
|         <div class="content-card" style="flex: 1; display: flex; flex-direction: column"> | ||||
|           <div class="card-header"> | ||||
|             <h2 class="card-title">最近巡检结果</h2> | ||||
|           </div> | ||||
|  | ||||
|           <!-- 巡检结果列表 --> | ||||
|           <div class="card-body" style="flex: 1; overflow-y: auto"> | ||||
|             <div class="inspection-results space-y-4"> | ||||
|               <!-- 结果1:正常 --> | ||||
|               <div class="inspection-card bg-white border border-gray-200 rounded-lg p-4 shadow-sm"> | ||||
|                 <div class="flex justify-between items-start mb-4"> | ||||
|                   <h3 class="text-lg font-medium text-gray-800">数据库性能巡检</h3> | ||||
|                   <span class="status-tag status-normal px-3 py-1 text-xs">正常</span> | ||||
|                 </div> | ||||
|                 <p class="text-sm text-gray-500 mb-3">2025-06-15 14:00-16:45 张明</p> | ||||
|  | ||||
|                 <div class="flex justify-between items-center mb-4"> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-check-circle text-green-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">系统连接量</span> | ||||
|                     <span class="text-sm font-medium">128<500</span> | ||||
|                   </div> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-check-circle text-green-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">查询响应时间</span> | ||||
|                     <span class="text-sm font-medium">平均0.3S</span> | ||||
|                   </div> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-check-circle text-green-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">表空间使用率</span> | ||||
|                     <span class="text-sm font-medium">75%</span> | ||||
|                   </div> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-check-circle text-green-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">日志文件</span> | ||||
|                     <span class="text-sm font-medium">正常轮转</span> | ||||
|                   </div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="flex justify-end gap-2"> | ||||
|                   <el-button size="small" class="text-sm border-gray-300 text-gray-600">查看详情</el-button> | ||||
|                   <el-button type="primary" size="small" class="text-sm">生成报告</el-button> | ||||
|                 </div> | ||||
|               </div> | ||||
|  | ||||
|               <!-- 结果2:需关注 --> | ||||
|               <div class="inspection-card bg-white border border-gray-200 rounded-lg p-4 shadow-sm"> | ||||
|                 <div class="flex justify-between items-start mb-4"> | ||||
|                   <h3 class="text-lg font-medium text-gray-800">生产服务器日常巡检</h3> | ||||
|                   <span class="status-tag status-attention px-3 py-1 text-xs">需关注</span> | ||||
|                 </div> | ||||
|                 <p class="text-sm text-gray-500 mb-3">2025-06-15 14:00-16:45 张明</p> | ||||
|  | ||||
|                 <div class="flex justify-between items-center mb-4"> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-check-circle text-green-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">CPU使用率</span> | ||||
|                     <span class="text-sm font-medium">平均35%,峰值59%</span> | ||||
|                   </div> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-exclamation-circle text-yellow-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">内存使用率</span> | ||||
|                     <span class="text-sm font-medium">85%</span> | ||||
|                   </div> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-check-circle text-green-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">磁盘空间</span> | ||||
|                     <span class="text-sm font-medium">62%</span> | ||||
|                   </div> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-check-circle text-green-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">服务状态</span> | ||||
|                     <span class="text-sm font-medium">正常运行</span> | ||||
|                   </div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="bg-yellow-50 border border-yellow-200 rounded-md p-3 mb-4"> | ||||
|                   <div class="flex items-start"> | ||||
|                     <i class="fas fa-info-circle text-yellow-500 mt-0.5 mr-2"></i> | ||||
|                     <p class="text-xs text-yellow-800">已创建问题单 #PRB-2023061501,计划于今晚进行内存扩容</p> | ||||
|                   </div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="flex justify-end gap-2"> | ||||
|                   <el-button size="small" class="text-sm border-gray-300 text-gray-600">查看详情</el-button> | ||||
|                   <el-button type="primary" size="small" class="text-sm">生成报告</el-button> | ||||
|                 </div> | ||||
|               </div> | ||||
|  | ||||
|               <!-- 结果3:有问题 --> | ||||
|               <div class="inspection-card bg-white border border-gray-200 rounded-lg p-4 shadow-sm"> | ||||
|                 <div class="flex justify-between items-start mb-4"> | ||||
|                   <h3 class="text-lg font-medium text-gray-800">网络设备安全巡检</h3> | ||||
|                   <span class="status-tag status-problem px-3 py-1 text-xs">有问题</span> | ||||
|                 </div> | ||||
|                 <p class="text-sm text-gray-500 mb-3">2025-06-14 10:00-11:30 李华</p> | ||||
|  | ||||
|                 <div class="grid grid-cols-2 gap-2 mb-4"> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-times-circle text-red-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">防火墙规则</span> | ||||
|                     <span class="text-sm font-medium">部分规则异常</span> | ||||
|                   </div> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-exclamation-circle text-yellow-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">安全补丁</span> | ||||
|                     <span class="text-sm font-medium">需更新</span> | ||||
|                   </div> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-check-circle text-green-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">访问控制</span> | ||||
|                     <span class="text-sm font-medium">正常</span> | ||||
|                   </div> | ||||
|                   <div class="flex flex-col items-center"> | ||||
|                     <i class="fas fa-check-circle text-green-500 text-lg mb-1"></i> | ||||
|                     <span class="text-xs text-gray-600 mb-1">流量监控</span> | ||||
|                     <span class="text-sm font-medium">正常</span> | ||||
|                   </div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="flex justify-end gap-2"> | ||||
|                   <el-button size="small" class="text-sm border-gray-300 text-gray-600">查看详情</el-button> | ||||
|                   <el-button type="primary" size="small" class="text-sm">生成报告</el-button> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup> | ||||
| import { ref } from 'vue'; | ||||
| import router from '@/router'; | ||||
| import TitleComponent from '@/views/demo/components/TitleComponent.vue'; | ||||
|  | ||||
| // 筛选条件 | ||||
| const filterStatus = ref('all'); | ||||
| const filterType = ref('all'); | ||||
| const dateRange = ref([]); | ||||
|  | ||||
| // 时间范围选择 | ||||
| const timeRange = ref('month'); // 默认选中"月" | ||||
|  | ||||
| // 时间范围切换函数 | ||||
| const handleTimeRangeChange = (range) => { | ||||
|   timeRange.value = range; | ||||
|   // 在实际应用中,这里应该根据选择的时间范围重新获取数据 | ||||
|   console.log(`切换到${range}视图`); | ||||
| }; | ||||
|  | ||||
| // 导航方法 | ||||
| const handleInspection1 = () => { | ||||
|   router.push('/rili/rili'); | ||||
| }; | ||||
| const handleInspection2 = () => { | ||||
|   router.push('/rili/InspectionManagement'); | ||||
| }; | ||||
| const handleInspectionManagement1 = () => { | ||||
|   router.push('/rili/InspectionManagement'); | ||||
| }; | ||||
| const handleInspectionManagement2 = () => { | ||||
|   router.push('/rili/xunjianrenwu'); | ||||
| }; | ||||
| const handleInspectionManagement3 = () => { | ||||
|   router.push('/rili/xunjianjihua'); | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| /* 主容器样式 */ | ||||
| .operation-inspection { | ||||
|   padding: 20px; | ||||
|   background-color: #f5f7fa; | ||||
|   min-height: 100vh; | ||||
| } | ||||
|  | ||||
| /* 导航栏样式 */ | ||||
| .navigation-tabs { | ||||
|   display: flex; | ||||
|   margin-bottom: 20px; | ||||
|   background-color: #fff; | ||||
|   border-radius: 4px; | ||||
|   box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08); | ||||
|   padding: 2px; | ||||
| } | ||||
|  | ||||
| .nav-tab { | ||||
|   padding: 12px 24px; | ||||
|   cursor: pointer; | ||||
|   transition: all 0.3s ease; | ||||
|   border-radius: 4px; | ||||
|   font-size: 14px; | ||||
|   color: #606266; | ||||
|   border-right: 1px solid #f0f0f0; | ||||
|   flex: 1; | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| .nav-tab:last-child { | ||||
|   border-right: none; | ||||
| } | ||||
|  | ||||
| .nav-tab:hover { | ||||
|   color: #409eff; | ||||
|   background-color: #ecf5ff; | ||||
| } | ||||
|  | ||||
| .nav-tab.active { | ||||
|   background-color: #409eff; | ||||
|   color: #fff; | ||||
|   box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3); | ||||
| } | ||||
|  | ||||
| .nav-tab { | ||||
|   cursor: pointer; | ||||
|   user-select: none; | ||||
| } | ||||
|  | ||||
| /* 选项卡样式 */ | ||||
| .tabs-wrapper { | ||||
|   background-color: #fff; | ||||
|   padding: 20px; | ||||
|   border-radius: 8px; | ||||
|   margin-bottom: 16px; | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); | ||||
| } | ||||
|  | ||||
| /* 筛选栏样式 */ | ||||
| .filter-bar { | ||||
|   background-color: #fff; | ||||
|   padding: 20px; | ||||
|   border-radius: 8px; | ||||
|   margin-bottom: 16px; | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   flex-wrap: wrap; | ||||
|   gap: 16px; | ||||
| } | ||||
|  | ||||
| .filter-item { | ||||
|   flex-shrink: 0; | ||||
| } | ||||
|  | ||||
| .filter-bar .el-select, | ||||
| .filter-bar .el-date-picker { | ||||
|   width: 150px; | ||||
|   height: 36px; | ||||
| } | ||||
|  | ||||
| .filter-actions { | ||||
|   margin-left: auto; | ||||
|   display: flex; | ||||
|   gap: 10px; | ||||
| } | ||||
|  | ||||
| .search-btn, | ||||
| .export-btn, | ||||
| .create-btn { | ||||
|   height: 36px; | ||||
|   border-radius: 4px; | ||||
| } | ||||
|  | ||||
| /* 内容卡片样式 */ | ||||
| .content-card { | ||||
|   background-color: #fff; | ||||
|   border-radius: 8px; | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); | ||||
|   overflow: hidden; | ||||
| } | ||||
|  | ||||
| .card-header { | ||||
|   padding: 20px; | ||||
|   border-bottom: 1px solid #e4e7ed; | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .card-title { | ||||
|   font-size: 16px; | ||||
|   font-weight: 500; | ||||
|   color: #303133; | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| .card-body { | ||||
|   padding: 0 20px; | ||||
| } | ||||
|  | ||||
| /* 统计卡片样式 */ | ||||
| .stat-card { | ||||
|   background-color: #f5f7fa; | ||||
|   border-radius: 6px; | ||||
|   padding: 16px; | ||||
| } | ||||
|  | ||||
| .stat-label { | ||||
|   font-size: 14px; | ||||
|   color: #606266; | ||||
|   margin: 0 0 8px 0; | ||||
| } | ||||
|  | ||||
| .stat-value { | ||||
|   font-size: 24px; | ||||
|   font-weight: 600; | ||||
|   color: #303133; | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| /* 分隔线 */ | ||||
| .divider { | ||||
|   height: 1px; | ||||
|   background-color: #e4e7ed; | ||||
|   margin: 16px 0; | ||||
| } | ||||
|  | ||||
| /* 图表标题 */ | ||||
| .chart-title { | ||||
|   font-size: 14px; | ||||
|   color: #606266; | ||||
|   margin: 0 0 8px 0; | ||||
| } | ||||
|  | ||||
| /* 区域标题 */ | ||||
| .section-title { | ||||
|   font-size: 14px; | ||||
|   font-weight: 500; | ||||
|   color: #303133; | ||||
|   margin: 0 0 12px 0; | ||||
| } | ||||
|  | ||||
| /* 记录列表样式 */ | ||||
| .record-list { | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
| } | ||||
|  | ||||
| .record-item { | ||||
|   padding: 16px 0; | ||||
| } | ||||
|  | ||||
| .record-title { | ||||
|   font-size: 14px; | ||||
|   font-weight: 500; | ||||
|   color: #303133; | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| .record-time, | ||||
| .record-type { | ||||
|   font-size: 12px; | ||||
|   color: #909399; | ||||
|   margin: 4px 0 0 0; | ||||
| } | ||||
|  | ||||
| /* 状态标签 */ | ||||
| .status-tag { | ||||
|   font-size: 12px; | ||||
|   padding: 2px 8px; | ||||
|   border-radius: 4px; | ||||
| } | ||||
|  | ||||
| .status-normal { | ||||
|   background-color: #f0f9eb; | ||||
|   color: #52c41a; | ||||
|   border: 1px solid #e1f3d8; | ||||
| } | ||||
|  | ||||
| .status-attention { | ||||
|   background-color: #fffbe6; | ||||
|   color: #faad14; | ||||
|   border: 1px solid #fff1b8; | ||||
| } | ||||
|  | ||||
| .status-problem { | ||||
|   background-color: #fff2f0; | ||||
|   color: #f5222d; | ||||
|   border: 1px solid #ffe3e0; | ||||
| } | ||||
|  | ||||
| /* 操作按钮 */ | ||||
| .action-btn { | ||||
|   color: #409eff; | ||||
|   font-size: 12px; | ||||
|   padding: 4px 8px; | ||||
| } | ||||
|  | ||||
| .action-btn:hover { | ||||
|   color: #66b1ff; | ||||
|   background-color: #ecf5ff; | ||||
| } | ||||
|  | ||||
| /* 响应式设计 */ | ||||
| @media (max-width: 1200px) { | ||||
|   .filter-bar { | ||||
|     flex-direction: column; | ||||
|     align-items: stretch; | ||||
|   } | ||||
|  | ||||
|   .filter-actions { | ||||
|     margin-left: 0; | ||||
|     justify-content: flex-end; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										892
									
								
								src/views/dhr_demo/xunjianrenwu.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										892
									
								
								src/views/dhr_demo/xunjianrenwu.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,892 @@ | ||||
| <template> | ||||
|   <div> | ||||
|     <div class="inspection-tasks"> | ||||
|       <div class="navigation-tabs"> | ||||
|         <div class="nav-tab" @click="handleInspection1">待办事项</div> | ||||
|         <div class="nav-tab active" @click="handleInspection2">巡检管理</div> | ||||
|         <div class="nav-tab">试验管理</div> | ||||
|         <div class="nav-tab">报修管理</div> | ||||
|         <div class="nav-tab">抢修管理</div> | ||||
|         <div class="nav-tab">工单管理</div> | ||||
|       </div> | ||||
|       <!-- 页面标题 --> | ||||
|       <TitleComponent title="运维巡检管理" subtitle="制定巡检计划,安排巡检任务,跟进巡检记录"></TitleComponent> | ||||
|  | ||||
|       <!-- 选项卡 --> | ||||
|       <div class="tabs-wrapper"> | ||||
|         <div style="display: flex; align-items: center; gap: 10px"> | ||||
|           <el-button type="primary" @click="handleInspectionManagement1">巡检计划</el-button> | ||||
|           <el-button type="primary" @click="handleInspectionManagement2">巡检任务</el-button> | ||||
|           <el-button type="primary" @click="handleInspectionManagement3">巡检记录</el-button> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <!-- 筛选栏 --> | ||||
|       <div class="filter-bar"> | ||||
|         <div class="filter-container"> | ||||
|           <div class="filter-item"> | ||||
|             <el-select v-model="taskStatus" placeholder="任务状态"> | ||||
|               <el-option label="待执行" value="pending"></el-option> | ||||
|               <el-option label="执行中" value="executing"></el-option> | ||||
|               <el-option label="已延期" value="delayed"></el-option> | ||||
|               <el-option label="已完成" value="completed"></el-option> | ||||
|             </el-select> | ||||
|           </div> | ||||
|           <div class="filter-item"> | ||||
|             <el-select v-model="planType" placeholder="全部计划"> | ||||
|               <el-option label="每日巡检计划" value="daily"></el-option> | ||||
|               <el-option label="每周巡检计划" value="weekly"></el-option> | ||||
|               <el-option label="每月巡检计划" value="monthly"></el-option> | ||||
|               <el-option label="每季度巡检计划" value="quarterly"></el-option> | ||||
|             </el-select> | ||||
|           </div> | ||||
|           <div class="filter-item"> | ||||
|             <el-select v-model="executor" placeholder="执行人"> | ||||
|               <el-option label="全部人员" value="all"></el-option> | ||||
|               <el-option label="张明" value="zhangming"></el-option> | ||||
|               <el-option label="李华" value="lihua"></el-option> | ||||
|               <el-option label="王强" value="wangqiang"></el-option> | ||||
|             </el-select> | ||||
|           </div> | ||||
|           <div class="filter-actions"> | ||||
|             <el-button type="primary" class="search-btn" @click="handleSearch"> <i class="el-icon-search mr-1"></i>搜索 </el-button> | ||||
|             <el-button type="primary" icon="el-icon-plus" class="create-btn" @click="handleCreateTask"> 手动创建任务 </el-button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <!-- 任务卡片列表 --> | ||||
|       <div class="task-cards"> | ||||
|         <div class="task-card" v-for="(task, index) in pagedTasks" :key="index"> | ||||
|           <div class="task-header"> | ||||
|             <div class="task-title"> | ||||
|               {{ task.title }} | ||||
|             </div> | ||||
|             <div class="task-status" :class="task.statusClass"> | ||||
|               {{ task.statusText }} | ||||
|             </div> | ||||
|           </div> | ||||
|  | ||||
|           <div class="task-details"> | ||||
|             <div class="detail-item"> | ||||
|               <span class="detail-label">计划时间</span> | ||||
|               <span class="detail-value">{{ task.planTime }}</span> | ||||
|             </div> | ||||
|             <div class="detail-item"> | ||||
|               <span class="detail-label">巡检对象</span> | ||||
|               <span class="detail-value">{{ task.target }}</span> | ||||
|             </div> | ||||
|             <div class="detail-item"> | ||||
|               <span class="detail-label">执行人</span> | ||||
|               <span class="detail-value">{{ task.executor }}</span> | ||||
|             </div> | ||||
|             <div class="detail-item"> | ||||
|               <span class="detail-label">关联计划</span> | ||||
|               <span class="detail-value">{{ task.relatedPlan }}</span> | ||||
|             </div> | ||||
|  | ||||
|             <!-- 特定状态的额外信息 --> | ||||
|             <div v-if="task.status === 'delayed'" class="delay-reason"> | ||||
|               <span class="detail-label">延期原因</span> | ||||
|               <span class="detail-value">{{ task.delayReason }}</span> | ||||
|             </div> | ||||
|  | ||||
|             <div v-if="task.status === 'executing'" class="progress-container"> | ||||
|               <span class="detail-label">完成进度</span> | ||||
|               <div class="progress-bar"> | ||||
|                 <el-progress :percentage="task.progress" stroke-width="6" :stroke-color="task.progressColor"></el-progress> | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
|             <div v-if="task.status === 'completed'" class="task-result"> | ||||
|               <span class="detail-label">结果</span> | ||||
|               <span class="detail-value" :class="task.resultClass">{{ task.result }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|  | ||||
|           <div class="task-actions"> | ||||
|             <el-button type="text" size="small" class="action-btn view-btn" @click="handleView(task)"> 详情 </el-button> | ||||
|             <el-button type="primary" size="small" :class="task.actionClass" @click="handleAction(task)"> | ||||
|               {{ task.actionText }} | ||||
|             </el-button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <!-- 分页区域 --> | ||||
|       <div class="pagination-section"> | ||||
|         <div class="pagination-controls"> | ||||
|           <el-pagination | ||||
|             @size-change="handleSizeChange" | ||||
|             @current-change="handleCurrentChange" | ||||
|             :current-page="currentPage" | ||||
|             :page-sizes="[8, 12, 16, 20]" | ||||
|             :page-size="pageSize" | ||||
|             layout="prev, pager, next, jumper" | ||||
|             :total="total" | ||||
|             background | ||||
|           > | ||||
|           </el-pagination> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <!-- 添加新任务弹窗 --> | ||||
|       <el-dialog v-model="createTaskDialogVisible" title="添加新任务" width="500px" :before-close="handleCancelCreateTask"> | ||||
|         <el-form ref="createTaskFormRef" :model="createTaskForm" :rules="createTaskRules" label-width="80px"> | ||||
|           <el-form-item label="任务名称" prop="taskName"> | ||||
|             <el-input v-model="createTaskForm.taskName" placeholder="输入任务名称" /> | ||||
|           </el-form-item> | ||||
|  | ||||
|           <el-form-item label="巡检对象" prop="inspectionTarget"> | ||||
|             <el-input v-model="createTaskForm.inspectionTarget" placeholder="输入巡检内容" /> | ||||
|           </el-form-item> | ||||
|  | ||||
|           <el-form-item label="时间" prop="timeRange"> | ||||
|             <el-date-picker | ||||
|               v-model="createTaskForm.timeRange" | ||||
|               type="datetimerange" | ||||
|               start-placeholder="开始时间" | ||||
|               end-placeholder="结束时间" | ||||
|               format="YYYY-MM-DD HH:mm" | ||||
|               value-format="YYYY-MM-DD HH:mm" | ||||
|               placeholder="选择时间范围" | ||||
|             /> | ||||
|           </el-form-item> | ||||
|  | ||||
|           <el-form-item label="关联计划"> | ||||
|             <el-select v-model="createTaskForm.relatedPlan" placeholder="选择关联计划"> | ||||
|               <el-option label="全部计划" value="all" /> | ||||
|               <el-option label="每日巡检计划" value="daily" /> | ||||
|               <el-option label="每周巡检计划" value="weekly" /> | ||||
|               <el-option label="每月巡检计划" value="monthly" /> | ||||
|               <el-option label="每季度巡检计划" value="quarterly" /> | ||||
|             </el-select> | ||||
|           </el-form-item> | ||||
|  | ||||
|           <el-form-item label="执行人"> | ||||
|             <el-select v-model="createTaskForm.executor" placeholder="选择执行人"> | ||||
|               <el-option label="全部人员" value="all" /> | ||||
|               <el-option label="张明" value="zhangming" /> | ||||
|               <el-option label="李华" value="lihua" /> | ||||
|               <el-option label="王强" value="wangqiang" /> | ||||
|               <el-option label="赵伟" value="zhaowei" /> | ||||
|             </el-select> | ||||
|           </el-form-item> | ||||
|         </el-form> | ||||
|  | ||||
|         <template #footer> | ||||
|           <span class="dialog-footer"> | ||||
|             <el-button @click="handleCancelCreateTask">取消</el-button> | ||||
|             <el-button type="primary" @click="handleSaveTask">保存任务</el-button> | ||||
|           </span> | ||||
|         </template> | ||||
|       </el-dialog> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup> | ||||
| import { ref, computed } from 'vue'; | ||||
| import router from '@/router'; | ||||
| import TitleComponent from '@/views/demo/components/TitleComponent.vue'; | ||||
|  | ||||
| // 激活的选项卡 | ||||
| const activeTab = ref('task'); | ||||
|  | ||||
| // 筛选条件 | ||||
| const taskStatus = ref(''); | ||||
| const planType = ref(''); | ||||
| const executor = ref(''); | ||||
|  | ||||
| // 任务数据 | ||||
| const tasks = ref([ | ||||
|   { | ||||
|     title: '生产服务器日常巡检', | ||||
|     status: 'pending', | ||||
|     statusText: '待执行', | ||||
|     statusClass: 'status-pending', | ||||
|     planTime: '2025-06-16 08:30', | ||||
|     target: '生产服务器集群(12台)', | ||||
|     executor: '张明', | ||||
|     relatedPlan: '每日巡检计划', | ||||
|     actionText: '开始执行', | ||||
|     actionClass: 'start-btn' | ||||
|   }, | ||||
|   { | ||||
|     title: '机房环境检查', | ||||
|     status: 'delayed', | ||||
|     statusText: '已延期', | ||||
|     statusClass: 'status-delayed', | ||||
|     planTime: '2025-06-16 08:30', | ||||
|     target: '机房温度、湿度、电源', | ||||
|     executor: '李华', | ||||
|     relatedPlan: '每周巡检计划', | ||||
|     delayReason: '设备维修处理中', | ||||
|     actionText: '重新安排', | ||||
|     actionClass: 'reschedule-btn' | ||||
|   }, | ||||
|   { | ||||
|     title: '网络设备安全巡检', | ||||
|     status: 'executing', | ||||
|     statusText: '执行中', | ||||
|     statusClass: 'status-executing', | ||||
|     planTime: '2025-06-16 09:30', | ||||
|     target: '核心交换机、防火墙', | ||||
|     executor: '王强', | ||||
|     relatedPlan: '每周巡检计划', | ||||
|     progress: 60, | ||||
|     progressColor: '#FF7D00', | ||||
|     actionText: '完成', | ||||
|     actionClass: 'complete-btn' | ||||
|   }, | ||||
|   { | ||||
|     title: '数据库性能巡检', | ||||
|     status: 'completed', | ||||
|     statusText: '已完成', | ||||
|     statusClass: 'status-completed', | ||||
|     planTime: '2025-06-16 10:30', | ||||
|     target: '生产数据库集群(2组)', | ||||
|     executor: '赵伟', | ||||
|     relatedPlan: '每月巡检计划', | ||||
|     result: '正常', | ||||
|     resultClass: 'result-normal', | ||||
|     actionText: '查看报告', | ||||
|     actionClass: 'report-btn' | ||||
|   }, | ||||
|   { | ||||
|     title: '生产服务器日常巡检', | ||||
|     status: 'pending', | ||||
|     statusText: '待执行', | ||||
|     statusClass: 'status-pending', | ||||
|     planTime: '2025-06-16 13:30', | ||||
|     target: '生产服务器集群(12台)', | ||||
|     executor: '张明', | ||||
|     relatedPlan: '每日巡检计划', | ||||
|     actionText: '开始执行', | ||||
|     actionClass: 'start-btn' | ||||
|   }, | ||||
|   { | ||||
|     title: '机房环境检查', | ||||
|     status: 'delayed', | ||||
|     statusText: '已延期', | ||||
|     statusClass: 'status-delayed', | ||||
|     planTime: '2025-06-16 14:00', | ||||
|     target: '机房温度、湿度、电源', | ||||
|     executor: '李华', | ||||
|     relatedPlan: '每周巡检计划', | ||||
|     delayReason: '设备维修处理中', | ||||
|     actionText: '重新安排', | ||||
|     actionClass: 'reschedule-btn' | ||||
|   }, | ||||
|   { | ||||
|     title: '网络设备安全巡检', | ||||
|     status: 'executing', | ||||
|     statusText: '执行中', | ||||
|     statusClass: 'status-executing', | ||||
|     planTime: '2025-06-16 15:00', | ||||
|     target: '核心交换机、防火墙', | ||||
|     executor: '王强', | ||||
|     relatedPlan: '每周巡检计划', | ||||
|     progress: 35, | ||||
|     progressColor: '#FF7D00', | ||||
|     actionText: '完成', | ||||
|     actionClass: 'complete-btn' | ||||
|   }, | ||||
|   { | ||||
|     title: '数据库性能巡检', | ||||
|     status: 'completed', | ||||
|     statusText: '已完成', | ||||
|     statusClass: 'status-completed', | ||||
|     planTime: '2025-06-16 16:00', | ||||
|     target: '生产数据库集群(2组)', | ||||
|     executor: '赵伟', | ||||
|     relatedPlan: '每月巡检计划', | ||||
|     result: '正常', | ||||
|     resultClass: 'result-normal', | ||||
|     actionText: '查看报告', | ||||
|     actionClass: 'report-btn' | ||||
|   } | ||||
| ]); | ||||
|  | ||||
| // 分页相关 | ||||
| const currentPage = ref(1); | ||||
| const pageSize = ref(8); | ||||
| const total = ref(tasks.value.length); | ||||
|  | ||||
| // 状态排序映射 | ||||
| const statusOrder = { | ||||
|   pending: 0, // 待完成 | ||||
|   delayed: 1, // 已延期 | ||||
|   executing: 2, // 执行中 | ||||
|   completed: 3 // 已完成 | ||||
| }; | ||||
|  | ||||
| // 分页处理后的数据(含排序) | ||||
| const pagedTasks = computed(() => { | ||||
|   // 先按状态排序 | ||||
|   const sortedTasks = [...tasks.value].sort((a, b) => { | ||||
|     return statusOrder[a.status] - statusOrder[b.status]; | ||||
|   }); | ||||
|  | ||||
|   // 再进行分页 | ||||
|   const startIndex = (currentPage.value - 1) * pageSize.value; | ||||
|   const endIndex = startIndex + pageSize.value; | ||||
|   return sortedTasks.slice(startIndex, endIndex); | ||||
| }); | ||||
|  | ||||
| // 搜索处理 | ||||
| const handleSearch = () => { | ||||
|   currentPage.value = 1; // 重置到第一页 | ||||
|   // 实际应用中这里会根据筛选条件过滤数据 | ||||
| }; | ||||
|  | ||||
| // 创建任务弹窗相关 | ||||
| const createTaskDialogVisible = ref(false); | ||||
| const createTaskForm = ref({ | ||||
|   taskName: '', | ||||
|   inspectionTarget: '', | ||||
|   timeRange: [], | ||||
|   relatedPlan: 'all', | ||||
|   executor: 'all' | ||||
| }); | ||||
|  | ||||
| const createTaskRules = { | ||||
|   taskName: [{ required: true, message: '请输入任务名称', trigger: 'blur' }], | ||||
|   inspectionTarget: [{ required: true, message: '请输入巡检对象', trigger: 'blur' }], | ||||
|   timeRange: [{ required: true, message: '请选择时间范围', trigger: 'change' }] | ||||
| }; | ||||
|  | ||||
| // 创建任务 | ||||
| const handleCreateTask = () => { | ||||
|   createTaskDialogVisible.value = true; | ||||
| }; | ||||
|  | ||||
| // 保存任务 | ||||
| const handleSaveTask = () => { | ||||
|   // 模拟保存任务逻辑 | ||||
|   console.log('保存任务:', createTaskForm.value); | ||||
|   // 关闭弹窗 | ||||
|   createTaskDialogVisible.value = false; | ||||
|   // 重置表单 | ||||
|   createTaskForm.value = { | ||||
|     taskName: '', | ||||
|     inspectionTarget: '', | ||||
|     timeRange: [], | ||||
|     relatedPlan: 'all', | ||||
|     executor: 'all' | ||||
|   }; | ||||
|   // 这里可以添加成功提示和刷新任务列表的逻辑 | ||||
| }; | ||||
|  | ||||
| // 取消创建任务 | ||||
| const handleCancelCreateTask = () => { | ||||
|   createTaskDialogVisible.value = false; | ||||
|   // 重置表单 | ||||
|   createTaskForm.value = { | ||||
|     taskName: '', | ||||
|     inspectionTarget: '', | ||||
|     timeRange: [], | ||||
|     relatedPlan: 'all', | ||||
|     executor: 'all' | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| // 分页事件 | ||||
| const handleSizeChange = (val) => { | ||||
|   pageSize.value = val; | ||||
|   currentPage.value = 1; | ||||
| }; | ||||
|  | ||||
| const handleCurrentChange = (val) => { | ||||
|   currentPage.value = val; | ||||
| }; | ||||
|  | ||||
| // 查看任务详情 | ||||
| const handleView = (task) => { | ||||
|   console.log('查看任务详情:', task); | ||||
| }; | ||||
|  | ||||
| const handleInspectionManagement1 = () => { | ||||
|   router.push('/rili/InspectionManagement'); | ||||
| }; | ||||
|  | ||||
| const handleInspectionManagement2 = () => { | ||||
|   router.push('/rili/xunjianrenwu'); | ||||
| }; | ||||
| const handleInspectionManagement3 = () => { | ||||
|   router.push('/rili/xunjianjihua'); | ||||
| }; | ||||
| const handleInspection1 = () => { | ||||
|   router.push('/rili/rili'); | ||||
| }; | ||||
| const handleInspection2 = () => { | ||||
|   router.push('/rili/InspectionManagement'); | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .inspection-tasks { | ||||
|   padding: 20px; | ||||
|   background-color: #f5f7fa; | ||||
|   min-height: 100vh; | ||||
| } | ||||
|  | ||||
| /* 选项卡样式 */ | ||||
| .tabs-wrapper { | ||||
|   background-color: #fff; | ||||
|   padding: 20px; | ||||
|   border-radius: 8px; | ||||
|   margin-bottom: 16px; | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); | ||||
| } | ||||
|  | ||||
| .custom-tabs { | ||||
|   border-bottom: none; | ||||
|   padding-top: 20px; | ||||
| } | ||||
|  | ||||
| .custom-tabs .el-tabs__header { | ||||
|   margin: 0 -20px 0 -20px; | ||||
|   padding: 0 20px; | ||||
|   border-bottom: 1px solid #e4e7ed; | ||||
| } | ||||
|  | ||||
| .custom-tabs .el-tabs__nav-wrap::after { | ||||
|   height: 0; | ||||
| } | ||||
|  | ||||
| .custom-tabs .el-tabs__item { | ||||
|   font-size: 14px; | ||||
|   color: #606266; | ||||
|   padding: 12px 20px; | ||||
|   margin-right: 20px; | ||||
|   border-bottom: 2px solid transparent; | ||||
| } | ||||
|  | ||||
| .custom-tabs .el-tabs__item.is-active { | ||||
|   color: #409eff; | ||||
|   border-bottom-color: #409eff; | ||||
| } | ||||
|  | ||||
| .custom-tabs .el-tabs__item:hover { | ||||
|   color: #409eff; | ||||
| } | ||||
| /* 筛选栏样式 */ | ||||
| .filter-bar { | ||||
|   background-color: #fff; | ||||
|   border-radius: 8px; | ||||
|   margin-bottom: 24px; | ||||
|   box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); | ||||
|   padding: 16px 24px; | ||||
| } | ||||
|  | ||||
| .filter-container { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   flex-wrap: wrap; | ||||
|   gap: 16px; | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| .filter-item { | ||||
|   flex-shrink: 0; | ||||
| } | ||||
|  | ||||
| .filter-bar .el-select { | ||||
|   width: 180px; | ||||
|   height: 36px; | ||||
| } | ||||
|  | ||||
| .filter-bar .el-select .el-input__inner { | ||||
|   border-radius: 4px; | ||||
|   border-color: #dcdfe6; | ||||
|   transition: all 0.2s ease; | ||||
| } | ||||
|  | ||||
| .filter-bar .el-select .el-input__inner:focus { | ||||
|   border-color: #165dff; | ||||
|   box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.1); | ||||
| } | ||||
|  | ||||
| .filter-actions { | ||||
|   margin-left: auto; | ||||
|   display: flex; | ||||
|   gap: 12px; | ||||
|   flex-shrink: 0; | ||||
| } | ||||
|  | ||||
| .search-btn { | ||||
|   background-color: #f2f3f5; | ||||
|   color: #303133; | ||||
|   border-color: #f2f3f5; | ||||
|   transition: all 0.2s ease; | ||||
| } | ||||
|  | ||||
| .search-btn:hover { | ||||
|   background-color: #e5e6eb; | ||||
|   color: #303133; | ||||
|   border-color: #e5e6eb; | ||||
| } | ||||
|  | ||||
| .create-btn { | ||||
|   background-color: #165dff; | ||||
|   border-color: #165dff; | ||||
|   transition: all 0.2s ease; | ||||
| } | ||||
|  | ||||
| .create-btn:hover { | ||||
|   background-color: #0e42d2; | ||||
|   border-color: #0e42d2; | ||||
| } | ||||
|  | ||||
| /* 任务卡片样式 */ | ||||
| .task-cards { | ||||
|   display: grid; | ||||
|   grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); | ||||
|   gap: 20px; | ||||
|   margin-bottom: 30px; | ||||
| } | ||||
|  | ||||
| .task-card { | ||||
|   background-color: #fff; | ||||
|   border-radius: 8px; | ||||
|   box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05); | ||||
|   padding: 16px 16px 60px 16px; /* 底部留出更多空间给按钮 */ | ||||
|   transition: box-shadow 0.2s ease; | ||||
|   position: relative; | ||||
|   overflow: hidden; | ||||
|   min-height: 280px; /* 确保有足够高度显示所有内容 */ | ||||
| } | ||||
|  | ||||
| .task-actions { | ||||
|   display: flex; | ||||
|   justify-content: flex-end; | ||||
|   align-items: center; | ||||
|   padding-top: 12px; | ||||
|   border-top: 1px solid #f0f2f5; | ||||
|   position: absolute; | ||||
|   bottom: 16px; | ||||
|   right: 16px; | ||||
|   left: 16px; | ||||
|   background-color: #fff; | ||||
|   padding: 12px 0 0 0; | ||||
|   z-index: 10; | ||||
| } | ||||
|  | ||||
| .task-card::before { | ||||
|   content: ''; | ||||
|   position: absolute; | ||||
|   left: 0; | ||||
|   top: 0; | ||||
|   bottom: 0; | ||||
|   width: 4px; | ||||
| } | ||||
|  | ||||
| .task-card.status-pending::before { | ||||
|   background-color: #1677ff; | ||||
| } | ||||
|  | ||||
| .task-card.status-delayed::before { | ||||
|   background-color: #ff4d4f; | ||||
| } | ||||
|  | ||||
| .task-card.status-executing::before { | ||||
|   background-color: #fa8c16; | ||||
| } | ||||
|  | ||||
| .task-card.status-completed::before { | ||||
|   background-color: #52c41a; | ||||
| } | ||||
|  | ||||
| .task-card:hover { | ||||
|   transform: translateY(-3px); | ||||
|   box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08); | ||||
| } | ||||
|  | ||||
| .task-header { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: flex-start; | ||||
|   margin-bottom: 16px; | ||||
|   padding-bottom: 12px; | ||||
|   border-bottom: 1px solid #f0f2f5; | ||||
| } | ||||
|  | ||||
| .task-title { | ||||
|   font-size: 16px; | ||||
|   font-weight: 500; | ||||
|   color: #1d2129; | ||||
|   line-height: 1.4; | ||||
| } | ||||
|  | ||||
| .task-status { | ||||
|   padding: 4px 10px; | ||||
|   border-radius: 6px; | ||||
|   font-size: 12px; | ||||
|   font-weight: 500; | ||||
|   border: 1px solid transparent; | ||||
| } | ||||
|  | ||||
| /* 待执行状态 - 蓝色 */ | ||||
| .status-pending { | ||||
|   background-color: #e6f7ff; | ||||
|   color: #1677ff; | ||||
|   border-color: #91d5ff; | ||||
| } | ||||
|  | ||||
| /* 已延期状态 - 红色 */ | ||||
| .status-delayed { | ||||
|   background-color: #fff2f0; | ||||
|   color: #ff4d4f; | ||||
|   border-color: #ffccc7; | ||||
| } | ||||
|  | ||||
| /* 执行中状态 - 黄色 */ | ||||
| .status-executing { | ||||
|   background-color: #fffbe6; | ||||
|   color: #fa8c16; | ||||
|   border-color: #ffe58f; | ||||
| } | ||||
|  | ||||
| /* 已完成状态 - 绿色 */ | ||||
| .status-completed { | ||||
|   background-color: #f6ffed; | ||||
|   color: #52c41a; | ||||
|   border-color: #b7eb8f; | ||||
| } | ||||
|  | ||||
| .task-details { | ||||
|   margin-bottom: 16px; | ||||
| } | ||||
|  | ||||
| .detail-item { | ||||
|   display: flex; | ||||
|   margin-bottom: 10px; | ||||
|   font-size: 13px; | ||||
| } | ||||
|  | ||||
| .detail-label { | ||||
|   flex: 0 0 80px; | ||||
|   color: #86909c; | ||||
| } | ||||
|  | ||||
| .detail-value { | ||||
|   flex: 1; | ||||
|   color: #4e5969; | ||||
|   word-break: break-all; | ||||
| } | ||||
|  | ||||
| .delay-reason { | ||||
|   display: flex; | ||||
|   margin: 10px 0; | ||||
|   font-size: 13px; | ||||
|   padding-top: 8px; | ||||
|   border-top: 1px dashed #f0f2f5; | ||||
| } | ||||
|  | ||||
| .progress-container { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   margin: 10px 0; | ||||
|   padding-top: 8px; | ||||
|   border-top: 1px dashed #f0f2f5; | ||||
|   z-index: 1; | ||||
| } | ||||
|  | ||||
| .progress-bar { | ||||
|   flex: 1; | ||||
|   padding-left: 80px; | ||||
|   margin-top: 4px; | ||||
|   position: relative; | ||||
|   z-index: 1; | ||||
| } | ||||
|  | ||||
| .progress-text { | ||||
|   position: absolute; | ||||
|   right: 0; | ||||
|   top: 0; | ||||
|   font-size: 12px; | ||||
|   color: #86909c; | ||||
| } | ||||
|  | ||||
| .task-result { | ||||
|   display: flex; | ||||
|   margin: 10px 0; | ||||
|   font-size: 13px; | ||||
|   padding-top: 8px; | ||||
|   border-top: 1px dashed #f0f2f5; | ||||
| } | ||||
|  | ||||
| .result-normal { | ||||
|   color: #00b42a; | ||||
| } | ||||
|  | ||||
| .result-abnormal { | ||||
|   color: #f53f3f; | ||||
| } | ||||
|  | ||||
| .task-actions { | ||||
|   display: flex; | ||||
|   justify-content: flex-end; | ||||
|   align-items: center; | ||||
|   padding-top: 12px; | ||||
|   border-top: 1px solid #f0f2f5; | ||||
|   position: absolute; | ||||
|   bottom: 16px; | ||||
|   right: 16px; | ||||
|   left: 16px; | ||||
|   background-color: #fff; | ||||
|   padding: 12px 0 0 0; | ||||
|   z-index: 10; | ||||
| } | ||||
|  | ||||
| .action-btn { | ||||
|   font-size: 13px; | ||||
|   padding: 4px 10px; | ||||
| } | ||||
|  | ||||
| .view-btn { | ||||
|   color: #165dff; | ||||
| } | ||||
|  | ||||
| .view-btn:hover { | ||||
|   color: #0e42d2; | ||||
|   background-color: #e8f3ff; | ||||
| } | ||||
|  | ||||
| .start-btn { | ||||
|   background-color: #165dff; | ||||
|   border-color: #165dff; | ||||
| } | ||||
|  | ||||
| .start-btn:hover { | ||||
|   background-color: #0e42d2; | ||||
|   border-color: #0e42d2; | ||||
| } | ||||
|  | ||||
| .reschedule-btn { | ||||
|   background-color: #ff7d00; | ||||
|   border-color: #ff7d00; | ||||
| } | ||||
|  | ||||
| .reschedule-btn:hover { | ||||
|   background-color: #e86a00; | ||||
|   border-color: #e86a00; | ||||
| } | ||||
|  | ||||
| .complete-btn { | ||||
|   background-color: #00b42a; | ||||
|   border-color: #00b42a; | ||||
| } | ||||
|  | ||||
| .complete-btn:hover { | ||||
|   background-color: #008718; | ||||
|   border-color: #008718; | ||||
| } | ||||
|  | ||||
| .report-btn { | ||||
|   background-color: #86909c; | ||||
|   border-color: #86909c; | ||||
| } | ||||
|  | ||||
| .report-btn:hover { | ||||
|   background-color: #6b7785; | ||||
|   border-color: #6b7785; | ||||
| } | ||||
|  | ||||
| /* 分页区域样式 */ | ||||
| .pagination-section { | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
|   margin-top: 20px; | ||||
| } | ||||
|  | ||||
| .pagination-controls .el-pagination { | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| .pagination-controls .el-pagination button, | ||||
| .pagination-controls .el-pagination .el-pager li { | ||||
|   min-width: 36px; | ||||
|   height: 36px; | ||||
|   line-height: 36px; | ||||
|   border-radius: 4px; | ||||
| } | ||||
|  | ||||
| .pagination-controls .el-pagination .el-pager li.active { | ||||
|   background-color: #165dff; | ||||
|   color: #fff; | ||||
| } | ||||
|  | ||||
| /* 响应式设计 */ | ||||
| @media (max-width: 1200px) { | ||||
|   .task-cards { | ||||
|     grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @media (max-width: 768px) { | ||||
|   .inspection-tasks { | ||||
|     padding: 16px; | ||||
|   } | ||||
|  | ||||
|   .filter-container { | ||||
|     flex-direction: column; | ||||
|     align-items: stretch; | ||||
|   } | ||||
|  | ||||
|   .filter-actions { | ||||
|     margin-left: 0; | ||||
|     justify-content: flex-end; | ||||
|   } | ||||
|  | ||||
|   .filter-bar .el-select { | ||||
|     width: 100%; | ||||
|   } | ||||
|  | ||||
|   .task-cards { | ||||
|     grid-template-columns: 1fr; | ||||
|   } | ||||
| } | ||||
| /* 导航栏样式 */ | ||||
| .navigation-tabs { | ||||
|   display: flex; | ||||
|   margin-bottom: 20px; | ||||
|   background-color: #fff; | ||||
|   border-radius: 4px; | ||||
|   box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08); | ||||
|   padding: 2px; | ||||
| } | ||||
|  | ||||
| .nav-tab { | ||||
|   padding: 12px 24px; | ||||
|   cursor: pointer; | ||||
|   transition: all 0.3s ease; | ||||
|   border-radius: 4px; | ||||
|   font-size: 14px; | ||||
|   color: #606266; | ||||
|   border-right: 1px solid #f0f0f0; | ||||
|   flex: 1; | ||||
|   text-align: center; | ||||
| } | ||||
|  | ||||
| .nav-tab:last-child { | ||||
|   border-right: none; | ||||
| } | ||||
|  | ||||
| .nav-tab:hover { | ||||
|   color: #409eff; | ||||
|   background-color: #ecf5ff; | ||||
| } | ||||
|  | ||||
| .nav-tab.active { | ||||
|   background-color: #409eff; | ||||
|   color: #fff; | ||||
|   box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3); | ||||
| } | ||||
|  | ||||
| .nav-tab { | ||||
|   cursor: pointer; | ||||
|   user-select: none; | ||||
| } | ||||
| </style> | ||||
| @ -4,7 +4,7 @@ | ||||
|       <div ref="mapRef" class="map-container" style="width: 100%; height: 100%" /> | ||||
|     </div> | ||||
|     <div class="centerPage_bottom"> | ||||
|       <Title title="风险预警"> | ||||
|       <Title title="风险预警" style="font-size: 22px"> | ||||
|         <img src="@/assets/projectLarge/robot.svg" alt="" height="20px" width="20px" /> | ||||
|       </Title> | ||||
|       <div class="centerPage_bottom_table"> | ||||
| @ -48,6 +48,7 @@ const loading = ref(false); | ||||
| const tableData = ref([]); | ||||
| const risk_level_type = ref(); | ||||
| const safety_inspection_type = ref(); | ||||
| const router = useRouter(); | ||||
| // 新增:获取项目地理信息数据 | ||||
| const getProjectGisData = async () => { | ||||
|   try { | ||||
| @ -159,6 +160,7 @@ const initEcharts = () => { | ||||
|                     <div style="font-weight: bold;">${data.name}</div> | ||||
|                     <div>地点:${data.projectSite}</div> | ||||
|                     <div>经纬度:${data.value[0].toFixed(6)}, ${data.value[1].toFixed(6)}</div> | ||||
|                      | ||||
|                 `; | ||||
|         } | ||||
|         if (params.seriesType === 'map') { | ||||
| @ -196,6 +198,17 @@ const initEcharts = () => { | ||||
|   }; | ||||
|  | ||||
|   myChart.setOption(option); | ||||
|   // 添加点击事件监听 - 这是关键修改部分 | ||||
|   myChart.on('click', function (params: any) { | ||||
|     // 检查点击的是散点图系列 | ||||
|     if (params.componentType === 'series' && params.seriesType === 'scatter') { | ||||
|       // 跳转到项目详情页 | ||||
|       navigateToProjectDetail(); | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
| const navigateToProjectDetail = () => { | ||||
|   window.open('http://xny.yj-3d.com:7788/ProjectScreen', '_blank'); | ||||
| }; | ||||
| const risk_level_type1 = ref([]); | ||||
| const safety_inspection_type1 = ref([]); | ||||
|  | ||||
| @ -11,8 +11,8 @@ | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="title"> | ||||
|       <div>煤科建管-新能源项目数智化管理平台</div> | ||||
|       <div>Coal Science Construction Management - New Energy Project Digital Intelligent Management Platform</div> | ||||
|       <div>新能源项目数智化管理平台</div> | ||||
|       <div>New Energy Project Digital Intelligent Management Platform</div> | ||||
|     </div> | ||||
|     <div class="header_right"> | ||||
|       <div class="top-bar"> | ||||
| @ -25,7 +25,7 @@ | ||||
|               class="weather-item" | ||||
|               :style="{ transform: `translateY(-${offsetY}px)`, transition: transition }" | ||||
|             > | ||||
|               <img :src="`../../../src/assets/images/${item.icon}.png`" alt="" /> | ||||
|               <img :src="`/assets/demo/${item.icon}.png`" alt="" /> | ||||
|               <div>{{ item.weather }}{{ item.tempMin }}°/{{ item.tempMax }}°</div> | ||||
|               <div>{{ item.week }}({{ item.date }})</div> | ||||
|             </div> | ||||
| @ -214,6 +214,7 @@ onUnmounted(() => { | ||||
|   .header_left_text { | ||||
|     font-weight: 500; | ||||
|     text-shadow: 0px 1.24px 6.21px rgba(25, 179, 250, 1); | ||||
|     font-size: 26px; | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <div class="leftPage"> | ||||
|     <div class="topPage"> | ||||
|       <Title style="font-size: 22px" title="企业关键指标" /> | ||||
|       <Title title="企业关键指标" /> | ||||
|       <div class="indicators"> | ||||
|         <div class="indicator-card" v-for="indicator in indicators" :key="indicator.id"> | ||||
|           <div style="display: flex; align-items: baseline; gap: 4px; margin-bottom: 5px"> | ||||
| @ -17,44 +17,74 @@ | ||||
|     </div> | ||||
|  | ||||
|     <div class="endPage"> | ||||
|       <Title style="font-size: 22px" title="人员情况" /> | ||||
|       <div class="map"> | ||||
|         <div class="project_attendance_chart"> | ||||
|           <Title style="font-size: 22px" title="各项目人员出勤率" /> | ||||
|           <div class="chart_content" ref="attendanceChartRef"></div> | ||||
|         </div> | ||||
|         <div class="attendance_tag"> | ||||
|           <div class="tag_item"> | ||||
|             <img src="@/assets/projectLarge/people.svg" alt="" /> | ||||
|             <div class="tag_title">出勤人</div> | ||||
|             <div class="tag_info"> | ||||
|               {{ attendanceCount }} | ||||
|               <span style="font-size: 14px">人</span> | ||||
|             </div> | ||||
|       <Title title="人员情况" /> | ||||
|       <!-- 人员总览区域 --> | ||||
|       <div class="people_overview"> | ||||
|         <div class="people_overview_content"> | ||||
|           <div class="people_image"> | ||||
|             <!-- 本地图片占位,后续可替换为实际图片路径 --> | ||||
|             <img src="@/assets/images/man.png" alt="人员总览" class="placeholder_image" /> | ||||
|           </div> | ||||
|           <div class="tag_item"> | ||||
|             <img src="@/assets/projectLarge/people.svg" alt="" /> | ||||
|             <div class="tag_title">在岗人</div> | ||||
|             <div class="tag_info"> | ||||
|               {{ peopleCount }} | ||||
|               <span style="font-size: 14px">人</span> | ||||
|           <div class="people_stats"> | ||||
|             <div class="stat_item"> | ||||
|               <div class="stat_label">出勤人数</div> | ||||
|               <div class="stat_value">{{ attendanceCount }}</div> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="tag_item"> | ||||
|             <img src="@/assets/projectLarge/people.svg" alt="" /> | ||||
|             <div class="tag_title">出勤率</div> | ||||
|             <div class="tag_info"> | ||||
|               {{ attendanceRate }} | ||||
|               <span style="font-size: 14px">%</span> | ||||
|             <div class="stat_item"> | ||||
|               <div class="stat_label">出勤率</div> | ||||
|               <div class="stat_rate">{{ attendanceRate }}%</div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <!-- 点阵地图 --> | ||||
|       <div class="people_map"> | ||||
|         <div class="map_container"> | ||||
|           <img src="@/assets/images/map.png" /> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <div class="attendance_tag"></div> | ||||
|       <!-- 人员分类统计 --> | ||||
|       <div class="people_categories"> | ||||
|         <div class="category_item"> | ||||
|           <div class="category_icon"> | ||||
|             <!-- 本地图片占位,后续可替换为实际图片路径 --> | ||||
|             <img src="@/assets/images/constructor.png" alt="施工人员" class="category_image" /> | ||||
|           </div> | ||||
|           <div class="category_info"> | ||||
|             <div class="category_label">施工人员</div> | ||||
|             <div class="category_count">{{ constructionPersonnelCount }}</div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="category_item"> | ||||
|           <div class="category_icon"> | ||||
|             <!-- 本地图片占位,后续可替换为实际图片路径 --> | ||||
|             <img src="@/assets/images/subcontractor.png" alt="分包人员" class="category_image" /> | ||||
|           </div> | ||||
|           <div class="category_info"> | ||||
|             <div class="category_label">分包人员</div> | ||||
|             <div class="category_count">{{ subcontractorsCount }}</div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="category_item"> | ||||
|           <div class="category_icon"> | ||||
|             <!-- 本地图片占位,后续可替换为实际图片路径 --> | ||||
|             <img src="@/assets/images/manager.png" alt="管理人员" class="category_image" /> | ||||
|           </div> | ||||
|           <div class="category_info"> | ||||
|             <div class="category_label">管理人员</div> | ||||
|             <div class="category_count">{{ managersCount }}</div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <!-- 项目出勤率柱状图 --> | ||||
|       <div class="project_attendance_chart"> | ||||
|         <Title title="项目出勤率统计" /> | ||||
|  | ||||
|         <div class="chart_content" ref="attendanceChartRef"></div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 项目出勤率柱状图 --> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| @ -62,7 +92,7 @@ | ||||
| import { ref } from 'vue'; | ||||
| import Title from './title.vue'; | ||||
| import { getScreenNews, getScreenPeople } from '@/api/projectScreen'; | ||||
| import { keyIndex } from '@/api/enterpriseLarge/index'; | ||||
| import { keyIndex, projectAttendanceCount, peopleCount, allAttendanceCount } from '@/api/enterpriseLarge/index'; | ||||
| import { mapOption } from './optionList'; | ||||
| import * as echarts from 'echarts'; | ||||
|  | ||||
| @ -78,30 +108,30 @@ const mapChartRef = ref<HTMLDivElement | null>(null); | ||||
| const indicators = ref([ | ||||
|   { | ||||
|     id: '1', | ||||
|     name: '在建项目', | ||||
|     name: '光伏项目', | ||||
|     value: '28', | ||||
|     unit: '个', | ||||
|     iconPath: '/src/assets/images/beUnder.png' | ||||
|     iconPath: '/assets/demo/beUnder.png' | ||||
|   }, | ||||
|   { | ||||
|     id: '2', | ||||
|     name: '合同总额', | ||||
|     name: '风电项目', | ||||
|     value: '288.88', | ||||
|     unit: '亿元', | ||||
|     unit: '个', | ||||
|     iconPath: '/src/assets/images/contract.png' | ||||
|   }, | ||||
|   { | ||||
|     id: '3', | ||||
|     name: '总容量', | ||||
|     name: '光伏系统总容量', | ||||
|     value: '158.88', | ||||
|     unit: '个', | ||||
|     unit: 'MW', | ||||
|     iconPath: '/src/assets/images/totalCapacity.png' | ||||
|   }, | ||||
|   { | ||||
|     id: '4', | ||||
|     name: '今日施工', | ||||
|     name: '风电项目总容量', | ||||
|     value: '18', | ||||
|     unit: '个', | ||||
|     unit: 'MW', | ||||
|     iconPath: '/src/assets/images/todayConstruction.png' | ||||
|   } | ||||
| ]); | ||||
| @ -114,9 +144,14 @@ const newDetail = ref({ | ||||
| const newId = ref(''); | ||||
| const attendanceCount = ref(0); | ||||
| const attendanceRate = ref(0); | ||||
| const peopleCount = ref(0); | ||||
| const totalPeopleCount = ref(0); | ||||
| const teamAttendanceList = ref([{ id: '', teamName: '', attendanceNumber: 0, allNumber: 0, attendanceRate: 0, attendanceTime: '' }]); | ||||
|  | ||||
| // 人员分类统计数据 | ||||
| const constructionPersonnelCount = ref(0); | ||||
| const managersCount = ref(0); | ||||
| const subcontractorsCount = ref(0); | ||||
|  | ||||
| // 项目出勤率数据 | ||||
| const projectAttendanceData = ref([ | ||||
|   { name: 'A项目', value: 62 }, | ||||
| @ -129,6 +164,11 @@ const projectAttendanceData = ref([ | ||||
| let attendanceChart = null; | ||||
| const attendanceChartRef = ref<HTMLDivElement | null>(null); | ||||
|  | ||||
| // 滚动相关状态 | ||||
| const scrollInterval = ref<number | null>(null); | ||||
| const currentScrollIndex = ref(0); | ||||
| const scrollSpeed = 1000; // 滚动间隔时间(ms) | ||||
|  | ||||
| /** | ||||
|  * 获取项目人员出勤数据 | ||||
|  */ | ||||
| @ -136,13 +176,167 @@ const getPeopleData = async () => { | ||||
|   const res = await getScreenPeople(props.projectId); | ||||
|   const { data, code } = res; | ||||
|   if (code === 200) { | ||||
|     attendanceCount.value = data.attendanceCount; | ||||
|     attendanceRate.value = data.attendanceRate; | ||||
|     peopleCount.value = data.peopleCount; | ||||
|     totalPeopleCount.value = data.peopleCount; | ||||
|     teamAttendanceList.value = data.teamAttendanceList; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 获取人员分类统计数据 | ||||
|  */ | ||||
| const getPeopleCategoryData = async () => { | ||||
|   try { | ||||
|     const res = await peopleCount(); | ||||
|     const { data, code } = res; | ||||
|     if (code === 200 && data) { | ||||
|       constructionPersonnelCount.value = data.constructionPersonnelCount || 0; | ||||
|       managersCount.value = data.managersCount || 0; | ||||
|       subcontractorsCount.value = data.subcontractorsCount || 0; | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.error('获取人员分类统计数据失败:', error); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 获取人员总览数据 - 通过allAttendanceCount接口 | ||||
|  */ | ||||
| const getProjectAttendanceCount = async () => { | ||||
|   try { | ||||
|     const res = await allAttendanceCount(); | ||||
|     const { data, code } = res; | ||||
|     if (code === 0 && data) { | ||||
|       // 直接使用接口返回的数据 | ||||
|       attendanceCount.value = data.attendanceCount || 0; | ||||
|       attendanceRate.value = data.attendanceRate || 0; | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.error('获取人员总览数据失败:', error); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 滚动到指定项目 | ||||
|  */ | ||||
| const scrollToProject = (index: number) => { | ||||
|   if (!attendanceChart || projectAttendanceData.value.length === 0) return; | ||||
|  | ||||
|   // 计算实际索引 | ||||
|   const realIndex = index % projectAttendanceData.value.length; | ||||
|   currentScrollIndex.value = realIndex; | ||||
|  | ||||
|   // 获取项目名称 | ||||
|   const projectName = projectAttendanceData.value[realIndex].name; | ||||
|  | ||||
|   // 触发tooltip显示 | ||||
|   attendanceChart.dispatchAction({ | ||||
|     type: 'showTip', | ||||
|     seriesIndex: 0, | ||||
|     dataIndex: realIndex | ||||
|   }); | ||||
|  | ||||
|   // 高亮当前项目的柱子 | ||||
|   attendanceChart.dispatchAction({ | ||||
|     type: 'highlight', | ||||
|     seriesIndex: 0, | ||||
|     dataIndex: realIndex | ||||
|   }); | ||||
|  | ||||
|   // 取消高亮其他项目的柱子 | ||||
|   attendanceChart.dispatchAction({ | ||||
|     type: 'downplay', | ||||
|     seriesIndex: 0, | ||||
|     dataIndex: Array.from({ length: projectAttendanceData.value.length }, (_, i) => i).filter((i) => i !== realIndex) | ||||
|   }); | ||||
|  | ||||
|   // 更新滚动条位置,确保滚动时滚动条同步移动 | ||||
|   // 无论项目数量多少,都应该同步滚动条 | ||||
|   if (projectAttendanceData.value.length > 0) { | ||||
|     // 计算滚动条应该移动到的位置 | ||||
|     // 确保当前项目居中显示 | ||||
|     const totalProjects = projectAttendanceData.value.length; | ||||
|     const visiblePercentage = 20; // 与dataZoom的end值保持一致 | ||||
|     const itemPercentage = 100 / totalProjects; // 每个项目所占总宽度的百分比 | ||||
|  | ||||
|     // 计算新的start值,使当前项目尽量居中显示 | ||||
|     let newStart = realIndex * itemPercentage - visiblePercentage / 2 + itemPercentage / 2; | ||||
|  | ||||
|     // 确保start值在有效范围内 | ||||
|     newStart = Math.max(0, Math.min(100 - visiblePercentage, newStart)); | ||||
|  | ||||
|     // 更新dataZoom组件的位置 | ||||
|     attendanceChart.dispatchAction({ | ||||
|       type: 'dataZoom', | ||||
|       start: newStart, | ||||
|       end: newStart + visiblePercentage | ||||
|     }); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 获取项目出勤率统计数据 - 保持项目出勤率图表功能 | ||||
|  */ | ||||
| const getProjectAttendanceStats = async () => { | ||||
|   try { | ||||
|     const res = await projectAttendanceCount(); | ||||
|     const { data, code } = res; | ||||
|  | ||||
|     // 添加日志信息以便调试 | ||||
|     console.log('projectAttendanceCount接口返回数据:', res); | ||||
|  | ||||
|     if (code === 200 && data && data.length > 0) { | ||||
|       console.log('有效数据:', data); | ||||
|  | ||||
|       // 更新项目出勤率图表数据 | ||||
|       projectAttendanceData.value = data.map((project) => ({ | ||||
|         name: project.projectName, | ||||
|         value: project.attendanceRate | ||||
|       })); | ||||
|  | ||||
|       console.log('处理后的数据:', projectAttendanceData.value); | ||||
|  | ||||
|       // 如果图表已初始化,重新设置数据 | ||||
|       if (attendanceChart) { | ||||
|         console.log('更新图表数据'); | ||||
|         attendanceChart.setOption({ | ||||
|           xAxis: { | ||||
|             data: projectAttendanceData.value.map((item) => item.name) | ||||
|           }, | ||||
|           series: [ | ||||
|             { | ||||
|               data: projectAttendanceData.value.map((item) => item.value) | ||||
|             } | ||||
|           ] | ||||
|         }); | ||||
|       } | ||||
|     } else { | ||||
|       console.warn('数据不符合预期:', { code, data }); | ||||
|       // 使用默认数据确保图表有内容显示 | ||||
|       if (!projectAttendanceData.value.length) { | ||||
|         projectAttendanceData.value = [ | ||||
|           { name: 'A项目', value: 62 }, | ||||
|           { name: 'B项目', value: 56 }, | ||||
|           { name: 'C项目', value: 95 }, | ||||
|           { name: 'D项目', value: 64 }, | ||||
|           { name: 'E项目', value: 97.5 } | ||||
|         ]; | ||||
|       } | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.error('获取项目出勤率数据失败:', error); | ||||
|     // 发生错误时使用默认数据 | ||||
|     if (!projectAttendanceData.value.length) { | ||||
|       projectAttendanceData.value = [ | ||||
|         { name: 'A项目', value: 62 }, | ||||
|         { name: 'B项目', value: 56 }, | ||||
|         { name: 'C项目', value: 95 }, | ||||
|         { name: 'D项目', value: 64 }, | ||||
|         { name: 'E项目', value: 97.5 } | ||||
|       ]; | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 获取企业关键指标数据 | ||||
|  */ | ||||
| @ -151,10 +345,10 @@ const getKeyIndexData = async () => { | ||||
|   const { data, code } = res; | ||||
|   if (code === 200) { | ||||
|     // 更新指标数据,使用接口返回的指定字段 | ||||
|     indicators.value[0].value = data.ongoingProject || 0; | ||||
|     indicators.value[1].value = data.totalContractAmount || 0; | ||||
|     indicators.value[2].value = data.totalCapacity || 0; | ||||
|     indicators.value[3].value = data.todayProject || 0; | ||||
|     indicators.value[0].value = data.photovoltaicCount || 0; | ||||
|     indicators.value[1].value = data.windElectricityCount || 0; | ||||
|     indicators.value[2].value = data.photovoltaicTotalCapacity || 0; | ||||
|     indicators.value[3].value = data.windElectricityTotalCapacity || 0; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| @ -163,8 +357,23 @@ const getKeyIndexData = async () => { | ||||
|  */ | ||||
| const initAttendanceChart = () => { | ||||
|   if (!attendanceChartRef.value) { | ||||
|     console.warn('attendanceChartRef不存在'); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // 确保有数据可显示 | ||||
|   if (!projectAttendanceData.value || !projectAttendanceData.value.length) { | ||||
|     console.log('使用默认数据初始化图表'); | ||||
|     projectAttendanceData.value = [ | ||||
|       { name: 'A项目', value: 62 }, | ||||
|       { name: 'B项目', value: 56 }, | ||||
|       { name: 'C项目', value: 95 }, | ||||
|       { name: 'D项目', value: 64 }, | ||||
|       { name: 'E项目', value: 97.5 } | ||||
|     ]; | ||||
|   } | ||||
|  | ||||
|   console.log('开始初始化图表,当前数据:', projectAttendanceData.value); | ||||
|   attendanceChart = echarts.init(attendanceChartRef.value); | ||||
|  | ||||
|   const option = { | ||||
| @ -191,13 +400,45 @@ const initAttendanceChart = () => { | ||||
|     grid: { | ||||
|       top: 40, | ||||
|       right: 30, | ||||
|       bottom: 40, | ||||
|       bottom: 60, // 增加底部空间以确保标签完全显示 | ||||
|       left: 30, | ||||
|       containLabel: true, | ||||
|       backgroundColor: 'rgba(10, 24, 45, 0.1)', | ||||
|       borderColor: 'rgba(29, 214, 255, 0.1)', | ||||
|       borderWidth: 1 | ||||
|     }, | ||||
|     // 添加dataZoom组件实现水平滚动 | ||||
|     dataZoom: [ | ||||
|       { | ||||
|         type: 'slider', | ||||
|         show: true, | ||||
|         xAxisIndex: [0], | ||||
|         start: 0, | ||||
|         end: 20, // 固定为20%,与visiblePercentage保持一致 | ||||
|         height: 20, | ||||
|         bottom: 10, | ||||
|         backgroundColor: 'rgba(10, 24, 45, 0.2)', | ||||
|         fillerColor: 'rgba(29, 214, 255, 0.2)', | ||||
|         borderColor: 'rgba(29, 214, 255, 0.3)', | ||||
|         textStyle: { | ||||
|           color: '#e6f7ff' | ||||
|         }, | ||||
|         handleStyle: { | ||||
|           color: 'rgba(29, 214, 255, 0.6)', | ||||
|           borderColor: 'rgba(255, 255, 255, 0.3)' | ||||
|         }, | ||||
|         moveHandleStyle: { | ||||
|           color: 'rgba(29, 214, 255, 0.8)' | ||||
|         } | ||||
|       }, | ||||
|       // 支持鼠标滚轮缩放 | ||||
|       { | ||||
|         type: 'inside', | ||||
|         xAxisIndex: [0], | ||||
|         start: 0, | ||||
|         end: 20 // 固定为20%,与visiblePercentage保持一致 | ||||
|       } | ||||
|     ], | ||||
|     xAxis: { | ||||
|       type: 'category', | ||||
|       data: projectAttendanceData.value.map((item) => item.name), | ||||
| @ -209,9 +450,18 @@ const initAttendanceChart = () => { | ||||
|       axisLabel: { | ||||
|         color: '#e6f7ff', | ||||
|         fontSize: 14, | ||||
|         interval: 0, | ||||
|         interval: 0, // 强制显示所有标签 | ||||
|         fontWeight: 'bold', | ||||
|         padding: [10, 0, 0, 0] | ||||
|         padding: [10, 0, 0, 0], | ||||
|         // 防止标签重叠,旋转角度调整 | ||||
|         rotate: 0, | ||||
|         // 添加formatter函数,当名称超过6个汉字时显示省略号 | ||||
|         formatter: function (value) { | ||||
|           if (value.length > 6) { | ||||
|             return value.substring(0, 6) + '...'; | ||||
|           } | ||||
|           return value; | ||||
|         } | ||||
|       }, | ||||
|       axisTick: { | ||||
|         show: true, | ||||
| @ -321,6 +571,11 @@ const initAttendanceChart = () => { | ||||
|  | ||||
|   attendanceChart.setOption(option); | ||||
|  | ||||
|   // 移除自动滚动功能,保留其他事件监听 | ||||
|   if (attendanceChartRef.value) { | ||||
|     // 保留其他可能需要的事件监听器 | ||||
|   } | ||||
|  | ||||
|   // 添加窗口大小变化时的图表更新 | ||||
|   const handleResize = () => { | ||||
|     if (attendanceChart) { | ||||
| @ -333,6 +588,8 @@ const initAttendanceChart = () => { | ||||
|   // 清理函数 | ||||
|   onUnmounted(() => { | ||||
|     window.removeEventListener('resize', handleResize); | ||||
|  | ||||
|     // 移除鼠标事件监听(已在上面移除添加的事件监听) | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| @ -347,17 +604,20 @@ const initMapChart = () => { | ||||
|   mapChart.setOption(mapOption); | ||||
| }; | ||||
|  | ||||
| onMounted(() => { | ||||
| onMounted(async () => { | ||||
|   // nextTick(() => { | ||||
|   //   initMapChart(); | ||||
|   // }); | ||||
|   getPeopleData(); | ||||
|   getKeyIndexData(); | ||||
|   getProjectAttendanceCount(); // 获取人员总览数据 | ||||
|   getPeopleCategoryData(); | ||||
|  | ||||
|   // 初始化项目出勤率柱状图 | ||||
|   setTimeout(() => { | ||||
|     initAttendanceChart(); | ||||
|   }, 100); | ||||
|   // 先等待获取项目出勤率数据 | ||||
|   await getProjectAttendanceStats(); // 获取项目出勤率图表数据 | ||||
|  | ||||
|   // 再初始化图表 | ||||
|   initAttendanceChart(); | ||||
| }); | ||||
|  | ||||
| onUnmounted(() => { | ||||
| @ -383,37 +643,59 @@ onUnmounted(() => { | ||||
|   .endPage { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: center; | ||||
|     width: 100%; | ||||
|     padding: 15px 0; | ||||
|     height: 250; | ||||
|     border: 1px solid rgba(29, 214, 255, 0.1); | ||||
|     box-sizing: border-box; | ||||
|   } | ||||
|  | ||||
|   .endPage { | ||||
|     height: auto; | ||||
|     flex: 1; | ||||
|     margin-top: 23px; | ||||
|     min-height: 550px; | ||||
|   } | ||||
|  | ||||
|   .project_attendance_chart { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: center; | ||||
|     width: 100%; | ||||
|     padding: 15px 0; | ||||
|     border: 1px solid rgba(29, 214, 255, 0.1); | ||||
|     box-sizing: border-box; | ||||
|     margin-top: 15px; | ||||
|     padding-bottom: 10px; | ||||
|  | ||||
|     .chart_title { | ||||
|       font-size: 16px; | ||||
|       color: #e6f7ff; | ||||
|       margin-bottom: 15px; | ||||
|       margin-bottom: 5px; | ||||
|       text-align: left; | ||||
|     } | ||||
|  | ||||
|     .scroll_controls { | ||||
|       display: flex; | ||||
|       justify-content: flex-end; | ||||
|       gap: 10px; | ||||
|       margin-bottom: 10px; | ||||
|       padding-right: 10px; | ||||
|     } | ||||
|  | ||||
|     .control_btn { | ||||
|       padding: 5px 15px; | ||||
|       background: rgba(10, 24, 45, 0.8); | ||||
|       border: 1px solid rgba(29, 214, 255, 0.3); | ||||
|       color: #e6f7ff; | ||||
|       font-size: 12px; | ||||
|       cursor: pointer; | ||||
|       border-radius: 4px; | ||||
|       transition: all 0.3s ease; | ||||
|     } | ||||
|  | ||||
|     .control_btn:hover { | ||||
|       background: rgba(29, 214, 255, 0.2); | ||||
|       border-color: rgba(29, 214, 255, 0.6); | ||||
|     } | ||||
|  | ||||
|     .chart_content { | ||||
|       width: 100%; | ||||
|       height: 200px; | ||||
|       height: 320px; /* 增加高度以容纳滚动条 */ | ||||
|       position: relative; | ||||
|       overflow: hidden; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -422,20 +704,20 @@ onUnmounted(() => { | ||||
|   width: 100%; | ||||
|   display: grid; | ||||
|   grid-template-columns: repeat(2, 1fr); | ||||
|   gap: 15px; | ||||
|   margin-top: 15px; | ||||
|   padding: 0 15px; | ||||
|   gap: 10px; | ||||
|   margin-bottom: 8px; | ||||
|   padding: 0 10px; | ||||
|   box-sizing: border-box; | ||||
| } | ||||
|  | ||||
| .indicator-card { | ||||
|   position: relative; | ||||
|   width: 100%; | ||||
|   height: 100px; | ||||
|   height: 80px; | ||||
|   background: rgba(10, 24, 45, 0.7); | ||||
|   border: 1px solid rgba(29, 214, 255, 0.2); | ||||
|   border-radius: 4px; | ||||
|   padding: 15px; | ||||
|   padding: 10px; | ||||
|   box-sizing: border-box; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
| @ -488,53 +770,149 @@ onUnmounted(() => { | ||||
|   object-fit: contain; | ||||
| } | ||||
|  | ||||
| .map { | ||||
|   margin-top: 15px; | ||||
| } | ||||
|  | ||||
| .attendance_tag { | ||||
| /* 人员总览样式 */ | ||||
| .people_overview { | ||||
|   width: 100%; | ||||
|   margin-top: 5px; | ||||
|   box-sizing: border-box; | ||||
|   border: 1px solid rgba(29, 214, 255, 0.1); | ||||
|   background: rgba(10, 24, 45, 0.3); | ||||
| } | ||||
|  | ||||
| .people_overview_title { | ||||
|   font-size: 16px; | ||||
|   color: #e6f7ff; | ||||
|   margin-bottom: 5px; | ||||
|   border-bottom: 1px solid rgba(29, 214, 255, 0.1); | ||||
| } | ||||
|  | ||||
| .people_overview_content { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   padding: 0 30px; | ||||
|   margin-top: 15px; | ||||
|  | ||||
|   .tag_item { | ||||
|     width: 28%; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: center; | ||||
|     gap: 10px; | ||||
|     border: 1px dashed rgba(29, 214, 255, 0.3); | ||||
|     padding: 10px; | ||||
|  | ||||
|     .tag_info { | ||||
|       font-size: 20px; | ||||
|       font-weight: 700; | ||||
|       color: rgba(230, 247, 255, 1); | ||||
|       text-shadow: 0px 1.24px 6.21px rgba(0, 190, 247, 1); | ||||
|     } | ||||
|  | ||||
|     .tag_title { | ||||
|       font-size: 14px; | ||||
|       font-weight: 400; | ||||
|       color: rgba(230, 247, 255, 1); | ||||
|     } | ||||
|   } | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .attendance_list { | ||||
|   padding: 0px 30px; | ||||
| .people_image { | ||||
|   width: 60px; | ||||
|   height: 60px; | ||||
|   background: linear-gradient(135deg, rgba(29, 214, 255, 0.1) 0%, rgba(29, 214, 255, 0.05) 100%); | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   flex-shrink: 0; | ||||
| } | ||||
|  | ||||
| .placeholder_image { | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   object-fit: contain; | ||||
| } | ||||
|  | ||||
| .people_stats { | ||||
|   flex: 1; | ||||
|   display: flex; | ||||
|   justify-content: space-around; | ||||
| } | ||||
|  | ||||
| .stat_item { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .stat_label { | ||||
|   font-size: 14px; | ||||
|  | ||||
|   .attendance_item { | ||||
|     display: grid; | ||||
|     grid-template-columns: 3fr 2fr 2fr 3fr; | ||||
|     margin-top: 20px; | ||||
|   } | ||||
|   color: #8ab2ff; | ||||
|   margin-bottom: 5px; | ||||
| } | ||||
|  | ||||
| .subfont { | ||||
|   color: rgba(138, 149, 165, 1); | ||||
| .stat_value { | ||||
|   font-size: 28px; | ||||
|   font-weight: bold; | ||||
|   color: #e6f7ff; | ||||
|   text-shadow: 0px 1.24px 6.21px rgba(0, 190, 247, 0.5); | ||||
| } | ||||
|  | ||||
| .stat_rate { | ||||
|   font-size: 28px; | ||||
|   font-weight: bold; | ||||
|   color: #00c853; | ||||
|   text-shadow: 0px 1.24px 6.21px rgba(0, 200, 83, 0.5); | ||||
| } | ||||
|  | ||||
| .people_map { | ||||
|   width: 100%; | ||||
|   margin-top: 8px; | ||||
|   background: rgba(10, 24, 45, 0.5); | ||||
|   border: 1px solid rgba(29, 214, 255, 0.1); | ||||
|   border-radius: 4px; | ||||
|   overflow: hidden; | ||||
|   position: relative; | ||||
| } | ||||
|  | ||||
| .map_background { | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   background-image: radial-gradient(circle, rgba(29, 214, 255, 0.3) 1px, transparent 1px), | ||||
|     radial-gradient(circle, rgba(29, 214, 255, 0.3) 1px, transparent 1px); | ||||
|   background-size: 40px 40px; | ||||
|   background-position: | ||||
|     0, | ||||
|     0, | ||||
|     20px 20px; | ||||
|   position: relative; | ||||
| } | ||||
|  | ||||
| /* 人员分类统计样式 */ | ||||
| .people_categories { | ||||
|   display: flex; | ||||
|   justify-content: space-around; | ||||
|   margin-top: 5px; | ||||
| } | ||||
|  | ||||
| .category_item { | ||||
|   display: flex; | ||||
|   flex: 1; | ||||
|   margin: 10px, 30px; | ||||
| } | ||||
|  | ||||
| .category_icon { | ||||
|   margin-left: 15px; | ||||
|   margin-top: 10px; | ||||
|   width: 30px; | ||||
|   height: 30px; | ||||
|   background: linear-gradient(135deg, rgba(29, 214, 255, 0.1) 0%, rgba(10, 120, 200, 0.1) 100%); | ||||
|   border: 1px solid rgba(29, 214, 255, 0.2); | ||||
|   border-radius: 5px; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   flex-shrink: 0; | ||||
| } | ||||
|  | ||||
| .category_image { | ||||
|   width: 45px; | ||||
|   height: 45px; | ||||
|   object-fit: contain; | ||||
| } | ||||
|  | ||||
| .category_info { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   margin-left: 8px; | ||||
|   margin-top: 8px; | ||||
|   flex: 1; | ||||
| } | ||||
|  | ||||
| .category_label { | ||||
|   font-size: 12px; | ||||
|   color: #8ab2ff; | ||||
|   margin-bottom: 1px; | ||||
| } | ||||
|  | ||||
| .category_count { | ||||
|   font-size: 16px; | ||||
|   font-weight: bold; | ||||
|   color: #e6f7ff; | ||||
|   text-shadow: 0px 1.24px 6.21px rgba(0, 190, 247, 0.3); | ||||
| } | ||||
| </style> | ||||
|  | ||||
| @ -75,7 +75,7 @@ export let barOption = { | ||||
|     itemWidth: 12, | ||||
|     itemHeight: 12, | ||||
|     // 调整文字与图标间距 | ||||
|     data: ['计划产值', '实际产值'], | ||||
|     data: ['实际进度', '计划进度'], | ||||
|     top: 0, | ||||
|     right: 10, | ||||
|     bottom: 10, | ||||
| @ -90,11 +90,17 @@ export let barOption = { | ||||
|     trigger: 'axis', | ||||
|     // formatter: '{b0}:{c0}万元', | ||||
|     formatter: (params: any) => { | ||||
|       console.log(params); | ||||
|       const projectName = params[0].name; | ||||
|       // params 是数组,对应每条柱子 | ||||
|       return params | ||||
|         .map((p: any) => `${p.seriesName}:${Number(p.value).toFixed(2)} 亿元`) | ||||
|  | ||||
|         .join('<br/>'); | ||||
|       // return params.map((p: any) => `${p.name} <br/>  ${p.seriesName}:${Number(p.value).toFixed(2)} MW`).join('<br/>'); | ||||
|       return ( | ||||
|         `${projectName}<br/>` + | ||||
|         params | ||||
|           .slice(0, 2) | ||||
|           .map((p) => `${p.seriesName}:${Number(p.value).toFixed(2)} MW`) | ||||
|           .join('<br/>') | ||||
|       ); | ||||
|     }, | ||||
|     textStyle: { | ||||
|       color: '#fff' | ||||
| @ -119,7 +125,7 @@ export let barOption = { | ||||
|     } | ||||
|   }, | ||||
|   yAxis: { | ||||
|     name: '单位:亿元', | ||||
|     name: 'MW', | ||||
|     type: 'value', | ||||
|     axisLabel: { | ||||
|       formatter: '{value}' | ||||
| @ -136,7 +142,7 @@ export let barOption = { | ||||
|   }, | ||||
|   series: [ | ||||
|     { | ||||
|       name: '计划产值', | ||||
|       name: '实际进度', | ||||
|       type: 'bar', | ||||
|       data: [], | ||||
|       barWidth: '10', | ||||
| @ -161,7 +167,7 @@ export let barOption = { | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       name: '实际产值', | ||||
|       name: '计划进度', | ||||
|       type: 'bar', | ||||
|       data: [], | ||||
|       barWidth: '10', | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <div class="leftPage"> | ||||
|     <div class="topPage"> | ||||
|       <Title title="项目进度分析" /> | ||||
|       <Title title="项目进度分析" style="font-size: 22px" /> | ||||
|       <div class="progress"> | ||||
|         <div class="progress_item"> | ||||
|           <div class="progress_imgBox"> | ||||
| @ -53,7 +53,7 @@ | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="output"> | ||||
|       <Title title="实际产值与预期产值对比" /> | ||||
|       <Title title="实际进度与计划进度对比" style="font-size: 22px" /> | ||||
|       <div class="chart_container"> | ||||
|         <div ref="lineChartRef" class="echart" /> | ||||
|       </div> | ||||
| @ -155,8 +155,8 @@ const initPieChart = () => { | ||||
| const getOutputData = async () => { | ||||
|   const res = await outpuProgress(); | ||||
|   if (res.code == 200) { | ||||
|     designAreaData.value = res.data.map((item: any) => Number(item.planValue)); | ||||
|     transferAreaData.value = res.data.map((item: any) => Number(item.actualValue)); | ||||
|     designAreaData.value = res.data.map((item: any) => Number(item.plannedCapacity * item.progressPercentage)); | ||||
|     transferAreaData.value = res.data.map((item: any) => Number(item.plannedCapacity)); | ||||
|     barNames.value = res.data.map((item: any) => item.projectName); | ||||
|     initLineChart(); | ||||
|   } | ||||
|  | ||||
| @ -71,15 +71,17 @@ let data = [ | ||||
| const getTrajectoryData = async () => { | ||||
|   try { | ||||
|     // 从URL参数中获取clientId、projectId和userId | ||||
|     const { clientId, projectId, userId } = route.query; | ||||
|     const { clientId, projectId, userId, gpsType } = route.query; | ||||
|  | ||||
|     if (!clientId || !projectId || !userId) { | ||||
|     if (!projectId || !userId || !gpsType) { | ||||
|       ElMessage.warning('缺少必要参数,请检查传入的参数'); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     loading.value = true; | ||||
|     const res = await getFootNote({ clientId, projectId, userId }); | ||||
|     // 确保gpsType转换为数字类型,以便正确传递给后端 | ||||
|     const gpsTypeNum = parseInt(gpsType, 10); | ||||
|     const res = await getFootNote({ clientId, projectId, userId, gpsType: gpsTypeNum }); | ||||
|  | ||||
|     if (res && res.code === 200 && res.data && res.data.length > 0) { | ||||
|       data = res.data; | ||||
|  | ||||
| @ -22,7 +22,7 @@ | ||||
|  | ||||
|     <el-card shadow="never"> | ||||
|       <template #header> | ||||
|         <el-row :gutter="10" class="mb8"> | ||||
|         <el-row :gutter="20" class="mb8"> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['gps:equipment:edit']" | ||||
|               >修改</el-button | ||||
| @ -39,7 +39,12 @@ | ||||
|             > | ||||
|           </el-col> | ||||
|           <el-col :span="2"> | ||||
|             <el-button type="primary" plain @click="handleViewAll">{{ viewAllButtonText }}</el-button> | ||||
|             <el-button type="primary" plain @click="toggleGpsType"> | ||||
|               {{ currentGpsType === 0 ? '显示用户数据' : '显示设备数据' }} | ||||
|             </el-button> | ||||
|           </el-col> | ||||
|           <el-col :span="2"> | ||||
|             <el-button type="primary" v-if="queryParams.gpsType !== 1" plain @click="handleViewAll">{{ viewAllButtonText }}</el-button> | ||||
|           </el-col> | ||||
|  | ||||
|           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> | ||||
| @ -102,7 +107,7 @@ | ||||
|                 type="primary" | ||||
|                 icon="Location" | ||||
|                 v-hasPermi="['gps:equipmentSon:getList']" | ||||
|                 @click="handleGoToEmptyPage(scope.row.userId, scope.row.projectId, scope.row.clientId)" | ||||
|                 @click="handleGoToEmptyPage(scope.row.userId, scope.row.projectId, scope.row.clientId, scope.row.gpsType)" | ||||
|                 :disabled="!scope.row.userId || !scope.row.projectId" | ||||
|               ></el-button> | ||||
|             </el-tooltip> | ||||
| @ -189,7 +194,7 @@ | ||||
|                   type="primary" | ||||
|                   icon="Location" | ||||
|                   v-hasPermi="['gps:equipmentSon:getList']" | ||||
|                   @click="handleGoToEmptyPage(scope.row.userId, scope.row.projectId, currentHistoryClientId)" | ||||
|                   @click="handleGoToEmptyPage(scope.row.userId, scope.row.projectId, currentHistoryClientId, currentGpsType)" | ||||
|                 ></el-button> | ||||
|               </el-tooltip> | ||||
|             </template> | ||||
| @ -301,6 +306,9 @@ const initFormData: EquipmentForm = { | ||||
|   remark: undefined | ||||
| }; | ||||
|  | ||||
| // 当前GPS类型 (0:设备数据, 1:用户数据) | ||||
| const currentGpsType = ref(0); | ||||
|  | ||||
| // 页面数据 | ||||
| const data = reactive<PageData<EquipmentForm, EquipmentQuery>>({ | ||||
|   form: { ...initFormData }, | ||||
| @ -317,6 +325,7 @@ const data = reactive<PageData<EquipmentForm, EquipmentQuery>>({ | ||||
|     creationTime: undefined, | ||||
|     lastAccessedTime: undefined, | ||||
|     registered: undefined, | ||||
|     gpsType: 0, // 默认显示设备数据 | ||||
|     params: {} | ||||
|   }, | ||||
|   rules: { | ||||
| @ -385,6 +394,15 @@ const formatDateTime = (timestamp: any): string => { | ||||
|   return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | ||||
| }; | ||||
|  | ||||
| /** 切换GPS数据类型 */ | ||||
| const toggleGpsType = () => { | ||||
|   currentGpsType.value = currentGpsType.value === 0 ? 1 : 0; | ||||
|   queryParams.value.gpsType = currentGpsType.value; | ||||
|   queryParams.value.pageNum = 1; | ||||
|   getList(); | ||||
|   proxy?.$modal.msgSuccess(`已切换到${currentGpsType.value === 0 ? '设备数据' : '用户数据'}模式`); | ||||
| }; | ||||
|  | ||||
| /** 获取设备列表 */ | ||||
| const getList = async () => { | ||||
|   loading.value = true; | ||||
| @ -397,6 +415,9 @@ const getList = async () => { | ||||
|       queryParams.value.projectId = undefined; | ||||
|     } | ||||
|  | ||||
|     // 确保gpsType参数正确设置 | ||||
|     queryParams.value.gpsType = currentGpsType.value; | ||||
|  | ||||
|     const res = await listEquipment(queryParams.value); | ||||
|     equipmentList.value = res.rows as ExtendedEquipmentVO[]; | ||||
|     total.value = res.total; | ||||
| @ -490,16 +511,24 @@ const handleViewAll = () => { | ||||
|   getList(); | ||||
| }; | ||||
|  | ||||
| const handleGoToEmptyPage = (userId: any, projectId: any, clientId: any) => { | ||||
|   console.log('userId:', userId, 'projectId:', projectId, 'clientId:', clientId); | ||||
| const handleGoToEmptyPage = (userId: any, projectId: any, clientId: any, gpsType: number) => { | ||||
|   console.log('userId:', userId, 'projectId:', projectId, 'clientId:', clientId, 'gpsType:', gpsType); | ||||
|  | ||||
|   const queryParams: any = { | ||||
|     userId: userId, | ||||
|     projectId: projectId, | ||||
|     gpsType: gpsType, | ||||
|     clientId: clientId | ||||
|   }; | ||||
|  | ||||
|   // 当gpsType为0时传入clientId,为1时不传入 | ||||
|   if (gpsType === 1 && clientId) { | ||||
|     queryParams.clientId = ''; | ||||
|   } | ||||
|  | ||||
|   router.push({ | ||||
|     path: './equipmentGPS', | ||||
|     query: { | ||||
|       userId: userId, | ||||
|       projectId: projectId, | ||||
|       clientId: clientId | ||||
|     } | ||||
|     query: queryParams | ||||
|   }); | ||||
| }; | ||||
|  | ||||
|  | ||||
| @ -82,18 +82,11 @@ | ||||
|         </el-row> | ||||
|       </template> | ||||
|  | ||||
|       <el-table | ||||
|         v-loading="loading" | ||||
|         :table-layout="'auto'" | ||||
|         :data="formalitiesAreConsolidatedList" | ||||
|         @selection-change="handleSelectionChange" | ||||
|         row-key="id" | ||||
|         default-expand-all | ||||
|       > | ||||
|       <el-table v-loading="loading" :data="formalitiesAreConsolidatedList" @selection-change="handleSelectionChange" row-key="id" default-expand-all> | ||||
|         <el-table-column type="selection" width="55" align="center" /> | ||||
|         <el-table-column label="手续办理清单" align="left" prop="formalitiesName"> | ||||
|           <template #default="scope"> | ||||
|             {{ scope.row.formalitiesName }} | ||||
|             <div>{{ scope.row.formalitiesName }}</div> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="计划开始时间" align="center" prop="planTheStartTime" width="180"> | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <template> | ||||
|   <div class="ol-map" id="olMap"></div> | ||||
|   <div class="left_title_button"> | ||||
|     <div class="title">{{ projectName }}</div> | ||||
|     <div class="title">{{ currentProject.name }}</div> | ||||
|     <div class="btn" @click="updateZhiJiaZhuanDian('zhuangdian')"> | ||||
|       <SvgIcon :name="bottomSvg" :isStyle="true" :className="'width:250px;height:50px;'" /> | ||||
|       <span>桩点-更新高程</span> | ||||
| @ -29,6 +29,11 @@ | ||||
| import { workScheduleDel } from '@/api/progress/plan'; | ||||
| import { renderFacilitiesToCesium } from '@/views/gisHome/js/renderFacilities'; | ||||
| import { CenterHeight } from '@/views/gis2D/js/center'; | ||||
| import { useUserStoreHook } from '@/store/modules/user'; | ||||
| const userStore = useUserStoreHook(); | ||||
| const currentProject = computed(() => userStore.selectedProject); | ||||
| console.log('projectName', currentProject); | ||||
|  | ||||
| import md5 from 'js-md5'; | ||||
| const arr = ref(); | ||||
| const initFacilities = async () => { | ||||
| @ -129,8 +134,10 @@ onMounted(async () => { | ||||
|     username: 'admin', | ||||
|     password: md5('admin_admin123'), | ||||
|     host: 'http://192.168.110.2:8895/' | ||||
|   }).then((res) => { | ||||
|     createEarth(); | ||||
|     console.log(res); | ||||
|   }); | ||||
|   createEarth(); | ||||
|   await handletilList(); | ||||
|   await initFacilities(); | ||||
|   console.log(YJ); | ||||
|  | ||||
| @ -9,7 +9,7 @@ | ||||
|         <!-- 合同利润:保持万元显示 --> | ||||
|         <RevenueContractCard title="合同利润" :value="formatToTenThousand(data.profitAmount, 'tenThousand')" /> | ||||
|         <!-- 工程变更:改为百分比显示 --> | ||||
|         <RevenueContractCard title="工程变更" :value="formatToTenThousand(data.changeAmount, 'percentage')" unit="" /> | ||||
|         <!-- <RevenueContractCard title="工程变更" :value="formatToTenThousand(data.changeAmount, 'percentage')" unit="" /> --> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="centerPage_map"> | ||||
|  | ||||
| @ -25,7 +25,7 @@ | ||||
|               class="weather-item" | ||||
|               :style="{ transform: `translateY(-${offsetY}px)`, transition: transition }" | ||||
|             > | ||||
|               <img :src="`../../../src/assets/images/${item.icon}.png`" alt="" /> | ||||
|               <img :src="`/assets/demo/${item.icon}.png`" alt="" /> | ||||
|               <div>{{ item.weather }}{{ item.tempMin }}°/{{ item.tempMax }}°</div> | ||||
|               <div>{{ item.week }}({{ item.date }})</div> | ||||
|             </div> | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| ID<template> | ||||
| <template> | ||||
|   <div class="large-screen"> | ||||
|     <Header /> | ||||
|     <div class="nav"> | ||||
| @ -21,7 +21,6 @@ import leftPage from './components/leftPage.vue'; | ||||
| import centerPage from './components/centerPage.vue'; | ||||
| import rightPage from './components/rightPage.vue'; | ||||
| // import '@/assets/styles/element.scss'; | ||||
|  | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
|  | ||||
| @ -3,13 +3,19 @@ | ||||
|     <div class="max-w-4xl mx-auto"> | ||||
|       <!-- 顶部按钮区域 --> | ||||
|       <el-card class="mb-4 rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md"> | ||||
|         <approvalButton @submitForm="submitForm" @approvalVerifyOpen="approvalVerifyOpen" | ||||
|           @handleApprovalRecord="handleApprovalRecord" :buttonLoading="buttonLoading" :id="form.mrpBaseBo.id" | ||||
|           :status="form.mrpBaseBo.status" :pageType="routeParams.type" /> | ||||
|         <approvalButton | ||||
|           @submitForm="submitForm" | ||||
|           @approvalVerifyOpen="approvalVerifyOpen" | ||||
|           @handleApprovalRecord="handleApprovalRecord" | ||||
|           :buttonLoading="buttonLoading" | ||||
|           :id="form.mrpBaseBo.id" | ||||
|           :status="form.mrpBaseBo.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|       <el-card | ||||
|         class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden"> | ||||
|       <el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden"> | ||||
|         <div class="p-4 bg-gradient-to-r from-blue-50 to-indigo-50 border-b border-gray-100"> | ||||
|           <h3 class="text-lg font-semibold text-gray-800">物资设备批次需求计划</h3> | ||||
|           <el-row :gutter="20"> | ||||
| @ -20,8 +26,7 @@ | ||||
|             </el-col> | ||||
|             <el-col :span="8" :offset="0"> | ||||
|               <el-form-item label="编制日期" prop="mrpBaseBo.preparedDate"> | ||||
|                 <el-date-picker v-model="form.mrpBaseBo.preparedDate" type="date" value-format="YYYY-MM-DD" disabled | ||||
|                   placeholder="请选择编制日期" /> | ||||
|                 <el-date-picker v-model="form.mrpBaseBo.preparedDate" type="date" value-format="YYYY-MM-DD" disabled placeholder="请选择编制日期" /> | ||||
|               </el-form-item> | ||||
|             </el-col> | ||||
|             <el-col :span="8" :offset="0"> | ||||
| @ -50,8 +55,14 @@ | ||||
|       <submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" /> | ||||
|       <approvalRecord ref="approvalRecordRef"></approvalRecord> | ||||
|       <!-- 流程选择对话框 --> | ||||
|       <el-dialog draggable v-model="dialogVisible.visible" :title="dialogVisible.title" :before-close="handleClose" | ||||
|         width="500" class="rounded-lg shadow-lg"> | ||||
|       <el-dialog | ||||
|         draggable | ||||
|         v-model="dialogVisible.visible" | ||||
|         :title="dialogVisible.title" | ||||
|         :before-close="handleClose" | ||||
|         width="500" | ||||
|         class="rounded-lg shadow-lg" | ||||
|       > | ||||
|         <div class="p-4"> | ||||
|           <p class="text-gray-600 mb-4">请选择要启动的流程:</p> | ||||
|           <el-select v-model="flowCode" placeholder="请选择流程" style="width: 100%"> | ||||
| @ -60,10 +71,12 @@ | ||||
|         </div> | ||||
|         <template #footer> | ||||
|           <div class="dialog-footer p-4 border-t border-gray-100 flex justify-end space-x-3"> | ||||
|             <el-button @click="handleClose" | ||||
|               class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">取消</el-button> | ||||
|             <el-button type="primary" @click="submitFlow()" | ||||
|               class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors">确认</el-button> | ||||
|             <el-button @click="handleClose" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors" | ||||
|               >取消</el-button | ||||
|             > | ||||
|             <el-button type="primary" @click="submitFlow()" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors" | ||||
|               >确认</el-button | ||||
|             > | ||||
|           </div> | ||||
|         </template> | ||||
|       </el-dialog> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.approvalDesign" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -8,27 +8,35 @@ | ||||
|           <span>{{ scope.row.residue }}</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="出库数量" align="center" prop="number"> | ||||
|       <el-table-column label="出库数量" align="center" prop="number" width="150px"> | ||||
|         <template #default="scope"> | ||||
|           <el-input-number v-if="scope.row.type" v-model="scope.row.number" :controls="false" :min="0" :max="scope.row.residue" :precision="0" /> | ||||
|           <el-input-number | ||||
|             v-if="scope.row.type" | ||||
|             v-model="scope.row.number" | ||||
|             :controls="false" | ||||
|             :min="0" | ||||
|             :max="scope.row.residue" | ||||
|             :precision="0" | ||||
|             style="width: 100px" | ||||
|           /> | ||||
|           <span v-else>{{ scope.row.number }}</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="交接单位" align="center" prop="recipient"> | ||||
|       <el-table-column label="交接单位" align="center" prop="recipient" width="150px"> | ||||
|         <template #default="scope"> | ||||
|           <el-input v-if="scope.row.type" style="width: 150px" v-model="scope.row.recipient" /> | ||||
|           <el-input v-if="scope.row.type" v-model="scope.row.recipient" width="100px" /> | ||||
|           <span v-else>{{ scope.row.recipient }}</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="领用人" align="center" prop=" shipper"> | ||||
|       <el-table-column label="领用人" align="center" prop=" shipper" width="150px"> | ||||
|         <template #default="scope"> | ||||
|           <el-input v-if="scope.row.type" style="width: 150px" v-model="scope.row.shipper" /> | ||||
|           <el-input v-if="scope.row.type" v-model="scope.row.shipper" width="100px" /> | ||||
|           <span v-else>{{ scope.row.shipper }}</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="操作人" align="center" prop="operator"> | ||||
|       <el-table-column label="操作人" align="center" prop="operator" width="150px"> | ||||
|         <template #default="scope"> | ||||
|           <el-input v-if="scope.row.type" style="width: 150px" v-model="scope.row.operator" /> | ||||
|           <el-input v-if="scope.row.type" v-model="scope.row.operator" width="100px" /> | ||||
|           <span v-else>{{ scope.row.operator }}</span> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|  | ||||
| @ -70,6 +70,13 @@ | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="备注" align="center" prop="remark" /> | ||||
|         <el-table-column label="附件" align="center" prop="attachmentName"> | ||||
|           <template #default="scope"> | ||||
|             <el-button :href="scope.row.attachmentName" link type="primary" @click="downloadAttachment(scope.row)">{{ | ||||
|               scope.row.attachmentName | ||||
|             }}</el-button> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="操作" align="center" min-width="120" fixed="right"> | ||||
|           <template #default="scope"> | ||||
|             <!-- <el-button link type="primary" icon="edit" @click="handleUpdate(scope.row)" v-hasPermi="['materials:materialReceive:edit']" | ||||
| @ -254,6 +261,11 @@ | ||||
|               <file-upload :isShowTip="false" :fileType="['pdf', 'png', 'jpg', 'jpeg']" v-model="form.licenseCountFileId" /> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="附件" prop="attachmentId"> | ||||
|               <file-upload :isShowTip="false" :fileType="['pdf', 'png', 'jpg', 'jpeg', 'zip']" v-model="form.attachmentId" /> | ||||
|             </el-form-item> | ||||
|           </el-col> | ||||
|           <el-col :span="24"> | ||||
|             <span style="color: #ff0000ab; margin-bottom: 10px; display: block">注意:pdf/png/jpg/jpeg格式文件</span> | ||||
|           </el-col> | ||||
| @ -351,6 +363,7 @@ const getInitFormData = (): MaterialReceiveForm => { | ||||
|     techDocCountFileId: undefined, | ||||
|     licenseCount: undefined, | ||||
|     licenseCountFileId: undefined, | ||||
|     attachmentId: undefined, | ||||
|     storageType: '1', | ||||
|     remark: undefined, | ||||
|     docId: undefined, | ||||
| @ -538,6 +551,17 @@ const handleUpdate = async (row?: MaterialReceiveVO) => { | ||||
|     proxy?.$modal.msgError('获取详情失败'); | ||||
|   } | ||||
| }; | ||||
| //下载附件 | ||||
| const downloadAttachment = (row: any) => { | ||||
|   if (row.attachmentUrl) { | ||||
|     const link = document.createElement('a'); | ||||
|     link.href = row.attachmentUrl; | ||||
|     link.download = row.fileName || 'download'; | ||||
|     document.body.appendChild(link); | ||||
|     link.click(); | ||||
|     document.body.removeChild(link); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** 提交按钮 */ | ||||
| const submitForm = () => { | ||||
|  | ||||
| @ -3,7 +3,25 @@ | ||||
|     <el-row :gutter="10" class="mb8"> | ||||
|       <el-col :span="5"> | ||||
|         <el-card shadow="never"> | ||||
|           <el-tree style="max-width: 600px" :data="TreeData" :props="defaultProps" @node-click="handleNodeClick" /> | ||||
|           <!-- <el-tree style="max-width: 600px" :data="TreeData" :props="defaultProps" @node-click="handleNodeClick" /> --> | ||||
|           <el-tree | ||||
|             :data="TreeData" | ||||
|             :props="defaultProps" | ||||
|             @node-click="handleNodeClick" | ||||
|             node-key="id" | ||||
|             default-expand-all | ||||
|             :expand-on-click-node="false" | ||||
|           > | ||||
|             <template #default="{ node, data }"> | ||||
|               <span class="custom-tree-node"> | ||||
|                 <span class="tree-title"> | ||||
|                   <div> | ||||
|                     <div>{{ node.label }}</div> | ||||
|                   </div> | ||||
|                 </span> | ||||
|               </span> | ||||
|             </template> | ||||
|           </el-tree> | ||||
|         </el-card> | ||||
|       </el-col> | ||||
|  | ||||
| @ -473,3 +491,53 @@ onMounted(() => { | ||||
|   getMaterialsListData(); | ||||
| }); | ||||
| </script> | ||||
| <style lang="scss" scoped> | ||||
| .custom-tree-node { | ||||
|   flex: 1; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: space-between; | ||||
|   font-size: 14px; | ||||
|   padding-right: 8px; | ||||
|   height: 40px; /* 固定高度 */ | ||||
| } | ||||
| .tree-title { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
| } | ||||
| :deep(.el-tree) { | ||||
|   font-weight: normal; | ||||
| } | ||||
|  | ||||
| :deep(.el-tree-node) { | ||||
|   margin: 2px 0; | ||||
| } | ||||
|  | ||||
| :deep(.el-tree-node__content) { | ||||
|   height: auto !important; | ||||
|   margin: 2px 0; | ||||
|   border-radius: 4px; | ||||
|   transition: all 0.3s; | ||||
| } | ||||
|  | ||||
| :deep(.el-tree-node__content:hover) { | ||||
|   background-color: #ecf5ff !important; | ||||
| } | ||||
|  | ||||
| /* 为不同层级添加不同的边框颜色 */ | ||||
| :deep(.el-tree-node:focus > .el-tree-node__content) { | ||||
|   background-color: #d9ecff !important; | ||||
| } | ||||
|  | ||||
| :deep(.el-tree-node > .el-tree-node__content) { | ||||
|   border-left: 3px solid #409eff; | ||||
| } | ||||
|  | ||||
| :deep(.el-tree-node .el-tree-node__children .el-tree-node__content) { | ||||
|   border-left: 3px solid #67c23a; | ||||
| } | ||||
|  | ||||
| :deep(.el-tree-node .el-tree-node__children .el-tree-node__children .el-tree-node__content) { | ||||
|   border-left: 3px solid #e6a23c; | ||||
| } | ||||
| </style> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.approvalOrder" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
| @ -319,7 +320,9 @@ onMounted(() => { | ||||
|   .el-input__inner, | ||||
|   .el-select .el-input__inner { | ||||
|     border-radius: 4px; | ||||
|     transition: border-color 0.2s, box-shadow 0.2s; | ||||
|     transition: | ||||
|       border-color 0.2s, | ||||
|       box-shadow 0.2s; | ||||
|  | ||||
|     &:focus { | ||||
|       border-color: var(--primary-light); | ||||
| @ -329,7 +332,9 @@ onMounted(() => { | ||||
|  | ||||
|   .el-textarea__inner { | ||||
|     border-radius: 4px; | ||||
|     transition: border-color 0.2s, box-shadow 0.2s; | ||||
|     transition: | ||||
|       border-color 0.2s, | ||||
|       box-shadow 0.2s; | ||||
|  | ||||
|     &:focus { | ||||
|       border-color: var(--primary-light); | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|  | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.approvalPlan" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
							
								
								
									
										311
									
								
								src/views/mechanism/deviceType/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										311
									
								
								src/views/mechanism/deviceType/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,311 @@ | ||||
| <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="code"> | ||||
|               <el-input v-model="queryParams.code" 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="never"> | ||||
|       <template #header> | ||||
|         <el-row :gutter="10" class="mb8"> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['mechanical:mechanicaltype:add']">新增</el-button> | ||||
|           </el-col> | ||||
|           <!-- <el-col :span="1.5"> | ||||
|             <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['mechanical:mechanicaltype:edit']" | ||||
|               >修改</el-button | ||||
|             > | ||||
|           </el-col> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button | ||||
|               type="danger" | ||||
|               plain | ||||
|               icon="Delete" | ||||
|               :disabled="multiple" | ||||
|               @click="handleDelete()" | ||||
|               v-hasPermi="['mechanical:mechanicaltype:remove']" | ||||
|               >删除</el-button | ||||
|             > | ||||
|           </el-col> --> | ||||
|           <!-- <el-col :span="1.5"> | ||||
|             <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['mechanical:mechanicaltype:export']">导出</el-button> | ||||
|           </el-col> --> | ||||
|           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> | ||||
|         </el-row> | ||||
|       </template> | ||||
|  | ||||
|       <el-table v-loading="loading" :data="mechanicaltypeList"> | ||||
|         <!-- <el-table-column type="selection" width="55" align="center" /> --> | ||||
|         <!-- <el-table-column label="id" align="center" prop="id" v-if="true" /> --> | ||||
|         <el-table-column label="编码" align="center" prop="code" /> | ||||
|         <el-table-column label="父编码" align="center" prop="pcode" /> | ||||
|         <el-table-column label="大" align="center" prop="largeclass" /> | ||||
|         <el-table-column label="中" align="center" prop="middleclass" /> | ||||
|         <el-table-column label="子类" align="center" prop="subclass" /> | ||||
|         <el-table-column label="备注" align="center" prop="remark" /> | ||||
|         <el-table-column label="全名" align="center" prop="fullName" /> | ||||
|         <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||||
|           <template #default="scope"> | ||||
|             <el-tooltip content="修改" placement="top"> | ||||
|               <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['mechanical:mechanicaltype:edit']" | ||||
|                 >修改</el-button | ||||
|               > | ||||
|             </el-tooltip> | ||||
|             <el-tooltip content="删除" placement="top"> | ||||
|               <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['mechanical:mechanicaltype:remove']" | ||||
|                 >删除</el-button | ||||
|               > | ||||
|             </el-tooltip> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
|  | ||||
|       <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> | ||||
|     </el-card> | ||||
|     <!-- 添加或修改设备类型对话框 --> | ||||
|     <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> | ||||
|       <el-form ref="mechanicaltypeFormRef" :model="form" :rules="rules" label-width="80px"> | ||||
|         <el-form-item label="编码" prop="code"> | ||||
|           <el-input v-model="form.code" placeholder="请输入编码" :disabled="form.id ? true : false" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="父编码" prop="pcode"> | ||||
|           <el-input v-model="form.pcode" placeholder="请输入父编码" :disabled="form.id ? true : false" /> | ||||
|         </el-form-item> | ||||
|  | ||||
|         <el-form-item label="类型" prop="deviceType"> | ||||
|           <el-select v-model="form.deviceType" placeholder="选择类型" @change="changeDeviceType" :disabled="form.id ? true : false"> | ||||
|             <el-option v-for="item in devicelist" :key="item.value" :label="item.label" :value="item.value" /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="大类" prop="largeclass" v-if="form.deviceType == '1'"> | ||||
|           <el-input v-model="form.largeclass" placeholder="请输入大类" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="中" prop="middleclass" v-if="form.deviceType == '2'"> | ||||
|           <el-input v-model="form.middleclass" placeholder="请输入中" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="子类" prop="subclass" v-if="form.deviceType == '3'"> | ||||
|           <el-input v-model="form.subclass" placeholder="请输入子类" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="备注" prop="remark"> | ||||
|           <el-input v-model="form.remark" placeholder="请输入备注" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="全名" prop="fullName" v-if="form.deviceType == '3'"> | ||||
|           <el-input v-model="form.fullName" placeholder="请输入全名" /> | ||||
|         </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="Mechanicaltype" lang="ts"> | ||||
| import { listMechanicaltype, getMechanicaltype, delMechanicaltype, addMechanicaltype, updateMechanicaltype } from '@/api/mechanical/mechanicaltype'; | ||||
| import { MechanicaltypeVO, MechanicaltypeQuery, MechanicaltypeForm } from '@/api/mechanical/mechanicaltype/types'; | ||||
|  | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
|  | ||||
| const mechanicaltypeList = ref<MechanicaltypeVO[]>([]); | ||||
| 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 mechanicaltypeFormRef = ref<ElFormInstance>(); | ||||
|  | ||||
| const dialog = reactive<DialogOption>({ | ||||
|   visible: false, | ||||
|   title: '' | ||||
| }); | ||||
| const devicelist = ref([ | ||||
|   { | ||||
|     label: '大', | ||||
|     value: '1' | ||||
|   }, | ||||
|   { | ||||
|     label: '中', | ||||
|     value: '2' | ||||
|   }, | ||||
|   { | ||||
|     label: '子类', | ||||
|     value: '3' | ||||
|   } | ||||
| ]); | ||||
| const initFormData: MechanicaltypeForm = { | ||||
|   id: undefined, | ||||
|   code: undefined, | ||||
|   pcode: undefined, | ||||
|   largeclass: undefined, | ||||
|   middleclass: undefined, | ||||
|   subclass: undefined, | ||||
|   remark: undefined, | ||||
|   fullName: undefined, | ||||
|   deviceType: undefined | ||||
| }; | ||||
| const data = reactive<PageData<MechanicaltypeForm, MechanicaltypeQuery>>({ | ||||
|   form: { ...initFormData }, | ||||
|   queryParams: { | ||||
|     pageNum: 1, | ||||
|     pageSize: 10, | ||||
|     code: undefined, | ||||
|     pcode: undefined, | ||||
|     largeclass: undefined, | ||||
|     middleclass: undefined, | ||||
|     subclass: undefined, | ||||
|     fullName: undefined, | ||||
|     params: {} | ||||
|   }, | ||||
|   rules: { | ||||
|     code: [{ required: true, message: '编码不能为空', trigger: 'blur' }], | ||||
|     pcode: [{ required: true, message: '父编码不能为空', trigger: 'blur' }], | ||||
|     deviceType: [{ required: true, message: '类型不能为空', trigger: 'blur' }], | ||||
|     largeclass: [{ required: true, message: '大不能为空', trigger: 'blur' }], | ||||
|     middleclass: [{ required: true, message: '中不能为空', trigger: 'blur' }], | ||||
|     subclass: [{ required: true, message: '子类不能为空', trigger: 'blur' }], | ||||
|     // remark: [{ required: true, message: '备注不能为空', trigger: 'blur' }], | ||||
|     fullName: [{ required: true, message: '全名不能为空', trigger: 'blur' }] | ||||
|   } | ||||
| }); | ||||
|  | ||||
| const { queryParams, form, rules } = toRefs(data); | ||||
| const changeDeviceType = () => { | ||||
|   if (form.value.deviceType == '1') { | ||||
|     form.value.middleclass = undefined; | ||||
|     form.value.subclass = undefined; | ||||
|     form.value.fullName = undefined; | ||||
|   } else if (form.value.deviceType == '2') { | ||||
|     form.value.largeclass = undefined; | ||||
|     form.value.subclass = undefined; | ||||
|     form.value.fullName = undefined; | ||||
|   } else if (form.value.deviceType == '3') { | ||||
|     form.value.largeclass = undefined; | ||||
|     form.value.middleclass = undefined; | ||||
|   } | ||||
| }; | ||||
| /** 查询设备类型列表 */ | ||||
| const getList = async () => { | ||||
|   loading.value = true; | ||||
|   const res = await listMechanicaltype(queryParams.value); | ||||
|   mechanicaltypeList.value = res.rows; | ||||
|   total.value = res.total; | ||||
|   loading.value = false; | ||||
| }; | ||||
|  | ||||
| /** 取消按钮 */ | ||||
| const cancel = () => { | ||||
|   reset(); | ||||
|   dialog.visible = false; | ||||
| }; | ||||
|  | ||||
| /** 表单重置 */ | ||||
| const reset = () => { | ||||
|   form.value = { ...initFormData }; | ||||
|   mechanicaltypeFormRef.value?.resetFields(); | ||||
| }; | ||||
|  | ||||
| /** 搜索按钮操作 */ | ||||
| const handleQuery = () => { | ||||
|   queryParams.value.pageNum = 1; | ||||
|   getList(); | ||||
| }; | ||||
|  | ||||
| /** 重置按钮操作 */ | ||||
| const resetQuery = () => { | ||||
|   queryFormRef.value?.resetFields(); | ||||
|   handleQuery(); | ||||
| }; | ||||
|  | ||||
| /** 多选框选中数据 */ | ||||
| const handleSelectionChange = (selection: MechanicaltypeVO[]) => { | ||||
|   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?: MechanicaltypeVO) => { | ||||
|   reset(); | ||||
|   const _id = row?.id || ids.value[0]; | ||||
|   const res = await getMechanicaltype(_id); | ||||
|   console.log(res); | ||||
|   if (res.data.subclass) { | ||||
|     res.data.deviceType = '3'; | ||||
|   } | ||||
|   if (res.data.middleclass) { | ||||
|     res.data.deviceType = '2'; | ||||
|   } | ||||
|   if (res.data.largeclass) { | ||||
|     res.data.deviceType = '1'; | ||||
|   } | ||||
|   Object.assign(form.value, res.data); | ||||
|   dialog.visible = true; | ||||
|   dialog.title = '修改设备类型'; | ||||
| }; | ||||
|  | ||||
| /** 提交按钮 */ | ||||
| const submitForm = () => { | ||||
|   mechanicaltypeFormRef.value?.validate(async (valid: boolean) => { | ||||
|     if (valid) { | ||||
|       buttonLoading.value = true; | ||||
|       if (form.value.id) { | ||||
|         await updateMechanicaltype(form.value).finally(() => (buttonLoading.value = false)); | ||||
|       } else { | ||||
|         await addMechanicaltype(form.value).finally(() => (buttonLoading.value = false)); | ||||
|       } | ||||
|       proxy?.$modal.msgSuccess('操作成功'); | ||||
|       dialog.visible = false; | ||||
|       await getList(); | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** 删除按钮操作 */ | ||||
| const handleDelete = async (row?: MechanicaltypeVO) => { | ||||
|   const _ids = row?.id || ids.value; | ||||
|   await proxy?.$modal.confirm('是否确认删除设备类型编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false)); | ||||
|   await delMechanicaltype(_ids); | ||||
|   proxy?.$modal.msgSuccess('删除成功'); | ||||
|   await getList(); | ||||
| }; | ||||
|  | ||||
| /** 导出按钮操作 */ | ||||
| const handleExport = () => { | ||||
|   proxy?.download( | ||||
|     'mechanical/mechanicaltype/export', | ||||
|     { | ||||
|       ...queryParams.value | ||||
|     }, | ||||
|     `mechanicaltype_${new Date().getTime()}.xlsx` | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| onMounted(() => { | ||||
|   getList(); | ||||
| }); | ||||
| </script> | ||||
							
								
								
									
										300
									
								
								src/views/mechanism/ledger/components/add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								src/views/mechanism/ledger/components/add.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,300 @@ | ||||
| <template> | ||||
|   <!-- 添加或修改机械台账对话框 --> | ||||
|   <el-dialog :title="dialog.title" v-model="dialog.visible" width="50%" append-to-body> | ||||
|     <el-form ref="mechanicalrewritingFormRef" :model="form" :rules="rules" label-width="120px"> | ||||
|       <el-row> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="设备名称" prop="devicename"> | ||||
|             <el-input v-model="form.devicename" placeholder="请输入设备名称" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|       <el-row> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="设备类型" prop="equipmentType"> | ||||
|             <!-- <el-cascader v-model="form.deviceType" :options="options" @change="handleChange" /> --> | ||||
|             <el-cascader | ||||
|               placeholder="请选择设备类型" | ||||
|               :emitPath="false" | ||||
|               filterable | ||||
|               v-model="form.equipmentType" | ||||
|               :options="options" | ||||
|               :props="propsConfig" | ||||
|               @change="handleChange" | ||||
|               style="width: 300px" | ||||
|             /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="设备编号" prop="deviceNumber"> | ||||
|             <el-input v-model="form.deviceNumber" placeholder="请输入设备编号" disabled /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|       <el-row> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="班组名称" prop="teamName"> | ||||
|             <el-input v-model="form.teamName" placeholder="请输入班组名称" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="入场日期" prop="entryTime"> | ||||
|             <el-date-picker clearable v-model="form.entryTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择入场日期"> </el-date-picker> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|       <el-row> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="规格型号" prop="specification"> | ||||
|             <el-input v-model="form.specification" placeholder="请输入规格型号" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="生产能力" prop="production"> | ||||
|             <el-input v-model="form.production" placeholder="请输入生产能力" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|       <el-row> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="车牌号码" prop="plateNumber"> | ||||
|             <el-input v-model="form.plateNumber" placeholder="请输入车牌号码" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="设备管理员" prop="deviceKeeper"> | ||||
|             <el-input v-model="form.deviceKeeper" placeholder="请输入设备管理员" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|       <el-row> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="车辆行驶证" prop="drivingLicence"> | ||||
|             <el-input v-model="form.drivingLicence" placeholder="请输入车辆行驶证" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="新旧程度" prop="degree"> | ||||
|             <el-input v-model="form.degree" placeholder="请输入新旧程度" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|       <el-row> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="车辆容量" prop="vehicleCapacity"> | ||||
|             <el-input v-model="form.vehicleCapacity" placeholder="请输入车辆容量" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="车辆净重" prop="suttle"> | ||||
|             <el-input v-model="form.suttle" placeholder="请输入车辆净重" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|       <el-row> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="铭牌" prop="nameplateId"> | ||||
|             <image-upload v-model="form.nameplateId" :limit="1" :is-show-tip="false" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="合格证书" prop="qualificationId"> | ||||
|             <image-upload v-model="form.qualificationId" :limit="1" :is-show-tip="false" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|       <el-row> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="设备照片" prop="equipmentPhotoId"> | ||||
|             <image-upload v-model="form.equipmentPhotoId" :limit="1" :is-show-tip="false" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="检验报告" prop="verificationReportId"> | ||||
|             <image-upload v-model="form.verificationReportId" :limit="1" :is-show-tip="false" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|       <el-row> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="备注" prop="remark"> | ||||
|             <el-input v-model="form.remark" type="textarea" 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> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { getType, addMechanicalrewriting, getMechanicalrewriting, updateMechanicalrewriting } from '@/api/mechanical/mechanicalrewriting'; | ||||
| import { useUserStoreHook } from '@/store/modules/user'; | ||||
|  | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
| const dialog = reactive<DialogOption>({ | ||||
|   visible: false, | ||||
|   title: '添加机械台账' | ||||
| }); | ||||
| const form: any = ref({ | ||||
|   id: undefined, | ||||
|   projectId: undefined, | ||||
|   teamName: undefined, | ||||
|   devicename: undefined, | ||||
|   deviceType: undefined, | ||||
|   equipmentType: undefined, | ||||
|   deviceNumber: undefined, | ||||
|   entryTime: undefined, | ||||
|   specification: undefined, | ||||
|   production: undefined, | ||||
|   plateNumber: undefined, | ||||
|   deviceKeeper: undefined, | ||||
|   drivingLicence: undefined, | ||||
|   degree: undefined, | ||||
|   vehicleCapacity: undefined, | ||||
|   suttle: undefined, | ||||
|   nameplateId: undefined, | ||||
|   qualificationId: undefined, | ||||
|   equipmentPhotoId: undefined, | ||||
|   verificationReportId: undefined, | ||||
|   remark: undefined | ||||
| }); | ||||
| const rules = ref({ | ||||
|   devicename: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }], | ||||
|   equipmentType: [{ required: true, message: '设备类型不能为空', trigger: 'blur' }], | ||||
|   deviceNumber: [{ required: true, message: '设备编号不能为空', trigger: 'blur' }], | ||||
|   entryTime: [{ required: true, message: '入场时间不能为空', trigger: 'blur' }], | ||||
|   specification: [{ required: true, message: '规格不能为空', trigger: 'blur' }], | ||||
|   production: [{ required: true, message: '生产能力不能为空', trigger: 'blur' }], | ||||
|   teamName: [{ required: true, message: '班组名称不能为空', trigger: 'blur' }], | ||||
|   degree: [{ required: true, message: '新旧程度不能为空', trigger: 'blur' }], | ||||
|   nameplateId: [{ required: true, message: '铭牌不能为空', trigger: 'blur' }], | ||||
|   qualificationId: [{ required: true, message: '合格证书不能为空', trigger: 'blur' }], | ||||
|   equipmentPhotoId: [{ required: true, message: '设备照片不能为空', trigger: 'blur' }] | ||||
| }); | ||||
| const buttonLoading = ref(false); | ||||
| const mechanicalrewritingFormRef = ref(); | ||||
| const propsConfig = { | ||||
|   expandTrigger: 'hover' as const, | ||||
|   value: 'code', | ||||
|   label: 'name', | ||||
|   children: 'children' | ||||
| }; | ||||
| const userStore = useUserStoreHook(); | ||||
| const currentProject = computed(() => userStore.selectedProject); | ||||
| const emit = defineEmits(['success']); | ||||
|  | ||||
| const submitForm = () => { | ||||
|   mechanicalrewritingFormRef.value?.validate(async (valid: boolean) => { | ||||
|     if (valid) { | ||||
|       //   buttonLoading.value = true; | ||||
|       console.log(form.value); | ||||
|       const parmas = { | ||||
|         ...form.value, | ||||
|         projectId: currentProject.value.id | ||||
|       }; | ||||
|       if (form.value.id) { | ||||
|         const res = await updateMechanicalrewriting(parmas); | ||||
|         if (res.code === 200) { | ||||
|           proxy?.$modal.msgSuccess('操作成功'); | ||||
|           dialog.visible = false; | ||||
|           emit('success'); | ||||
|         } | ||||
|       } else { | ||||
|         const res = await addMechanicalrewriting(parmas); | ||||
|         if (res.code === 200) { | ||||
|           proxy?.$modal.msgSuccess('操作成功'); | ||||
|           dialog.visible = false; | ||||
|           emit('success'); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
| /** 取消按钮 */ | ||||
| const cancel = () => { | ||||
|   reset(); | ||||
|   dialog.visible = false; | ||||
| }; | ||||
|  | ||||
| /** 表单重置 */ | ||||
| const reset = () => { | ||||
|   form.value = { | ||||
|     id: undefined, | ||||
|     projectId: undefined, | ||||
|     teamName: undefined, | ||||
|     devicename: undefined, | ||||
|     deviceType: undefined, | ||||
|     deviceNumber: undefined, | ||||
|     entryTime: undefined, | ||||
|     specification: undefined, | ||||
|     production: undefined, | ||||
|     plateNumber: undefined, | ||||
|     deviceKeeper: undefined, | ||||
|     drivingLicence: undefined, | ||||
|     degree: undefined, | ||||
|     vehicleCapacity: undefined, | ||||
|     suttle: undefined, | ||||
|     nameplateId: undefined, | ||||
|     qualificationId: undefined, | ||||
|     equipmentPhotoId: undefined, | ||||
|     verificationReportId: undefined, | ||||
|     equipmentType: undefined, | ||||
|     remark: undefined | ||||
|   }; | ||||
|   mechanicalrewritingFormRef.value?.resetFields(); | ||||
| }; | ||||
| const options: any = ref([]); | ||||
| const open = async (id?: number) => { | ||||
|   const title = id ? '修改机械台账' : '添加机械台账'; | ||||
|   dialog.title = title; | ||||
|   dialog.visible = true; | ||||
|   getTypeList(); | ||||
|   if (id) { | ||||
|     const res = await getMechanicalrewriting(id); | ||||
|     console.log(res); | ||||
|     form.value = res.data; | ||||
|     form.value.equipmentType = res.data.deviceNumber + '_' + res.data.deviceType; | ||||
|     // Object.assign(form.value, res.data); | ||||
|   } | ||||
| }; | ||||
| //获取类型 | ||||
| const getTypeList = async () => { | ||||
|   const res = await getType(); | ||||
|   if (res.code === 200) { | ||||
|     res.data.forEach((element) => { | ||||
|       element.name = element.largeclass; | ||||
|       element.code = element.code + '_' + element.largeclass; | ||||
|       if (element.children && element.children.length) { | ||||
|         element.children.forEach((elements) => { | ||||
|           elements.name = elements.middleclass; | ||||
|           elements.code = elements.code + '_' + elements.middleclass; | ||||
|           if (elements.children && elements.children.length) { | ||||
|             elements.children.forEach((elementss) => { | ||||
|               elementss.code = elementss.code + '_' + elementss.subclass; | ||||
|               elementss.name = elementss.subclass; | ||||
|             }); | ||||
|           } | ||||
|         }); | ||||
|       } | ||||
|     }); | ||||
|     options.value = res.data; | ||||
|     console.log(options.value); | ||||
|   } | ||||
| }; | ||||
| //选择了类型 | ||||
| const handleChange = (val: any) => { | ||||
|   form.value.deviceNumber = val[val.length - 1].split('_')[0]; | ||||
|   form.value.deviceType = val[val.length - 1].split('_')[1]; | ||||
| }; | ||||
| defineExpose({ | ||||
|   open | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style scoped></style> | ||||
							
								
								
									
										0
									
								
								src/views/mechanism/ledger/components/details.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/views/mechanism/ledger/components/details.vue
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										266
									
								
								src/views/mechanism/ledger/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								src/views/mechanism/ledger/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,266 @@ | ||||
| <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> | ||||
|               <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="never"> | ||||
|       <template #header> | ||||
|         <el-row :gutter="10" class="mb8"> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['mechanical:mechanicalrewriting:add']">新增</el-button> | ||||
|           </el-col> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['mechanical:mechanicalrewriting:export']" | ||||
|               >导出</el-button | ||||
|             > | ||||
|           </el-col> | ||||
|           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> | ||||
|         </el-row> | ||||
|       </template> | ||||
|  | ||||
|       <el-table v-loading="loading" :data="mechanicalrewritingList"> | ||||
|         <!-- <el-table-column type="selection" width="55" align="center" /> --> | ||||
|         <!-- <el-table-column label="自增ID" align="center" prop="id" v-if="true" /> | ||||
|         <el-table-column label="项目ID" align="center" prop="projectId" /> --> | ||||
|         <el-table-column label="班组名称" align="center" prop="teamName" /> | ||||
|         <el-table-column label="设备名称" align="center" prop="devicename" /> | ||||
|         <el-table-column label="设备类型" align="center" prop="deviceType" /> | ||||
|         <el-table-column label="设备编号" align="center" prop="deviceNumber" /> | ||||
|         <el-table-column label="入场日期" align="center" prop="entryTime" width="180"> | ||||
|           <template #default="scope"> | ||||
|             <span>{{ parseTime(scope.row.entryTime, '{y}-{m}-{d}') }}</span> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="规格型号" align="center" prop="specification" /> | ||||
|         <el-table-column label="生产能力" align="center" prop="production" /> | ||||
|         <el-table-column label="车牌号码" align="center" prop="plateNumber" /> | ||||
|         <el-table-column label="设备管理员" align="center" prop="deviceKeeper" /> | ||||
|         <el-table-column label="车辆行驶证" align="center" prop="drivingLicence" /> | ||||
|         <el-table-column label="新旧程度" align="center" prop="degree" /> | ||||
|         <el-table-column label="车辆容量" align="center" prop="vehicleCapacity" /> | ||||
|         <el-table-column label="车辆净重" align="center" prop="suttle" /> | ||||
|  | ||||
|         <el-table-column label="备注" align="center" prop="remark" /> | ||||
|         <el-table-column label="操作" align="center" fixed="right" min-width="200" fixed-width> | ||||
|           <template #default="scope"> | ||||
|             <el-tooltip content="修改" placement="top"> | ||||
|               <el-button link type="primary" icon="View" @click="handleUpdate(scope.row)" v-hasPermi="['mechanical:mechanicalrewriting:edit']" | ||||
|                 >详情</el-button | ||||
|               > | ||||
|             </el-tooltip> | ||||
|             <el-tooltip content="修改" placement="top"> | ||||
|               <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['mechanical:mechanicalrewriting:edit']" | ||||
|                 >修改</el-button | ||||
|               > | ||||
|             </el-tooltip> | ||||
|             <el-tooltip content="删除" placement="top"> | ||||
|               <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['mechanical:mechanicalrewriting:remove']" | ||||
|                 >删除</el-button | ||||
|               > | ||||
|             </el-tooltip> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
|  | ||||
|       <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> | ||||
|     </el-card> | ||||
|  | ||||
|     <addComponent ref="addComponentRef" @success="getList" /> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup name="Mechanicalrewriting" lang="ts"> | ||||
| import { | ||||
|   listMechanicalrewriting, | ||||
|   getMechanicalrewriting, | ||||
|   delMechanicalrewriting, | ||||
|   addMechanicalrewriting, | ||||
|   updateMechanicalrewriting | ||||
| } from '@/api/mechanical/mechanicalrewriting'; | ||||
| import { MechanicalrewritingVO, MechanicalrewritingQuery, MechanicalrewritingForm } from '@/api/mechanical/mechanicalrewriting/types'; | ||||
| import addComponent from './components/add.vue'; | ||||
|  | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
|  | ||||
| const mechanicalrewritingList = ref<MechanicalrewritingVO[]>([]); | ||||
| 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 mechanicalrewritingFormRef = ref<ElFormInstance>(); | ||||
|  | ||||
| const dialog = reactive<DialogOption>({ | ||||
|   visible: false, | ||||
|   title: '' | ||||
| }); | ||||
|  | ||||
| const initFormData: MechanicalrewritingForm = { | ||||
|   id: undefined, | ||||
|   projectId: undefined, | ||||
|   teamName: undefined, | ||||
|   devicename: undefined, | ||||
|   deviceType: undefined, | ||||
|   deviceNumber: undefined, | ||||
|   entryTime: undefined, | ||||
|   specification: undefined, | ||||
|   production: undefined, | ||||
|   plateNumber: undefined, | ||||
|   deviceKeeper: undefined, | ||||
|   drivingLicence: undefined, | ||||
|   degree: undefined, | ||||
|   vehicleCapacity: undefined, | ||||
|   suttle: undefined, | ||||
|   nameplate: undefined, | ||||
|   qualification: undefined, | ||||
|   equipmentPhoto: undefined, | ||||
|   verificationReport: undefined, | ||||
|   remark: undefined | ||||
| }; | ||||
| const data = reactive<PageData<MechanicalrewritingForm, MechanicalrewritingQuery>>({ | ||||
|   form: { ...initFormData }, | ||||
|   queryParams: { | ||||
|     pageNum: 1, | ||||
|     pageSize: 10, | ||||
|     projectId: undefined, | ||||
|     teamName: undefined, | ||||
|     devicename: undefined, | ||||
|     deviceType: undefined, | ||||
|     deviceNumber: undefined, | ||||
|     entryTime: undefined, | ||||
|     specification: undefined, | ||||
|     production: undefined, | ||||
|     plateNumber: undefined, | ||||
|     deviceKeeper: undefined, | ||||
|     drivingLicence: undefined, | ||||
|     degree: undefined, | ||||
|     vehicleCapacity: undefined, | ||||
|     suttle: undefined, | ||||
|     nameplate: undefined, | ||||
|     qualification: undefined, | ||||
|     equipmentPhoto: undefined, | ||||
|     verificationReport: undefined, | ||||
|     params: {} | ||||
|   }, | ||||
|   rules: { | ||||
|     id: [{ required: true, message: '自增ID不能为空', trigger: 'blur' }] | ||||
|   } | ||||
| }); | ||||
|  | ||||
| const { queryParams, form, rules } = toRefs(data); | ||||
|  | ||||
| /** 查询机械台账列表 */ | ||||
| const getList = async () => { | ||||
|   loading.value = true; | ||||
|   const res = await listMechanicalrewriting(queryParams.value); | ||||
|   mechanicalrewritingList.value = res.rows; | ||||
|   total.value = res.total; | ||||
|   loading.value = false; | ||||
| }; | ||||
|  | ||||
| /** 取消按钮 */ | ||||
| const cancel = () => { | ||||
|   reset(); | ||||
|   dialog.visible = false; | ||||
| }; | ||||
|  | ||||
| /** 表单重置 */ | ||||
| const reset = () => { | ||||
|   form.value = { ...initFormData }; | ||||
|   mechanicalrewritingFormRef.value?.resetFields(); | ||||
| }; | ||||
|  | ||||
| /** 搜索按钮操作 */ | ||||
| const handleQuery = () => { | ||||
|   queryParams.value.pageNum = 1; | ||||
|   getList(); | ||||
| }; | ||||
|  | ||||
| /** 重置按钮操作 */ | ||||
| const resetQuery = () => { | ||||
|   queryFormRef.value?.resetFields(); | ||||
|   handleQuery(); | ||||
| }; | ||||
|  | ||||
| /** 多选框选中数据 */ | ||||
| const handleSelectionChange = (selection: MechanicalrewritingVO[]) => { | ||||
|   ids.value = selection.map((item) => item.id); | ||||
|   single.value = selection.length != 1; | ||||
|   multiple.value = !selection.length; | ||||
| }; | ||||
| const addComponentRef = ref(); | ||||
| /** 新增按钮操作 */ | ||||
| const handleAdd = () => { | ||||
|   addComponentRef.value?.open(); | ||||
| }; | ||||
|  | ||||
| /** 修改按钮操作 */ | ||||
| const handleUpdate = async (row?: MechanicalrewritingVO) => { | ||||
|   //   reset(); | ||||
|   const _id = row?.id || ids.value[0]; | ||||
|   //   const res = await getMechanicalrewriting(_id); | ||||
|   //   Object.assign(form.value, res.data); | ||||
|   //   dialog.visible = true; | ||||
|   //   dialog.title = '修改机械台账'; | ||||
|   addComponentRef.value?.open(_id); | ||||
| }; | ||||
|  | ||||
| /** 提交按钮 */ | ||||
| const submitForm = () => { | ||||
|   mechanicalrewritingFormRef.value?.validate(async (valid: boolean) => { | ||||
|     if (valid) { | ||||
|       buttonLoading.value = true; | ||||
|       if (form.value.id) { | ||||
|         await updateMechanicalrewriting(form.value).finally(() => (buttonLoading.value = false)); | ||||
|       } else { | ||||
|         await addMechanicalrewriting(form.value).finally(() => (buttonLoading.value = false)); | ||||
|       } | ||||
|       proxy?.$modal.msgSuccess('操作成功'); | ||||
|       dialog.visible = false; | ||||
|       await getList(); | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** 删除按钮操作 */ | ||||
| const handleDelete = async (row?: MechanicalrewritingVO) => { | ||||
|   const _ids = row?.id || ids.value; | ||||
|   await proxy?.$modal.confirm('是否确认删除机械台账编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false)); | ||||
|   await delMechanicalrewriting(_ids); | ||||
|   proxy?.$modal.msgSuccess('删除成功'); | ||||
|   await getList(); | ||||
| }; | ||||
|  | ||||
| /** 导出按钮操作 */ | ||||
| const handleExport = () => { | ||||
|   proxy?.download( | ||||
|     'mechanical/mechanicalrewriting/export', | ||||
|     { | ||||
|       ...queryParams.value | ||||
|     }, | ||||
|     `mechanicalrewriting_${new Date().getTime()}.xlsx` | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| onMounted(() => { | ||||
|   getList(); | ||||
| }); | ||||
| </script> | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.auditStatus" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.completeAuditStatus" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form[0]?.id" | ||||
|           :status="form[0]?.planAuditStatus" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -170,7 +170,7 @@ | ||||
|       </el-form> | ||||
|       <template #footer> | ||||
|         <div class="dialog-footer"> | ||||
|           <el-button type="primary" @click="submitFormMatrix">确 定</el-button> | ||||
|           <el-button type="primary" @click="submitFormMatrix" v-hasPermi="['land:landBlockUnitProject:LandUnit']">确 定</el-button> | ||||
|           <el-button @click="cancelMatrix">取 消</el-button> | ||||
|         </div> | ||||
|       </template> | ||||
|  | ||||
| @ -101,10 +101,10 @@ | ||||
|  | ||||
|         <el-table-column label="操作" align="center" fixed="right" width="200"> | ||||
|           <template #default="scope"> | ||||
|             <!-- 查看子项按钮 --> | ||||
|             <el-tooltip content="查看子项" placement="top"> | ||||
|             <!-- 查看流转台账按钮 --> | ||||
|             <el-tooltip content="查看流转台账" placement="top"> | ||||
|               <el-button link type="primary" @click="handleViewSons(scope.row)" v-hasPermi="['land:landTransferLedger:childrenList']"> | ||||
|                 查看子项 | ||||
|                 查看流转台账 | ||||
|               </el-button> | ||||
|             </el-tooltip> | ||||
|             <el-tooltip content="删除" placement="top"> | ||||
| @ -162,7 +162,7 @@ | ||||
|           <el-row :gutter="10" class="mb8"> | ||||
|             <el-col :span="1.5"> | ||||
|               <el-button type="primary" plain icon="Plus" @click="handleAddSon" v-hasPermi="['land:landTransferLedger:childrenAdd']"> | ||||
|                 新增子项 | ||||
|                 新增流转台账 | ||||
|               </el-button> | ||||
|             </el-col> | ||||
|           </el-row> | ||||
| @ -397,9 +397,7 @@ | ||||
|       </el-form> | ||||
|       <template #footer> | ||||
|         <div class="dialog-footer"> | ||||
|           <el-button v-hasPermi="['land:landTransferLedger:addSon']" :loading="sonButtonLoading" type="primary" @click="submitSonForm" | ||||
|             >确 定</el-button | ||||
|           > | ||||
|           <el-button :loading="sonButtonLoading" type="primary" @click="submitSonForm">确 定</el-button> | ||||
|           <el-button @click="cancelSonForm">取 消</el-button> | ||||
|         </div> | ||||
|       </template> | ||||
| @ -1026,7 +1024,7 @@ const handleAdd = () => { | ||||
|   dialog.visible = true; | ||||
| }; | ||||
|  | ||||
| /** 查看子项按钮操作(打开子项弹窗时) */ | ||||
| /** 新增流转台账按钮操作(打开子项弹窗时) */ | ||||
| const handleViewSons = async (row: LandTransferLedgerVO) => { | ||||
|   if (!row?.id) return; | ||||
|  | ||||
| @ -1093,7 +1091,7 @@ const handleAddSon = async () => { | ||||
|   await getListRoad(); | ||||
|  | ||||
|   // 5. 打开弹窗 | ||||
|   sonFormDialog.title = '添加子项(继承父项数据)'; | ||||
|   sonFormDialog.title = '新增流转台账'; | ||||
|   sonFormDialog.visible = true; | ||||
| }; | ||||
|  | ||||
|  | ||||
| @ -616,6 +616,44 @@ const handleSetChild = async () => { | ||||
|   } | ||||
| }; | ||||
|  | ||||
| const scopeSubmit = () => { | ||||
|   // 提交打卡范围 | ||||
| }; | ||||
| // 添加规则 | ||||
| const handleCheckRules = async (row?: ProjectVO) => { | ||||
|   reset(); | ||||
|   const _id = row?.id || ids.value[0]; | ||||
|   const res = await byProjectIdDetail(_id); | ||||
|   if (res.data) { | ||||
|     console.log(res.data); | ||||
|     res.data.weekday = res.data.weekday.split(','); | ||||
|     Object.assign(form.value, res.data); | ||||
|   } | ||||
|   projectId.value = row.id; | ||||
|   ruleFlag.value = true; | ||||
| }; | ||||
| const ruleSubmit = async () => { | ||||
|   console.log(form.value); | ||||
|   projectFormRef.value?.validate(async (valid: boolean) => { | ||||
|     if (valid) { | ||||
|       let obj = { | ||||
|         weekday: form.value.weekday.join(','), | ||||
|         projectId: projectId.value, | ||||
|         id: form.value.id, | ||||
|         clockInTime: form.value.clockInTime, | ||||
|         clockOutTime: form.value.clockOutTime, | ||||
|         type: form.value.type | ||||
|       }; | ||||
|       if (form.value.id) { | ||||
|         await attendanceRuleEdit(obj); | ||||
|       } else { | ||||
|         await attendanceRuleAdd(obj); | ||||
|       } | ||||
|       ruleFlag.value = false; | ||||
|       await getList(); | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
| /** 导出按钮操作 */ | ||||
| const handleExport = () => { | ||||
|   proxy?.download( | ||||
|  | ||||
| @ -11,8 +11,8 @@ | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="title"> | ||||
|       <div>XXX智慧工地管理平台</div> | ||||
|       <div>XXX Smart Construction Stic Management Dashboard</div> | ||||
|       <div>煤科建管-新能源项目级管理平台</div> | ||||
|       <div>Coal Science Construction Management - New Energy Project Level Management Platform</div> | ||||
|     </div> | ||||
|     <div class="header_right"> | ||||
|       <div class="top-bar"> | ||||
| @ -25,7 +25,7 @@ | ||||
|               class="weather-item" | ||||
|               :style="{ transform: `translateY(-${offsetY}px)`, transition: transition }" | ||||
|             > | ||||
|               <img :src="`../../../src/assets/images/${item.icon}.png`" alt="" /> | ||||
|               <img :src="`/assets/demo/${item.icon}.png`" alt="" /> | ||||
|               <div>{{ item.weather }}{{ item.tempMin }}°/{{ item.tempMax }}°</div> | ||||
|               <div>{{ item.week }}({{ item.date }})</div> | ||||
|             </div> | ||||
|  | ||||
| @ -2,13 +2,18 @@ | ||||
|   <div class="leftPage"> | ||||
|     <div class="topPage"> | ||||
|       <Title title="项目公告" /> | ||||
|       <div class="content"> | ||||
|       <div | ||||
|         class="content" | ||||
|         ref="contentRef" | ||||
|         id="event_scroll" | ||||
|         @mouseenter.native="autoScrollTable(true, false)" | ||||
|         @mouseleave.native="autoScrollTable(false, true)" | ||||
|       > | ||||
|         <div class="content_item" v-for="item in news" :key="item.id"> | ||||
|           <img src="@/assets/projectLarge/round.svg" alt=""> | ||||
|           <img src="@/assets/projectLarge/round.svg" alt="" /> | ||||
|           <div class="ellipsis"> | ||||
|             {{ item.title }} | ||||
|             <span @click="showNewsDetail(item)" style="color: rgba(138, 149, 165, 1);">{{ item.id === newId ? '关闭' : | ||||
|               '查看' }}</span> | ||||
|             <span @click="showNewsDetail(item)" style="color: rgba(138, 149, 165, 1)">{{ item.id === newId ? '关闭' : '查看' }}</span> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
| @ -17,38 +22,41 @@ | ||||
|     <div class="detailBox" :class="{ 'show': newId }"> | ||||
|       <!-- <div class="detail_title">{{ newDetail.title }}</div> --> | ||||
|       <div class="detail_content" v-html="newDetail.content"></div> | ||||
|       <div class="close" @click="newId = ''"> | ||||
|         <CircleClose style="width: 1.2em; height: 1.2em" /> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="endPage"> | ||||
|       <Title title="人员情况" /> | ||||
|       <div class="map"> | ||||
|         <img src="@/assets/projectLarge/map.svg" alt=""> | ||||
|         <img src="@/assets/projectLarge/map.svg" alt="" /> | ||||
|         <!-- <div ref="mapChartRef"></div> --> | ||||
|       </div> | ||||
|  | ||||
|       <div class="attendance_tag"> | ||||
|         <div class="tag_item"> | ||||
|           <img src="@/assets/projectLarge/people.svg" alt=""> | ||||
|           <img src="@/assets/projectLarge/people.svg" alt="" /> | ||||
|           <div class="tag_title">出勤人</div> | ||||
|           <div class="tag_info"> | ||||
|             {{ attendanceCount }} | ||||
|             <span style="font-size: 14px;">人</span> | ||||
|             <span style="font-size: 14px">人</span> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="tag_item"> | ||||
|           <img src="@/assets/projectLarge/people.svg" alt=""> | ||||
|           <img src="@/assets/projectLarge/people.svg" alt="" /> | ||||
|           <div class="tag_title">在岗人</div> | ||||
|           <div class="tag_info"> | ||||
|             {{ peopleCount }} | ||||
|             <span style="font-size: 14px;">人</span> | ||||
|             <span style="font-size: 14px">人</span> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="tag_item"> | ||||
|           <img src="@/assets/projectLarge/people.svg" alt=""> | ||||
|           <img src="@/assets/projectLarge/people.svg" alt="" /> | ||||
|           <div class="tag_title">出勤率</div> | ||||
|           <div class="tag_info"> | ||||
|             {{ attendanceRate }} | ||||
|             <span style="font-size: 14px;">%</span> | ||||
|             <span style="font-size: 14px">%</span> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
| @ -62,8 +70,9 @@ | ||||
|         </div> | ||||
|         <div v-for="item in teamAttendanceList" :key="item.id" class="attendance_item"> | ||||
|           <div class="attendance_item_title">{{ item.teamName }}</div> | ||||
|           <div class="attendance_item_number">{{ item.attendanceNumber }} <span class="subfont">人/{{ item.allNumber | ||||
|               }}</span></div> | ||||
|           <div class="attendance_item_number"> | ||||
|             {{ item.attendanceNumber }} <span class="subfont">人/{{ item.allNumber }}</span> | ||||
|           </div> | ||||
|           <div class="attendance_item_rate">{{ item.attendanceRate }} %</div> | ||||
|           <div class="attendance_item_date subfont">{{ item.attendanceTime }}</div> | ||||
|         </div> | ||||
| @ -73,10 +82,10 @@ | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { ref } from "vue" | ||||
| import Title from './title.vue' | ||||
| import { getScreenNews, getScreenPeople } from '@/api/projectScreen'; | ||||
| import { mapOption } from './optionList' | ||||
| import { ref } from 'vue'; | ||||
| import Title from './title.vue'; | ||||
| import { getScreenNews, getScreenPeople } from '@/api/projectScreen/index'; | ||||
| import { mapOption } from './optionList'; | ||||
| import * as echarts from 'echarts'; | ||||
|  | ||||
| const props = defineProps({ | ||||
| @ -84,86 +93,111 @@ const props = defineProps({ | ||||
|     type: String, | ||||
|     default: '' | ||||
|   } | ||||
| }) | ||||
| }); | ||||
|  | ||||
| let mapChart = null | ||||
| let mapChart = null; | ||||
| const mapChartRef = ref<HTMLDivElement | null>(null); | ||||
| const news = ref([]) | ||||
| const contentRef = ref<HTMLDivElement | null>(null); | ||||
| const news = ref([]); | ||||
| const newDetail = ref({ | ||||
|   title: '', | ||||
|   content: '' | ||||
| }) | ||||
| const newId = ref('') | ||||
| const attendanceCount = ref(0) | ||||
| const attendanceRate = ref(0) | ||||
| const peopleCount = ref(0) | ||||
| const teamAttendanceList = ref([ | ||||
|   { id: "", teamName: "", attendanceNumber: 0, allNumber: 0, attendanceRate: 0, attendanceTime: "" }, | ||||
| ]) | ||||
| }); | ||||
| const newId = ref(''); | ||||
| const attendanceCount = ref(0); | ||||
| const attendanceRate = ref(0); | ||||
| const peopleCount = ref(0); | ||||
| const teamAttendanceList = ref([{ id: '', teamName: '', attendanceNumber: 0, allNumber: 0, attendanceRate: 0, attendanceTime: '' }]); | ||||
|  | ||||
| /** | ||||
|  * 显示新闻详情 | ||||
|  */ | ||||
| const showNewsDetail = (item: any) => { | ||||
|   if (newId.value === item.id) { | ||||
|     newId.value = '' | ||||
|     return | ||||
|     newId.value = ''; | ||||
|     return; | ||||
|   } | ||||
|   newDetail.value = item | ||||
|   newId.value = item.id | ||||
| } | ||||
|   newDetail.value = item; | ||||
|   newId.value = item.id; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 获取项目人员出勤数据 | ||||
|  */ | ||||
| const getPeopleData = async () => { | ||||
|   const res = await getScreenPeople(props.projectId); | ||||
|   const { data, code } = res | ||||
|   const { data, code } = res; | ||||
|   if (code === 200) { | ||||
|     attendanceCount.value = data.attendanceCount | ||||
|     attendanceRate.value = data.attendanceRate | ||||
|     peopleCount.value = data.peopleCount | ||||
|     teamAttendanceList.value = data.teamAttendanceList | ||||
|     attendanceCount.value = data.attendanceCount; | ||||
|     attendanceRate.value = data.attendanceRate; | ||||
|     peopleCount.value = data.peopleCount; | ||||
|     teamAttendanceList.value = data.teamAttendanceList; | ||||
|   } | ||||
| } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 获取项目新闻数据 | ||||
|  */ | ||||
| const getNewsData = async () => { | ||||
|   const res = await getScreenNews(props.projectId); | ||||
|   const { data, code } = res | ||||
|   const { data, code } = res; | ||||
|   if (code === 200) { | ||||
|     news.value = data | ||||
|     news.value = data; | ||||
|     autoScrollTable(5); | ||||
|   } | ||||
| } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 初始化地图 | ||||
|  */ | ||||
| const initMapChart = () => { | ||||
|   if (!mapChartRef.value) { | ||||
|     return; | ||||
| var lastTime = 0; | ||||
| const state = reactive({ | ||||
|   events: [], | ||||
|   outputList: [], | ||||
|   detialInfoShow: false, | ||||
|   notShowPro: [{ id: 37 }, { id: 44 }, { id: 48 }], //模块内容区域不展示的项目(中煤科工 广东户用光伏项目 兴隆光伏) | ||||
|   scrolltimerTable: null, | ||||
|   flagPause: true //滚动继续滚动 | ||||
| }); | ||||
|  | ||||
| const autoScrollTable = (time: number) => { | ||||
|   const divData = document.getElementById('event_scroll'); | ||||
|  | ||||
|   if (time - lastTime < 25) { | ||||
|     scrolltimerTable = requestAnimationFrame(autoScrollTable); | ||||
|     return; // 如果时间未到,则返回,不执行动画更新 | ||||
|   } | ||||
|   mapChart = echarts.init(mapChartRef.value); | ||||
|   mapChart.setOption(mapOption); | ||||
| } | ||||
|   lastTime = time; | ||||
|   divData.scrollTop += 1; | ||||
|   if (divData.clientHeight + divData.scrollTop >= divData.scrollHeight - 1) { | ||||
|     divData.scrollTop = 0; | ||||
|     scrolltimerTable = requestAnimationFrame(autoScrollTable); | ||||
|   } else { | ||||
|     scrolltimerTable = requestAnimationFrame(autoScrollTable); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // 暂停滚动 | ||||
| const pauseScroll = () => { | ||||
|   if (scrolltimerTable) { | ||||
|     cancelAnimationFrame(scrolltimerTable); | ||||
|     scrolltimerTable = null; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // 恢复滚动 | ||||
| const resumeScroll = () => { | ||||
|   if (!scrolltimerTable) { | ||||
|     requestAnimationFrame((timestamp) => autoScrollTable(timestamp)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| onMounted(() => { | ||||
|   // nextTick(() => { | ||||
|   //   initMapChart(); | ||||
|   // }); | ||||
|   getPeopleData() | ||||
|   getNewsData() | ||||
| }) | ||||
|  | ||||
| onUnmounted(() => { | ||||
|   // if (mapChart) { | ||||
|   //   mapChart.dispose(); | ||||
|   //   mapChart = null; | ||||
|   // } | ||||
|   getPeopleData(); | ||||
|   getNewsData(); | ||||
| }); | ||||
|  | ||||
| onUnmounted(() => {}); | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| @ -294,7 +328,7 @@ onUnmounted(() => { | ||||
|   height: 300px; | ||||
|   max-height: 500px; | ||||
|   overflow-y: auto; | ||||
|   padding: 0 15px; | ||||
|   padding: 10px 15px; | ||||
|   box-sizing: border-box; | ||||
|   background: rgba(255, 255, 255, 0.2); | ||||
|   border-radius: 4px; | ||||
| @ -307,6 +341,13 @@ onUnmounted(() => { | ||||
|     opacity: 1; | ||||
|     z-index: 1; | ||||
|   } | ||||
|  | ||||
|   .close { | ||||
|     position: absolute; | ||||
|     top: 5px; | ||||
|     right: 5px; | ||||
|     cursor: pointer; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .detailBox::before { | ||||
|  | ||||
| @ -4,11 +4,26 @@ import CesiumImageLabelEntity from '../js/CesiumImageLabelEntity.js'; | ||||
| import CesiumFlyToRoamingController from '../js/CesiumFlyToRoamingController.js'; | ||||
| import { setSelect, getSelectList, getGps } from '@/api/projectScreen/index.ts' | ||||
| import videoDialog from "./video.vue" | ||||
| import { getToken } from '@/utils/auth'; | ||||
| const defaultExpandedKeys = [1, 2, 3] //默认展开第一级节点 | ||||
| const defaultCheckedKeys = ref([]) //默认选中节点  | ||||
| const data = ref([]); | ||||
| const deviceId = ref(''); | ||||
| const videoDialogRef = ref(null); | ||||
| let token = 'Bearer '+ getToken() | ||||
| let ws = new ReconnectingWebSocket( import.meta.env.VITE_APP_BASE_WS_API + '?Authorization='+token+'&clientid='+import.meta.env.VITE_APP_CLIENT_ID+'&projectId='+'1897160897167638529'); | ||||
| // 连接ws | ||||
| const connectWs = () => { | ||||
|     ws.onopen = (e) => { | ||||
|     //   let message ={ | ||||
|     //     projectId:'1897160897167638529', | ||||
|     //   } | ||||
|     //   ws.send(JSON.stringify(message)); | ||||
|       ws.onmessage = (e) => { | ||||
|        console.log('ws', e); | ||||
|       }; | ||||
|     }; | ||||
| } | ||||
| const props = defineProps({ | ||||
|     isHide:{ | ||||
|         type:Boolean, | ||||
| @ -214,6 +229,8 @@ function stopRoaming() { | ||||
|     } | ||||
| } | ||||
| onMounted(() => { | ||||
|     // 连接ws | ||||
|     connectWs(); | ||||
|     // 获取选中节点 | ||||
|     getCheckedNode(); | ||||
|     // 获取GPS数据 | ||||
|  | ||||
| @ -7,7 +7,7 @@ | ||||
|             <el-form :model="queryForm" :inline="true"> | ||||
|               <el-form-item label="版本号" prop="versions"> | ||||
|                 <el-select v-model="queryForm.versions" placeholder="选择版本号" @change="changeVersions"> | ||||
|                   <el-option v-for="item in options" :key="item.versions" :label="item.versions" :value="item.versions" /> | ||||
|                   <el-option v-for="item in options" :key="item.versions" :label="item.versionsName" :value="item.versions" /> | ||||
|                 </el-select> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="表名" prop="sheet" v-if="activeTab != '3'"> | ||||
| @ -71,7 +71,7 @@ | ||||
|                 {{ scope.row.children.length > 0 ? '' : scope.row.quantity }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|             <el-table-column prop="remark" label="单价" align="center"> | ||||
|             <el-table-column prop="remark" label="单价" align="center" width="200px"> | ||||
|               <template #default="scope"> | ||||
|                 <el-input-number | ||||
|                   :model-value="scope.row.unitPrice" | ||||
| @ -86,6 +86,7 @@ | ||||
|                   :controls="false" | ||||
|                   v-if="scope.row.quantity && scope.row.quantity != 0" | ||||
|                   :disabled="versionsData.status != 'draft'" | ||||
|                   width="200px" | ||||
|                 /> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.versions" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
| @ -162,7 +163,7 @@ const { form, rules, tableData } = toRefs(data); | ||||
| //   form.value = { ...initFormData }; | ||||
| //   leaveFormRef.value?.resetFields(); | ||||
| // }; | ||||
|  | ||||
| const projectId = ref(''); | ||||
| /** 获取详情 */ | ||||
| const getInfo = () => { | ||||
|   loading.value = true; | ||||
| @ -170,6 +171,7 @@ const getInfo = () => { | ||||
|   nextTick(async () => { | ||||
|     const res = await getVersionDetail(routeParams.value.id); | ||||
|     console.log(res); | ||||
|     projectId.value = res.data.projectId; | ||||
|     Object.assign(form.value, res.data); | ||||
|     loading.value = false; | ||||
|     buttonLoading.value = false; | ||||
| @ -181,7 +183,7 @@ const sheets = ref([]); | ||||
| const getSheetName = async () => { | ||||
|   try { | ||||
|     const params = { | ||||
|       projectId: currentProject.value?.id, | ||||
|       projectId: projectId.value, | ||||
|       versions: form.value.versions | ||||
|     }; | ||||
|     const res = await sheetList(params); | ||||
| @ -201,7 +203,7 @@ const changeSheet = () => { | ||||
| //获取列表 | ||||
| const getListTable = async () => { | ||||
|   const res = await getTableList({ | ||||
|     projectId: currentProject.value?.id, | ||||
|     projectId: projectId.value, | ||||
|     versions: form.value.versions, | ||||
|     sheet: form.value.sheet, | ||||
|     type: '2' | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.versions" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
| @ -26,11 +27,11 @@ | ||||
|                   <el-form-item label="版本号" prop="formNo"> | ||||
|                     <el-input :disabled="true" v-model="form.versions" placeholder="请输入文件名称" /> | ||||
|                   </el-form-item> | ||||
|                   <el-form-item label="表名" prop="sheet"> | ||||
|                   <!-- <el-form-item label="表名" prop="sheet"> | ||||
|                     <el-select v-model="form.sheet" placeholder="选择表名" @change="changeSheet"> | ||||
|                       <el-option v-for="item in sheets" :key="item" :label="item" :value="item" /> | ||||
|                     </el-select> | ||||
|                   </el-form-item> | ||||
|                   </el-form-item> --> | ||||
|                 </el-col> | ||||
|               </el-row> | ||||
|             </div> | ||||
| @ -162,7 +163,7 @@ const { form, rules, tableData } = toRefs(data); | ||||
| //   form.value = { ...initFormData }; | ||||
| //   leaveFormRef.value?.resetFields(); | ||||
| // }; | ||||
|  | ||||
| const projectId = ref(''); | ||||
| /** 获取详情 */ | ||||
| const getInfo = () => { | ||||
|   loading.value = true; | ||||
| @ -170,10 +171,11 @@ const getInfo = () => { | ||||
|   nextTick(async () => { | ||||
|     const res = await getVersionDetail(routeParams.value.id); | ||||
|     console.log(res); | ||||
|     projectId.value = res.data.projectId; | ||||
|     Object.assign(form.value, res.data); | ||||
|     loading.value = false; | ||||
|     buttonLoading.value = false; | ||||
|     getSheetName(); | ||||
|     getListTable(); | ||||
|   }); | ||||
| }; | ||||
| const sheets = ref([]); | ||||
| @ -201,9 +203,9 @@ const changeSheet = () => { | ||||
| //获取列表 | ||||
| const getListTable = async () => { | ||||
|   const res = await getTableList({ | ||||
|     projectId: currentProject.value?.id, | ||||
|     projectId: projectId.value, | ||||
|     versions: form.value.versions, | ||||
|     sheet: form.value.sheet, | ||||
|     // sheet: form.value.sheet, | ||||
|     type: '3' | ||||
|   }); | ||||
|   if (res.code == 200) { | ||||
|  | ||||
| @ -13,8 +13,7 @@ | ||||
|             <el-form-item> | ||||
|               <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> | ||||
|               <el-button icon="Refresh" @click="resetQuery">重置</el-button> | ||||
|               <el-button type="primary" plain :icon="Plus" @click="openDialog" | ||||
|                 v-hasPermi="['tender:biddingPlan:add']">新增</el-button> | ||||
|               <el-button type="primary" plain :icon="Plus" @click="openDialog" v-hasPermi="['tender:biddingPlan:add']">新增</el-button> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
|         </el-card> | ||||
| @ -34,8 +33,9 @@ | ||||
|           <el-table-column prop="bidd" align="center"> | ||||
|             <template #header> <span style="color: red">*</span>招标文件 </template> | ||||
|             <template #default="scope"> | ||||
|               <el-button type="primary" link v-hasPermi="['tender:biddingPlan:getAnnex']" @click="biddView(scope.row)" | ||||
|                 v-if="scope.row.annexCount > 0">查看文件({{ scope.row.annexCount }})</el-button> | ||||
|               <el-button type="primary" link v-hasPermi="['tender:biddingPlan:getAnnex']" @click="biddView(scope.row)" v-if="scope.row.annexCount > 0" | ||||
|                 >查看文件({{ scope.row.annexCount }})</el-button | ||||
|               > | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column prop="winningBidder" align="center"> | ||||
| @ -47,57 +47,104 @@ | ||||
|           <el-table-column prop="bidFileName" align="center"> | ||||
|             <template #header> <span style="color: red">*</span>中标文件 </template> | ||||
|             <template #default="scope"> | ||||
|               <el-button type="primary" link @click="openPdf(scope.row.bidFile)">{{ scope.row.bidFileName }} | ||||
|               </el-button> | ||||
|               <el-button type="primary" link @click="openPdf(scope.row.bidFile)">{{ scope.row.bidFileName }} </el-button> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column prop="plannedBiddingTime" align="center" width="250"> | ||||
|           <el-table-column prop="plannedBiddingTime" align="center" width="200px"> | ||||
|             <template #header> <span style="color: red">*</span>计划招标时间 </template> | ||||
|             <template #default="scope"> | ||||
|               <el-date-picker v-model="scope.row.plannedBiddingTime" @change=" | ||||
|                 (val: any) => { | ||||
|                   changeBiddingTime(val, scope.row); | ||||
|                 } | ||||
|               " type="date" value-format="YYYY-MM-DD" placeholder="选择时间" :disabled="scope.row.bidStatus == 1" | ||||
|                 v-hasPermi="['tender:biddingPlan:edit']" /> | ||||
|               <el-date-picker | ||||
|                 v-model="scope.row.plannedBiddingTime" | ||||
|                 @change=" | ||||
|                   (val: any) => { | ||||
|                     changeBiddingTime(val, scope.row); | ||||
|                   } | ||||
|                 " | ||||
|                 type="date" | ||||
|                 value-format="YYYY-MM-DD" | ||||
|                 placeholder="选择时间" | ||||
|                 :disabled="scope.row.bidStatus == 1" | ||||
|                 v-hasPermi="['tender:biddingPlan:edit']" | ||||
|                 style="width: 150px" | ||||
|               /> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column prop="contractPrice" align="center" width="200"> | ||||
|           <el-table-column prop="contractPrice" align="center" width="200px"> | ||||
|             <template #header> <span style="color: red">*</span>合同金额 </template> | ||||
|             <template #default="scope"> | ||||
|               <el-input-number :model-value="scope.row.contractPrice" @change=" | ||||
|                 (val) => { | ||||
|                   scope.row.contractPrice = val; | ||||
|                   changeContractPrice(val, scope.row); | ||||
|                 } | ||||
|               " :precision="4" :min="0" :controls="false" :disabled="scope.row.bidStatus == 1" | ||||
|                 v-hasPermi="['tender:biddingPlan:edit']" /> | ||||
|               <el-input-number | ||||
|                 :model-value="scope.row.contractPrice" | ||||
|                 @change=" | ||||
|                   (val) => { | ||||
|                     scope.row.contractPrice = val; | ||||
|                     changeContractPrice(val, scope.row); | ||||
|                   } | ||||
|                 " | ||||
|                 :precision="4" | ||||
|                 :min="0" | ||||
|                 :controls="false" | ||||
|                 :disabled="scope.row.bidStatus == 1" | ||||
|                 v-hasPermi="['tender:biddingPlan:edit']" | ||||
|                 width="200px" | ||||
|               /> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|  | ||||
|           <el-table-column prop="price" label="操作" align="center" width="400"> | ||||
|             <template #default="scope"> | ||||
|               <el-button type="primary" link icon="FolderOpened" @click="handleSave(scope.row)" | ||||
|                 v-hasPermi="['tender:biddingPlan:uploadBiddingDocuments']" :disabled="scope.row.bidStatus == 1">招标上传 | ||||
|               <el-button | ||||
|                 type="primary" | ||||
|                 link | ||||
|                 icon="FolderOpened" | ||||
|                 @click="handleSave(scope.row)" | ||||
|                 v-hasPermi="['tender:biddingPlan:uploadBiddingDocuments']" | ||||
|                 :disabled="scope.row.bidStatus == 1" | ||||
|                 >招标上传 | ||||
|               </el-button> | ||||
|               <el-button type="primary" link icon="FolderOpened" @click="handleWinTheBid(scope.row)" | ||||
|                 v-hasPermi="['tender:biddingPlan:uploadBiddingDocuments']" :disabled="scope.row.bidStatus == 1">中标上传 | ||||
|               <el-button | ||||
|                 type="primary" | ||||
|                 link | ||||
|                 icon="FolderOpened" | ||||
|                 @click="handleWinTheBid(scope.row)" | ||||
|                 v-hasPermi="['tender:biddingPlan:uploadBiddingDocuments']" | ||||
|                 :disabled="scope.row.bidStatus == 1" | ||||
|                 >中标上传 | ||||
|               </el-button> | ||||
|               <!-- <el-button type="primary" link icon="Edit" @click="handleSave(scope.row)" v-hasPermi="['tender:segmentedIndicatorPlanning:edit']" | ||||
|                 >信息 | ||||
|               </el-button> --> | ||||
|               <el-button type="primary" link icon="View" @click="handleDetail(scope.row)" | ||||
|                 :disabled="scope.row.bidStatus == 1" v-hasPermi="['tender:biddingPlan:getMore']">详情</el-button> | ||||
|               <el-button | ||||
|                 type="primary" | ||||
|                 link | ||||
|                 icon="View" | ||||
|                 @click="handleDetail(scope.row)" | ||||
|                 :disabled="scope.row.bidStatus == 1" | ||||
|                 v-hasPermi="['tender:biddingPlan:getMore']" | ||||
|                 >详情</el-button | ||||
|               > | ||||
|  | ||||
|               <el-button type="primary" link icon="Delete" @click="delHandle(scope.row)" | ||||
|                 :disabled="scope.row.bidStatus == 1" v-hasPermi="['tender:biddingPlan:remove']">删除</el-button> | ||||
|               <el-button type="primary" link icon="Lock" @click="editStatusBtn(scope.row)" | ||||
|                 :disabled="scope.row.bidStatus == 1" v-hasPermi="['tender:biddingPlan:editStatus']">确定</el-button> | ||||
|               <el-button | ||||
|                 type="primary" | ||||
|                 link | ||||
|                 icon="Delete" | ||||
|                 @click="delHandle(scope.row)" | ||||
|                 :disabled="scope.row.bidStatus == 1" | ||||
|                 v-hasPermi="['tender:biddingPlan:remove']" | ||||
|                 >删除</el-button | ||||
|               > | ||||
|               <el-button | ||||
|                 type="primary" | ||||
|                 link | ||||
|                 icon="Lock" | ||||
|                 @click="editStatusBtn(scope.row)" | ||||
|                 :disabled="scope.row.bidStatus == 1" | ||||
|                 v-hasPermi="['tender:biddingPlan:editStatus']" | ||||
|                 >确定</el-button | ||||
|               > | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </el-table> | ||||
|         <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" | ||||
|           v-model:limit="queryParams.pageSize" @pagination="getList" /> | ||||
|         <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> | ||||
|       </el-tab-pane> | ||||
|     </el-tabs> | ||||
|     <el-dialog title="新增" v-model="dialogVisible" width="75%" draggable> | ||||
| @ -119,8 +166,7 @@ | ||||
|             <el-form :model="treeForm" :inline="true"> | ||||
|               <el-form-item label="版本号" prop="versions"> | ||||
|                 <el-select v-model="treeForm.versions" placeholder="选择版本号" @change="changeVersions"> | ||||
|                   <el-option v-for="item in options" :key="item.versions" :label="item.versions" | ||||
|                     :value="item.versions" /> | ||||
|                   <el-option v-for="item in options" :key="item.versions" :label="item.versions" :value="item.versions" /> | ||||
|                 </el-select> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="表名" prop="sheet" v-if="planType == '2'"> | ||||
| @ -133,8 +179,16 @@ | ||||
|               </el-form-item> | ||||
|             </el-form> | ||||
|           </el-card> | ||||
|           <el-table :data="treeData" ref="treeTableRef" v-loading="treeLoading" row-key="id" border lazy | ||||
|             default-expand-all @selection-change="handleSelection"> | ||||
|           <el-table | ||||
|             :data="treeData" | ||||
|             ref="treeTableRef" | ||||
|             v-loading="treeLoading" | ||||
|             row-key="id" | ||||
|             border | ||||
|             lazy | ||||
|             default-expand-all | ||||
|             @selection-change="handleSelection" | ||||
|           > | ||||
|             <el-table-column type="selection" width="55" /> | ||||
|             <el-table-column prop="num" label="编号" /> | ||||
|             <el-table-column prop="name" label="工程或费用名称" /> | ||||
| @ -148,27 +202,34 @@ | ||||
|                   (scope.row.quantity ? Number(scope.row.quantity) : 0) - | ||||
|                     (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) - | ||||
|                     (scope.row.selectNum ? Number(scope.row.selectNum) : 0) == | ||||
|                     0 | ||||
|                   0 | ||||
|                     ? activeTab == 2 | ||||
|                       ? 0 | ||||
|                       : '' | ||||
|                     : ( | ||||
|                       (scope.row.quantity ? Number(scope.row.quantity) : 0) - | ||||
|                       (scope.row.selectNum ? Number(scope.row.selectNum) : 0) - | ||||
|                       (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) | ||||
|                     ).toFixed(2) | ||||
|                         (scope.row.quantity ? Number(scope.row.quantity) : 0) - | ||||
|                         (scope.row.selectNum ? Number(scope.row.selectNum) : 0) - | ||||
|                         (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) | ||||
|                       ).toFixed(2) | ||||
|                 }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|             <el-table-column prop="selectNum" label="设计量" align="center"> | ||||
|               <template #default="scope"> | ||||
|                 <el-input-number :model-value="scope.row.selectNum" @change=" | ||||
|                   (val) => { | ||||
|                     scope.row.selectNum = val; | ||||
|                     handleNumberChange(scope.row); | ||||
|                   } | ||||
|                 " :precision="2" :step="1" :controls="false" :max="Math.floor(scope.row.quantity)" | ||||
|                   v-if="scope.row.quantity && scope.row.quantity != 0 && scope.row.unitPrice" /> | ||||
|                 <el-input-number | ||||
|                   :model-value="scope.row.selectNum" | ||||
|                   @change=" | ||||
|                     (val) => { | ||||
|                       scope.row.selectNum = val; | ||||
|                       handleNumberChange(scope.row); | ||||
|                     } | ||||
|                   " | ||||
|                   :precision="2" | ||||
|                   :step="1" | ||||
|                   :controls="false" | ||||
|                   :max="Math.floor(scope.row.quantity)" | ||||
|                   v-if="scope.row.quantity && scope.row.quantity != 0 && scope.row.unitPrice" | ||||
|                 /> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|             <el-table-column prop="unitPrice" label="单价" align="center"> | ||||
| @ -187,9 +248,9 @@ | ||||
|                       0 | ||||
|                       ? '' | ||||
|                       : ((scope.row.quantity ? Number(scope.row.quantity) : 0) - | ||||
|                         (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) - | ||||
|                         (scope.row.selectNum ? Number(scope.row.selectNum) : 0)) * | ||||
|                       Number(scope.row.unitPrice), | ||||
|                           (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) - | ||||
|                           (scope.row.selectNum ? Number(scope.row.selectNum) : 0)) * | ||||
|                           Number(scope.row.unitPrice), | ||||
|                     false | ||||
|                   ) | ||||
|                 }} | ||||
| @ -228,8 +289,15 @@ | ||||
|         <el-table-column prop="price" label="操作" align="center"> | ||||
|           <template #default="scope"> | ||||
|             <el-button type="primary" link icon="View" @click="openPdf(scope.row.url)">查看</el-button> | ||||
|             <el-button type="primary" link icon="Delete" @click="delHandlebidd(scope.row)" | ||||
|               v-if="scope.row.bidStatus != 1" v-hasPermi="['tender:biddingPlanAnnex:remove']">删除</el-button> | ||||
|             <el-button | ||||
|               type="primary" | ||||
|               link | ||||
|               icon="Delete" | ||||
|               @click="delHandlebidd(scope.row)" | ||||
|               v-if="scope.row.bidStatus != 1" | ||||
|               v-hasPermi="['tender:biddingPlanAnnex:remove']" | ||||
|               >删除</el-button | ||||
|             > | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
| @ -662,7 +730,7 @@ const delHandlebidd = (row: any) => { | ||||
|       }); | ||||
|       biddView(biddViewRow.value); | ||||
|     } | ||||
|     getList() | ||||
|     getList(); | ||||
|   }); | ||||
| }; | ||||
| //修改状态 | ||||
|  | ||||
| @ -35,7 +35,9 @@ | ||||
|             <el-button type="warning" plain icon="Upload" @click="handleImport" v-hasPermi="['supplierInput:supplierInput:import']">导入</el-button> | ||||
|           </el-col> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['supplierInput:supplierInput:export']">导出模板</el-button> | ||||
|             <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['supplierInput:supplierInput:export']" | ||||
|               >导出模板</el-button | ||||
|             > | ||||
|           </el-col> | ||||
|           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> | ||||
|         </el-row> | ||||
| @ -703,7 +705,7 @@ const handleExport = () => { | ||||
|   try { | ||||
|     // 创建a标签并直接下载public目录下的静态文件 | ||||
|     const link = document.createElement('a'); | ||||
|     link.href = '/assets/files/供应商导入模板.xlsx'; // 使用public目录下现有的Excel文件作为模板 | ||||
|     link.href = '/xx.xlsx'; | ||||
|     link.download = '供应商导入模板.xlsx'; | ||||
|     document.body.appendChild(link); | ||||
|     link.click(); | ||||
| @ -746,7 +748,7 @@ const handleImport = () => { | ||||
|         loading.value = true; | ||||
|         // 调用导入接口 | ||||
|         const res = await leadingIn(formData, queryParams.value.projectId); | ||||
|         console.log("111111111111",queryParams.value.projectId); | ||||
|         console.log('111111111111', queryParams.value.projectId); | ||||
|  | ||||
|         if (res.code === 200) { | ||||
|           proxy?.$modal.msgSuccess('导入成功'); | ||||
|  | ||||
| @ -11,6 +11,7 @@ | ||||
|           :id="form.id" | ||||
|           :status="form.state" | ||||
|           :pageType="routeParams.type" | ||||
|           :projectName="routeParams.projectName" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|  | ||||
| @ -9,6 +9,7 @@ | ||||
|         :id="form.id" | ||||
|         :status="form.status" | ||||
|         :pageType="routeParams.type" | ||||
|         :projectName="routeParams.projectName" | ||||
|       /> | ||||
|     </el-card> | ||||
|     <el-card shadow="never" style="height: 78vh; overflow-y: auto"> | ||||
|  | ||||
| @ -38,6 +38,7 @@ | ||||
|         <el-table v-loading="loading" border :data="taskList" @selection-change="handleSelectionChange"> | ||||
|           <el-table-column type="selection" width="55" align="center" /> | ||||
|           <el-table-column align="center" type="index" label="序号" width="60"></el-table-column> | ||||
|           <el-table-column align="center" prop="projectName" label="项目名称" :show-overflow-tooltip="true"></el-table-column> | ||||
|           <el-table-column :show-overflow-tooltip="true" prop="flowName" align="center" label="流程名称"></el-table-column> | ||||
|           <el-table-column align="center" prop="categoryName" label="流程分类"></el-table-column> | ||||
|           <el-table-column align="center" prop="version" label="版本号" width="90"> | ||||
|  | ||||
| @ -28,7 +28,7 @@ | ||||
|                   <el-input v-model="queryParams.flowName" placeholder="请输入流程名称" @keyup.enter="handleQuery" /> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="项目" prop="projectId"> | ||||
|                   <el-select v-model="queryParams.projectId" placeholder="全部" clearable filterable style="width: 150px; margin-right: 20px"> | ||||
|                   <el-select v-model="queryParams.projectId" placeholder="全部" filterable style="width: 150px; margin-right: 20px"> | ||||
|                     <el-option v-for="project in projects" :key="project.id" :label="project.name" :value="project.id" /> | ||||
|                   </el-select> | ||||
|                 </el-form-item> | ||||
| @ -49,6 +49,7 @@ | ||||
|  | ||||
|           <el-table v-loading="loading" border :data="processInstanceList" @selection-change="handleSelectionChange"> | ||||
|             <el-table-column align="center" type="index" label="序号" width="60"></el-table-column> | ||||
|             <el-table-column align="center" prop="projectName" label="项目名称" :show-overflow-tooltip="true"></el-table-column> | ||||
|             <el-table-column v-if="false" align="center" prop="id" label="id"></el-table-column> | ||||
|             <el-table-column :show-overflow-tooltip="true" prop="flowName" align="center" label="流程名称"> </el-table-column> | ||||
|             <!-- <el-table-column align="center" prop="flowCode" label="流程定义编码"></el-table-column> --> | ||||
| @ -248,7 +249,8 @@ const handleOpen = async (row, type) => { | ||||
|     taskId: row.id, | ||||
|     type: type, | ||||
|     formCustom: row.formCustom, | ||||
|     formPath: row.formPath | ||||
|     formPath: row.formPath, | ||||
|     projectName: row.projectName | ||||
|   }); | ||||
|   workflowCommon.routerJump(routerJumpVo, proxy); | ||||
| }; | ||||
|  | ||||
| @ -11,7 +11,7 @@ | ||||
|               <el-input v-model="queryParams.flowName" placeholder="请输入流程名称" @keyup.enter="handleQuery" /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="项目" prop="projectId"> | ||||
|               <el-select v-model="queryParams.projectId" placeholder="全部" clearable filterable style="width: 150px; margin-right: 20px"> | ||||
|               <el-select v-model="queryParams.projectId" placeholder="全部" filterable style="width: 150px; margin-right: 20px"> | ||||
|                 <el-option v-for="project in projects" :key="project.id" :label="project.name" :value="project.id" /> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
| @ -33,6 +33,7 @@ | ||||
|       <el-table v-loading="loading" border :data="taskList" @selection-change="handleSelectionChange"> | ||||
|         <el-table-column type="selection" width="55" align="center" /> | ||||
|         <el-table-column align="center" type="index" label="序号" width="60"></el-table-column> | ||||
|         <el-table-column align="center" prop="projectName" label="项目名称" :show-overflow-tooltip="true"></el-table-column> | ||||
|         <el-table-column :show-overflow-tooltip="true" prop="flowName" align="center" label="流程名称"></el-table-column> | ||||
|         <el-table-column align="center" prop="categoryName" label="流程分类"></el-table-column> | ||||
|         <el-table-column align="center" prop="nodeName" label="任务名称"></el-table-column> | ||||
| @ -44,7 +45,7 @@ | ||||
|         <el-table-column align="center" prop="updateTime" label="更新时间" width="150"></el-table-column> | ||||
|         <el-table-column label="操作" align="center" width="200"> | ||||
|           <template #default="scope"> | ||||
|             <el-button type="primary"  icon="View" @click="handleView(scope.row)">查看</el-button> | ||||
|             <el-button type="primary" icon="View" @click="handleView(scope.row)">查看</el-button> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
| @ -131,7 +132,8 @@ const handleView = (row) => { | ||||
|     taskId: row.id, | ||||
|     type: 'view', | ||||
|     formCustom: row.formCustom, | ||||
|     formPath: row.formPath | ||||
|     formPath: row.formPath, | ||||
|     projectName: row.projectName | ||||
|   }); | ||||
|   workflowCommon.routerJump(routerJumpVo, proxy); | ||||
| }; | ||||
|  | ||||
| @ -16,7 +16,7 @@ | ||||
|               <el-input v-model="queryParams.flowName" placeholder="请输入流程名称" @keyup.enter="handleQuery" /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="项目" prop="projectId"> | ||||
|               <el-select v-model="queryParams.projectId" placeholder="全部" clearable filterable style="width: 150px; margin-right: 20px"> | ||||
|               <el-select v-model="queryParams.projectId" placeholder="全部" filterable style="width: 150px; margin-right: 20px"> | ||||
|                 <el-option v-for="project in projects" :key="project.id" :label="project.name" :value="project.id" /> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
| @ -37,6 +37,7 @@ | ||||
|  | ||||
|       <el-table v-loading="loading" border :data="taskList" @selection-change="handleSelectionChange"> | ||||
|         <el-table-column align="center" type="index" label="序号" width="60"></el-table-column> | ||||
|         <el-table-column align="center" prop="projectName" label="项目名称" :show-overflow-tooltip="true"></el-table-column> | ||||
|         <el-table-column align="center" prop="flowName" label="流程名称"></el-table-column> | ||||
|         <el-table-column align="center" prop="categoryName" label="流程分类"></el-table-column> | ||||
|         <el-table-column align="center" prop="version" label="版本号" width="90"> | ||||
| @ -64,7 +65,7 @@ | ||||
|         <el-table-column align="center" prop="createTime" label="创建时间" width="160"></el-table-column> | ||||
|         <el-table-column label="操作" align="center" width="200"> | ||||
|           <template #default="scope"> | ||||
|             <el-button type="primary" link  icon="View" @click="handleView(scope.row)">查看</el-button> | ||||
|             <el-button type="primary" link icon="View" @click="handleView(scope.row)">查看</el-button> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
| @ -164,7 +165,8 @@ const handleView = (row: FlowTaskVO) => { | ||||
|     taskId: row.id, | ||||
|     type: 'view', | ||||
|     formCustom: row.formCustom, | ||||
|     formPath: row.formPath | ||||
|     formPath: row.formPath, | ||||
|     projectName: row.projectName | ||||
|   }); | ||||
|   workflowCommon.routerJump(routerJumpVo, proxy); | ||||
| }; | ||||
|  | ||||
| @ -16,7 +16,7 @@ | ||||
|               <el-input v-model="queryParams.flowName" placeholder="请输入流程名称" @keyup.enter="handleQuery" /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="项目" prop="projectId"> | ||||
|               <el-select v-model="queryParams.projectId" placeholder="全部" clearable filterable style="width: 150px; margin-right: 20px"> | ||||
|               <el-select v-model="queryParams.projectId" placeholder="全部" filterable style="width: 150px; margin-right: 20px"> | ||||
|                 <el-option v-for="project in projects" :key="project.id" :label="project.name" :value="project.id" /> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
| @ -36,6 +36,7 @@ | ||||
|       </template> | ||||
|       <el-table v-loading="loading" border :data="taskList" @selection-change="handleSelectionChange"> | ||||
|         <el-table-column align="center" type="index" label="序号" width="60"></el-table-column> | ||||
|         <el-table-column align="center" prop="projectName" label="项目名称" :show-overflow-tooltip="true"></el-table-column> | ||||
|         <el-table-column :show-overflow-tooltip="true" prop="flowName" align="center" label="流程名称"></el-table-column> | ||||
|         <el-table-column align="center" prop="categoryName" label="流程分类"></el-table-column> | ||||
|         <el-table-column align="center" prop="nodeName" label="任务名称"></el-table-column> | ||||
| @ -167,7 +168,8 @@ const handleOpen = async (row: FlowTaskVO) => { | ||||
|     type: 'approval', | ||||
|     formCustom: row.formCustom, | ||||
|     planMonth: row.businessId.split('_')[1], | ||||
|     formPath: row.formPath | ||||
|     formPath: row.formPath, | ||||
|     projectName: row.projectName | ||||
|   }); | ||||
|   workflowCommon.routerJump(routerJumpVo, proxy); | ||||
| }; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user