Your Name
2023-01-30 d8afe78f6a31bf0cf6743f85fb05a121f541c6aa
复制框架
已添加568个文件
114692 ■■■■■ 文件已修改
.env 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.development 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.production 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.eslintignore 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.eslintrc.js 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.prettierrc.js 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CHANGELOG.md 356 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LICENSE 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
index.html 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json 8210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
plugins.d.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
shim.d.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
source.d.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/App.vue 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/accidentManagementSystem/index.ts 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/contingencyManagement/contingency/index.ts 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/contingencyManagement/emergencyDrillEvaluation/index.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/contingencyManagement/emergencyDrillExecute/index.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/contingencyManagement/emergencyDrillPlan/index.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/contingencyManagement/emergencyMaterialsInspection/index.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/contingencyManagement/emergencyPlan/index.ts 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/contingencyManagement/emergencyPlanLog/index.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/contingencyManagement/emergencyResources/index.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/contingencyManagement/maintenanceEmergencyMaterials/index.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/doublePreventSystem/check/index.ts 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/doublePreventSystem/checkUnit/index.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/doublePreventSystem/productionDevice/index.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/doublePreventSystem/record/index.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/doublePreventSystem/rectify/index.ts 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/doublePreventSystem/report/index.ts 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/doublePreventSystem/riskControlMeasure/index.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/doublePreventSystem/safetyRiskAnalyseUnit/index.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/doublePreventSystem/safetyRiskEvent/index.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/doublePreventSystem/work/index.ts 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/facilityManagement/claimReturnRecords/index.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/facilityManagement/goodsDetailManage/index.ts 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/facilityManagement/index.ts 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/facilityManagement/safetyGoodsAndEquipment/index.ts 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/goalManagement/index.ts 412 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/intellectInspectSystem/RFID/index.ts 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/intellectInspectSystem/facilityAreaManage/index.ts 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/intellectInspectSystem/inspectPointManage/index.ts 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/intellectInspectSystem/inspectRecord/index.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/intellectInspectSystem/inspectTargetManage/index.ts 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/intellectInspectSystem/inspectTask/index.ts 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/intelligentLine/index.ts 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/login/index.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/specialWorkSystem/approveBasic/index.ts 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/specialWorkSystem/approveRule/index.ts 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/specialWorkSystem/material/index.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/specialWorkSystem/safetyAction/index.ts 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/specialWorkSystem/workApply/index.ts 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/specialWorkSystem/workApproval/index.ts 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/specialWorkSystem/workPlan/workAppoint/index.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/specialWorkSystem/workPlan/workReservation/index.ts 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/specialWorkSystem/workProcess/index.ts 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/appVersion/index.ts 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/basicDateManage/personShiftManage/holidayTime/index.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/basicDateManage/personShiftManage/holidayTimeGroup/index.ts 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/basicDateManage/personShiftManage/teamManage/index.ts 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/basicDateManage/personShiftManage/teamStrategy/index.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/basicDateManage/personShiftManage/timeStrategy/index.ts 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/basicDateManage/personShiftManage/workingHours/index.ts 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/basicDateManage/personShiftManage/workingHoursSet/index.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/department/index.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/menu/index.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/personShiftManage/holidayTime/index.ts 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/personShiftManage/holidayTimeGroup/index.ts 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/personShiftManage/teamManage/index.ts 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/personShiftManage/teamStrategy/index.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/personShiftManage/timeStrategy/index.ts 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/personShiftManage/workingHours/index.ts 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/personShiftManage/workingHoursSet/index.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/role/index.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/systemManage/user/index.ts 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/workInjuryDeclaration/index.ts 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/avator.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/companyLogo.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/default-img.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/icon.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/index.css 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/index.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/login-icon-two.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/arrow-r.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/back-icon.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/device-pic.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/equipment.JPG 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/login-bg.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/login-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/login_icon_password.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/login_icon_user.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/map-bg.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/map-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/star-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/task-job-pic.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/watersys.JPG 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/wind.JPG 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/xj-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/loginPage/xj-icon.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/logo-mini.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/admin.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/bg_home.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/bg_home1.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/card1.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/card10.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/card11.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/card2.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/card3.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/card4.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/card5.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/card6.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/card7.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/card8.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/card9.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/companyLogo.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/icon1.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/icon10.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/icon11.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/icon2.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/icon3.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/icon4.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/icon5.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/icon6.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/icon7.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/icon8.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/menu/icon9.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/methods/index.ts 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/card-1.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/card-10.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/card-11.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/card-2.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/card-3.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/card-4.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/card-5.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/card-6.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/card-7.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/card-8.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/card-9.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/icon1.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/icon10.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/icon11.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/icon2.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/icon3.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/icon4.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/icon5.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/icon6.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/icon7.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/icon8.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/icon9.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/leftbg.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/leftbg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/pic_line1.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/pic_line2.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/topbg.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/newMenu/toplogo.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/style/index.scss 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/body-bg.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/logo_dark.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/logo_light.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/pagebg-l-light.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/pagebg-l.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/pagebg-r-light.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/pagebg-r.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/pagebg-t-light.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/pagebg-t.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/riskprocast-light.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/riskprocast.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/skin-light.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/skin.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/small-full.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/warningScreen/video.png 补丁 | 查看 | 原始文档 | blame | 历史
src/components/DailogClass/index.vue 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/DailogSearch/DailogSearch.vue 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/DailogSearchUser/index.vue 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/DailogSearchUserManger/index.vue 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/auth/auth.vue 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/auth/authAll.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/auth/auths.vue 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/checkTemplate/index.vue 230 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/cropper/index.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/editor/index.vue 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/editor/toolbar.ts 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/emergencySupplies/index.vue 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/equipmentDailog/Dailog.vue 903 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/equipmentDailog/DailogS.vue 701 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/equipmentDailog/categoryDailog.vue 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/equipmentDailog/detectDailog.vue 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/equipmentDailog/maintenanceDailog.vue 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/equipmentDailog/planDailog.vue 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/equipmentDailog/regionDailog.vue 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/equipmentDailog/repairDailog.vue 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/equipmentDailog/standardDailog.vue 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/iconSelector/index.vue 252 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/noticeBar/index.vue 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/regionsDialog/index.vue 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/svgIcon/index.vue 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/updata/updata.vue 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/uploaderFile/index.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/uploaderImg/index.vue 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/userCheckbox/index.vue 422 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/userSelections/index.vue 446 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/index.ts 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/lang/en.ts 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/lang/zh-cn.ts 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/lang/zh-tw.ts 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/pages/formI18n/en.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/pages/formI18n/zh-cn.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/pages/formI18n/zh-tw.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/pages/login/en.ts 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/pages/login/zh-cn.ts 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/pages/login/zh-tw.ts 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/component/aside.vue 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/component/columnsAside.vue 292 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/component/header.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/component/main.vue 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/footer/index.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/index.vue 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/lockScreen/index.vue 372 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/logo/index.vue 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/main/classic.vue 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/main/columns.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/main/defaults.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/main/transverse.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navBars/breadcrumb/breadcrumb.vue 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navBars/breadcrumb/closeFull.vue 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navBars/breadcrumb/index.vue 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navBars/breadcrumb/search.vue 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navBars/breadcrumb/setings.vue 816 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navBars/breadcrumb/user.vue 430 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navBars/breadcrumb/userNews.vue 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navBars/index.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navBars/tagsView/contextmenu.vue 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navBars/tagsView/tagsView.vue 734 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navMenu/horizontal.vue 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navMenu/subItem.vue 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/navMenu/vertical.vue 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/routerView/iframes.vue 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/routerView/link.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/routerView/parent.vue 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/backEnd.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/frontEnd.ts 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/route.ts 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/index.ts 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/interface/index.ts 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/keepAliveNames.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/loginInfo.ts 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/requestOldRoutes.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/routesList.ts 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/screenTheme.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/tagsViewRoutes.ts 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/themeConfig.ts 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/userInfo.ts 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/app.scss 281 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/bigScreen.css 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/common/transition.scss 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/dark.scss 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/element.scss 282 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/iconSelector.scss 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/index.scss 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/loading.scss 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/chart.scss 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/cityLinkage.scss 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/date.scss 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/dialog.scss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/error.scss 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/form.scss 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/home.scss 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/index.scss 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/layout.scss 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/login.scss 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/media.scss 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/pagination.scss 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/personal.scss 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/scrollbar.scss 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/media/tagsView.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/mixins/index.scss 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/other.scss 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/theme/waves.scss 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/arrayOperation.ts 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/authDirective.ts 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/authFunction.ts 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/commonFunction.ts 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/customDirective.ts 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/directive.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/formatTime.ts 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/getStyleSheets.ts 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/loading.ts 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/other.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.ts 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/setIconfont.ts 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/storage.ts 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/theme.ts 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/throttle.ts 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/toolsValidate.ts 368 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/wartermark.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/accidentCases/component/DailogCases.vue 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/accidentCases/component/wangEditor/index.vue 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/accidentCases/index.vue 274 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/accidentCasesCop/component/wangEditor/index.vue 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/accidentCasesCop/index.vue 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/accidentExpress/component/numberOfCasualties.vue 461 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/accidentExpress/component/openAdd.vue 534 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/accidentExpress/index.vue 359 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/accidentReport/component/openAdd.vue 723 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/accidentReport/index.vue 404 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/accidentStatistics/index.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/workInjuryDeclaration/component/accidentName.vue 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/workInjuryDeclaration/component/openAdd.vue 547 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/workInjuryDeclaration/component/openEdit.vue 400 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/accidentManagementSystem/workInjuryDeclaration/index.vue 397 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/abolishDialog/abolishDialog.vue 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/abolishDialog/component/formInformationTop.vue 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/abolishDialog/component/formInformationTops.vue 318 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/abolishDialog/component/lowerPlate.vue 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/contingency/component/addEmergencyPersonnel.vue 305 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/contingency/component/openAdd.vue 569 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/contingency/component/upData.vue 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/contingency/index.vue 401 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/drillImplementationEvaluation/component/approvalProgress.vue 925 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/drillImplementationEvaluation/component/flowChart.vue 307 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/drillImplementationEvaluation/component/rectificationDialog.vue 775 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/drillImplementationEvaluation/index.vue 502 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/implementationOfEmergencyDrill/component/openAdd.vue 629 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/implementationOfEmergencyDrill/component/regionsDialog.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/implementationOfEmergencyDrill/component/userSelect.vue 443 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/implementationOfEmergencyDrill/index.vue 375 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/releaseOfDrillPlan/component/flowChart.vue 325 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/releaseOfDrillPlan/component/openAdd.vue 591 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/releaseOfDrillPlan/component/regionsDialog.vue 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrill/releaseOfDrillPlan/index.vue 404 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyDrillStatistics/index.vue 359 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyPlanStartRecord/component/openSee.vue 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyPlanStartRecord/component/selectEmergencyPlan.vue 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyPlanStartRecord/index.vue 408 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyResources/emergencyMaterialsInspection/component/openAdd.vue 284 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyResources/emergencyMaterialsInspection/index.vue 391 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyResources/emergencySupplies/component/inspect.vue 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyResources/emergencySupplies/component/maintain.vue 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyResources/emergencySupplies/component/openAdd.vue 515 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyResources/emergencySupplies/component/openEdit.vue 549 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyResources/emergencySupplies/component/personInCharge.vue 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyResources/emergencySupplies/component/regionsCheckbox.vue 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyResources/emergencySupplies/index.vue 397 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyResources/maintenanceOfEmergencyMaterials/component/openAdd.vue 277 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/emergencyResources/maintenanceOfEmergencyMaterials/index.vue 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/panManagement/component/abolishLibrary.vue 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/panManagement/component/approval.vue 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/panManagement/component/approvalProcess.vue 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/panManagement/component/initiateApproval.vue 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/panManagement/component/openAdd.vue 471 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/panManagement/component/startUp.vue 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/panManagement/component/upData.vue 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/panManagement/index.vue 614 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/processForm/component/formInformationTop.vue 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/processForm/component/formInformationTops.vue 312 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/processForm/component/lowerPlate.vue 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/processForm/processForm.vue 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/releaseOfDrillStart/component/formInformationTop.vue 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/releaseOfDrillStart/component/formInformationTops.vue 440 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/releaseOfDrillStart/component/lowerPlate.vue 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/contingencyManagement/releaseOfDrillStart/releaseOfDrillStart.vue 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/dpIndex/index.vue 596 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/checkTaskManage/checkTask/components/recordDialog.vue 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/checkTaskManage/checkTask/index.vue 316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/checkTaskManage/checkWork/components/workDialog.vue 313 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/checkTaskManage/checkWork/index.vue 361 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenCheck/components/checkDialog.vue 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenCheck/index.vue 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenRectify/components/rectifyDialog.vue 303 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenRectify/index.vue 437 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenReport/components/reportDialog.vue 391 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenReport/index.vue 352 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/riskCheckUnit/components/checkUnitDialog.vue 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/riskCheckUnit/components/selectMeasureControlDialog.vue 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskCheckManage/riskCheckUnit/index.vue 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/action/components/riskControlMeasureDialog.vue 265 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/action/index.vue 323 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/device/components/productionDeviceDialog.vue 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/device/index.vue 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/event/components/safetyRiskEventDialog.vue 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/event/index.vue 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/map/components/rectifyDialog.vue 327 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/map/index.vue 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/riskCheckUnit/components/checkUnitDialog.vue 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/riskCheckUnit/components/selectMeasureControlDialog.vue 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/riskCheckUnit/index.vue 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/unit/components/safetyRiskAnalyseUnitDialog.vue 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/doublePrevent/riskLevel/unit/index.vue 265 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/error/401.vue 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/error/404.vue 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/EquipmentStatistics/index.vue 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/InstrumentationInformation/index.vue 391 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/ProductionEquipment/index.vue 390 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/claimReturnRecords/components/invalidDealDialog.vue 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/claimReturnRecords/components/returnAndWatch.vue 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/claimReturnRecords/index.ts 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/claimReturnRecords/index.vue 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/deviceType/component/Dailog.vue 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/deviceType/index.vue 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/goodsDetailManage/components/checkOut.vue 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/goodsDetailManage/components/goodsDetailAdd.vue 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/goodsDetailManage/components/goodsDetailEdit.vue 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/goodsDetailManage/index.ts 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/goodsDetailManage/index.vue 444 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/goodsTypeManage/index.vue 435 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/keyEquipment/index.vue 449 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/safetyEquipment/index.vue 391 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/safetyGoodsAndEquipment/components/addGoodsDialog.vue 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/safetyGoodsAndEquipment/components/batchInStorage.vue 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/safetyGoodsAndEquipment/components/batchOutStorage.vue 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/safetyGoodsAndEquipment/components/safetyGoodsAndEquipmentDialog.vue 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/safetyGoodsAndEquipment/index.ts 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/safetyGoodsAndEquipment/index.vue 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/facilityManagement/securities/index.vue 860 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/Goalsummary/index.vue 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/IncentiveRecording/component/DailogAdd.vue 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/IncentiveRecording/component/DailogSearch.vue 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/IncentiveRecording/index.vue 302 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/Incentivestandard/component/DailogAdd.vue 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/Incentivestandard/index.vue 283 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/TargetBook/component/DailogAdd.vue 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/TargetBook/component/DailogSearch.vue 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/TargetBook/index.vue 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/index.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/performanceAppraisal/component/DailogAq.vue 455 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/performanceAppraisal/component/DailogKh.vue 247 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/performanceAppraisal/component/DailogKhS.vue 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/performanceAppraisal/component/DailogSearch.vue 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/performanceAppraisal/index.vue 526 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/processForms/component/formInformationTop.vue 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/processForms/component/formInformationTops.vue 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/processForms/component/lowerPlate.vue 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/processForms/processForms.vue 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/safetyAssessment/component/Dailog.vue 264 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/safetyAssessment/component/DailogAdd.vue 281 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/safetyAssessment/index.vue 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetClassification/index.vue 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetDecompositionHalfYear/index.vue 286 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetDecompositionMonth/index.vue 286 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetDecompositionQuarter/index.vue 286 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetDecompositionYear/component/Dailog.vue 262 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetDecompositionYear/component/DailogAdd.vue 308 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetDecompositionYear/index.vue 284 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetEscalation/component/Dailog.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetEscalation/component/TypeDailog.vue 341 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetEscalation/index.vue 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetImprovements/component/Dailogprove.vue 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetImprovements/index.vue 307 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetSettings/component/dailogAdd.vue 284 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetSettings/component/search.vue 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetSettings/index.vue 300 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/goalManagement/targetStatistics/index.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectBasic/discriminate/components/RFIDDialog.vue 248 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectBasic/discriminate/index.vue 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectBasic/facility/components/facilityAreaDialog.vue 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectBasic/facility/index.vue 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectBasic/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectBasic/inspectPoint/components/inspectPointDialog.vue 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectBasic/inspectPoint/index.vue 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectBasic/inspectTarget/components/inspectTargetDialog.vue 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectBasic/inspectTarget/index.vue 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectIndex/components/inspectRecordDialog.vue 592 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectIndex/components/sum.vue 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectIndex/index.vue 587 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectRecordManage/inspectRecord/components/inspectRecordDialog.vue 560 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectRecordManage/inspectRecord/components/sum.vue 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectRecordManage/inspectRecord/index.vue 546 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectTaskManage/inspectTask/components/inspectTaskDialog.vue 782 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/inspectTaskManage/inspectTask/index.vue 595 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/intellectInspect/intelligentLine/index.vue 1412 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/layoutPage/index.vue 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/loginPage/component/accountLogin.vue 371 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/loginPage/loginPage.vue 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/newHome/index.vue 967 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/components/SPI.vue 441 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/components/accident.vue 328 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/components/danger.vue 330 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/components/educate.vue 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/components/message.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/components/monitor.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/components/profession.vue 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/components/risk.vue 505 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/components/stock.vue 681 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/components/training.vue 423 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/index.vue 1043 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/indexs/index.vue 470 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/riskWarningSys/warningBigScreen/indexs/msgDetail.vue 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeKnowledge/bmgz/index.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeKnowledge/df/index.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeKnowledge/index.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeKnowledge/inner/index.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeKnowledge/internationalRules/index.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeKnowledge/law/index.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeKnowledge/sfjs/index.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeKnowledge/xzfg/index.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/alarm/zyyjjl/index.vue 364 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/flow/basicApprove/components/approveBasicDialog.vue 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/flow/basicApprove/index.vue 448 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/flow/ruleofApp/components/approveItemDialog.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/flow/ruleofApp/components/approveLevelDialog.vue 327 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/flow/ruleofApp/components/approveRuleDialog.vue 526 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/flow/ruleofApp/index.vue 477 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/foundationSet/goods/index.vue 989 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/foundationSet/safetyAction/components/safetyActionDialog.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/foundationSet/safetyAction/index.vue 453 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/plan/appoint/index.vue 616 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/plan/reservation/index.vue 632 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/plan/sumReserve/index.vue 436 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/process/components/dialogPermitNo.vue 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/process/qtjcfx/index.vue 511 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/process/zyjcgl/index.vue 632 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsp/components/brokenLog.vue 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsp/components/fireLog.vue 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsp/components/groundLog.vue 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsp/components/heightLog.vue 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsp/components/hoistLog.vue 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsp/components/plateLog.vue 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsp/components/powerLog.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsp/components/spaceLog.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsp/index.vue 815 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsq/components/brokenLog.vue 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsq/components/fireLog.vue 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsq/components/groundLog.vue 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsq/components/heightLog.vue 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsq/components/hoistLog.vue 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsq/components/plateLog.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsq/components/powerLog.vue 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsq/components/spaceLog.vue 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsq/index.vue 877 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/wdsqjl/index.vue 888 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/zysq/components/broken.vue 504 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/zysq/components/fire.vue 366 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/zysq/components/ground.vue 563 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/zysq/components/height.vue 413 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/zysq/components/hoist.vue 308 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/zysq/components/materialDialog.vue 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/zysq/components/plate.vue 619 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/zysq/components/power.vue 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/zysq/components/space.vue 379 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/specialWorkSystem/workTicket/zysq/index.vue 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/appVersion/index.vue 698 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/department/component/deptDialog.vue 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/department/index.vue 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/dic/component/addDic.vue 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/dic/component/editDic.vue 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/dic/index.vue 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/menu/component/menuDialog.vue 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/menu/index.vue 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/personShiftManage/personTimeManage/durationManage/index.vue 561 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/personShiftManage/personTimeManage/holidayTime/index.vue 660 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/personShiftManage/personTimeManage/holidayTimeGroup/index.vue 561 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/personShiftManage/personTimeManage/timeStrategy/index.vue 587 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/personShiftManage/personTimeManage/workingHoursSet/index.vue 564 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/personShiftManage/scheduleManage/schedule/index.vue 574 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/personShiftManage/scheduleManage/strategy/index.vue 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/role/component/roleDialog.vue 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/role/index.vue 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/component/userDialog.vue 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/index.vue 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/loginPage.js/login.js 1544 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/loginPage.js/loginApp.js 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tsconfig.json 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vite.config.ts 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yarn.lock 2419 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env
对比新文件
@@ -0,0 +1,19 @@
# port 端口号
VITE_PORT = 8888
# open 运行 npm run dev 时自动打开浏览器
VITE_OPEN = false
# public path 配置线上环境路径(打包)、本地通过 http-server 访问时,请置空即可
#内网test环境
#VITE_PUBLIC_PATH = 'http://192.168.0.52:6002'
#内网UAT环境
#VITE_PUBLIC_PATH = 'http://192.168.0.52:6006'
#线上UAT预发环境
#VITE_PUBLIC_PATH = 'http://121.239.169.27:6006'
#国泰线上试用环境
VITE_PUBLIC_PATH = 'http://121.239.169.27:6622'
.env.development
对比新文件
@@ -0,0 +1,51 @@
# 本地环境
ENV = 'development'
#VITE_API_URL = 'http://192.168.0.35:8008'
#李宇飞接口地址
VITE_API_URL = 'http://192.168.0.50:8008'
#张凤接口地址
#VITE_API_URL = 'http://192.168.0.29:8008'
#黄振接口地址
#VITE_API_URL = 'http://192.168.0.179:8008'
#施正红接口地址
#VITE_API_URL = 'http://192.168.0.69:8008'
#戚会山接口地址
#VITE_API_URL = 'http://121.239.169.27:16006/safeplatform'
#线上正式环境接口地址
#VITE_API_URL_OUT = 'http://121.239.169.27:16006/safeplatform-out'
#线上正式环境外包接口地址
#VITE_API_URL = 'http://192.168.0.52:8011/safeplatform'
#本地预发接口地址
#VITE_API_URL_OUT = 'http://192.168.0.52:8011/safeplatform-out'
#本地外包预发接口地址
VITE_API_URL_OUT = 'http://192.168.0.50:8009'
#张凤外包接口地址
#VITE_API_URL_OUT = 'http://192.168.0.52:7021/safeplatform-out'
#VITE_API_URL = 'http://192.168.0.52:7021/safeplatform'
#本地测试接口地址
VITE_API_URL_SOCKET = 'http://192.168.0.52:7021/safeplatform'
#本地测试websocket接口地址
#VITE_API_URL = 'http://192.168.0.29:7008'
#黄振接口test地址
#VITE_API_URL_SOCKET = 'http://192.168.0.29:16107'
#黄振websocket test接口地址
#VITE_API_URL_SOCKET = 'http://192.168.0.29:8018'
#黄振websocket接口地址
.env.production
对比新文件
@@ -0,0 +1,22 @@
# 线上环境
ENV = 'production'
#内网test环境接口地址
#VITE_API_URL = 'http://192.168.0.52:7021/safeplatform'
#VITE_API_URL_OUT = 'http://192.168.0.52:7021/safeplatform-out'
#VITE_API_URL_SOCKET = 'http://192.168.0.52:7021/safeplatform'
#内网UAT环境接口地址
#VITE_API_URL = 'http://192.168.0.52:8011/safeplatform'
#VITE_API_URL_OUT = 'http://192.168.0.52:8011/safeplatform-out'
#VITE_API_URL_SOCKET = 'http://192.168.0.52:8011/safeplatform'
# 线上UAT预发环境接口地址
#VITE_API_URL = 'http://121.239.169.27:16006/safeplatform'
#VITE_API_URL_OUT = 'http://121.239.169.27:16006/safeplatform-out'
#VITE_API_URL_SOCKET = 'http://121.239.169.27:16006/safeplatform'
# 国泰线上试用环境接口地址
VITE_API_URL = 'http://121.239.169.27:16016/safeplatform'
VITE_API_URL_OUT = 'http://121.239.169.27:16016/safeplatform-out'
VITE_API_URL_SOCKET = 'http://121.239.169.27:16016/safeplatform'
.eslintignore
对比新文件
@@ -0,0 +1,18 @@
*.sh
node_modules
lib
*.md
*.scss
*.woff
*.ttf
.vscode
.idea
dist
mock
public
bin
build
config
index.html
src/assets
.eslintrc.js
对比新文件
@@ -0,0 +1,63 @@
module.exports = {
    root: true,
    env: {
        browser: true,
        es2021: true,
        node: true,
    },
    parser: 'vue-eslint-parser',
    parserOptions: {
        ecmaVersion: 12,
        parser: '@typescript-eslint/parser',
        sourceType: 'module',
    },
    extends: ['plugin:vue/vue3-essential', 'plugin:vue/essential', 'eslint:recommended'],
    plugins: ['vue', '@typescript-eslint'],
    rules: {
        // http://eslint.cn/docs/rules/
        // https://eslint.vuejs.org/rules/
        '@typescript-eslint/ban-ts-ignore': 'off',
        '@typescript-eslint/explicit-function-return-type': 'off',
        '@typescript-eslint/no-explicit-any': 'off',
        '@typescript-eslint/no-var-requires': 'off',
        '@typescript-eslint/no-empty-function': 'off',
        '@typescript-eslint/no-use-before-define': 'off',
        '@typescript-eslint/ban-ts-comment': 'off',
        '@typescript-eslint/ban-types': 'off',
        '@typescript-eslint/no-non-null-assertion': 'off',
        '@typescript-eslint/explicit-module-boundary-types': 'off',
        'vue/custom-event-name-casing': 'off',
        'vue/attributes-order': 'off',
        'vue/one-component-per-file': 'off',
        'vue/html-closing-bracket-newline': 'off',
        'vue/max-attributes-per-line': 'off',
        'vue/multiline-html-element-content-newline': 'off',
        'vue/singleline-html-element-content-newline': 'off',
        'vue/attribute-hyphenation': 'off',
        'vue/html-self-closing': 'off',
        'vue/no-multiple-template-root': 'off',
        'vue/require-default-prop': 'off',
        'vue/no-v-model-argument': 'off',
        'vue/no-arrow-functions-in-watch': 'off',
        'vue/no-template-key': 'off',
        'vue/no-v-html': 'off',
        'vue/comment-directive': 'off',
        'vue/no-parsing-error': 'off',
        'vue/no-deprecated-v-on-native-modifier': 'off',
        'vue/multi-word-component-names': 'off',
        'no-useless-escape': 'off',
        'no-sparse-arrays': 'off',
        'no-prototype-builtins': 'off',
        'no-constant-condition': 'off',
        'no-use-before-define': 'off',
        'no-restricted-globals': 'off',
        'no-restricted-syntax': 'off',
        'generator-star-spacing': 'off',
        'no-unreachable': 'off',
        'no-multiple-template-root': 'off',
        'no-unused-vars': 'error',
        'no-v-model-argument': 'off',
        'no-case-declarations': 'off',
        'no-console': 'error',
    },
};
.prettierrc.js
对比新文件
@@ -0,0 +1,40 @@
module.exports = {
    // 一行最多多少个字符
    printWidth: 1500,
    // 指定每个缩进级别的空格数
    tabWidth: 4,
    // 使用制表符而不是空格缩进行
    useTabs: false,
    // // 在语句末尾打印分号
    // semi: true,
    // 使用单引号而不是双引号
    singleQuote: true,
    // // 更改引用对象属性的时间 可选值"<as-needed|consistent|preserve>"
    // quoteProps: 'as-needed',
    // // 在JSX中使用单引号而不是双引号
    // jsxSingleQuote: false,
    // // 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"<none|es5|all>",默认none
    trailingComma: 'none',
    bracketSpacing: true,
    // 在对象文字中的括号之间打印空格
    // bracketSpacing: true,
    // // jsx 标签的反尖括号需要换行
    // jsxBracketSameLine: false,
    // // 在单独的箭头函数参数周围包括括号 always:(x) => x \ avoid:x => x
    // arrowParens: 'always',
    // // 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码
    // rangeStart: 2,
    // rangeEnd: Infinity,
    // // 指定要使用的解析器,不需要写文件开头的 @prettier
    // requirePragma: false,
    // // 不需要自动在文件开头插入 @prettier
    // insertPragma: false,
    // // 使用默认的折行标准 always\never\preserve
    // proseWrap: 'preserve',
    // // 指定HTML文件的全局空格敏感度 css\strict\ignore
    // htmlWhitespaceSensitivity: 'css',
    // // Vue文件脚本和样式标签缩进
    // vueIndentScriptAndStyle: false,
    // 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
    endOfLine: 'lf'
};
CHANGELOG.md
对比新文件
@@ -0,0 +1,356 @@
# <a href="https://gitee.com/lyt-top/vue-next-admin" target="_blank">vue-next-admin 更新日志</a>
🎉🎉🔥 `vue-next-admin` 基于 vue3.x 、Typescript、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支)
## 2.1.1
`2022.05.27`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 深色模式下,`<el-button text></el-button>` 时,`:active` 样式
- 🎯 优化 [页面缓存在刷新之后失效 #I58U75](https://gitee.com/lyt-top/vue-next-admin/issues/I58U75)),感谢[@ls0428](https://gitee.com/ls0428)
- 🎯 优化 [SvgIcon 对下载的 Svg 图像设置颜色无效 #I59ND0](https://gitee.com/lyt-top/vue-next-admin/issues/I59ND0)),感谢[@elus_z](https://gitee.com/elus_z)
- 🎯 优化 `/src/utils/toolsValidate.ts` 工具类
- 🐞 修复 [布局切换,TagsView 显示的 tab 会多一个出来 #I58WGM](https://gitee.com/lyt-top/vue-next-admin/issues/I58WGM),感谢[@lg_boy](https://gitee.com/lg_boy)
- 🐞 修复 [如果设置顶部面包屑导航开启图标 isBreadcrumbIcon=true 后,样式有点问题 如果不开启就是正常的 #I58VB8](https://gitee.com/lyt-top/vue-next-admin/issues/I58VB8)
- 🐞 修复 地址栏路由地址输入错误时,返回首页后,再次输入路由地址错误时,不跳转 404 问题
- 🐞 修复 [2.1.0 版本的图标选择组件多次点击后功能失效 #I590TH](https://gitee.com/lyt-top/vue-next-admin/issues/I590TH),感谢[@quber](https://gitee.com/quber)
## 2.1.0
`2022.04.18`
⚡⚡⚡ 此版本为破环性更新,优化内容如下:(谨慎更新!谨慎更新!!谨慎更新!!!)。因为 `vuex` 替换成 `pinia`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 部分界面图片不显示问题(更换 gitee 在线图片地址源)
- 🎯 优化 各界面方法引入与逻辑之间添加一行空行,方便区分内容
- 🎯 优化 图标选择器 [#I4YAHB](https://gitee.com/lyt-top/vue-next-admin/issues/I4YAHB),感谢[@真有你的](https://gitee.com/sunliusen)
- 🎯 优化 图标选择器 icon type 类型为 all 时,类型 ali、ele、awe 回显问题
- 🎯 优化 去掉开发环境 i18n 控制台警告,页面代码:[i18n/index.ts](https://gitee.com/lyt-top/vue-next-admin/blob/master/src/i18n/index.ts)
- 🎯 优化 `NextLoading.start()` 方法,防止第一次进入界面时出现短暂空白
- 🎯 优化 地址栏有参数退出登录,再次登录不跳之前界面问题 `src/layout/navBars/breadcrumb/user.vue`
- 🎯 优化 `SvgIcon` 组件,防止 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题,工作流不可连线、全屏时关闭按钮消失问题
- 🎯 优化 [如果 url 中有中文等特殊字符,第一次切换该 tab 时 keep-alive 失效#I55JS7](https://gitee.com/lyt-top/vue-next-admin/issues/I55JS7),感谢[yuyong1566](https://gitee.com/yuyong1566)
- 🎯 优化 [wangEditor](https://www.wangeditor.com/) 更新到 v5,[vue3 版本线上示例中 wangeditor 富文本编辑器 demo 实例,无法换行#I5565B](https://gitee.com/lyt-top/vue-next-admin/issues/I5565B),感谢@[jenchih](https://gitee.com/jenchih)
- 🎯 优化 [在关闭 tagview 时,高度刷新时会会变化,出现滚动条](https://gitee.com/lyt-top/vue-next-admin/issues/I55FHM),感谢[张松](https://gitee.com/zs310071113)
- 🎯 优化 [路由参数](https://lyt-top.gitee.io/vue-next-admin-preview/#/params/common)演示
- 🎉 新增 [vuex](https://vuex.vuejs.org/) 替换成 [pinia](https://pinia.vuejs.org/getting-started.html)
- 🎉 新增 tagsView 支持自定义 tagsView 名称(文章详情时有用),前往体验:[路由参数/普通路由](https://lyt-top.gitee.io/vue-next-admin-preview/#/params/common)。新增 tagsView 支持自定义名称国际化,感谢[@q7but](https://gitee.com/q7but)、[!22 add 添加自定义 tagVIewName 拓展,支持国际化](https://gitee.com/lyt-top/vue-next-admin/pulls/22/files)、感谢[@tony_tong_xin](https://gitee.com/tony_tong_xin)
- 🐞 修复 适配 `"element-plus": "^2.1.9",2.2.0` 版本
- 🐞 修复 [导航栏横向布局后,一级菜单显示问题#I4Z3M3](https://gitee.com/lyt-top/vue-next-admin/issues/I4Z3M3)
- 🐞 修复 横向布局三级及以上导航菜单高亮、导航高度不统一问题
- 🐞 修复 分栏模式下,选中的菜单是 primary 样式,鼠标移入字也变成 primary 色了,感谢群友@孤夜-流殇
- 🐞 修复 [vuex 里面改了颜色 但是不生效 #I4WFMA](https://gitee.com/lyt-top/vue-next-admin/issues/I4WFMA)
- 🐞 修复 全局主题 primary 清空颜色后报错,[#I4X0LG](https://gitee.com/lyt-top/vue-next-admin/issues/I4X0LG),感谢[面向 BUG 编程](https://gitee.com/fhtfy)
- 🐞 修复 [.eslintrc.js 文件 rules 标签名错误 #I53IPK](https://gitee.com/lyt-top/vue-next-admin/issues/I53IPK),感谢[yuyong1566](https://gitee.com/yuyong1566)
- 🐞 修复 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题
- 🐞 修复 `router.push` 路径找不到时报错问题,`404、401 界面` 已移入到 `main` 主布局里(之前全屏)
- 🐞 修复 [全局修改组件大小失效了](https://gitee.com/lyt-top/vue-next-admin/issues/I551RP),感谢[lg_boy](https://gitee.com/lg_boy)
- 🐞 修复 [修改一下配置时,需要每次都清理 `window.localStorage` 浏览器永久缓存,配置才会生效,问题解决#I567R1](https://gitee.com/lyt-top/vue-next-admin/issues/I567R1),感谢[@lanbao123](https://gitee.com/lanbao123)
- 🐞 修复 [标记为需要缓存的 tab 页后,再次从左侧菜单打开,还是显示被缓存的页面内容#I4UY3G](https://gitee.com/lyt-top/vue-next-admin/issues/I4UY3G),感谢@axcc1234、特别感谢群友@华仔
- 🌈 重构 路由(`/src/router/index.ts`)解决 No match found for location with path "xxx"(前端控制,后端控制未解决) 问题
## 2.0.2
`2022.03.04`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 Alert 提示添加边框
- 🎯 优化 功能 / 数字滚动 演示界面
- 🐞 修复 全局主题按钮颜色 :active 问题
- 🐞 修复 Dropdown 下拉菜单样式问题
- 🐞 修复 SvgIcon 图标组件动态切换时报警告问题,[SvgIcon 改变 name 时可能导致图像不显示](https://gitee.com/lyt-top/vue-next-admin/issues/I4VGE0),感谢@axcc1234
## 2.0.1
`2022.02.25`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 svgIcon 图标组件
- 🎯 优化 vite.config.ts 打包,感谢群友@YourObjec
- 🐞 修复 tagViews 开启图标不显示问题(风格 5),感谢群友@坏人
- 🐞 修复 [Element Plus 1.2.0-beta.6 以后的版本 el-table 在移动端无法左右滑动](https://gitee.com/lyt-top/vue-next-admin/issues/I4UPTP),感谢@YGDada
## 2.0.0
`2022.02.21`
⚡⚡⚡ 此版本为破环性更新,优化内容如下:(谨慎更新!谨慎更新!!谨慎更新!!!)。演示界面建议直接覆盖文件。如需使用之前版本,请前往[gitee 发行版](https://gitee.com/lyt-top/vue-next-admin/releases) 进行对应版本下载。基础版会基于 `master` 分支进行修改
- 🌟 更新 依赖更新最新版本
- 🌟 更新 登录页、首页
- 💔 移除 vue-web-screen-shot
- 💔 移除 城市多级联动,完整 json 数据请去 [vue-next-admin-images/menu](https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu) 仓库查看
- 💔 移除 功能/echartsTree 树图
- 💔 移除 其它设置/Tagsview 风格 2、Tagsview 风格 3
- 💔 移除 功能/验证器
- 🚧 调整 src/api 编写方式
- 🚧 调整 自定义封装公用组件演示,更好的维护
- 🎉 新增 Volar 支持,vs code 配置参考 [Vue Language Features (Volar)](https://lyt-top.gitee.io/vue-next-admin-doc-preview/home/vscode/)
- 🎉 新增 `SvgIcon` 支持本地 svg 图标使用
- 🎉 新增 表单表格验证演示
- 🎯 优化 全局主题(移除 success、info、warning、danger)
- 🎯 优化 工作流(开源)
- 🎯 优化 element plus svg 图标,`elementXXX` 改成 `ele-XXX`
- 🌈 重构 深色模式
- 🌹 合并 [处理 parent 的 h100 由于外层有 min-height 导致失效的问题](https://gitee.com/lyt-top/vue-next-admin/pulls/20),感谢@MaxNull、@21030442-mao
- 🐞 修复 element plus 升级 `^1.3.0-beta.5` 后 组件 size 大小问题(大改:涉及布局、演示界面)
- 🐞 修复 vs code 使用 Vue Language Features (Volar) 插件 代码报红问题(可以把公用的 ts 类型定义封装起来公用)
## 1.2.2
`2021.12.21`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 iframes 滚动条问题
- 🎯 优化 部署后每次都要强制刷新清浏览器缓存问题
- 🎉 新增 工具类百分比验证演示
- 🐞 修复 [tag-view 标签右键会超出浏览器 #I4KN78](https://gitee.com/lyt-top/vue-next-admin/issues/I4KN78)
## 1.2.1
`2021.12.12`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 cropper 裁剪时卡顿问题 [#I4M2VQ](https://gitee.com/lyt-top/vue-next-admin/issues/I4M2VQ)
- 🎯 优化 Wangeditor 富文本编辑器的问题 [#I4LPC1](https://gitee.com/lyt-top/vue-next-admin/issues/I4LPC1)、[#I4LM7I](https://gitee.com/lyt-top/vue-next-admin/issues/I4LM7I)
- 🐞 修复 浏览器标题问题
- 🐞 修复 element plus svg 图标引入
- 🐞 修复 工作流不可以拖线连接问题
## 1.2.0
`2021.11.28`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 深色模式
- 🎯 优化 `/@/utils` 文件夹,合并删除单一内容
- 🎯 优化 系统设置:菜单管理(新增、修改)、角色管理(新增菜单权限)、用户管理、部门管理、字典管理
- 🎯 优化 登录界面逻辑、权限管理逻辑
- 🎯 优化 同步 [vue-next-admin-images](https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu) 后端控制菜单模拟数据
- 🎉 新增 适配 Font Icon 向 SVG Icon 迁移(改动大,"element-plus": "^1.2.0-beta.4" 谨慎更新)
- 🐞 修复 热更新问题,感谢@甜蜜蜜
- 🐞 修复 页面/element 字体图标演示
- 🐞 修复 功能/图标选择器演示,新增高级功能 [issues #I4GJXQ](https://gitee.com/lyt-top/vue-next-admin/issues/I4GJXQ)
## 1.1.2
`2021.10.17`
- 🌟 更新 依赖更新最新版本
- 🐞 修复 开启全屏时,刷新界面被还原成未全屏的状态
- 🎯 优化 tagsView 右键菜单关闭逻辑
- 🎯 优化 wangeditor 富文本编辑器(增加双向绑定)
- 🎉 新增 工作流(暂不开源)
- 🎉 新增 基础版 ts(不带国际化),切换 `vue-next-admin-template` 分支
## 1.1.1
`2021.09.25`
- 🌟 更新 依赖更新最新版本(`"element-plus": "^1.1.0-beta.13"` 版本运行错误,`^1.1.0-beta.16`修复横向菜单卡死问题)
- 🐞 修复 Dialog 弹窗位置错误、Drawer 抽屉内边距、el-menu 菜单收起时背景色问题
- 🎯 优化 锁屏界面自动锁屏(s/秒)必须设置至少 1 秒
- 🎉 新增 分栏布局,鼠标移入当前项时,显示当前项菜单内容
- 🎉 新增 工作流(未完成)
## 1.1.0
`2021.09.10`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 小屏模式下登录页二维码遮挡标题问题
- 🎉 新增 图片验证器
- 🎉 新增 动态复杂表单
- 🎉 新增 工作流(未完成)
- 🎉 新增 深色主题(伪深色,样式变动大,谨慎更新)
## 1.0.18
`2021.08.29`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 权限组件去掉顶级 div(`/src/components/auth`)
- 🎉 新增 布局配置添加恢复默认按钮
- 🐞 修复 升级 <a href="https://element-plus.gitee.io/#/zh-CN/component/changelog" target="_blank">element plus 1.1.0-beta.7</a>后项目无法启动、el-menu 菜单
- 🐞 修复 表格固定列时的层级、设置了相对定位时,遮挡左侧导航菜单问题
## 1.0.17
`2021.08.22`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 去除设置布局切换,重置主题样式(initSetLayoutChange),切换布局需手动设置样式,设置的样式自动同步各布局
- 🎯 优化 Dropdown 下拉菜单用户账号靠边时换行问题
- 🎯 优化 左侧导航菜单,共用菜单树,防止 `布局配置` 设置 `菜单 / 顶栏` 时,样式丢失等问题
- 🐞 修复 固定 header 后没有回到顶部的 bug,拉取项目后运行不起来的 bug。<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/14" target="_blank">!14</a>,感谢<a href="https://gitee.com/wjs0509" target="_blank">@wjs0509</a>
- 🐞 修复 tagView 右键全屏后,浏览器窗口大小发生任何变化都会导致左边菜单显示出来,并且可点击打开对应页面。<a href="https://gitee.com/lyt-top/vue-next-admin/issues/I46E6T" target="_blank">I46E6T</a>
- 🐞 修复 默认设置 `菜单 / 顶栏` 样式不生效问题(/@/src/store/modules/themeConfig.ts)
## 1.0.16
`2021.08.14`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 菜单高亮(详情且详情设置了 meta.isHide 时,顶级菜单高亮),感谢群友@YourObject
- 🎯 优化 详情路径写法:如父级(/pages/filtering),那么详情为(/pages/filtering/details?id=1)。这样写可实现(详情时,父级菜单高亮),否则写成(/pages/filteringDetails?id=1)顶级菜单将不会高亮。可参考:`页面/过滤筛选组件`,点击当前图片进行测试
- 🎯 优化 tagsView 右键菜单全屏时,打开的界面高度问题
- 🎯 优化 图表批量 resize 问题
- 🐞 修复 菜单收起时(设置全局主题:primary 且有二级菜单时),文字高亮颜色不对
- 🐞 修复 国际化 <a href="https://gitee.com/lyt-top/vue-next-admin/issues/I43NPE" target="_blank">#I43NPE</a>。可参考:`页面/过滤筛选组件`,点击顶部语言切换,进行底部分页国际化查看
## 1.0.15
`2021.08.06`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 tagsView 右键菜单点击时的字段名(id 已修改成 contextMenuClickId)与路由中返回的 id 名冲突问题,感谢群友@伯牙已遇钟子期
- 🎉 新增 多个 form 表单验证界面演示
## 1.0.14
`2021.07.29`
- 🌟 更新 依赖更新最新版本(vue、vuex、vue-router),出现问题,请手动降级。版本查看:<a href="https://www.npmjs.com/" target="_blank">vnpm</a>
- 🎯 优化 数据可视化图表演示加载卡顿问题、优化有图表的演示界面
- 🎯 优化 路由参数演示界面
- 🎯 优化 tagsView 操作演示界面,由于存在相同路由多标签,必须要传全部参数值(query 或者 params)
- 🎉 新增 开启 TagsView 共用,开启时:(多个路由菜单共用一个详情组件(参数为后点击的覆盖前面点击的),tagsView 中只会出现一个(不支持同时出现多个 tagsView 标签))。关闭时:(多个路由菜单共用一个详情组件,参数不同,会同时出现多个 tagsView 标签)
- 🐞 修复 tagsView 共用(单标签)时,右键菜单功能点击,参数不对的问题(第 2n+个参数未覆盖第一个参数值)
- 🐞 修复 多 tagsView 标签(参数不同)、单个 tagsView 标签公用(参数不同)所带来的刷新功能、横向自动滚动等问题
- 🐞 修复 处理全屏若干问题,<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/12" target="_blank">pr!12</a>,感谢群友@另一个前端
## 1.0.13
`2021.07.25`
- 🌟 更新 依赖更新最新版本
- 🎉 新增 数据可视化演示界面(/visualizingDemo1、/visualizingDemo2)
- 🎉 新增 登录页扫码登录
## 1.0.12
`2021.07.16`
- 🌟 更新 依赖更新最新版本
- 🎉 新增 数据可视化演示空界面(待完善)
- 🎯 优化 tagsView 动态路由(xxx/:id/:name)时的右键菜单刷新、关闭其它时参数丢失问题(2021.07.15 优化)
- 🐞 修复 路由带参数时,复制路径到登录页,跳转后参数消失的问题
- 🐞 修复 设置多个外链,点击后,页面内容停留在上一个内容(内容未改变)、国际化处理、打开新窗口 sessionStorage 共享等
## 1.0.11
`2021.07.14`
- 🌟 更新 依赖更新最新版本
- 🎉 新增 路由参数、图片懒加载界面演示
- ⚠️ 警告 Form 表单 `binding value must be a string or number`,解决:加上 `label-position="top"` 不报警告(等待官方修复)
- 🎯 优化 锁屏界面动画效果、首页图表显示
- 🎯 优化 tagsView 右键菜单 `关闭` 功能逻辑
- 🐞 修复 开启 TagsView 拖拽报错及小于 `1000px` 时自动设置禁止拖拽(<a href="https://gitee.com/lyt-top/vue-next-admin/issues/I3ZRRI" target="_blank">#I3ZRRI</a>)
- 🐞 修复 `iframe 内嵌、外链` 高度问题,使用 computed 进行计算
- 🐞 修复 默认布局开启 `侧边栏 Logo` 与关闭 `菜单水平折叠`,切换到横向布局时,菜单看不见的问题
- 🐞 修复 切换不同布局时,再去开启 `经典布局分割菜单` 功能不生效问题
- 🐞 修复 浏览器窗口标题中/英文切换不实时生效的问题
- 🐞 修复 切换布局时,某些功能不可以使用。部分界面不需要取消事件监听(proxy.mittBus.off('xxx'))
- 🐞 修复 动态路由带参数,router-link 跳转问题(<a href="hhttps://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G" target="_blank">#I3YX6G</a>)
- 🐞 修复 横向菜单有二级菜单时,点击子级菜单不高亮问题
- 🐞 修复 功能 tagsView 操作演示不生效
## 1.0.10
`2021.07.07`
- 🌟 更新 依赖更新最新版本(字体图标无问题)
- 🎯 优化 内嵌 iframe、外链,解决 tagsView 刷新问题
## 1.0.9
`2021.07.02`
- 🌟 更新 依赖更新最新版本
- 🎯 优化 图标选择器设置宽度、v-model 等问题
- 🎯 优化 滚动通知栏在手机上的体验
- 🎯 优化 系统管理/新增菜单(编辑菜单),使用 `图标选择器` 进行模拟
- 🎯 优化 字体图标(自动载入) 逻辑
- 🐞 修复 screenfull 全屏时,按键盘 esc 键图标不改变问题,感谢群友@伯牙已遇钟子期
## 1.0.8
`2021.06.29`
- 🌟 更新 依赖更新最新版本
- 🎉 新增 表单中英文切换演示
- 🎯 优化 登录页查看密码 icon 图标
- 🎯 优化 图标选择器
- 🎯 优化 拖动指令
- 🐞 修复 form 表单在页面小于 576px 时的排版问题
## 1.0.7
`2021.06.24`
- 🌟 更新 依赖更新最新版本
- 🎉 新增 拖动指令及其演示界面
- 🎯 优化 锁屏界面,解锁提示
- 🎯 优化 登录页在手机上显示的效果
## 1.0.6
`2021.06.23`
- 🎯 优化 去掉内嵌 iframe 内边距(padding)
- 🎯 优化 城市多级联动组件
- 🎯 优化 Tree 树形控件改成表格组件
- 🐞 修复 Cascader 级联选择器高度问题
## 1.0.5
`2021.06.22`
- 🌟 更新 vite 降级为@vite2.3.7,降级方法 `cnpm install vite@2.3.7`,防止 element plus 字体图标消失
- 🐞 修复 开启后端控制路由(isRequestRoutes = true)时,内嵌 iframe、外链不可使用的问题
## 1.0.4
`2021.06.19`
- 🌟 更新 依赖更新最新版本("vite": "^2.3.7")热更新无问题
- 🎉 新增 深克隆工具,方便开发,感谢<a href="https://gitee.com/kangert" target="_blank">@kangert</a>(<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/6" target="_blank">#6</a>)
- 🎯 优化 vuex 模块自动导入。感谢<a href="https://gitee.com/kangert" target="_blank">@kangert</a>(<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/4" target="_blank">#4</a>),感谢群友@web 小学生-第五君
- 🎯 优化 类型定义提高编码体验,修复不能将类型“string | undefined”分配给类型“string”的问题。感谢<a href="https://gitee.com/kangert" target="_blank">@kangert</a>(<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/5" target="_blank">#5</a>)
- 🎯 优化 `layout` 文件夹移动到与 `views` 文件夹同级(改动较大,`/@/views/layout` 变成 `/@/layout`)
- 🎯 优化 页面有 `console.log` 时 `eslint` 不生效问题
- 🎯 优化 页面、ts 中 `any` 类型问题(改动较大)
- 🎯 优化 登录页在手机上显示的效果
- 🎯 优化 多行注释信息,鼠标放到方法名即可查看,更加直观的知道方法参数等。引入方法时需去掉以 `.ts` 结尾的后缀(改动较大)
- 🎯 优化 移除 `utils/storage.ts` 下的旧写法(改动较大)
- 🎯 优化 拆分 `router` 下内容,路由、前端、后端控制分开写,方便理解
- 🐞 修复 鼠标移入顶部用户信息栏 `开/关全屏` 文字反向问题
- 🐞 修复 热更新时,NextLoading(界面 loading) 不消失问题 `window.nextLoading === undefined`
- 🐞 修复 vuex 中不可以使用 `/@/api/xxx` 下的接口调用问题
## 1.0.3
`2021.06.02`
- ❄️ 删除 G6 思维导图界面
- 🌟 更新 手动更新 vue、vue-router、vuex 到最近最多人使用的版本,出现不可预测的问题请降低版本。版本查看:<a href="https://www.npmjs.com/package/vue" target="_blank">vue 版本查看</a>
- 🐞 修复 开启后端控制路由 `isRequestRoutes` 在非首页刷新页面后,回到首页的问题,感谢群友@伯牙已遇钟子期
## 1.0.2
`2021.06.01`
- 🌟 更新 依赖更新最新版本
- 🐞 修复 菜单搜索中文不可以搜索的问题,感谢群友@逍遥天意
## 1.0.1
`2021.05.31`
- 🎉 新增 更新日志文件 `CHANGELOG.md`,以后每次更新都会在这里显示对应内容
- 🌟 更新 依赖更新最新版本
- 🐞 修复 分栏、经典布局路由设置 `meta.isHide` 为 `true` 时报错问题,感谢群友@29、@芭芭拉
- 🐞 修复 经典布局点击 `tagsView` 左侧菜单数据不变问题
LICENSE
对比新文件
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 lyt-Top
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
index.html
对比新文件
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta
            name="keywords"
            content="vue-next-admin,vue-prev-admin,vue-admin-wonderful,后台管理系统一站式平台模板,希望可以帮你完成快速开发。vue2.x,vue2.0,vue2,vue3,vue3.x,vue3.0,CompositionAPI,typescript,element plus,element,plus,admin,wonderful,wonderful-next,vue-next-admin,vite,vite-admin,快速,高效,后台模板,后台系统,管理系统"
        />
        <meta
            name="description"
            content="vue-next-admin,基于 vue3 + CompositionAPI + typescript + vite + element plus,适配手机、平板、pc 的后台开源免费管理系统模板!vue-prev-admin,基于 vue2 +  element ui,适配手机、平板、pc 的后台开源免费管理系统模板!"
        />
        <title>vue-next-admin</title>
    </head>
    <body>
        <div id="app"></div>
        <script type="text/javascript">
            var _hmt = _hmt || [];
            (function () {
                var hm = document.createElement('script');
                hm.src = 'https://hm.baidu.com/hm.js?d9c8b87d10717013641458b300c552e4';
                var s = document.getElementsByTagName('script')[0];
                s.parentNode.insertBefore(hm, s);
            })();
        </script>
        <script type="module" src="/src/main.ts"></script>
        <script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=wsijQt8sLXrCW71YesmispvYHitfG9gv&s=1"></script>
    </body>
</html>
package-lock.json
对比新文件
文件太大
package.json
对比新文件
@@ -0,0 +1,88 @@
{
    "name": "vue-next-admin",
    "version": "2.1.1",
    "description": "vue3 vite next admin template",
    "author": "lyt_20201208",
    "license": "MIT",
    "scripts": {
        "dev": "vite --force",
        "build": "vite build",
        "lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/"
    },
    "dependencies": {
        "@element-plus/icons-vue": "^2.0.6",
        "@kjgl77/datav-vue3": "^1.2.1",
        "@wangeditor/editor": "^5.1.14",
        "axios": "^0.27.2",
        "countup.js": "^2.2.0",
        "cropperjs": "^1.5.12",
        "echarts": "^5.3.3",
        "echarts-gl": "^2.0.9",
        "echarts-wordcloud": "^2.0.0",
        "element-plus": "^2.2.9",
        "js-base64": "^3.7.2",
        "js-cookie": "^3.0.1",
        "json-bigint": "^1.0.0",
        "jsplumb": "^2.15.6",
        "mitt": "^3.0.0",
        "nprogress": "^0.2.0",
        "pinia": "^2.0.14",
        "pinia-plugin-persistedstate": "^2.1.1",
        "print-js": "^1.6.0",
        "qrcodejs2-fixes": "^0.0.2",
        "screenfull": "^6.0.1",
        "sortablejs": "^1.15.0",
        "splitpanes": "^3.1.1",
        "vue": "^3.2.36",
        "vue-clipboard3": "^2.0.0",
        "vue-grid-layout": "^3.0.0-beta1",
        "vue-i18n": "^9.1.10",
        "vue-router": "^4.0.15",
        "wangeditor": "^4.7.15",
        "xlsx": "^0.18.5"
    },
    "devDependencies": {
        "@types/json-bigint": "^1.0.1",
        "@types/node": "^17.0.39",
        "@types/nprogress": "^0.2.0",
        "@types/sortablejs": "^1.13.0",
        "@typescript-eslint/eslint-plugin": "^5.27.0",
        "@typescript-eslint/parser": "^5.27.0",
        "@vitejs/plugin-vue": "^2.3.3",
        "@vue/compiler-sfc": "^3.2.36",
        "dotenv": "^16.0.1",
        "eslint": "^8.17.0",
        "eslint-plugin-vue": "^9.1.0",
        "prettier": "^2.6.2",
        "sass": "^1.52.2",
        "sass-loader": "^13.0.0",
        "typescript": "^4.7.3",
        "vite": "^2.9.9",
        "vue-eslint-parser": "^9.0.2"
    },
    "browserslist": [
        "> 1%",
        "last 2 versions",
        "not dead"
    ],
    "bugs": {
        "url": "https://gitee.com/lyt-top/vue-next-admin/issues"
    },
    "engines": {
        "node": ">=12.0.0",
        "npm": ">= 6.0.0"
    },
    "keywords": [
        "vue",
        "vue3",
        "vuejs/vue-next",
        "element-ui",
        "element-plus",
        "vue-next-admin",
        "next-admin"
    ],
    "repository": {
        "type": "git",
        "url": "https://gitee.com/lyt-top/vue-next-admin.git"
    }
}
plugins.d.ts
对比新文件
@@ -0,0 +1,4 @@
declare module 'vue-grid-layout';
declare module 'qrcodejs2-fixes';
declare module 'splitpanes';
declare module 'js-cookie';
public/favicon.ico
shim.d.ts
对比新文件
@@ -0,0 +1,13 @@
/* eslint-disable */
// 声明文件,*.vue 后缀的文件交给 vue 模块来处理
declare module '*.vue' {
    import type { DefineComponent } from 'vue';
    const component: DefineComponent<{}, {}, any>;
    export default component;
}
// 声明文件,定义全局变量。其它 app.config.globalProperties.xxx,使用 getCurrentInstance() 来获取
interface Window {
    nextLoading: boolean;
}
source.d.ts
对比新文件
@@ -0,0 +1,6 @@
declare module '*.json';
declare module '*.png';
declare module '*.jpg';
declare module '*.scss';
declare module '*.ts';
declare module '*.js';
src/App.vue
对比新文件
@@ -0,0 +1,115 @@
<template>
<!--        <transition name="fade" mode="out-in">-->
<!--            <keep-alive :exclude="excludeList">-->
<!--                <router-view v-if="!$route.meta.iskeepAlive" :key="$route.path"></router-view>-->
<!--            </keep-alive>-->
<!--        </transition>-->
    <!--    <router-view v-if="!$route.meta.iskeepAlive" v-slot="{ Component }">-->
    <!--        <transition name="fade" mode="in-out">-->
    <!--            <keep-alive :exclude="excludeList" :include="includeList">-->
    <!--                <components :is="Component" :key="$route.id"></components>-->
    <!--            </keep-alive>-->
    <!--        </transition>-->
    <!--    </router-view>-->
    <el-config-provider :size="getGlobalComponentSize" :locale="i18nLocale">
        <router-view v-show="themeConfig.lockScreenTime > 1" />
        <LockScreen v-if="themeConfig.isLockScreen" />
        <Setings ref="setingsRef" v-show="themeConfig.lockScreenTime > 1" />
        <CloseFull v-if="!themeConfig.isLockScreen" />
    </el-config-provider>
</template>
<script lang="ts">
import { computed, ref, getCurrentInstance, onBeforeMount, onMounted, onUnmounted, nextTick, defineComponent, watch, reactive, toRefs } from 'vue';
import { useRoute } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { useThemeConfig } from '/@/stores/themeConfig';
import other from '/@/utils/other';
import { Local, Session } from '/@/utils/storage';
import setIntroduction from '/@/utils/setIconfont';
import LockScreen from '/@/layout/lockScreen/index.vue';
import Setings from '/@/layout/navBars/breadcrumb/setings.vue';
import CloseFull from '/@/layout/navBars/breadcrumb/closeFull.vue';
import { initBackEndControlRoutes } from './router/backEnd';
export default {
    name: 'app',
    components: { LockScreen, Setings, CloseFull },
    setup() {
        const { proxy } = <any>getCurrentInstance();
        const setingsRef = ref();
        const route = useRoute();
        const stores = useTagsViewRoutes();
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const state = reactive({
            i18nLocale: null,
            excludeList: ['a-e'],
            includeList: []
        });
        // 获取全局组件大小
        const getGlobalComponentSize = computed(() => {
            return other.globalComponentSize();
        });
        // 布局配置弹窗打开
        const openSetingsDrawer = () => {
            setingsRef.value.openDrawer();
        };
        // 设置初始化,防止刷新时恢复默认
        onBeforeMount(() => {
            // 设置批量第三方 icon 图标
            setIntroduction.cssCdn();
            // 设置批量第三方 js
            setIntroduction.jsCdn();
        });
        // 页面加载时
        onMounted(() => {
            nextTick(() => {
                // 监听布局配置弹窗点击打开
                proxy.mittBus.on('openSetingsDrawer', () => {
                    openSetingsDrawer();
                });
                // 设置 i18n,App.vue 中的 el-config-provider
                proxy.mittBus.on('getI18nConfig', (locale: string) => {
                    (state.i18nLocale as string | null) = locale;
                });
                // 获取缓存中的布局配置;
                if (Local.get('themeConfig')) {
                    storesThemeConfig.setThemeConfig(themeConfig.value);
                    // storesThemeConfig.setThemeConfig(Local.get('themeConfig'));
                    document.documentElement.style.cssText = Local.get('themeConfigStyle');
                }
                // 获取缓存中的全屏配置
                if (Session.get('isTagsViewCurrenFull')) {
                    stores.setCurrenFullscreen(Session.get('isTagsViewCurrenFull'));
                }
            });
            // if(!Session.get('token')) return
            // initBackEndControlRoutes()
        });
        // 页面销毁时,关闭监听布局配置/i18n监听
        onUnmounted(() => {
            proxy.mittBus.off('openSetingsDrawer', () => {});
            proxy.mittBus.off('getI18nConfig', () => {});
        });
        // 监听路由的变化,设置网站标题
        watch(
            () => route.path,
            () => {
                other.useTitle();
            },
            {
                deep: true
            }
        );
        return {
            themeConfig,
            setingsRef,
            getGlobalComponentSize,
            ...toRefs(state)
        };
    }
};
</script>
src/api/accidentManagementSystem/index.ts
对比新文件
@@ -0,0 +1,145 @@
import request from '/@/utils/request';
export function accidentManagementSystemApi() {
    return {
        // 事故快报一览
        accidentList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/accidentExpress/page/list',
                method: 'post',
                data: params
            });
        },
        // 事故快报新增
        accidentAdd: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/accidentExpress/add',
                method: 'post',
                data: params
            });
        },
        // 事故快报详情
        accidentScarh: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentExpress/info/${params}`,
                method: 'get'
            });
        },
        // 事故快报修改
        accidentView: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/accidentExpress/update',
                method: 'post',
                data: params
            });
        },
        // 事故快报删除
        accidentDele: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentExpress/batchDelete`,
                method: 'post',
                data: params
            });
        },
        //  工伤申报一览
        workList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/workInjuryDeclaration/page/list',
                method: 'post',
                data: params
            });
        },
        // 工伤申报新增
        workAdd: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/workInjuryDeclaration/add',
                method: 'post',
                data: params
            });
        },
        // 工伤申报详情
        workScarh: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/workInjuryDeclaration/info/${params}`,
                method: 'get'
            });
        },
        // 工伤申报修改
        workView: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/workInjuryDeclaration/update',
                method: 'post',
                data: params
            });
        },
        // 工伤申报删除/批量删除
        workDelete: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/workInjuryDeclaration/batchDelete`,
                method: 'post',
                data: params
            });
        },
        // 伤亡人员一览
        casualtyList: (id: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentExpress/casualty/list/${id}`,
                method: 'get'
            });
        },
        // 伤亡人员新增
        casualtyAdd: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentExpress/casualty/add`,
                method: 'post',
                data: params
            });
        },
        // 伤亡人员删除
        casualtyDel: (id: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentExpress/casualty/del/${id}`,
                method: 'get'
            });
        },
        // 事故案例 一览
        getaccidentCaseList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentCase/page/list`,
                method: 'post',
                data: params
            });
        },
        //事故案例 新增
        getaccidentCaseAdd: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentCase/add`,
                method: 'post',
                data: params
            });
        },
        //事故案例 新增
        getaccidentCaseUpdata: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentCase/update`,
                method: 'post',
                data: params
            });
        },
        //事故案例 详情
        getaccidentCaseDetail: (id: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentCase/info/${id}`,
                method: 'get'
            });
        },
        //事故案例 删除
        getaccidentCaseDelete: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentCase/batchDelete`,
                method: 'post',
                data: params
            });
        }
    };
}
src/api/contingencyManagement/contingency/index.ts
对比新文件
@@ -0,0 +1,83 @@
import request from '/@/utils/request';
export function contingencyApi() {
    return {
        //应急队伍一览
        getTeamManagementList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyTeam/page/list`,
                method: 'post',
                data: params
            });
        },
        // 应急队伍新增
        addEmergencyTeam: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyTeam/add`,
                method: 'post',
                data: params
            });
        },
        // 应急队伍详情
        seeEmergencyTeam: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyTeam/info/${params}`,
                method: 'get'
            });
        },
        // 应急队伍编辑
        editEmergencyTeam: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyTeam/update`,
                method: 'post',
                data: params
            });
        },
        // 应急队伍删除
        deleteEmergencyTeam: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyTeam/batchDelete`,
                method: 'post',
                data: params
            });
        },
        // 应急队伍人员一览
        getEmergencyTeamPersonnelList: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyTeam/memberList/${params}`,
                method: 'get'
                // data:params
            });
        },
        // 应急队伍人员新增
        addEmergencyTeamPersonnel: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyTeam/addMember`,
                method: 'post',
                data: params
            });
        },
        // 应急队伍人员详情
        seeEmergencyTeamPersonnel: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyTeam/infoMember/${params}`,
                method: 'get'
            });
        },
        // 应急队伍人员编辑
        editEmergencyTeamPersonnel: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyTeam/updateMember`,
                method: 'post',
                data: params
            });
        },
        // 应急队伍人员删除
        deleteEmergencyTeamPersonnel: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyTeam/deleteMember/${params}`,
                method: 'get'
            });
        }
    };
}
src/api/contingencyManagement/emergencyDrillEvaluation/index.ts
对比新文件
@@ -0,0 +1,45 @@
import request from '/@/utils/request';
export function emergencyDrillEvaluationApi() {
    return {
        // 应急演练实施评价一览
        getEmergencyDrillEvaluationList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencyDrillEvaluation/page/list',
                method: 'post',
                data: params
            });
        },
        // 应急演练实施评价新增
        addEmergencyDrillEvaluation: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillEvaluation/add`,
                method: 'post',
                data: params
            });
        },
        // 应急演练实施评价详情
        seeEmergencyDrillEvaluation: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillEvaluation/info/${params}`,
                method: 'get'
            });
        },
        // 应急演练实施评价编辑
        editEmergencyDrillEvaluation: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillEvaluation/update`,
                method: 'post',
                data: params
            });
        },
        // 应急演练实施评价删除
        deleteEmergencyDrillEvaluation: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillEvaluation/batchDelete`,
                method: 'post',
                data: params
            });
        }
    };
}
src/api/contingencyManagement/emergencyDrillExecute/index.ts
对比新文件
@@ -0,0 +1,45 @@
import request from '/@/utils/request';
export function emergencyDrillExecuteApi() {
    return {
        // 应急演练实施一览
        getEmergencyDrillExecuteList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencyDrillExecute/page/list',
                method: 'post',
                data: params
            });
        },
        // 应急演练实施新增
        addEmergencyDrillExecute: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillExecute/add`,
                method: 'post',
                data: params
            });
        },
        // 应急演练实施详情
        seeEmergencyDrillExecute: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillExecute/info/${params}`,
                method: 'get'
            });
        },
        // 应急演练实施编辑
        editEmergencyDrillExecute: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillExecute/update`,
                method: 'post',
                data: params
            });
        },
        // 应急演练实施删除
        deleteEmergencyDrillExecute: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillExecute/batchDelete`,
                method: 'post',
                data: params
            });
        }
    };
}
src/api/contingencyManagement/emergencyDrillPlan/index.ts
对比新文件
@@ -0,0 +1,45 @@
import request from '/@/utils/request';
export function releaseDrillPlanApi() {
    return {
        //演练计划发布一览
        getReleaseDrillPlanList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencyDrillPlan/page/list',
                method: 'post',
                data: params
            });
        },
        // 演练计划发布新增
        addReleaseDrillPlan: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillPlan/add`,
                method: 'post',
                data: params
            });
        },
        // 演练计划发布详情
        seeReleaseDrillPlan: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillPlan/info/${params}`,
                method: 'get'
            });
        },
        // 演练计划发布编辑
        editReleaseDrillPlan: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillPlan/update`,
                method: 'post',
                data: params
            });
        },
        // 演练计划发布删除
        deleteReleaseDrillPlan: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyDrillPlan/batchDelete`,
                method: 'post',
                data: params
            });
        }
    };
}
src/api/contingencyManagement/emergencyMaterialsInspection/index.ts
对比新文件
@@ -0,0 +1,45 @@
import request from '/@/utils/request';
export function emergencyMaterialsInspectionApi() {
    return {
        //应急物资检查一览
        getEmergencyMaterialsInspectionList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencySuppliesInspect/page/list',
                method: 'post',
                data: params
            });
        },
        // 应急物资检查新增
        addEmergencyMaterialsInspection: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencySuppliesInspect/add`,
                method: 'post',
                data: params
            });
        },
        // 应急物资检查详情
        seeEmergencyMaterialsInspection: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencySuppliesInspect/info/${params}`,
                method: 'get'
            });
        },
        // 应急物资检查编辑
        editEmergencyMaterialsInspection: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencySuppliesInspect/update`,
                method: 'post',
                data: params
            });
        },
        // 应急物资检查删除
        deleteEmergencyMaterialsInspection: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencySuppliesInspect/batchDelete`,
                method: 'post',
                data: params
            });
        }
    };
}
src/api/contingencyManagement/emergencyPlan/index.ts
对比新文件
@@ -0,0 +1,91 @@
import request from '/@/utils/request';
export function emergencyPlanApi() {
    return {
        // 应急预案管理一览
        getEmergencyPlanList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencyPlan/page/list',
                method: 'post',
                data: params
            });
        },
        // 应急预案管理新增
        addEmergencyPlan: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyPlan/add`,
                method: 'post',
                data: params
            });
        },
        // 应急队伍详情
        seeEmergencyTeam: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyPlan/info/${params}`,
                method: 'get'
            });
        },
        // 应急队伍编辑
        editEmergencyTeam: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyPlan/update`,
                method: 'post',
                data: params
            });
        },
        // 应急队伍删除
        deleteEmergencyTeam: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyPlan/batchDelete`,
                method: 'post',
                data: params
            });
        },
        // 应急队伍废止
        EmergencyTeam: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyPlan/updateAbolish?id=${params}&abolishStatus=true`,
                method: 'get'
            });
        },
        // 应急队伍还原
        reductionEmergencyTeam: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyPlan/updateAbolish?id=${params}&abolishStatus=false`,
                method: 'get'
            });
        },
        // 应急预案管理审批新增
        approvalEmergencyPlan: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyWorkApprove/add`,
                method: 'post',
                data: params
            });
        },
        // 应急预案管理审批修改
        editApprovalEmergencyPlan: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyWorkApprove/update`,
                method: 'post',
                data: params
            });
        },
        // 应急预案管理审批查看
        approvalProcessEmergencyPlan: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyWorkApprove/info/${params}`,
                method: 'get',
                data: params
            });
        },
        // 审批一览
        processEmergencyPlan: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyWorkApprove/page/list`,
                method: 'post',
                data: params
            });
        }
    };
}
src/api/contingencyManagement/emergencyPlanLog/index.ts
对比新文件
@@ -0,0 +1,45 @@
import request from '/@/utils/request';
export function emergencyPlanLogApi() {
    return {
        // 应急预案启动记录一览
        getEmergencyPlanLogList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencyPlanLog/page/list',
                method: 'post',
                data: params
            });
        },
        // 应急预案启动记录新增
        addEmergencyPlanLog: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencyPlanLog/add',
                method: 'post',
                data: params
            });
        },
        // 应急预案启动记录详情
        seeEmergencyPlanLog: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyPlanLog/info/${params}`,
                method: 'get'
            });
        },
        // 应急预案启动记录修改
        editEmergencyPlanLog: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencyPlanLog/update',
                method: 'post',
                data: params
            });
        },
        // 应急预案启动记录删除
        deleteEmergencyPlanLog: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyPlanLog/batchDelete`,
                method: 'post',
                data: params
            });
        }
    };
}
src/api/contingencyManagement/emergencyResources/index.ts
对比新文件
@@ -0,0 +1,45 @@
import request from '/@/utils/request';
export function emergencySuppliesApi() {
    return {
        // 应急物资一览
        getEmergencySuppliesList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencySupplies/page/list',
                method: 'post',
                data: params
            });
        },
        // 应急物资新增
        addEmergencySupplies: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencySupplies/add',
                method: 'post',
                data: params
            });
        },
        // 应急物资详情
        seeEmergencySupplies: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencySupplies/info/${params}`,
                method: 'get'
            });
        },
        // 应急物资编辑
        editEmergencySupplies: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencySupplies/update`,
                method: 'post',
                data: params
            });
        },
        // 应急物资删除
        deleteEmergencySupplies: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencySupplies/batchDelete`,
                method: 'post',
                data: params
            });
        }
    };
}
src/api/contingencyManagement/maintenanceEmergencyMaterials/index.ts
对比新文件
@@ -0,0 +1,45 @@
import request from '/@/utils/request';
export function maintenanceEmergencyMaterialsApi() {
    return {
        //应急物资保养一览
        getMaintenanceEmergencyMaterialsList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencySuppliesMaintain/page/list',
                method: 'post',
                data: params
            });
        },
        // 应急物资保养新增
        addMaintenanceEmergencyMaterials: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencySuppliesMaintain/add`,
                method: 'post',
                data: params
            });
        },
        // 应急物资保养详情
        seeMaintenanceEmergencyMaterials: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencySuppliesMaintain/info/${params}`,
                method: 'get'
            });
        },
        // 应急物资保养编辑
        editMaintenanceEmergencyMaterials: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencySuppliesMaintain/update`,
                method: 'post',
                data: params
            });
        },
        // 应急物资保养删除
        deleteMaintenanceEmergencyMaterials: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencySuppliesMaintain/batchDelete`,
                method: 'post',
                data: params
            });
        }
    };
}
src/api/doublePreventSystem/check/index.ts
对比新文件
@@ -0,0 +1,29 @@
import request from '/@/utils/request';
export function hiddenCheckApi() {
    return {
        // v1
        getHiddenCheckList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/dangerRectify/select/getRectifyOverPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        submitHiddenCheck: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/dangerRectify/update/reportRectify`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllHiddenCheckList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/device/select/listDevices`,
                method: 'post'
            });
        }
    };
}
src/api/doublePreventSystem/checkUnit/index.ts
对比新文件
@@ -0,0 +1,44 @@
import request from '/@/utils/request';
export function checkUnitApi() {
    return {
        // v1
        getCheckUnitList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/taskUnit/select/getTaskUnitPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        addCheckUnit: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/taskUnit/insert/saveTaskUnit`,
                method: 'post',
                data: data
            });
        },
        // v1
        modCheckUnit: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/taskUnit/update/updateTaskUnit`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteCheckUnit: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/taskUnit/delete/deleteTaskUnit`,
                method: 'post',
                data: data
            });
        },
        getAllCheckUnitList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/taskUnit/select/listTaskUnit`,
                method: 'post'
            });
        }
    };
}
src/api/doublePreventSystem/productionDevice/index.ts
对比新文件
@@ -0,0 +1,45 @@
import request from '/@/utils/request';
export function productionDeviceApi() {
    return {
        // v1
        getProductionDeviceList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/device/select/getDevicePage`,
                method: 'post',
                data: data
            });
        },
        // v1
        addProductionDevice: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/device/insert/saveDevice`,
                method: 'post',
                data: data
            });
        },
        // v1
        modProductionDevice: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/device/update/updateDevice`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteProductionDevice: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/device/delete/deleteDevice`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllProductionDeviceList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/device/select/listDevices`,
                method: 'post'
            });
        }
    };
}
src/api/doublePreventSystem/record/index.ts
对比新文件
@@ -0,0 +1,31 @@
import request from '/@/utils/request';
export function recordApi() {
    return {
        // v1
        getRecordList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/checkTask/select/getTaskPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        submitRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/checkTask/update/updateTask`,
                method: 'post',
                data: data
            });
        },
        getTask: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/checkTask/update/taskToUser`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/doublePreventSystem/rectify/index.ts
对比新文件
@@ -0,0 +1,51 @@
import request from '/@/utils/request';
export function hiddenRectifyApi() {
    return {
        // v1
        getHiddenRectifyList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/dangerRectify/select/getDangerRectifyPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        submitHiddenRectify: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/dangerRectify/update/applyReport`,
                method: 'post',
                data: data
            });
        },
        // v1
        delayHiddenRectifyTime: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/dangerRectify/update/timeOutRectify`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteHiddenRectify: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/dangerRectify/delete/deleteDangerRectify`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllHiddenRectifyList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/device/select/listDevices`,
                method: 'post'
            });
        },
        getCodeByTime: (date: string) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/dangerManage/count/byCreateDate?date=${date}`,
                method: 'get'
            });
        }
    };
}
src/api/doublePreventSystem/report/index.ts
对比新文件
@@ -0,0 +1,38 @@
import request from '/@/utils/request';
export function hiddenReportApi() {
    return {
        // v1
        getHiddenReportList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/dangerManage/select/getDangerManagePage`,
                method: 'post',
                data: data
            });
        },
        // v1
        addHiddenReport: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/dangerManage/insert/saveDangerManage`,
                method: 'post',
                data: data
            });
        },
        // v1
        modHiddenReport: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/dangerManage/update/updateDangerManage`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteHiddenReport: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/dangerManage/delete/deleteDangerManage`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/doublePreventSystem/riskControlMeasure/index.ts
对比新文件
@@ -0,0 +1,50 @@
import request from '/@/utils/request';
export function riskControlMeasureApi() {
    return {
        // v1
        getRiskControlMeasureList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskControlMeasure/select/getRiskControlMeasurePage`,
                method: 'post',
                data: data
            });
        },
        // v1
        addRiskControlMeasure: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskControlMeasure/insert/saveRiskControlMeasure`,
                method: 'post',
                data: data
            });
        },
        // v1
        modRiskControlMeasure: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskControlMeasure/update/updateRiskControlMeasure`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteRiskControlMeasure: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskControlMeasure/delete/deleteRiskControlMeasure`,
                method: 'post',
                data: data
            });
        },
        getAllRiskControlMeasureList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskControlMeasure/select/listControlMeasure`,
                method: 'post'
            });
        },
        getClassifyData: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskControlMeasure/select/listMeasures`,
                method: 'post'
            });
        }
    };
}
src/api/doublePreventSystem/safetyRiskAnalyseUnit/index.ts
对比新文件
@@ -0,0 +1,45 @@
import request from '/@/utils/request';
export function safetyRiskAnalyseUnitApi() {
    return {
        // v1
        getSafetyRiskAnalyseUnitList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskAnaUnit/select/getRiskUnitPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        addSafetyRiskAnalyseUnit: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskAnaUnit/insert/saveRiskAnaUnit`,
                method: 'post',
                data: data
            });
        },
        // v1
        modSafetyRiskAnalyseUnit: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskAnaUnit/update/updateRiskAnaUnit`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteSafetyRiskAnalyseUnit: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskAnaUnit/delete/deleteRiskAnaUnit`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllSafetyRiskAnalyseUnitList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskEvent/select/listRiskUnits`,
                method: 'post'
            });
        }
    };
}
src/api/doublePreventSystem/safetyRiskEvent/index.ts
对比新文件
@@ -0,0 +1,45 @@
import request from '/@/utils/request';
export function safetyRiskEventApi() {
    return {
        // v1
        getSafetyRiskEventList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskEvent/select/getRiskEventPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        addSafetyRiskEvent: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskEvent/insert/saveRiskEvent`,
                method: 'post',
                data: data
            });
        },
        // v1
        modSafetyRiskEvent: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskEvent/update/updateRiskEvent`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteSafetyRiskEvent: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskEvent/delete/deleteRiskEvent`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllSafetyRiskEventList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/riskEvent/select/getListEvents`,
                method: 'post'
            });
        }
    };
}
src/api/doublePreventSystem/work/index.ts
对比新文件
@@ -0,0 +1,38 @@
import request from '/@/utils/request';
export function workApi() {
    return {
        // v1
        getWorkList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/checkWork/select/getCheckWorkPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        addWork: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/checkWork/insert/saveCheckWork`,
                method: 'post',
                data: data
            });
        },
        // v1
        modWork: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/checkWork/update/updateCheckWork`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteWork: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/checkWork/delete/deleteCheckWork`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/facilityManagement/claimReturnRecords/index.ts
对比新文件
@@ -0,0 +1,27 @@
import request from "/@/utils/request";
export function claimReturnRecordsApi() {
    return {
        getClaimReturnRecords: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/material/record/page/list`,
                method: 'post',
                data
            });
        },
        returnGoods: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/material/record/revert`,
                method: 'post',
                data
            });
        },
        refreshReturnAndNoReturn: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/material/record/queryById`,
                method: 'post',
                data
            });
        },
    }
}
src/api/facilityManagement/goodsDetailManage/index.ts
对比新文件
@@ -0,0 +1,89 @@
import request from '/@/utils/request';
export function goodsDetailApi() {
    return {
        // 设备设施类型管理 查询单条数据
        getGoodsDetailList: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/page/list`,
                method: 'post',
                data
            });
        },
        addGoodsDetail: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/save`,
                method: 'post',
                data
            });
        },
        checkOutBySingle: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/single/delivery`,
                method: 'post',
                data
            });
        },
        checkOutByMore: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/batch/delivery/ids`,
                method: 'post',
                data
            });
        },
        updateGoodsDetail: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/update`,
                method: 'post',
                data
            });
        },
        getGoodsListByLevel: () => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/safeMaterial/list`,
                method: 'post',
            });
        },
        checkOutOne: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/single/delivery`,
                method: 'post',
                data
            });
        },
        checkOutMore: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/batch/delivery/ids`,
                method: 'post',
                data
            });
        },
        checkInOne: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/single/receipt`,
                method: 'post',
                data
            });
        },
        checkInMore: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/batch/receipt`,
                method: 'post',
                data
            });
        },
        deleteSingleGoods: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/delete`,
                method: 'post',
                data
            });
        },
        deleteBatchGoods: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/deleteBatch`,
                method: 'post',
                data
            });
        },
    }
}
src/api/facilityManagement/index.ts
对比新文件
@@ -0,0 +1,104 @@
import request from '/@/utils/request';
export function facilityManagementApi() {
    return {
        // 设备设施类型管理 查询单条数据
        getequipmentTypeMngDetail: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipmentTypeMng/selectOne/${params}`,
                method: 'get'
            });
        },
        // 设备设施类型管理 新增或者修改数据
        getequipmentTypeMngAddOrUpdate: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/equipmentTypeMng/addOrUpdate',
                method: 'post',
                data: params
            });
        },
        // 设备设施类型管理 删除
        getequipmentTypeMngDelete: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipmentTypeMng/delete`,
                method: 'post',
                data: params
            });
        },
        // 设备设施类型管理 查询树状数据
        getequipmentTypeMngTreeData: () => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipmentTypeMng/treeData`,
                method: 'get'
            });
        },
        // 仪器仪表信息、生产设备设施、安全设备设施 查询单条数据
        getequipmentInfoDetail: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipmentInfo/selectOne/${params}`,
                method: 'get'
            });
        },
        // 仪器仪表信息、生产设备设施、安全设备设施 新增或者修改数据
        getequipmentInfoAddOrUpdate: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/equipmentInfo/addOrUpdate',
                method: 'post',
                data: params
            });
        },
        // 仪器仪表信息、生产设备设施、安全设备设施 删除
        getequipmentInfoDelete: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipmentInfo/delete`,
                method: 'post',
                data: params
            });
        },
        // 仪器仪表信息、生产设备设施、安全设备设施 分页查询数据
        getequipmentInfoList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/equipmentInfo/page/list',
                method: 'post',
                data: params
            });
        },
        // 仪器仪表信息、生产设备设施、安全设备设施 统计
        getequipmentInfoStatistics: () => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipmentInfo/statistics`,
                method: 'get'
            });
        },
        // 重点监管装置/设备 查询单条数据
        getkeypointEquipmentInfoDetail: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/keypointEquipmentInfo/selectOne/${params}`,
                method: 'get'
            });
        },
        // 重点监管装置/设备 新增或者修改数据
        getkeypointEquipmentInfoAddOrUpdate: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/keypointEquipmentInfo/addOrUpdate`,
                method: 'post',
                data: params
            });
        },
        // 重点监管装置/设备 删除
        getkeypointEquipmentInfoDetele: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/keypointEquipmentInfo/delete`,
                method: 'post',
                data: params
            });
        },
        // 重点监管装置/设备 分页查询数据
        getkeypointEquipmentInfoAddOrList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/keypointEquipmentInfo/page/list`,
                method: 'post',
                data: params
            });
        }
    };
}
src/api/facilityManagement/safetyGoodsAndEquipment/index.ts
对比新文件
@@ -0,0 +1,82 @@
import request from '/@/utils/request';
export function goodsAndEquipmentApi() {
    return {
        // 设备设施类型管理 查询单条数据
        getGoodsEquipmentData: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/safeMaterial/page/list`,
                method: 'post',
                data
            });
        },
        getAllSafetyEquipment: () => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/classify/list`,
                method: 'post',
            });
        },
        getAllSafetyEquipmentByPage: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/classify/page/list`,
                method: 'post',
                data
            });
        },
        addGoodsEquipment: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/safeMaterial/save`,
                method: 'post',
                data
            });
        },
        updateGoodsEquipment: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/safeMaterial/update`,
                method: 'post',
                data
            });
        },
        deleteGoodsEquipment: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/safeMaterial/delete`,
                method: 'post',
                data
            });
        },
        addGoodsClassify: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/classify/save`,
                method: 'post',
                data
            });
        },
        updateGoodsClassify: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/classify/update`,
                method: 'post',
                data
            });
        },
        deleteGoodsClassify: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/classify/delete`,
                method: 'post',
                data
            });
        },
        batchInStorageGoods: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/saveBatch`,
                method: 'post',
                data
            });
        },
        batchOutStorageGoods: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/equipment/smDetail/batch/delivery/random`,
                method: 'post',
                data
            });
        },
    }
}
src/api/goalManagement/index.ts
对比新文件
@@ -0,0 +1,412 @@
import request from '/@/utils/request';
export function goalManagementApi() {
    return {
        // 目标设置、目标指标分解列表
        getTargetMngList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetMng/page/list',
                method: 'post',
                data: params
            });
        },
        // 目标设置详情
        getTargetMngDetail: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetMng/selectOne/${params}`,
                method: 'get'
            });
        },
        // 目标设置新增或者修改数据
        getTargetMngAddOrupdata: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetMng/addOrUpdate',
                method: 'post',
                data: params
            });
        },
        // 目标设置删除
        getTargetMngDelete: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetMng/delete`,
                method: 'post',
                data: params
            });
        },
        // 目标指标分解-新增或者修改数据
        gettargetDivideDetail: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetDivideDetail/addOrUpdate',
                method: 'post',
                data: params
            });
        },
        // 统计
        getEquipmentInfo: () => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/equipmentInfo/statistics',
                method: 'get'
            });
        },
        // 目标责任书 分页查询数据
        gettargetDutyfileInfoList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetDutyfileInfo/page/list',
                method: 'post',
                data: params
            });
        },
        // 目标责任书 查询单条数据
        gettargetDutyfileInfoDetail: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetDutyfileInfo/selectOne/${params}`,
                method: 'get'
            });
        },
        // 目标责任书 新增或者修改数据
        gettargetDutyfileInfoAddorUpdata: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetDutyfileInfo/addOrUpdate`,
                method: 'post',
                data: params
            });
        },
        // 目标责任书 删除
        gettargetDutyfileInfoDelete: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetDutyfileInfo/delete`,
                method: 'post',
                data: params
            });
        },
        // 奖惩标准设定 分页查询数据
        getrewardPunishmentStandardList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/rewardPunishmentStandard/page/list',
                method: 'post',
                data: params
            });
        },
        // 奖惩标准设定 查询单条数据
        getrewardPunishmentStandardDetail: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/rewardPunishmentStandard/selectOne/${params}`,
                method: 'get'
            });
        },
        // 奖惩标准设定 新增或者修改数据
        getrewardPunishmentStandardaddOrUpdate: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/rewardPunishmentStandard/addOrUpdate',
                method: 'post',
                data: params
            });
        },
        // 奖惩标准设定 删除
        getrewardPunishmentStandardDelete: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/rewardPunishmentStandard/delete`,
                method: 'post',
                data: params
            });
        },
        // 奖惩记录 分页查询数据
        getrewardPunishmentList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/rewardPunishmentDetail/page/list',
                method: 'post',
                data: params
            });
        },
        // 奖惩记录 查询单条数据
        getrewardPunishmentDetail: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/rewardPunishmentDetail/selectOne/${params}`,
                method: 'get'
            });
        },
        // 奖惩记录 新增或者修改数据
        getrewardPunishmentAddOrUpdate: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/rewardPunishmentDetail/addOrUpdate`,
                method: 'post',
                data: params
            });
        },
        // 奖惩记录 删除
        getrewardPunishmentDelete: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/rewardPunishmentDetail/delete`,
                method: 'post',
                data: params
            });
        },
        // 绩效考核管理 安全考核管理 分页查询数据
        getexamineMngList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/examineMng/page/list',
                method: 'post',
                data: params
            });
        },
        //  绩效考核管理 安全考核管理 查询单条数据
        getexamineMngDetail: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/examineMng/selectOne/${params}`,
                method: 'get'
            });
        },
        //  绩效考核管理 安全考核管理 新增或者修改数据
        getexamineMngAddOrUpdate: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/examineMng/addOrUpdate`,
                method: 'post',
                data: params
            });
        },
        //  绩效考核管理 安全考核管理 删除
        getexamineMngDelete: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/examineMng/delete`,
                method: 'post',
                data: params
            });
        },
        // 绩效考核管理 考核标准设定 分页查询数据
        getexamineTemplateList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/examineTemplate/page/list',
                method: 'post',
                data: params
            });
        },
        //  绩效考核管理 考核标准设定 查询单条数据
        getexamineTemplateDetail: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/examineTemplate/selectOne/${params}`,
                method: 'get'
            });
        },
        //  绩效考核管理 考核标准设定 新增或者修改数据
        getexamineTemplateAddOrUpdate: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/examineTemplate/addOrUpdate`,
                method: 'post',
                data: params
            });
        },
        //  绩效考核管理 考核标准设定 删除
        getexamineTemplateDelete: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/examineTemplate/delete`,
                method: 'post',
                data: params
            });
        },
        // 目标汇总 分页查询数据
        gettargetDutySummaryList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetDutySummary/page/list',
                method: 'post',
                data: params
            });
        },
        //  目标汇总 查询单条数据
        gettargetDutySummaryDetail: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetDutySummary/selectOne/${params}`,
                method: 'get'
            });
        },
        //  目标汇总 新增或者修改数据
        gettargetDutySummaryAddOrUpdate: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetDutySummary/addOrUpdate`,
                method: 'post',
                data: params
            });
        },
        //  目标汇总 删除
        gettargetDutySummaryDelete: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetDutySummary/delete?ids=${params}`,
                method: 'get'
            });
        },
        //安全目标考核 列表
        gettargetExamineList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetMng/page/list',
                method: 'post',
                data: params
            });
        },
        // 安全目标考核 查询单条数据
        gettargetExamineDetail: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetExamine/selectOne/${params}`,
                method: 'get'
            });
        },
        // 安全目标考核 新增或者修改数据
        gettargetExamineAddOrUpdate: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetExamine/addOrUpdate',
                method: 'post',
                data: params
            });
        },
        //   目标检查上报 分页查询数据
        getworkApproveList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetMng/checkAndSubimt/list',
                method: 'post',
                data: params
            });
        },
        //   目标检查上报 查看审批流程
        getworkApproveListCode: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetDutyWorkApprove/page/list',
                method: 'post',
                data: params
            });
        },
        //   目标检查上报 分页查询检查记录
        getworkApproveListCheckData: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetDutyWorkApprove/page/listCheckData',
                method: 'post',
                data: params
            });
        },
        //   目标检查上报 查询单条数据
        getworkApproveDetail: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetDutyWorkApprove/selectOne/${params}`,
                method: 'get'
            });
        },
        //   目标检查上报 新增数据
        getworkApproveAdd: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetDutyWorkApprove/add',
                method: 'post',
                data: params
            });
        },
        //   目标检查上报 新增数据
        getworkApproveUpdata: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetDutyWorkApprove/update',
                method: 'post',
                data: params
            });
        },
        //   目标检查上报 删除
        getworkApproveDelete: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetDutyWorkApprove/delete',
                method: 'post',
                data: params
            });
        },
        // 部门树
        getTreedepartment: () => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/department/list',
                method: 'post'
            });
        },
        // 人员
        getManName: (params: any) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/account/dep/list?depId=${params}`,
                method: 'get'
            });
        },
        beforeUploadFile(fileName1: string, fileName2: string) {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/minio/file/presign?prefixName=' + fileName1 + '&suffixName=' + fileName2,
                method: 'get'
            });
        },
        searchFile(fileName: string) {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/minio/file/view?obj=' + fileName,
                method: 'get'
            });
        },
        // 应急统计
        emergencyStat(params: object) {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/emergencyCount/emergencyDrillExecute/count`,
                method: 'post',
                data: params
            });
        },
        // 目标分类 分页查询数据
        gettargetClassList(params: object) {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetType/page/list',
                method: 'post',
                data: params
            });
        },
        // 目标分类 查询单条数据
        gettargetClassDetail(params: any) {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetType/selectOne/${params}`,
                method: 'get'
            });
        },
        // 目标分类 新增或者修改数据
        gettargetClassAdd(params: object) {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetType/addOrUpdate',
                method: 'post',
                data: params
            });
        },
        // 目标分类 删除
        gettargetClassDelete(params: any) {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetType/delete',
                method: 'post',
                data: params
            });
        },
        // 目标分类 查询所有数据All
        gettargetClassAll(params: any) {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/targetType/page/listAll',
                method: 'post',
                data: params
            });
        },
        // 统计  查询应急物资
        emergencySuppliesCount(params: any) {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/emergencyCount/emergencySupplies/count',
                method: 'post',
                data: params
            });
        },
        // 统计  事故快报
        accidentReportCount(params: any) {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/accidentCount/accidentReport/count',
                method: 'post',
                data: params
            });
        },
        // 目标 统计
        gettargetstatistics(params: any) {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/targetMng/statistics?targetType=${params}`,
                method: 'get'
                // data:params
            });
        }
    };
}
src/api/intellectInspectSystem/RFID/index.ts
对比新文件
@@ -0,0 +1,64 @@
import request from '/@/utils/request';
export function RFIDApi() {
    return {
        // v1
        getRFIDList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckRfid/select/listRfidByPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        addRFID: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckRfid/insert/saveRfid`,
                method: 'post',
                data: data
            });
        },
        // v1
        modRFID: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckRfid/update/updateRfidById`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteRFID: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckRfid/delete/deleteRfidById`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllRFIDList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckRfid/select/listRfidName`,
                method: 'get'
            });
        },
        // 获取图片上传地址
        getUploadUrl: (name: string) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheck/minio/file/presign`,
                method: 'post',
                data: { prefixName: name.split('.')[0], suffixName: name.split('.')[1] }
            });
        },
        uploadFile: (path: string, file: any) => {
            return request({
                headers: {
                    contentType: 'application/json;charset=UTF-8'
                },
                url: path,
                method: 'put',
                data: file
            });
        }
    };
}
src/api/intellectInspectSystem/facilityAreaManage/index.ts
对比新文件
@@ -0,0 +1,60 @@
import request from '/@/utils/request';
export function facilityAreaApi() {
    return {
        // v1
        getFacilityAreaList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckRegion/select/listRegionByPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        getFacilityAreaById: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckRegion/select/getRegionById`,
                method: 'post',
                data: data
            });
        },
        // v1
        addFacilityArea: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckRegion/insert/saveRegion`,
                method: 'post',
                data: data
            });
        },
        // v1
        modFacilityArea: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckRegion/update/updateRegionById`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteFacilityArea: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckRegion/delete/deleteRegionById`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllFacilityAreaList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckRegion/select/listRegionName`,
                method: 'get'
            });
        },
        // v1
        getFacilityAreaType: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckRegionType/select/listRegionType`,
                method: 'get'
            });
        }
    };
}
src/api/intellectInspectSystem/inspectPointManage/index.ts
对比新文件
@@ -0,0 +1,59 @@
import request from '/@/utils/request';
export function inspectPointApi() {
    return {
        // v1
        getInspectPointList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckPoint/select/listPointByPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        getInspectPointById: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckPoint/select/getPointById`,
                method: 'post',
                data: data
            });
        },
        // v1
        addInspectPoint: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckPoint/insert/savePoint`,
                method: 'post',
                data: data
            });
        },
        // v1
        modInspectPoint: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckPoint/update/updatePointById`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteInspectPoint: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckPoint/delete/deletePointById`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllInspectPointList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckRegion/select/listRegionName`,
                method: 'get'
            });
        },
        getInspectPointAll: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckPoint/select/getPointRegionRfidId`,
                method: 'post'
            });
        }
    };
}
src/api/intellectInspectSystem/inspectRecord/index.ts
对比新文件
@@ -0,0 +1,43 @@
import request from '/@/utils/request';
export function inspectRecordApi() {
    return {
        // v1
        getInspectRecordList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTask/select/listTaskByPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        getInspectRecordById: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTask/select/listTaskMainAndQuota`,
                method: 'post',
                data: data
            });
        },
        getInspectRecordByIndex: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTask/select/listTaskByPageAndStatusAndTime`,
                method: 'post',
                data: data
            });
        },
        getInspectRecordSum: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTask/select/listTaskQuotaGbRegionGbQuotaGbPoint`,
                method: 'post',
                data: data
            });
        },
        getDayRecord: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTask/select/listTaskByNoCheckTaskAndAbnormalTask`,
                method: 'get',
            });
        }
    };
}
src/api/intellectInspectSystem/inspectTargetManage/index.ts
对比新文件
@@ -0,0 +1,59 @@
import request from '/@/utils/request';
export function inspectTargetApi() {
    return {
        // v1
        getInspectTargetList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckQuota/select/listQuotaByPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        getInspectTargetById: (id: number) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckQuota/select/getQuotaById?id=${id}`,
                method: 'get'
            });
        },
        // v1
        addInspectTarget: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckQuota/insert/saveQuota`,
                method: 'post',
                data: data
            });
        },
        // v1
        modInspectTarget: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckQuota/update/updateQuotaById`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteInspectTarget: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckQuota/delete/deleteQuotaById`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllInspectTargetList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/device/select/listDevices`,
                method: 'post'
            });
        },
        // v1
        getQuotaTypeList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckQuotaType/select/listQuotaType`,
                method: 'get'
            });
        }
    };
}
src/api/intellectInspectSystem/inspectTask/index.ts
对比新文件
@@ -0,0 +1,83 @@
import request from '/@/utils/request';
export function inspectTaskApi() {
    return {
        // v1
        getInspectTaskList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTaskUnit/select/listTaskUnitByPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        getInspectTaskById: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTaskUnit/select/getTaskUnitById`,
                method: 'post',
                data: data
            });
        },
        // v1
        addInspectTask: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTaskUnit/insert/saveTaskUnit`,
                method: 'post',
                data: data
            });
        },
        // v1
        modInspectTask: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTaskUnit/update/updateTaskUnitMainById`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteInspectTask: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTaskUnit/delete/deleteTaskUnit`,
                method: 'post',
                data: data
            });
        },
        // v1
        addChainOfInspectTask: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTaskUnit/insert/saveTaskUnitPoint`,
                method: 'post',
                data: data
            });
        },
        // v1
        modChainOfInspectTask: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTaskUnit/update/updateTaskUnitPointById`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteChainOfInspectTask: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTaskUnit/delete/deleteTaskUnitPoint`,
                method: 'post',
                data: data
            });
        },
        getQuotaList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/safeCheckQuotaType/select/listQuotaType`,
                method: 'get'
            });
        },
        openOrCloseInspectTask: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckTaskUnit/update/updateTaskUnitStatusById`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/intelligentLine/index.ts
对比新文件
@@ -0,0 +1,22 @@
import request from '/@/utils/request';
export function lineApi() {
    return {
        // 分页获取休息日列表
        getLine: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/SafeCheckSmartScreen/select/getSmartScreenDataByTaskId`,
                method: 'post',
                data: data
            });
        },
        // 获取Url
        getUrl: () => {
            return request({
                url: import.meta.env.VITE_API_URL_SOCKET + `/ws/namesrv/get/one?srv=safeplatform-websocket`,
                method: 'get'
            });
        }
    };
}
src/api/login/index.ts
对比新文件
@@ -0,0 +1,34 @@
import request from '/@/utils/request';
/**
 * 登录api接口集合
 * @method signIn 用户登录
 * @method signOut 用户退出登录
 */
export function useLoginApi() {
    return {
        // v1
        signIn: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + '/auth/login',
                method: 'post',
                data: params
            });
        },
        // v1
        signOut: () => {
            return request({
                url: import.meta.env.VITE_API_URL + '/auth/logout',
                method: 'post'
            });
        },
        // 更改密码
        changeCode: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + '/account/pwd/forget',
                method: 'post',
                data: params
            });
        },
    };
}
src/api/specialWorkSystem/approveBasic/index.ts
对比新文件
@@ -0,0 +1,46 @@
import request from '/@/utils/request';
export function approveBasicApi() {
    return {
        // v1
        getApproveBasicList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/ruleItemStand/page/list`,
                method: 'post',
                data: data
            });
        },
        // v1
        addApproveBasic: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/ruleItemStand/save`,
                method: 'post',
                data: data
            });
        },
        // v1
        modApproveBasic: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/ruleItemStand/update`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteApproveBasic: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/ruleItemStand/delete`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllApproveBasicList: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/ruleItemStand/list`,
                method: 'post',
                data
            });
        }
    };
}
src/api/specialWorkSystem/approveRule/index.ts
对比新文件
@@ -0,0 +1,46 @@
import request from '/@/utils/request';
export function approveRuleApi() {
    return {
        // v1
        getApproveRuleList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/rule/listByPage`,
                method: 'post',
                data: data
            });
        },
        // v1
        addApproveRule: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/rule/save`,
                method: 'post',
                data: data
            });
        },
        // v1
        modApproveRule: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/rule/update`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteApproveRule: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/rule/del`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllApproveRuleList: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/prevent/device/select/listDevices`,
                method: 'post',
                data
            });
        }
    };
}
src/api/specialWorkSystem/material/index.ts
对比新文件
@@ -0,0 +1,50 @@
import request from '/@/utils/request';
export function materialApi() {
    return {
        //物资管理分页列表
        getRecordPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/material/page/list`,
                method: 'post',
                data: data
            });
        },
        //物资列表
        getRecordList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/material/equipment/materialClassify`,
                method: 'post'
            });
        },
        // 新增
        addRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/material/save`,
                method: 'post',
                data: data
            });
        },
        // 修改
        updateRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/material/update`,
                method: 'post',
                data: data
            });
        },
        // 删除
        deleteRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/material/delete`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/specialWorkSystem/safetyAction/index.ts
对比新文件
@@ -0,0 +1,46 @@
import request from '/@/utils/request';
export function safetyActionApi() {
    return {
        // v1
        getSafetyActionList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/rule/measure/page/list`,
                method: 'post',
                data: data
            });
        },
        // v1
        addSafetyAction: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/rule/measure/save`,
                method: 'post',
                data: data
            });
        },
        // v1
        modSafetyAction: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/rule/measure/mod`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteSafetyAction: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/rule/measure/delete`,
                method: 'post',
                data: data
            });
        },
        // v1
        getAllSafetyActionList: (data: {}) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/rule/measure/list`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/specialWorkSystem/workApply/index.ts
对比新文件
@@ -0,0 +1,190 @@
import request from '/@/utils/request';
export function workApplyApi() {
    return {
        // 分页获取申请列表
        getApplyListPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/applying/page/list`,
                method: 'post',
                data: data
            });
        },
        // 所有记录列表
        getApplyList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/all/page/list`,
                method: 'post',
                data: data
            });
        },
        // 分页获取申请列表
        getAllUsers: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/list`,
                method: 'get'
            });
        },
        // 导出打印接口
        postPrinting: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/printing`,
                method: 'post',
                data: data,
                responseType: 'blob',
                headers:{'Content-Type': 'application/json'}
            });
        },
        // 动火申请
        postFireApply: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/hot`,
                method: 'post',
                data: data
            });
        },
        // 受限空间申请
        postSpaceApply: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/confinedspace`,
                method: 'post',
                data: data
            });
        },
        // 吊装申请
        postHoistApply: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/hoisting`,
                method: 'post',
                data: data
            });
        },
        // 动土申请
        postGroundApply: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/groundBreaking`,
                method: 'post',
                data: data
            });
        },
        // 断路申请
        postBrokenApply: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/brokenCircuit`,
                method: 'post',
                data: data
            });
        },
        // 高处申请
        postHeightApply: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/height`,
                method: 'post',
                data: data
            });
        },
        // 临时用电申请
        postPowerApply: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/temporaryPower`,
                method: 'post',
                data: data
            });
        },
        // 盲板申请
        postPlateApply: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/blindPlatePlugging`,
                method: 'post',
                data: data
            });
        },
        // 取消申请
        cancelApply: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/cancel`,
                method: 'post',
                data: data
            });
        },
        // 查询进度
        getStatus: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/applicant/approved/view`,
                method: 'post',
                data: data
            });
        },
        // 查询所有进度
        getAllStatus: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/others/view`,
                method: 'post',
                data: data
            });
        },
        // 获取图片上传路径
        getUploadUrl: (name: string) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/file/getPresignUrl`,
                method: 'post',
                data: { prefixName: name.split('.')[0], suffixName: name.split('.')[1] }
            });
        },
        // 上传图片
        uploadFile: (path: string, file: any) => {
            return request({
                headers: {
                    contentType: 'application/json;charset=UTF-8'
                },
                url: path,
                method: 'put',
                data: file
            });
        },
        // 删除图片
        deleteFile: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/file/deleteFile`,
                method: 'post',
                data: data
            });
        },
        // 获取物资配置数据
        getMaterial: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/material/queryByWorkTypeOrLevel`,
                method: 'post',
                data: data
            });
        },
        // 根据物资配置id和领取人获取领取情况
        getMaterialDetail: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/material/receive`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/specialWorkSystem/workApproval/index.ts
对比新文件
@@ -0,0 +1,41 @@
import request from '/@/utils/request';
export function workApprovalApi() {
    return {
        // 分页获取审批列表
        getApprovalListPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/pending/page/list`,
                method: 'post',
                data: data
            });
        },
        // 获取当前层级审批数据
        getApprovalData: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/approval/pending/data`,
                method: 'post',
                data: data
            });
        },
        // 获取当前层级审批进度
        getApprovalStatus: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/approver/approved/view`,
                method: 'post',
                data: data
            });
        },
        // 终止当前审批进度
        postAbord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/apply/abord`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/specialWorkSystem/workPlan/workAppoint/index.ts
对比新文件
@@ -0,0 +1,50 @@
import request from '/@/utils/request';
export function workAppointApi() {
    return {
        // 分页获取列表
        getAppointListPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/appointment/listAll`,
                method: 'post',
                data: data
            });
        },
        // 新增列表
        addRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/appointment/save`,
                method: 'post',
                data: data
            });
        },
        //修改列表
        editRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/appointment/update`,
                method: 'post',
                data: data
            });
        },
        //删除列表
        deleteRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/appointment/delete`,
                method: 'post',
                data: data
            });
        },
        //获取各部门各作业的数量
        getAllRecords: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/appointment/statistics`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/specialWorkSystem/workPlan/workReservation/index.ts
对比新文件
@@ -0,0 +1,41 @@
import request from '/@/utils/request';
export function workReserveApi() {
    return {
        // 分页获取列表
        getReserveListPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/appointment/listByDep`,
                method: 'post',
                data: data
            });
        },
        // 新增列表
        addRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/appointment/save`,
                method: 'post',
                data: data
            });
        },
        //修改列表
        editRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/appointment/update`,
                method: 'post',
                data: data
            });
        },
        //删除列表
        deleteRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/specialWork/appointment/delete`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/specialWorkSystem/workProcess/index.ts
对比新文件
@@ -0,0 +1,59 @@
import request from '/@/utils/request';
export function workProcessApi() {
    return {
        // 分页获取检测列表
        getDetectionListPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/process/detection/page/list`,
                method: 'post',
                data: data
            });
        },
        // 分页获取检查列表
        getCheckListPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/process/check/page/list`,
                method: 'post',
                data: data
            });
        },
        // 检测上报
        postDetectionReport: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/process/detection/report`,
                method: 'post',
                data: data
            });
        },
        // 检查上报
        postCheckReport: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/process/check/report`,
                method: 'post',
                data: data
            });
        },
        // 获取可上报作业列表
        postReportList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/process/workApply/list`,
                method: 'post',
                data: data
            });
        },
        // 获取预警记录
        postAlertList: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/work/process/warning/page/list`,
                method: 'post',
                data: data
            });
        },
    };
}
src/api/systemManage/appVersion/index.ts
对比新文件
@@ -0,0 +1,59 @@
import request from '/@/utils/request';
export function appVersionApi() {
    return {
        //app版本分页列表
        getRecordPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/appVersion/page/list`,
                method: 'post',
                data: data
            });
        },
        //获取最新版本
        getRecordByNew: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/appVersion/lastest-release`,
                method: 'get'
            });
        },
        // app版本新增
        addRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/appVersion/add`,
                method: 'post',
                data: data
            });
        },
        // app版本修改
        updateRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/appVersion/mod`,
                method: 'post',
                data: data
            });
        },
        // app版本删除
        deleteRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/appVersion/del`,
                method: 'post',
                data: data
            });
        },
        // 获取上传路径
        getUploadUrl: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/appVersion/presign`,
                method: 'post',
                data: data
            });
        },
    };
}
src/api/systemManage/basicDateManage/personShiftManage/holidayTime/index.ts
对比新文件
@@ -0,0 +1,50 @@
import request from '/@/utils/request';
export function holidayTimeApi() {
    return {
        // 分页获取休息日列表
        getAllBreakTimeRuleByPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/getAllBreakTimeRuleByPage`,
                method: 'post',
                data: data
            });
        },
        // 新增休息日
        addBreakTime: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/addBreakTimeRule`,
                method: 'post',
                data: data
            });
        },
        // 修改休息日
        updateBreakTime: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/updateBreakTimeRule`,
                method: 'post',
                data: data
            });
        },
        // 删除休息日
        deleteBreakTime: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/deleteBreakTimeRule`,
                method: 'post',
                data: data
            });
        },
        // 删除休息日
        deleteBatch: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/deleteBatchBreakTimeRule`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/systemManage/basicDateManage/personShiftManage/holidayTimeGroup/index.ts
对比新文件
@@ -0,0 +1,58 @@
import request from '/@/utils/request';
export function holidayGroupApi() {
    return {
        //休息时间组分页列表
        getRecordPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/getAllBreakTimeGroupByPage`,
                method: 'post',
                data: data
            });
        },
        // 休息时间组新增
        addRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/addBreakTimeGroup`,
                method: 'post',
                data: data
            });
        },
        // 休息时间组修改
        updateRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/updateBreakTimeGroup`,
                method: 'post',
                data: data
            });
        },
        // 休息时间组删除
        deleteRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/deleteBreakTimeGroup`,
                method: 'post',
                data: data
            });
        },
        // 休息时间组批量删除
        deletBatchRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/deleteBatchBreakTimeGroup`,
                method: 'post',
                data: data
            });
        },
        //休息时间列表
        getAllBreak: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/getAllBreakTimeRule`,
                method: 'get'
            });
        }
    };
}
src/api/systemManage/basicDateManage/personShiftManage/teamManage/index.ts
对比新文件
@@ -0,0 +1,94 @@
import request from '/@/utils/request';
export function teamManageApi() {
    return {
        //班组分页列表
        getRecordPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/page/list`,
                method: 'post',
                data: data
            });
        },
        //班组列表
        getRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/list`,
                method: 'post',
                data: data
            });
        },
        //班组-班组成员分页列表
        getAllRecordPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/member/page/list`,
                method: 'post',
                data: data
            });
        },
        //所有部门列表
        getAllDepartment: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/department/list`,
                method: 'post'
            });
        },
        //用户-部门所有用户
        getAllMember: (data: number) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/dep/list?depId=${data}`,
                method: 'get',
                data: data
            });
        },
        // 班组-班组成员列表
        getAllRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/member/list`,
                method: 'get',
                data: data
            });
        },
        // 班组新增
        addRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/add`,
                method: 'post',
                data: data
            });
        },
        // 班组修改
        updateRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/mod`,
                method: 'post',
                data: data
            });
        },
        // 班组删除
        deleteRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/del`,
                method: 'post',
                data: data
            });
        }
        // 时间策略批量删除
        // deletBatchRecord: (data: object)=>{
        //     return request({
        //         url: `/timeStrategy/deleteBatchTimeStrategy`,
        //         method: 'post',
        //         data: data
        //     })
        // },
    };
}
src/api/systemManage/basicDateManage/personShiftManage/teamStrategy/index.ts
对比新文件
@@ -0,0 +1,50 @@
import request from '/@/utils/request';
export function teamStrategyApi() {
    return {
        //获取班组策略分页列表
        getRecordPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/groupStrategy/page/list`,
                method: 'post',
                data: data
            });
        },
        // 班组策略新增
        addRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/groupStrategy/add`,
                method: 'post',
                data: data
            });
        },
        // 班组策略修改
        updateRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/groupStrategy/mod`,
                method: 'post',
                data: data
            });
        },
        // 班组策略删除
        deleteRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/groupStrategy/del`,
                method: 'post',
                data: data
            });
        }
        // 时间策略批量删除
        // deletBatchRecord: (data: object)=>{
        //     return request({
        //         url: `/timeStrategy/deleteBatchTimeStrategy`,
        //         method: 'post',
        //         data: data
        //     })
        // },
    };
}
src/api/systemManage/basicDateManage/personShiftManage/timeStrategy/index.ts
对比新文件
@@ -0,0 +1,83 @@
import request from '/@/utils/request';
export function timeStrategyApi() {
    return {
        //获取工作时间组列表
        getWorkTimeList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/getWorkTimeGroup`,
                method: 'get'
            });
        },
        //获取休息时间组列表
        getRestTimeList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/getAllBreakTimeGroup`,
                method: 'get'
            });
        },
        //时间策略分页列表
        getRecordPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/getAllTimeStrategyByPage`,
                method: 'post',
                data: data
            });
        },
        // 时间策略全部列表
        getAllRecord: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/getAllTimeStrategy`,
                method: 'get'
            });
        },
        //根据id获取时间策略列表
        getRecordById: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/getTimeStrategyById`,
                method: 'post',
                data: data
            });
        },
        // 时间策略新增
        addRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/addTimeStrategy`,
                method: 'post',
                data: data
            });
        },
        // 时间策略修改
        updateRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/updateTimeStrategy`,
                method: 'post',
                data: data
            });
        },
        // 时间策略删除
        deleteRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/deleteTimeStrategy`,
                method: 'post',
                data: data
            });
        },
        // 时间策略批量删除
        deletBatchRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/deleteBatchTimeStrategy`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/systemManage/basicDateManage/personShiftManage/workingHours/index.ts
对比新文件
@@ -0,0 +1,58 @@
import request from '/@/utils/request';
export function workingHoursApi() {
    return {
        // 获取工作时间段列表
        getWorkTimePeriod: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/getWorkTimePeriod`,
                method: 'get'
            });
        },
        //工作时间段分页列表
        postPeriodPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/getWorkTimePeriodByPage?pageSiz`,
                method: 'post',
                data: data
            });
        },
        // 新增工作时间段
        postWorkTimePeriod: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/addWorkTimePeriod`,
                method: 'post',
                data: data
            });
        },
        // 修改工作时间段
        updateWorkTimePeriod: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/updateWorkTimePeriod`,
                method: 'post',
                data: data
            });
        },
        // 删除工作时间段
        deletWorkTimePeriod: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/deletWorkTimePeriod`,
                method: 'post',
                data: data
            });
        },
        // 批量删除
        deleteBatchWorkTimePeriod: (data: any) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/deleteBatchWorkTimePeriod`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/systemManage/basicDateManage/personShiftManage/workingHoursSet/index.ts
对比新文件
@@ -0,0 +1,50 @@
import request from '/@/utils/request';
export function workingHoursSetApi() {
    return {
        //工作时间组分页列表
        postWorkTimeGroupPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/getWorkTimeGroupByPage`,
                method: 'post',
                data: data
            });
        },
        // 工作时间组新增
        addWorkTimeGroup: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/addWorkTimeGroup`,
                method: 'post',
                data: data
            });
        },
        // 工作时间组修改
        updateWorkTimeGroup: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/updateWorkTimeGroup`,
                method: 'post',
                data: data
            });
        },
        // 工作时间组删除
        deleteWorkTimeGroup: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/deleteWorkTimeGroup`,
                method: 'post',
                data: data
            });
        },
        // 工作时间组批量删除
        deletBatchWorkTimeGroup: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/deletBatchWorkTimeGroup`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/systemManage/department/index.ts
对比新文件
@@ -0,0 +1,37 @@
import request from '/@/utils/request';
export function departmentApi() {
    return {
        // v2
        getDepartmentList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/department/list`,
                method: 'post'
            });
        },
        // v2
        addDepartment: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/department/add`,
                method: 'post',
                data: data
            });
        },
        // v2
        modDepartment: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/department/mod`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteDepartment: (value?: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/department/del`,
                method: 'post',
                data: value
            });
        }
    };
}
src/api/systemManage/menu/index.ts
对比新文件
@@ -0,0 +1,50 @@
import request from '/@/utils/request';
/**
 * 后端控制菜单模拟json,路径在 https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu
 * 后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
 * @method getMenuAdmin 获取后端动态路由菜单(admin)
 * @method getMenuTest 获取后端动态路由菜单(test)
 */
export function useMenuApi() {
    return {
        // v2
        getMenuAdmin: (value?: string) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/auth/menu?projectId= ${value}`,
                method: 'post'
            });
        },
        // v1
        addMenu: (value?: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/menu/add`,
                method: 'post',
                data: value
            });
        },
        // v1
        modMenu: (value?: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/menu/mod`,
                method: 'post',
                data: value
            });
        },
        // v1
        deleteMenu: (value?: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/menu/del`,
                method: 'post',
                data: value
            });
        },
        // v1
        getProjectList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/project/list`,
                method: 'post'
            });
        }
    };
}
src/api/systemManage/personShiftManage/holidayTime/index.ts
src/api/systemManage/personShiftManage/holidayTimeGroup/index.ts
src/api/systemManage/personShiftManage/teamManage/index.ts
对比新文件
@@ -0,0 +1,94 @@
import request from '/@/utils/request';
export function teamManageApi() {
    return {
        //班组分页列表
        getRecordPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/page/list`,
                method: 'post',
                data: data
            });
        },
        //班组列表
        getRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/list`,
                method: 'post',
                data: data
            });
        },
        //班组-班组成员分页列表
        getAllRecordPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/member/page/list`,
                method: 'post',
                data: data
            });
        },
        //所有部门列表
        getAllDepartment: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/department/list`,
                method: 'post'
            });
        },
        //用户-部门所有用户
        getAllMember: (data: number) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/dep/list?depId=${data}`,
                method: 'get',
                data: data
            });
        },
        // 班组-班组成员列表
        getAllRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/member/list`,
                method: 'get',
                data: data
            });
        },
        // 班组新增
        addRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/add`,
                method: 'post',
                data: data
            });
        },
        // 班组修改
        updateRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/mod`,
                method: 'post',
                data: data
            });
        },
        // 班组删除
        deleteRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/group/del`,
                method: 'post',
                data: data
            });
        }
        // 时间策略批量删除
        // deletBatchRecord: (data: object)=>{
        //     return request({
        //         url: `/timeStrategy/deleteBatchTimeStrategy`,
        //         method: 'post',
        //         data: data
        //     })
        // },
    };
}
src/api/systemManage/personShiftManage/teamStrategy/index.ts
对比新文件
@@ -0,0 +1,50 @@
import request from '/@/utils/request';
export function teamStrategyApi() {
    return {
        //获取班组策略分页列表
        getRecordPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/groupStrategy/page/list`,
                method: 'post',
                data: data
            });
        },
        // 班组策略新增
        addRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/groupStrategy/add`,
                method: 'post',
                data: data
            });
        },
        // 班组策略修改
        updateRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/groupStrategy/mod`,
                method: 'post',
                data: data
            });
        },
        // 班组策略删除
        deleteRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/schedule/groupStrategy/del`,
                method: 'post',
                data: data
            });
        }
        // 时间策略批量删除
        // deletBatchRecord: (data: object)=>{
        //     return request({
        //         url: `/timeStrategy/deleteBatchTimeStrategy`,
        //         method: 'post',
        //         data: data
        //     })
        // },
    };
}
src/api/systemManage/personShiftManage/timeStrategy/index.ts
对比新文件
@@ -0,0 +1,83 @@
import request from '/@/utils/request';
export function timeStrategyApi() {
    return {
        //获取工作时间组列表
        getWorkTimeList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/getWorkTimeGroup`,
                method: 'get'
            });
        },
        //获取休息时间组列表
        getRestTimeList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/breakTime/getAllBreakTimeGroup`,
                method: 'get'
            });
        },
        //时间策略分页列表
        getRecordPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/getAllTimeStrategyByPage`,
                method: 'post',
                data: data
            });
        },
        // 时间策略全部列表
        getAllRecord: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/getAllTimeStrategy`,
                method: 'get'
            });
        },
        //根据id获取时间策略列表
        getRecordById: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/getTimeStrategyById`,
                method: 'post',
                data: data
            });
        },
        // 时间策略新增
        addRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/addTimeStrategy`,
                method: 'post',
                data: data
            });
        },
        // 时间策略修改
        updateRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/updateTimeStrategy`,
                method: 'post',
                data: data
            });
        },
        // 时间策略删除
        deleteRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/deleteTimeStrategy`,
                method: 'post',
                data: data
            });
        },
        // 时间策略批量删除
        deletBatchRecord: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/timeStrategy/deleteBatchTimeStrategy`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/systemManage/personShiftManage/workingHours/index.ts
对比新文件
@@ -0,0 +1,58 @@
import request from '/@/utils/request';
export function workingHoursApi() {
    return {
        // 获取工作时间段列表
        getWorkTimePeriod: (value: { name: string }) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/getWorkTimePeriod`,
                method: 'get'
            });
        },
        //工作时间段分页列表
        postPeriodPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/getWorkTimePeriodByPage?pageSiz`,
                method: 'post',
                data: data
            });
        },
        // 新增工作时间段
        postWorkTimePeriod: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/addWorkTimePeriod`,
                method: 'post',
                data: data
            });
        },
        // 修改工作时间段
        updateWorkTimePeriod: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/updateWorkTimePeriod`,
                method: 'post',
                data: data
            });
        },
        // 删除工作时间段
        deletWorkTimePeriod: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/deletWorkTimePeriod`,
                method: 'post',
                data: data
            });
        },
        // 批量删除
        deleteBatchWorkTimePeriod: (data: any) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/deleteBatchWorkTimePeriod`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/systemManage/personShiftManage/workingHoursSet/index.ts
对比新文件
@@ -0,0 +1,50 @@
import request from '/@/utils/request';
export function workingHoursSetApi() {
    return {
        //工作时间组分页列表
        postWorkTimeGroupPage: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/getWorkTimeGroupByPage`,
                method: 'post',
                data: data
            });
        },
        // 工作时间组新增
        addWorkTimeGroup: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/addWorkTimeGroup`,
                method: 'post',
                data: data
            });
        },
        // 工作时间组修改
        updateWorkTimeGroup: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/updateWorkTimeGroup`,
                method: 'post',
                data: data
            });
        },
        // 工作时间组删除
        deleteWorkTimeGroup: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/deleteWorkTimeGroup`,
                method: 'post',
                data: data
            });
        },
        // 工作时间组批量删除
        deletBatchWorkTimeGroup: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/workTime/deletBatchWorkTimeGroup`,
                method: 'post',
                data: data
            });
        }
    };
}
src/api/systemManage/role/index.ts
对比新文件
@@ -0,0 +1,37 @@
import request from '/@/utils/request';
export function useRoleApi() {
    return {
        // v2
        getRoleList: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/role/list`,
                method: 'post'
            });
        },
        // v2
        addRole: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/role/add`,
                method: 'post',
                data: data
            });
        },
        // v2
        modRole: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/role/mod`,
                method: 'post',
                data: data
            });
        },
        // v2
        deleteRole: (value?: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/role/del`,
                method: 'post',
                data: value
            });
        }
    };
}
src/api/systemManage/user/index.ts
对比新文件
@@ -0,0 +1,51 @@
import request from '/@/utils/request';
export function userApi() {
    return {
        // v1
        getUserList: (data: any) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/page/list`,
                method: 'post',
                data: data
            });
        },
        // v1
        addUser: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/add`,
                method: 'post',
                data: data
            });
        },
        // v1
        modUser: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/mod`,
                method: 'post',
                data: data
            });
        },
        // v1
        deleteUser: (data: object) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/del`,
                method: 'post',
                data: data
            });
        },
        // v1
        getUserLByDepartment: (depId: number | null) => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/dep/list?depId=${depId == null ? '' : depId}`,
                method: 'get'
            });
        },
        getAllUser: () => {
            return request({
                url: import.meta.env.VITE_API_URL + `/account/list`,
                method: 'get'
            });
        }
    };
}
src/api/workInjuryDeclaration/index.ts
对比新文件
@@ -0,0 +1,123 @@
import request from '/@/utils/request';
export function accidentManagementSystemApi() {
    return {
        // 事故快报一览
        accidentList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/accidentExpress/page/list',
                method: 'post',
                data: params
            });
        },
        // 事故快报新增
        accidentAdd: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/accidentExpress/add',
                method: 'post',
                data: params
            });
        },
        // 事故快报详情
        accidentScarh: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentExpress/info/${params}`,
                method: 'get'
            });
        },
        // 事故快报修改
        accidentView: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/accidentExpress/update',
                method: 'post',
                data: params
            });
        },
        // 事故快报删除
        accidentDele: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentExpress/batchDelete/${params}`,
                method: 'get'
            });
        },
        // 事故报告一览
        getAccidentReportList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/accidentReport/page/list',
                method: 'post',
                data: params
            });
        },
        // 事故报告新增
        addAccidentReport: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentReport/add`,
                method: 'post',
                data: params
            });
        },
        // 事故报告详情
        seeAccidentReport: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentReport/info/${params}`,
                method: 'get'
            });
        },
        // 事故报告编辑
        editAccidentReport: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentReport/update`,
                method: 'post',
                data: params
            });
        },
        // 事故报告删除
        deleteAccidentReport: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/accidentReport/batchDelete`,
                method: 'post',
                data: params
            });
        },
        //  工伤申报一览
        workList: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/workInjuryDeclaration/page/list',
                method: 'post',
                data: params
            });
        },
        // 工伤申报新增
        workAdd: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/workInjuryDeclaration/add',
                method: 'post',
                data: params
            });
        },
        // 工伤申报详情
        seeAccidentManagementSystem: (params: number) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `workInjuryDeclaration/info/${params}`,
                method: 'get'
            });
        },
        // 工伤申报修改
        workView: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + '/workInjuryDeclaration/update',
                method: 'post',
                data: params
            });
        },
        // 工伤申报删除/批量删除
        workDelete: (params: object) => {
            return request({
                url: import.meta.env.VITE_API_URL_OUT + `/workInjuryDeclaration/batchDelete/${params}`,
                method: 'get'
            });
        }
    };
}
src/assets/avator.png
src/assets/companyLogo.png
src/assets/default-img.jpg
src/assets/icon.png
src/assets/index.css
对比新文件
@@ -0,0 +1,10 @@
.pot {
    position: absolute;
    top: 19px;
    right: 40px;
    border: none !important;
    padding: 0;
}
.pot:focus,.pot:hover{
  background-color: #fff !important;
}
src/assets/index.ts
对比新文件
@@ -0,0 +1,17 @@
export function timeDate(row: any, column: any, cellValue: any, index: any) {
    const daterc = row[column.property]
    if (daterc != null) {
        var date = new Date(daterc);
        var year = date.getFullYear();
        /* 在日期格式中,月份是从0开始,11结束,因此要加0
         * 使用三元表达式在小于10的前面加0,以达到格式统一  如 09:11:05
         * */
        var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
        var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
        var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
        var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
        var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
        // 拼接
        return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
    }
}
src/assets/login-icon-two.svg
对比新文件
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" width="1151.5635" height="842.24197" viewBox="0 0 1151.5635 842.24197" xmlns:xlink="http://www.w3.org/1999/xlink"><title>sunlight</title><path d="M1080.33549,309.07821h-.00006c-22.0216,0-39.87364,19.81184-39.87364,44.251v31.0502h9.54961l5.52868-11.50435-1.38218,11.50435h61.38126l5.02608-10.4585-1.25651,10.4585h6.91087v-24.38C1126.2196,331.87644,1105.67658,309.07821,1080.33549,309.07821Z" transform="translate(-24.21825 -28.87901)" fill="#2f2e41"/><path d="M1042.88322,452.6347l-6.62276,25.38724,61.81242-2.20758-1.1038-20.97207S1050.60977,442.70056,1042.88322,452.6347Z" transform="translate(-24.21825 -28.87901)" fill="#ffb9b9"/><polygon points="959.06 525.305 978.928 569.456 997.693 546.277 982.24 515.371 959.06 525.305" fill="#ffb9b9"/><polygon points="1008.731 687.562 1010.938 738.337 1035.222 738.337 1031.91 687.562 1008.731 687.562" fill="#ffb9b9"/><path d="M1004.25045,507.82436l11.03794,36.42517,16.55689,176.60691s15.45311,4.41518,26.491-1.10379l2.20759-24.28345,4.41517-139.07794s20.97207-11.03793,18.76448-26.491-7.72655-36.42517-7.72655-36.42517Z" transform="translate(-24.21825 -28.87901)" fill="#2f2e41"/><path d="M1038.468,755.074h-6.62276s-18.76448,19.86828-25.38724,22.07587-40.84035,20.97207-13.24552,24.28345,45.25552-11.03794,45.25552-11.03794,8.83035,5.519,20.97207,1.1038,5.519-17.66069,5.519-17.66069-6.16367-20.18749-6.39321-20.02789S1051.71356,763.90438,1038.468,755.074Z" transform="translate(-24.21825 -28.87901)" fill="#2f2e41"/><circle cx="1048.46738" cy="323.31051" r="25.38724" fill="#ffb9b9"/><path d="M1110.2146,385.30331l-11.67815,9.73547-1.56737,1.30247-1.10379,13.24551h-43.04794s5.87219-5.08847,11.32493-10.35358c.11036-.1214.23176-.25385.36427-.37532.73953-.71743,1.40178-1.37974,1.99787-1.97577.32007-.33112.6291-.64021.90505-.92721.45259-.47462.89414-.92715,1.33561-1.37974a.03829.03829,0,0,0,.01105-.022,43.07955,43.07955,0,0,0,3.17893-3.73083l.01105-.011a12.81791,12.81791,0,0,0,.73952-1.09274c3.31138-5.519-4.41517-16.5569-4.41517-16.5569l24.28345-12.14173c.84994,11.96508,10.97171,19.95654,15.49723,22.95889C1109.37571,384.85072,1110.2146,385.30331,1110.2146,385.30331Z" transform="translate(-24.21825 -28.87901)" fill="#ffb9b9"/><path d="M1169.81943,570.74057c-16.5569,4.41517-17.66069-28.69862-17.66069-28.69862l-22.59765-45.1953a104.51533,104.51533,0,0,1-9.73594-30.31979l-5.19538-32.65665-1.57841,1.88745v.01105l-2.83676,1.41288-17.24124-27.59483-4.83462-7.72655v-8.83034l16.55689-7.72656h6.62276s.1435-.02209.39735-.04419c3.04648-.32008,22.87063-1.64464,23.8861,17.70489.39969,7.59413.36519,13.88569.15854,18.82226a145.76191,145.76191,0,0,0,3.84972,40.63177c1.16857,4.79412,2.44343,8.95772,3.7183,11.18873,4.41517,7.72655,19.86827,68.43518,19.86827,68.43518S1186.37633,566.3254,1169.81943,570.74057Z" transform="translate(-24.21825 -28.87901)" fill="#ffb9b9"/><path d="M1068.27046,397.445l-4.18335,7.62718-2.47256,4.51454L1049.506,431.66263s-3.43278,2.80361-8.99594,6.42408c-9.24979,6.01562-24.4159,14.272-39.571,15.65178-24.28345,2.20759-1.10379-76.16173-1.10379-76.16173s7.72655-30.90621,18.76449-27.59483,2.20758,14.34931-5.519,35.32138S1011.977,429.455,1011.977,429.455s23.17965-14.34931,35.32138-25.38724c6.32471-5.75079,11.75542-7.30711,15.49723-7.4727h.011a14.05473,14.05473,0,0,1,3.69775.287A8.35071,8.35071,0,0,1,1068.27046,397.445Z" transform="translate(-24.21825 -28.87901)" fill="#ffb9b9"/><path d="M1071.93506,390.82228c-.04413.1214-.56294,1.10379-4.52559,5.1326A53.271,53.271,0,0,0,1071.93506,390.82228Z" transform="translate(-24.21825 -28.87901)" fill="#d0cde1"/><path d="M1114.07788,434.42211l-1.02652,1.3466-16.08228,27.90392s-20.97207-7.72655-36.42517-9.93414a21.64727,21.64727,0,0,0-22.06482,9.901l4.40413-17.62754-2.37319-7.92523c-.27594-.92721-.596-1.95373-.93819-3.1127-3.31138-11.03793,8.83034-23.17966,8.83034-23.17966l14.39344-15.19925h.011a14.05473,14.05473,0,0,1,3.69775.287c-.59609.596-1.25834,1.25834-1.99787,1.97577-.13251.12147-.25391.25392-.36427.37532-4.22754,4.3158-2.031,5.519-.05517,5.839a9.71986,9.71986,0,0,0,1.97576.09937c4.6028.66225,14.68044-3.3776,22.07587-6.75521,5.03329-2.29591,8.83034-4.28272,8.83034-4.28272l9.63609-8.83035,1.446-1.32456c1.32457.872,2.16346,1.32456,2.16346,1.32456h1.10379s.1435-.02209.39735-.04419l-5.02587,3.72943a18.68469,18.68469,0,0,0-7.5132,16.183h0Z" transform="translate(-24.21825 -28.87901)" fill="#d0cde1"/><path d="M1053.92115,465.88022l-16.1372,6.30165s-87.61936-33.89648-100.86488-6.30165,46.35931,93.82242,46.35931,93.82242l26.491-12.14173-11.03793-33.11379s64.02,54.08586,90.511,24.28345,8.83035-71.94211,8.83035-71.94211S1081.516,453.73849,1053.92115,465.88022Z" transform="translate(-24.21825 -28.87901)" fill="#2f2e41"/><path d="M1007.56183,586.19367l-9.93413,7.72656s8.83034,35.32138,5.519,40.84034-9.93414,20.97208,2.20759,19.86828,25.38724-19.86828,26.491-26.491,8.83035-26.491,8.83035-26.491,13.24552-30.90621,3.31138-32.01-25.75662-1.84256-25.75662-1.84256Z" transform="translate(-24.21825 -28.87901)" fill="#2f2e41"/><path d="M1091.67085,321.26789a20.91185,20.91185,0,0,0-16.50006-8.4201h-.78284c-15.09365,0-27.32941,13.658-27.32941,30.50606v.00006h5.05749l.81677-6.217,1.19755,6.217H1084.126l2.51307-5.25968-.62828,5.25968h5.901q4.13043,20.51274-11.86947,41.02548h10.05221l5.02608-10.51935-1.2565,10.51935h19.162l3.76958-24.19458C1116.79567,342.06532,1106.26771,326.70034,1091.67085,321.26789Z" transform="translate(-24.21825 -28.87901)" fill="#2f2e41"/><circle cx="971.03374" cy="113.59071" r="91" fill="#ff6584"/><path d="M771.29477,567.032c-1.6806,13.391-3.05862,26.28082-4.18757,38.571h36.55924q1.99625-19.38064,5.00548-38.571Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M801.19676,703.21105q-1.17629-19.19032-.9509-38.571H763.184c-.60171,14.7787-.83742,27.751-.88075,38.571Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M864.4142,361.58256C894.89157,280.388,924.75032,225.797,924.75032,225.797L893.6574,207.29872c-32.37571,48.82045-56.84558,101.59229-75.3218,154.28384Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M766.21242,615.836c-1.14212,13.751-1.97242,26.66388-2.56481,38.571h36.792q.53185-19.28516,2.25137-38.571Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M778.50126,518.22788c-2.24695,13.1965-4.19314,26.08124-5.8747,38.571h37.70491q3.28452-19.4853,7.41146-38.571Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M814.82354,371.81567q-6.5049,19.34635-11.981,38.571h44.39012c4.3882-13.35371,8.88306-26.24037,13.39195-38.571Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M787.981,469.42381q-4.29519,19.6076-7.68675,38.571H820.004q4.44783-19.61091,9.56837-38.571Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M762.3185,713.44417c.12069,16.62136.66994,25.97636.66994,25.97636l-.39358,7.478h43.29393q-2.59815-16.58382-3.96368-33.4544Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M799.97844,420.61974q-5.32646,19.46534-9.69876,38.571H832.379q5.53043-19.7784,11.542-38.571Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M1110.252,261.1651c-15.40963-32.21182-30.90977-56.23791-46.0196-73.94267l-7.89046,12.123.671-20.13755a158.22113,158.22113,0,0,0-16.6583-15.2789L1029.57149,180.496l.78947-23.69016a99.14041,99.14041,0,0,0-20.48314-10.11247l-7.97482,12.25252.48352-14.50965c-27.51475-6.905-50.1228,2.55337-63.22081,10.629l-7.86615-1.17354,13.49035-5.63347a99.1429,99.1429,0,0,0-6.25118-21.97146l-23.44384-3.4975L933.3355,115.172a158.21342,158.21342,0,0,0-12.02277-19.14149l-19.92822-2.973,13.34774-5.574c-14.68838-18.056-35.52378-37.63644-64.42682-58.60454,0,0-2.13827,18.67657-3.3293,44.71673l19.575,20.025-20.111-5.20116c-.21044,7.9976-.30047,16.41755-.20141,25.00812l14.43606,14.76794-14.20045-3.67257c.20688,6.56884.54118,13.17147,1.02835,19.7a77.7484,77.7484,0,0,0-37.38522.21323l.48352,14.50965-7.97482-12.25252A99.14066,99.14066,0,0,0,782.143,156.80588l.78947,23.69016L772.14939,163.929a158.22118,158.22118,0,0,0-16.65831,15.2789l.671,20.13755-7.89046-12.123c-15.10983,17.70476-30.61,41.73085-46.0195,73.94267,0,0,18.75584-1.2664,44.58355-4.79292l16.16488-22.86653L761.513,254.225c7.90429-1.2359,16.20236-2.66638,24.63409-4.31364l11.92111-16.86355-1.05035,14.63006c11.76-2.54214,23.55587-5.52,34.6978-8.989l8.00048,7.44239-14.31143-2.98448a99.14327,99.14327,0,0,0-7.27222,21.65494l17.35524,16.14443-19.35091-4.03541a158.216,158.216,0,0,0-.91179,22.58566l14.75256,13.72341-14.16008-2.95292c1.90026,23.19813,8.00769,51.13034,19.98347,84.7701,0,0,12.327-14.19261,28.03786-34.99356l-4.81657-27.58585,13.64313,15.66426c4.697-6.47636,9.53377-13.36913,14.311-20.50951l-3.55213-20.344L893.0578,318.329c9.67465-15.1043,18.722-30.948,25.38657-46.03838A385.08247,385.08247,0,0,0,946.086,304.50881l7.38-12.67579.33948,20.64894c6.03555,6.11391,12.08293,11.97343,17.91467,17.45027l10.45191-17.95172.46027,27.99943c19.34428,17.473,34.12174,29.09258,34.12174,29.09258,5.43182-35.29231,6.17421-63.8748,3.67531-87.01609l-13.35149,5.56466,11.9067-16.25425a158.22134,158.22134,0,0,0-5.14539-22.01061l-18.246,7.60454,8.67646-11.84438q5.59182,1.34816,11.21649,2.56145l-1.05035-14.63006,11.92111,16.86355c8.43173,1.64726,16.7298,3.07774,24.63409,4.31364l-1.48755-20.71932,16.16488,22.86653C1091.49615,259.8987,1110.252,261.1651,1110.252,261.1651Z" transform="translate(-24.21825 -28.87901)" fill="#e6a23c"/><path d="M706.516,543.343c1.1863,9.45251,2.159,18.55119,2.95593,27.2266H683.6654q-1.40913-13.68048-3.53328-27.2266Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M685.40871,639.4695q.83031-13.54614.67122-27.2266h26.16136c.42474,10.432.59112,19.589.62171,27.2266Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M640.78457,398.31967c-21.51346-57.31385-42.59025-95.84872-42.59025-95.84872l21.948-13.05765c22.85347,34.46154,40.12634,71.71229,53.16839,108.90637Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M710.10356,577.79293c.8062,9.70662,1.3923,18.82158,1.81046,27.22659H685.94319q-.37542-13.61307-1.5892-27.22659Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M701.42907,508.893c1.58609,9.31519,2.95987,18.41031,4.14686,27.22659H678.96066q-2.31847-13.75434-5.23162-27.22659Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M675.78979,405.54305q4.59169,13.65627,8.45716,27.2266H652.91271c-3.09755-9.42616-6.2704-18.52264-9.45315-27.2266Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M694.73746,474.443q3.0319,13.84068,5.42595,27.2266H672.133q-3.13965-13.843-6.75415-27.2266Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M712.85221,646.69288c-.08519,11.73274-.47289,18.33627-.47289,18.33627l.27782,5.27863H682.09668q1.834-11.70624,2.79789-23.6149Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M686.26869,439.993q3.75987,13.74026,6.8462,27.22659H663.39766q-3.90382-13.96124-8.14726-27.22659Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M467.25181,327.43668c10.87739-22.73779,21.81868-39.6974,32.48446-52.1949l5.56974,8.55742-.47364-14.21476a111.68489,111.68489,0,0,1,11.75882-10.78512l7.61163,11.69442-.55728-16.72249a69.98142,69.98142,0,0,1,14.4587-7.13822l5.6293,8.64885-.34131-10.24212c19.4222-4.8741,35.38084,1.80238,44.62651,7.50279l5.55258-.82838-9.52261-3.97657a69.98374,69.98374,0,0,1,4.4126-15.50928l16.54861-2.46883-12.87573-5.37687a111.68,111.68,0,0,1,8.48667-13.51166l14.067-2.09862-9.422-3.93455c10.36829-12.74544,25.07564-26.56694,45.47782-41.368,0,0,1.50937,13.18347,2.35009,31.56478l-13.81766,14.1353,14.196-3.67141c.14854,5.64537.21209,11.58887.14216,17.65281l-10.19016,10.42444,10.02385-2.59241c-.146,4.63684-.382,9.29752-.72589,13.90591a54.88123,54.88123,0,0,1,26.3896.15051l-.34131,10.24212,5.62929-8.64885a69.98117,69.98117,0,0,1,14.4587,7.13822l-.55727,16.72249,7.61163-11.69442a111.68687,111.68687,0,0,1,11.75882,10.78512l-.47364,14.21476,5.56974-8.55742c10.66577,12.4975,21.60706,29.45711,32.48439,52.1949,0,0-13.23943-.89394-31.47078-3.38325l-11.41052-16.1411,1.05,14.62542c-5.57951-.8724-11.437-1.88215-17.38879-3.04492l-8.41491-11.9037.74142,10.32711c-8.30116-1.79445-16.62769-3.8965-24.49259-6.34518l-5.6474,5.25346,10.10219-2.10669a69.98325,69.98325,0,0,1,5.13334,15.28586L661.2033,341.39976l13.65948-2.84853a111.68285,111.68285,0,0,1,.64362,15.94284l-10.41359,9.68713,9.99537-2.08442c-1.34137,16.37518-5.6525,36.092-14.106,59.83779,0,0-8.70142-10.01832-19.79145-24.70136l3.39993-19.47239L634.96021,388.818c-3.31556-4.57156-6.72974-9.437-10.10193-14.47732l2.50739-14.36046-6.80014,7.80752A247.60106,247.60106,0,0,1,602.64558,335.29a271.82334,271.82334,0,0,1-19.51173,22.74229l-5.20944-8.94763-.23963,14.57574c-4.2604,4.31571-8.52914,8.45185-12.64567,12.31786l-7.37783-12.67182-.32489,19.76432c-13.65481,12.33393-24.086,20.536-24.086,20.536-3.83423-24.91224-4.35827-45.08815-2.59434-61.4232l9.4246,3.928-8.40474-11.47361a111.68612,111.68612,0,0,1,3.632-15.53692l12.87953,5.36792-6.12457-8.36075q-3.94716.95164-7.91753,1.80808l.74143-10.32711-8.41492,11.9037c-5.95181,1.16277-11.80928,2.17252-17.38879,3.04492l1.05-14.62542-11.41052,16.1411C480.49124,326.54274,467.25181,327.43668,467.25181,327.43668Z" transform="translate(-24.21825 -28.87901)" fill="#e6a23c"/><ellipse cx="379.53374" cy="720.59071" rx="147.5" ry="14" fill="#3f3d56"/><ellipse cx="734.53374" cy="720.59071" rx="147.5" ry="14" fill="#3f3d56"/><path d="M870.752,606.96972s10.65,73.95-40.48,117.67c-33.09,28.29-80.27,32.92-118.99,13.01-14.38-7.39-29.72-18.62-44.37006-35.57a191.08437,191.08437,0,0,1-15.26-20.3,242.48469,242.48469,0,0,1-17.73-32.37q-4.8-10.485-9.17-22.44c-.56-1.53-1.08-3.03-1.58-4.52-26.55-78.91,25.09-101.93,72.49-107.45a243.44911,243.44911,0,0,1,29.96-1.51,268.64314,268.64314,0,0,1,35.13,2.48s.97.01,2.72.08a210.98673,210.98673,0,0,1,26.93005,2.99C827.022,525.46972,883.072,545.38971,870.752,606.96972Z" transform="translate(-24.21825 -28.87901)" fill="#e6a23c"/><path d="M544.752,626.96972c-23.34,64.07-56.95,95.47-86.53,110.68-38.72,19.91-85.9,15.28-118.99-13.01a104.52345,104.52345,0,0,1-9-8.67,108.90024,108.90024,0,0,1-15.01-20.66,128.65459,128.65459,0,0,1-12.09-30.09,161.53735,161.53735,0,0,1-5.17-35.23,140.93566,140.93566,0,0,1,.79-23.02c-11.53-57.65,36.85-78.78,73.12-86.52a215.32462,215.32462,0,0,1,31.83-4.29c3.21-.18,5.05-.19,5.05-.19a276.07877,276.07877,0,0,1,57.57-1.71C516.412,518.29968,576.402,540.09973,544.752,626.96972Z" transform="translate(-24.21825 -28.87901)" fill="#e6a23c"/><path d="M403.702,516.15973l-100.57,149.06a161.53735,161.53735,0,0,1-5.17-35.23l73.91-109.54A215.32462,215.32462,0,0,1,403.702,516.15973Z" transform="translate(-24.21825 -28.87901)" fill="#fff" opacity="0.2"/><path d="M466.322,514.2597l-136.09,201.71a108.90024,108.90024,0,0,1-15.01-20.66l122.6-181.71A262.51415,262.51415,0,0,1,466.322,514.2597Z" transform="translate(-24.21825 -28.87901)" fill="#fff" opacity="0.2"/><path d="M725.622,513.48968l-91.7,135.92q-4.8-10.485-9.17-22.44c-.56-1.53-1.08-3.03-1.58-4.52l72.49-107.45A243.44911,243.44911,0,0,1,725.622,513.48968Z" transform="translate(-24.21825 -28.87901)" fill="#fff" opacity="0.2"/><path d="M790.402,519.03973l-123.49,183.04a191.08437,191.08437,0,0,1-15.26-20.3l111.81995-165.73A210.98673,210.98673,0,0,1,790.402,519.03973Z" transform="translate(-24.21825 -28.87901)" fill="#fff" opacity="0.2"/><path d="M894.752,599.96972H871.86472c10.12915-83.03949-111.11273-84-111.11273-84a276.47448,276.47448,0,0,0-58-1.67132v-.32868h-237v.24872a276.75793,276.75793,0,0,0-57,1.75128s-121.24188.96051-111.11273,84H275.752v22H297.8389c-.22119,23.90107,4.52283,71.14319,41.39307,102.67,33.09,28.29,80.27,32.92,118.99,13.01,29.58-15.21,63.19-46.61,86.53-110.68,7.996-21.94982,10.13965-39.74377,8.07287-54.14819a635.39219,635.39219,0,0,1,63.85425,0c-2.06677,14.40442.07684,32.19837,8.07288,54.14819,23.34,64.07,56.95,95.47,86.53,110.68,38.72,19.91,85.9,15.28,118.99-13.01,36.87024-31.5268,41.61425-78.76892,41.39306-102.67H894.752Zm-360.54,27.41c-22.21,60.97-54.61,89.49-82.4,102.65-33.81,16.01-74.1,11.56-103.12-12.03-35.08-28.52-39.75-72.35-39.62-94.69.06-8.88-.34-17.74-.69-26.61-2.77-69.71,101.83-70.53,101.83-70.53S580.722,499.72973,534.212,627.3797Zm83.38928-59.56537a424.54686,424.54686,0,0,0-65.69861,0c-5.48632-24.48639-23.97729-38.28705-45.937-45.84461H663.53824C641.57859,529.52728,623.08762,543.32794,617.60129,567.81433ZM862.202,596.3797c-.36,8.95-.76,17.9-.7,26.85.14,22.55-4.58,66.79-39.98,95.56-29.28,23.81-69.92005,28.31-104.03,12.17-28.06-13.27-60.78-42.05-83.21-103.62-46.93006-128.83,125.15-102.14,125.15-102.14S864.992,526.01971,862.202,596.3797Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M428.14356,741.71275c-.11325-.18506-2.78356-4.64376-3.70932-13.90237-.84914-8.49429-.30313-22.81207,7.12226-42.7842,14.06719-37.83586-3.24186-68.36391-3.41872-68.668l.854-.49541a75.78134,75.78134,0,0,1,7.14973,20.25453,88.3638,88.3638,0,0,1-3.65968,49.253c-14.04309,37.77129-3.60282,55.65189-3.49584,55.82827Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><circle cx="398.4247" cy="578.84223" r="6.41529" fill="#3f3d56"/><circle cx="418.65754" cy="602.52946" r="6.41529" fill="#3f3d56"/><circle cx="404.83999" cy="618.32095" r="6.41529" fill="#fff"/><circle cx="421.61845" cy="631.64502" r="6.41529" fill="#fff"/><circle cx="399.90515" cy="652.37134" r="6.41529" fill="#3f3d56"/><path d="M432.01914,741.94889s-6.41529-15.79149,12.83059-27.63511Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M424.12933,741.66244s-2.91966-16.79294-25.51732-16.649Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/><path d="M363.072,370.10974a6.35543,6.35543,0,0,1-2.83,5.21l-.24.15h-106.8l.43-1.31c.07-.23,7.89-22.92005,42.5-18.54,3.26-1.12,35.12-11.52,54.19.17C358.782,360.96972,363.072,365.78973,363.072,370.10974Z" transform="translate(-24.21825 -28.87901)" fill="#f1f1f1"/><path d="M561.072,447.10974a6.35543,6.35543,0,0,1-2.83,5.21l-.24.15h-106.8l.43-1.31c.07-.23,7.89-22.92005,42.5-18.54,3.26-1.12,35.12-11.52,54.19.17C556.782,437.96972,561.072,442.78973,561.072,447.10974Z" transform="translate(-24.21825 -28.87901)" fill="#f1f1f1"/><path d="M606.072,137.10974a6.35543,6.35543,0,0,1-2.83,5.21l-.24.15h-106.8l.43-1.31c.07-.23,7.89-22.92,42.5-18.54,3.26-1.12,35.12-11.52,54.19.17C601.782,127.96972,606.072,132.78973,606.072,137.10974Z" transform="translate(-24.21825 -28.87901)" fill="#f1f1f1"/><path d="M53.17754,652.8835l9.13713,28.28159s-8.26692,26.54118-4.351,56.12807,1.7404,30.4571,1.7404,30.4571-39.12624-2.25247-35.21033,9.49526,42.172,4.86308,42.172,4.86308,7.34723-1.97821,10.828-22.86308S89.72606,698.134,89.72606,698.134l-8.22935-37.97489Z" transform="translate(-24.21825 -28.87901)" fill="#ffb8b8"/><path d="M56.22325,595.015S39.6894,601.10644,39.6894,617.64029s6.09142,39.15912,10.00733,40.46443,30.022,19.14446,34.80811,6.52652S56.22325,595.015,56.22325,595.015Z" transform="translate(-24.21825 -28.87901)" fill="#d0cde1"/><polygon points="170.367 761.932 205.175 760.626 231.717 756.71 223.885 782.816 159.49 784.557 170.367 761.932" fill="#ffb8b8"/><path d="M244.62214,794.29144s-.43511-9.57223-4.351-9.13713-1.3053-3.48081,2.17551-4.351,13.48814-5.22122,13.48814-5.22122l39.59422,2.61061S321.2,800.818,310.75754,813.0008s-37.41872,1.3053-37.41872,1.3053l-29.15179.4351S234.6148,799.07755,244.62214,794.29144Z" transform="translate(-24.21825 -28.87901)" fill="#2f2e41"/><polygon points="236.068 731.91 248.685 791.083 274.792 785.862 259.998 711.895 244.334 703.628 236.068 731.91" fill="#ffb8b8"/><path d="M110.17582,753.39191s-73.097,33.0677-42.20483,66.57051c0,0,0,15.66365,32.6326,12.61794s95.7223-8.702,98.768-6.96162,12.61793-34.373,4.351-36.11342-18.27426-3.91591-18.27426-3.91591,8.702-1.3053,8.702-8.702c0,0,24.80078-1.7404,32.1975-17.404S240.70622,732.072,240.70622,732.072l16.969,43.51013s19.57956-36.11341,34.373-20.01466c0,0-16.53385-103.98922-29.15179-113.56145s-21.32-12.61794-33.0677-3.91591-22.62527,30.89219-22.62527,30.89219Z" transform="translate(-24.21825 -28.87901)" fill="#2f2e41"/><path d="M284.65146,802.12326a98.03577,98.03577,0,0,0-8.702,7.39673c-3.48081,3.48081-8.26692,1.7404-8.702,0s-8.26692,1.3053-9.13712,13.92324-6.09142,23.93057,7.83182,27.84648,13.48814,15.22855,13.48814,15.22855a46.93427,46.93427,0,0,0,35.24321,2.17551c19.57956-6.52652,12.61794-13.48814,12.61794-13.48814l-26.10608-43.075S294.22369,799.07755,284.65146,802.12326Z" transform="translate(-24.21825 -28.87901)" fill="#2f2e41"/><path d="M212.42464,586.313s41.76972,14.35834,46.12074,17.404,23.93057,17.404,14.35834,24.80078-17.40405,12.18283-36.11341,6.52652S197.19609,611.984,197.19609,611.984Z" transform="translate(-24.21825 -28.87901)" fill="#ffb8b8"/><path d="M170.65491,567.16854s16.53385-3.04571,28.28158,3.48081,21.75507,19.57956,21.75507,19.57956S209.814,613.28928,201.9822,616.77009,179.792,602.84685,179.792,602.84685Z" transform="translate(-24.21825 -28.87901)" fill="#d0cde1"/><path d="M94.51217,554.5506s.4351,16.96895-1.3053,18.70936,20.88486,53.08236,45.68564,30.45709,5.65632-31.7624,5.65632-31.7624-9.13713-16.969-8.702-18.70936-40.46443,0-40.46443,0Z" transform="translate(-24.21825 -28.87901)" fill="#ffb8b8"/><path d="M94.51217,554.5506s.4351,16.96895-1.3053,18.70936,20.88486,53.08236,45.68564,30.45709,5.65632-31.7624,5.65632-31.7624-9.13713-16.969-8.702-18.70936-40.46443,0-40.46443,0Z" transform="translate(-24.21825 -28.87901)" opacity="0.1"/><path d="M101.47379,587.1832s16.53385,11.31263,23.49548,8.702,15.66364-13.92325,16.53385-14.79345,45.25054,88.32557,45.25054,88.32557-6.52652,32.6326-23.93058,42.20483-17.1865,17.18651-19.362,23.713-30.23954-20.66732-30.23954-20.66732L95.38237,638.96026V592.83952Z" transform="translate(-24.21825 -28.87901)" fill="#d0cde1"/><path d="M94.29462,566.951s-5.43877-1.08776-11.09508,3.69836S51.002,593.27462,52.30734,595.015s13.053,26.54118,15.66365,36.54852,6.52652,11.31263,6.52652,11.31263,9.13713,6.52652,7.83182,11.31264-6.96162,70.05131.87021,84.40966,6.52652,26.97628,4.351,30.45709,20.88486-10.00733,20.88486-10.00733,34.373-27.84649,36.98362-36.11341a97.263,97.263,0,0,0,3.48081-17.40406s-22.19017-87.89047-29.15179-92.67658S94.29462,566.951,94.29462,566.951Z" transform="translate(-24.21825 -28.87901)" fill="#575a89"/><path d="M142.0946,567.29509s10.72115-6.65307,12.89666-4.91267,22.62527,1.74041,23.06037,3.48081,1.3053,43.51014,16.09875,54.38767,5.22122,32.6326,5.22122,32.6326l10.87753,17.40406s-59.17285,56.99362-55.25787,37.41871c.21755-1.08775,0-1.3053,0-1.3053s-23.06037-98.768-20.01466-103.98922S143.55629,573.51306,142.0946,567.29509Z" transform="translate(-24.21825 -28.87901)" fill="#575a89"/><path d="M233.3095,607.19786l-59.17378,20.44976s-58.73868,13.92325-49.60156,30.022S172.39531,646.357,172.39531,646.357l78.7996-8.82909S282.476,611.11377,233.3095,607.19786Z" transform="translate(-24.21825 -28.87901)" fill="#ffb8b8"/><circle cx="93.78939" cy="509.57283" r="32.1975" fill="#ffb8b8"/><path d="M92.36668,506.4531l-5.95587-2.16578s12.45312-12.45312,29.77934-11.37019l-4.8731-4.873s11.91174-4.33148,22.74055,7.03872c5.69249,5.97707,12.27878,13.00279,16.38465,20.91719h6.37832l-2.66208,5.32415,9.31726,5.32415-9.56325-.95636a26.866,26.866,0,0,1-.90453,13.789l-2.16569,5.95579s-8.66312-17.32606-8.66312-19.49184v5.4144s-5.95587-4.87294-5.95587-8.12156l-3.24862,3.79009-1.62432-5.95587-20.0333,5.95587,3.24863-4.87294-12.45312,1.62431,4.8731-5.95587s-14.07744,7.03872-14.619,12.99459-7.58,13.536-7.58,13.536L81.538,538.93944S76.66493,514.57467,92.36668,506.4531Z" transform="translate(-24.21825 -28.87901)" fill="#2f2e41"/><path d="M146.61566,540.19858s1.05805,7.34674-4.02158,11.6902a10.68163,10.68163,0,0,1-11.82134,1.29251,14.7297,14.7297,0,0,1-4.40805-3.53378,18.98358,18.98358,0,0,1-1.516-2.01675,24.0899,24.0899,0,0,1-1.76144-3.21588q-.47687-1.04165-.911-2.22935c-.05564-.152-.1073-.301-.157-.449-2.63767-7.8395,2.49263-10.12648,7.20169-10.67488a24.18681,24.18681,0,0,1,2.97645-.15,26.68959,26.68959,0,0,1,3.49007.24639s.09637.001.27022.00794a20.96175,20.96175,0,0,1,2.67543.29706C142.2712,532.10177,147.83962,534.08077,146.61566,540.19858Z" transform="translate(-24.21825 -28.87901)" fill="#e6a23c"/><path d="M114.22842,542.18553c-2.31877,6.36518-5.65784,9.48469-8.59653,10.99576a10.68165,10.68165,0,0,1-11.82135-1.29251,10.38378,10.38378,0,0,1-.89412-.86134,10.81892,10.81892,0,0,1-1.49121-2.05252,12.78124,12.78124,0,0,1-1.2011-2.98936,16.04808,16.04808,0,0,1-.51363-3.5,14.00278,14.00278,0,0,1,.07848-2.287c-1.14547-5.72738,3.661-7.82659,7.26428-8.59554a21.39066,21.39066,0,0,1,3.16223-.42619c.3189-.01789.50171-.01888.50171-.01888a27.42839,27.42839,0,0,1,5.71942-.16989C111.41291,531.38944,117.37277,533.55522,114.22842,542.18553Z" transform="translate(-24.21825 -28.87901)" fill="#e6a23c"/><path d="M100.21547,531.17685l-9.99136,14.80871a16.04808,16.04808,0,0,1-.51363-3.5L97.05324,531.603A21.39066,21.39066,0,0,1,100.21547,531.17685Z" transform="translate(-24.21825 -28.87901)" fill="#fff" opacity="0.2"/><path d="M106.4366,530.98808,92.91642,551.02744a10.81892,10.81892,0,0,1-1.49121-2.05252l12.18-18.0524A26.08038,26.08038,0,0,1,106.4366,530.98808Z" transform="translate(-24.21825 -28.87901)" fill="#fff" opacity="0.2"/><path d="M132.19738,530.91158l-9.11016,13.5033q-.47687-1.04165-.911-2.22935c-.05564-.152-.1073-.301-.157-.449l7.20169-10.67488A24.18681,24.18681,0,0,1,132.19738,530.91158Z" transform="translate(-24.21825 -28.87901)" fill="#fff" opacity="0.2"/><path d="M138.6331,531.463l-12.26841,18.18454a18.98358,18.98358,0,0,1-1.516-2.01675l11.109-16.46485A20.96175,20.96175,0,0,1,138.6331,531.463Z" transform="translate(-24.21825 -28.87901)" fill="#fff" opacity="0.2"/><path d="M149,539.50315h-2.27379c1.0063-8.24976-11.03876-8.34518-11.03876-8.34518a27.46661,27.46661,0,0,0-5.76215-.166v-.03266H106.38v.02471a27.49535,27.49535,0,0,0-5.6628.174s-12.04507.09542-11.03876,8.34518H87.504v2.18564h2.19428c-.022,2.37451.44933,7.06789,4.11229,10.2a10.68165,10.68165,0,0,0,11.82135,1.29251c2.93869-1.51107,6.27776-4.63058,8.59653-10.99576a11.22868,11.22868,0,0,0,.802-5.37948,63.12484,63.12484,0,0,1,6.34375,0,11.22856,11.22856,0,0,0,.802,5.37948c2.31877,6.36518,5.65783,9.48469,8.59653,10.99576a10.68163,10.68163,0,0,0,11.82134-1.29251c3.663-3.1321,4.13427-7.82548,4.1123-10.2H149Zm-35.8187,2.72311c-2.20651,6.05721-5.42537,8.89059-8.18623,10.198a9.69145,9.69145,0,0,1-10.2447-1.19515c-3.48511-2.83339-3.94906-7.18778-3.93614-9.40721.006-.8822-.03378-1.76242-.06855-2.64363-.27519-6.92551,10.11654-7.007,10.11654-7.007S117.80194,529.54457,113.1813,542.22626Zm8.28451-5.91767a42.17881,42.17881,0,0,0-6.527,0c-.54505-2.43265-2.38208-3.80371-4.56371-4.55454h15.65441C123.84789,532.50488,122.01086,533.87594,121.46581,536.30859Zm24.30043,2.8379c-.03576.88916-.0755,1.77832-.06954,2.66748.01391,2.24028-.455,6.63541-3.97191,9.49363a9.77755,9.77755,0,0,1-10.33511,1.20906c-2.78768-1.31834-6.03833-4.17756-8.26669-10.29437-4.66238-12.79893,12.43332-10.14735,12.43332-10.14735S146.04342,532.15641,145.76624,539.14649Z" transform="translate(-24.21825 -28.87901)" fill="#3f3d56"/></svg>
src/assets/loginPage/arrow-r.png
src/assets/loginPage/back-icon.png
src/assets/loginPage/device-pic.png
src/assets/loginPage/equipment.JPG
src/assets/loginPage/login-bg.jpg
src/assets/loginPage/login-bg.png
src/assets/loginPage/login_icon_password.png
src/assets/loginPage/login_icon_user.png
src/assets/loginPage/map-bg.jpg
src/assets/loginPage/map-bg.png
src/assets/loginPage/star-bg.png
src/assets/loginPage/task-job-pic.png
src/assets/loginPage/watersys.JPG
src/assets/loginPage/wind.JPG
src/assets/loginPage/xj-bg.png
src/assets/loginPage/xj-icon.png
src/assets/logo-mini.svg
对比新文件
@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 50" width="64" height="50">
    <defs>
        <image width="64" height="50" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAyCAYAAADsg90UAAAAAXNSR0IB2cksfwAACI5JREFUeJy1WgtsW9UZdvNq0xU6WhZoCCVx7Gunbld1GSsMdYpGREhwr+2IMbQWqRoTk+iWPZi2wWhm1kwEmqV52feRJrbvvd6DiUnbQCAemzY2xh4tSB0wOqZIqAtLYzultIWEpt13btLq+sap/R8nRzpK4vh+5/++85///8851yEk1V+hX6B0tyE3OWwt0x789VR78AKlZ0KBz1oxBE3+BdUW9PNuQ7nJbk/BDQ/v4hi0x44z1R64jyrAVCjQ/fLNN8/ZoUWdgqGc57AFE6I86giH+QRw6XI9QE4RBz3iTAyVW3EyQdEDUmeIIhyeFNtMHO/o0B4e8qYASfVvLk2p4BKgdnioFCAvEQeddhnyFivOpOgvBaFXiAKcygQDrk927S/zjkae5xUA/X3YI/C5AFwHLrSPw+2+YYfCMugiCvDaCbGt0hc9uAXuP1OEAPACZQ+fAGguQ9nGgglx0OfsOAhq24lBcG/YYQa/kWLIz3XlCW4B6mKRCoCMEQdNu3VpnRVnMhBYA2L/LVCATCooXuNJSHXFzv58P+mMyyu5RQDAKNntdLnNjoN0+NMCM0D8901NDkGXuyBAseRZn3Ubagu3AFjTd1GXAdZdpCqurMgSIBS4BwRn8wgwje/d4pV6yz2adGQJyM/bo/ZyC+DSlWqApIiDHqtPyFdlCyBeD4Lv5xHgr5mAWO4ZjTRh9s8tlQDoryIbrOISoLYvvAIALxIHnIHn3GnFmfDfztLhH/IEv/vYd72xyKElJM/6Gdjj4fYCuNA3yYMa6ogdBwQfvIwAk+mguHZz3+MbMPsfLrEALD3v5RfAkH3UOID+Jqqwj2ULIDZeJvhF2He8I0NfX2ry8wI85VSy41LBzaUPsXT4L/Iy0OUbrTgpsXUlyI7lEOAsvGOboPRdKejK28shAPqpek1etxjHArxAiXCo/pAdB2QPLRQg8BLcv8ITi4h4bnaZBGD2+IsQQG0DCDUyv2LfjcHVQyB93iLAecz+bvY/T1x6YrnImwIkVakIAeSrAfIucdCz7qRcY8VJh8RrQDplWfvHxttaVvkGe6vg/h8tpwDoR926wpcOb9CkEhQ4Mbrqym4rTkrcydLhs5bU95Wwwwx+311m8qxPQ4CtvE6AdKjcLlCrQkNJXNXdnYUD0t+eF+AE1v76rV0/qvTEo/8kkkGJq/yFLIKhPsgtgEszl8E4cdAxPHdllgDBwGZW9k6Fguaa9A4PtMEwkrDe0chhCPAZ/E5dNn/kPiWqGe5mVSH1rJCdze2w4rDNDsi/gdn/FPtb0KTfUmeyQenvuE45WCLQd6unsc3fwKeAw0yHX+Zwu247DpbB3emQv3R7x7du8GgybdtrKGc39Ty23rQnqfKk5y9wCwD1XACZJg56xGUMZFVhx1taytjPBnWAfuihyT+3TEiAQwC1Mhzmqwrr9QhbBoeJg36A6Ou0Y/kGe2qQ+mhiGspHDcODTZfs0eRr8fkE0Z4xpyGt4RJgTnX1carq8Jw9dhzv6BB5k+VJyK9t6+y8dNK74bGHMSHK00Scc/CC7fwC6MotAjX6GuqTzsTBkosYW/f9YKUnIb1OFiAW/c4Ce5Lq18jLKKnu5xaApTWBHn0n8Nz6ixhw4zvJ5HXlvU2R3gWui02XizwhrEznbTW9vQ64nUEckBUut13EQOHzFFUA70jErBv+09xcYrXHqUXK8H9qIXXapSs1dm4FN1SF95DdzlD72LMNUt/15CMvXT65NfzIRtQOq5FCv7jAHkPppdqDZ3YvZFZgY8WEQN8dvvFxpB8hLvWT3T8uyWxckG9CEfX38fk0ahGgmboMMIk/2xg5UJKbYZ62sf9RbI7UPxGJzLgT0R2Y/RM0z1HO+QZ6Gl/3+dh2Wmdb6HQwUJc9IfI6fPc40Z5xCLeW2wvw8Pfoy0B5mfoMAuYLn+7oKE0FxZqp+YvWTHugw24PvvtLIjZLh83cAghzmxHqASb5qntz/4EvsfEy7UHroepvJoKtWdUcPPKrVGwsA6k2FuYTAPXAGoC8RfYCStflqRvv3VuB4Hc1SI9bBJjAZ1VWe+p1+TqBHpfG+M8Ksa0EgLacAnhiETNzIPjdbztLPIfPWrME0CSkQ+UfxDFmkQ5v5RPAYcYBckFTcDfUWc+hwZsw06tA+EiOi5RoDns66ctA/Qm3AE4tuhYgZ5Zl9uPR32165PtlINoMwjM5jtPfSvn9WTe/iEufw7PUW+U3a2NSKZ8CTU0s+DyzHAJgq9yuNDaywxNtkQuVWaTDBqs5SIdsQt4hjsXOCvmvzrDu6Fdnebo3Hj3u69xXngoFqkH09KL3ie2BB6y2XCsfZNt1apnOqsL7uY/KoB57k+SDJRUhIZlX2iD4UJ4b5ef+3dqabY9hlunUdPt0XXyIryqs1yKVAv3qbPFuKNNedaAR5FeD4NE8AqRTwZ1ZmxqnHv0EcI4Rxz3hNqSqxThevrEXqpJq31IJgOD3TN3+h0tYmmPpLt9bJex80W4SRBzmEF7kE8Bhbo5aONwutwCx6K4JUVyByu/JfOTn+6EFAiTNN1uoAgxyC1BvqFcAZLJo8pr8rlvuq8wExfpFUl+u/s7/dt6R9UKkS5ergHeaOP6Yc2SQLw7Mqa6SDznsHakvzLAyoeAPCyRvVoXpUGCb1ZZqRWFnhdQXPWcg3Jac5App7C2MImf/5Kb+nupJ0X8FSL1NEOACEyyHPQ9QbWA73CIEkBuEIqrCzUO9CsNB6esCqQ8pAqD/Oe33l9vs2SLQd6svuhJSWW6GeVptLFKGbMD9eltjZ2cjw5m4o60ChF4lCvBeJhjIuntAYF4N3KNEO9Lwgmo+F/D5mNt1cbr/2OeD916qx+HSB4gCsDdNdmXZM7dbjRJtYXeZd/EJ4DDX3Q4uARLSj604yO23UgVA2jRy2EO+OkNX/w+fZNm8pw5QbAAAAABJRU5ErkJggg=="/>
    </defs>
    <style>
        tspan { white-space:pre }
    </style>
    <use id="Background" href="#img1" x="0" y="0" />
</svg>
src/assets/menu/admin.png
src/assets/menu/bg_home.jpg
src/assets/menu/bg_home1.jpg
src/assets/menu/card1.png
src/assets/menu/card10.png
src/assets/menu/card11.png
src/assets/menu/card2.png
src/assets/menu/card3.png
src/assets/menu/card4.png
src/assets/menu/card5.png
src/assets/menu/card6.png
src/assets/menu/card7.png
src/assets/menu/card8.png
src/assets/menu/card9.png
src/assets/menu/companyLogo.png
src/assets/menu/icon1.png
src/assets/menu/icon10.png
src/assets/menu/icon11.png
src/assets/menu/icon2.png
src/assets/menu/icon3.png
src/assets/menu/icon4.png
src/assets/menu/icon5.png
src/assets/menu/icon6.png
src/assets/menu/icon7.png
src/assets/menu/icon8.png
src/assets/menu/icon9.png
src/assets/methods/index.ts
对比新文件
@@ -0,0 +1,15 @@
import { userApi } from '/@/api/systemManage/user';
import { ElMessage } from 'element-plus';
export async function getUserByDepartment(value: number | null) {
    let res = await userApi().getUserLByDepartment(value);
    if (res.data.code === '200') {
        return res.data.data;
    } else {
        ElMessage({
            type: 'warning',
            message: res.data.msg
        });
        return [];
    }
}
src/assets/newMenu/card-1.png
src/assets/newMenu/card-10.png
src/assets/newMenu/card-11.png
src/assets/newMenu/card-2.png
src/assets/newMenu/card-3.png
src/assets/newMenu/card-4.png
src/assets/newMenu/card-5.png
src/assets/newMenu/card-6.png
src/assets/newMenu/card-7.png
src/assets/newMenu/card-8.png
src/assets/newMenu/card-9.png
src/assets/newMenu/icon1.png
src/assets/newMenu/icon10.png
src/assets/newMenu/icon11.png
src/assets/newMenu/icon2.png
src/assets/newMenu/icon3.png
src/assets/newMenu/icon4.png
src/assets/newMenu/icon5.png
src/assets/newMenu/icon6.png
src/assets/newMenu/icon7.png
src/assets/newMenu/icon8.png
src/assets/newMenu/icon9.png
src/assets/newMenu/leftbg.jpg
src/assets/newMenu/leftbg.png
src/assets/newMenu/pic_line1.png
src/assets/newMenu/pic_line2.png
src/assets/newMenu/topbg.jpg
src/assets/newMenu/toplogo.png
src/assets/style/index.scss
对比新文件
@@ -0,0 +1,19 @@
.input-box{
  width: 200px !important;
  padding-right: 10px;
  padding-bottom: 10px;
}
.input-box2{
  width: 200px !important;
  padding-right: 10px;
}
.input-add{
  width: 90% !important;
}
.basic-line{
  display: inline-block;
  padding-left: 10px;
}
.page-position{
  float: right;
}
src/assets/warningScreen/body-bg.jpg
src/assets/warningScreen/logo_dark.png
src/assets/warningScreen/logo_light.png
src/assets/warningScreen/pagebg-l-light.png
src/assets/warningScreen/pagebg-l.png
src/assets/warningScreen/pagebg-r-light.png
src/assets/warningScreen/pagebg-r.png
src/assets/warningScreen/pagebg-t-light.png
src/assets/warningScreen/pagebg-t.png
src/assets/warningScreen/riskprocast-light.jpg
src/assets/warningScreen/riskprocast.jpg
src/assets/warningScreen/skin-light.png
src/assets/warningScreen/skin.png
src/assets/warningScreen/small-full.png
src/assets/warningScreen/video.png
src/components/DailogClass/index.vue
对比新文件
@@ -0,0 +1,147 @@
<template>
    <el-dialog v-model="dialogVisible" @close="resetForm(ruleFormRef)" :fullscreen="full" :title="titles" width="30%" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-form :model="form" ref="ruleFormRef" :rules="rules" :disabled="disabled" label-width="120px">
            <el-row>
                <el-col :span="20">
                    <el-form-item label="名称" size="default" prop="typeName">
                        <el-input v-model="form.typeName" />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="20">
                    <el-form-item label="描述" size="default" prop="memo">
                        <el-input v-model="form.memo" type="textarea" />
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="resetForm(ruleFormRef)" size="default">关闭</el-button>
                <el-button type="primary" v-if="disabled == false" @click="submitForm(ruleFormRef)" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts">
import { defineComponent, ref, reactive } from 'vue';
import { timeDate } from '/@/assets/index.ts';
import type { FormInstance, FormRules } from 'element-plus';
import { Search, FullScreen } from '@element-plus/icons-vue';
import { ElMessageBox, ElMessage, ElButton, ElInput, TabsPaneContext } from 'element-plus';
import { goalManagementApi } from '/@/api/goalManagement';
export default defineComponent({
    components: {},
    setup(props, { emit }) {
        const ruleFormRef = ref<FormInstance>();
        const dialogVisible = ref<boolean>(false);
        const form = ref({
            typeName: '',
            memo: '',
        });
        const targetType = ref();
        const disabled = ref(false);
        const titles = ref();
        const titleT=ref()
        const openDailog = (title: string, type: any, id: number) => {
            dialogVisible.value = true;
            titles.value = `${title}目标分解`;
            titleT.value=title
            targetType.value = type;
            disabled.value = title == '查看' ? true : false;
            if (title == '查看' || title == '修改') {
                goalManagementApi()
                    .gettargetClassDetail(id)
                    .then((res) => {
                        if (res.data.code == 200) {
                            form.value = res.data.data;
                        } else {
                            ElMessage.error(res.data.msg);
                        }
                    });
            }
        };
        const rules = reactive<FormRules>({
            typeName: [
                {
                    required: true,
                    message: '名称不能为空',
                    trigger: 'blur',
                },
            ],
            memo: [
                {
                    required: true,
                    message: '描述不能为空',
                    trigger: 'blur',
                },
            ],
        });
        const submitForm = async (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            await formEl.validate((valid, fields) => {
                if (valid) {
                    if(titleT.value=='新建'){
                        delete form.value.id
                    }
                    dialogVisible.value = false;
                    goalManagementApi()
                        .gettargetClassAdd(form.value)
                        .then((res) => {
                            if (res.data.code == 200) {
                                ElMessage({
                                    message: res.data.msg,
                                    type: 'success',
                                });
                                emit('onAdd');
                            } else {
                                ElMessage.error(res.data.msg);
                            }
                        });
                } else {
                    console.log('error submit!', fields);
                }
            });
        };
        const resetForm = (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            formEl.resetFields();
            dialogVisible.value = false;
        };
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        return {
            timeDate,
            ruleFormRef,
            titleT,
            rules,
            submitForm,
            resetForm,
            form,
            dialogVisible,
            openDailog,
            Search,
            full,
            toggleFullscreen,
            FullScreen,
            targetType,
            disabled,
            titles,
        };
    },
});
</script>
<style scoped>
.el-row {
    padding: 0 0 20px 0;
}
</style>
src/components/DailogSearch/DailogSearch.vue
对比新文件
@@ -0,0 +1,193 @@
<template>
    <el-dialog v-model="dialogVisible" :fullscreen="full" title="选择安全目标指标" width="50%" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-row>
            <el-col :span="17">
                <el-form ref="ruleFormRef" :model="ruleForm" status-icon>
                    <el-row>
                        <el-col :span="6">
                            <el-form-item size="default">
                                <el-input v-model="ruleForm.searchParams.qName" placeholder="安全目标指标" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="6" :offset="1">
                            <el-form-item size="default">
                                <el-input v-model="ruleForm.searchParams.indexNum" placeholder="目标指标编号" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="10" :offset="1">
                            <el-form-item>
                                <el-button size="default" type="primary" @click="listApi">查询</el-button>
                                <el-button size="default" @click="resetForm">重置</el-button>
                            </el-form-item>
                        </el-col>
                    </el-row>
                </el-form>
                <el-button size="default" :icon="Delete" @click="clear">清除选择</el-button>
                <el-table :data="tableData" style="width: 100%; margin-top: 20px">
                    <el-table-column align="center">
                        <template #default="scope">
                            <el-radio-group v-model="radio1">
                                <el-radio :label="scope.row.id" @click="radio(scope.row)" size="large">{{ null }}</el-radio>
                            </el-radio-group>
                        </template>
                    </el-table-column>
                    <el-table-column align="center" prop="qName" label="安全目标指标" width="180" />
                    <el-table-column align="center" prop="indexNum" label="目标指标编号" width="180" />
                    <el-table-column align="center" prop="year" label="年度" />
                    <el-table-column align="center" prop="value" label="指标值" />
                </el-table>
                <el-pagination
                    style="padding: 20px 0; border-bottom: 1px solid #dedede"
                    v-model:currentPage="currentPage4"
                    v-model:page-size="pageSize4"
                    :page-sizes="[10, 20, 30, 40]"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="total"
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                />
            </el-col>
            <el-col :span="7">
                <div v-if="dynamicTags[0]==''?false:true">
                <el-tag
                    v-for="tag in dynamicTags"
                    :key="tag"
                    class="mx-1"
                    style="margin: 5px"
                    closable
                    :disable-transitions="false"
                    @close="handleClose(tag)"
                >
                    {{ tag.qName }}
                </el-tag>
                </div>
            </el-col>
        </el-row>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false" size="default">关闭</el-button>
                <el-button type="primary" @click="submitForm" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, onMounted } from 'vue';
import { Delete, FullScreen } from '@element-plus/icons-vue';
import { ElMessageBox, ElMessage, ElButton, ElInput, TabsPaneContext, FormInstance } from 'element-plus';
import { goalManagementApi } from '/@/api/goalManagement';
export default defineComponent({
    setup(props,{emit}) {
        const dialogVisible = ref<boolean>(false);
        const openDailog = (type:any) => {
            dialogVisible.value = true;
            ruleForm.searchParams.targetType=type
            listApi();
        };
        // 搜索条件
        const ruleForm = reactive({
            pageSize: 10,
            pageIndex: 1,
            searchParams: {
                qName: '', ////安全目标指标
                indexNum: '', ////目标指标编号
                targetType: '', ////指标类型 1:年指标 2:月指标
                divideStatus: '2', ////分解状态 1:已分解 2:未分解
            },
        });
        // 下方导航与表格
        const tableData = ref([]);
        const currentPage4 = ref();
        const pageSize4 = ref();
        const total = ref();
        const resetForm = () => {
            ruleForm.searchParams.qName = '';
            ruleForm.searchParams.indexNum = '';
        };
        const listApi = () => {
            goalManagementApi()
                .getTargetMngList(ruleForm)
                .then((res) => {
                    if (res.data.code == 200) {
                        tableData.value = res.data.data;
                        currentPage4.value = res.data.pageIndex;
                        pageSize4.value = res.data.pageSize;
                        total.value = res.data.total;
                    } else {
                        ElMessage.error(res.data.msg);
                    }
                });
        };
        onMounted(() => {
        });
        const handleSizeChange = (val: number) => {
            // console.log(`${val} items per page`);
            ruleForm.pageSize = val;
            listApi();
        };
        const handleCurrentChange = (val: number) => {
            // console.log(`current page: ${val}`);
            ruleForm.pageIndex = val;
            listApi();
        };
        // 右方点击添加后显示标签
        const dynamicTags = ref(['']);
        const handleClose = (tag: string) => {
            dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
            radio1.value = '';
        };
        const radio1 = ref('');
        const radio = (data: any) => {
            dynamicTags.value[0] = data;
        };
        const clear=()=>{
            dynamicTags.value=['']
            radio1.value=""
        }
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        const submitForm=()=>{
            let obj=JSON.parse(JSON.stringify(dynamicTags.value))
            emit("backNum",obj[0])
            dialogVisible.value = false
        }
        return {
            dialogVisible,
            openDailog,
            ruleForm,
            tableData,
            currentPage4,
            total,
            pageSize4,
            resetForm,
            listApi,
            handleSizeChange,
            handleCurrentChange,
            dynamicTags,
            handleClose,
            radio1,
            radio,
            full,
            toggleFullscreen,
            Delete,
            FullScreen,
            clear,
            submitForm
        };
    },
});
</script>
<style scoped>
.el-row {
    padding: 0 0 20px 0;
}
</style>
src/components/DailogSearchUser/index.vue
对比新文件
@@ -0,0 +1,246 @@
<template>
    <el-dialog v-model="dialogVisible" :fullscreen="full" title="用户选择" width="60%" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-row>
            <el-col :span="6">
                <div class="userTree">
                    <el-input v-model="filterText" placeholder="请输入组织机构过滤"></el-input>
                    <div class="tree">
                        <el-tree ref="treeRef" :data="data" :props="propse" @node-click="handleNodeClick" :filter-node-method="filterNode" />
                    </div>
                </div>
            </el-col>
            <el-col :span="14" style="padding: 20px">
                <el-form ref="ruleFormRef" :model="ruleForm" status-icon>
                    <el-row>
                        <!-- <el-col :span="10" :offset="1">
                            <el-form-item size="default">
                                <el-input v-model="ruleForm.pass" placeholder="登录名" />
                            </el-form-item>
                        </el-col> -->
                        <el-col :span="8" :offset="1">
                            <el-form-item>
                                <!-- <el-button size="default" type="primary" >查询</el-button> -->
                                <el-button size="default" @click="clear">清除选择</el-button>
                            </el-form-item>
                        </el-col>
                    </el-row>
                </el-form>
                <el-table :data="tableData" style="width: 100%; margin-top: 20px" ref="clearAll"  @selection-change="handleSelectionChange">
                <el-table-column type="selection" width="55" v-if="types==0"/>
                    <el-table-column align="center"  v-if="types!=0">
                        <template #default="scope">
                            <el-radio-group v-model="radio1">
                                <el-radio :label="scope.row.uid" @click="radio(scope.row)" size="large">{{ null }}</el-radio>
                            </el-radio-group>
                        </template>
                    </el-table-column>
                    <el-table-column align="center" prop="realName" label="登录名" />
                    <el-table-column align="center" prop="username" label="用户名" />
                    <el-table-column align="center" prop="address" label="所属机构" />
                    <el-table-column align="center" prop="address" label="所属部门" />
                    <el-table-column align="center" prop="type" label="状态" />
                </el-table>
                <el-pagination
                    style="padding: 20px 0; border-bottom: 1px solid #dedede"
                    v-model:currentPage="currentPage4"
                    v-model:page-size="pageSize4"
                    :page-sizes="[10, 20, 30, 40]"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="total"
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                />
            </el-col>
            <el-col :span="4">
            <div v-if="dynamicTags[0]==''?false:true">
                <el-tag
                    v-for="tag in dynamicTags"
                    :key="tag"
                    class="mx-1"
                    style="margin: 5px"
                    closable
                    :disable-transitions="false"
                    @close="handleClose(tag)"
                >
                    {{ tag.realName }}
                </el-tag>
                </div>
            </el-col>
        </el-row>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false" size="default">关闭</el-button>
                <el-button type="primary" @click="submitForm" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, reactive, watch } from 'vue';
import { FullScreen } from '@element-plus/icons-vue';
import { ElMessageBox, ElTree, ElMessage, ElButton, ElInput, TabsPaneContext } from 'element-plus';
import { goalManagementApi } from '/@/api/goalManagement';
interface Tree {
    label: string;
    children?: Tree[];
}
export default defineComponent({
    setup(props, { emit }) {
        //部门树
        const department = () => {
            goalManagementApi()
                .getTreedepartment()
                .then((res) => {
                    if (res.data.code == 200) {
                        data.value = res.data.data;
                    } else {
                        ElMessage.error(res.data.msg);
                    }
                });
        };
        const propse = {
            label: 'depName',
            children: 'children',
            value: 'depId',
        };
        //部门树查询
        const filterText = ref('');
        const treeRef = ref<InstanceType<typeof ElTree>>();
        watch(filterText, (val) => {
            treeRef.value!.filter(val);
        });
        const filterNode = (depName: string, data: Tree) => {
            if (!depName) return true;
            return data.depName.includes(depName);
        };
        onMounted(() => {
            department();
        });
        //左边树形部分点击获取回调
        const names = ref<any>();
        const handleNodeClick = (data: Tree) => {
            goalManagementApi()
                .getManName(data.depId)
                .then((res) => {
                    if (res.data.code == 200) {
                        tableData.value=res.data.data
                        total.value=tableData.value.length
                    }else{
                        ElMessage.error(res.data.msg);
                    }
                });
        };
        const data = ref();
        //中间表格
        // 搜索条件
        const ruleForm = reactive({
            pass: '',
            checkPass: '',
        });
        // 表格
        const tableData = ref();
        const currentPage4 = ref(1);
        const pageSize4 = ref(10);
        const total=ref()
        const handleSizeChange = (val: number) => {
            // console.log(`${val} items per page`);
            pageSize4.value=val
        };
        const handleCurrentChange = (val: number) => {
            // console.log(`current page: ${val}`);
            currentPage4.value=val
        };
        // 右方点击添加后显示标签
        const dynamicTags = ref(['']);
        const handleClose = (tag: any) => {
            dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
            radio1.value = '';
        };
        const radio1 = ref('');
        const radio = (data: any) => {
            dynamicTags.value[0] = data;
        };
        const handleSelectionChange = (val:any) => {
             dynamicTags.value=val
        }
        const types=ref()
        // 开启弹窗
        const dialogVisible = ref(false);
        const openDailog = (type:any) => {
            types.value=type
            dialogVisible.value = true;
        };
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        const submitForm = () => {
            if(types.value==0){
                emit('SearchUser', dynamicTags.value,types.value);
            }else {
                emit('SearchUser', dynamicTags.value[0],types.value);
            }
            dialogVisible.value = false;
            clear()
        };
        const clearAll=ref()
        const clear=()=>{
           dynamicTags.value=[]
           radio1.value=""
          clearAll.value.clearSelection()
        }
        return {
            clear,
            clearAll,
            total,
            types,
            filterText,
            treeRef,
            filterNode,
            propse,
            dialogVisible,
            names,
            data,
            handleNodeClick,
            openDailog,
            ruleForm,
            tableData,
            currentPage4,
            pageSize4,
            handleSizeChange,
            handleCurrentChange,
            handleSelectionChange,
            radio1,
            dynamicTags,
            handleClose,
            FullScreen,
            full,
            toggleFullscreen,
            radio,
            submitForm,
        };
    },
});
</script>
<style scoped>
.userTree {
    border: 1px solid #ebeef5;
}
.userTree .el-input {
    padding: 10px;
    border-bottom: 1px solid #ebeef5;
}
.tree {
    height: 500px;
    overflow: hidden;
    overflow-y: auto;
}
</style>
src/components/DailogSearchUserManger/index.vue
对比新文件
@@ -0,0 +1,223 @@
<template>
    <el-dialog v-model="dialogVisible" :fullscreen="full" title="用户选择" width="60%" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-row>
            <el-col :span="6">
                <div class="userTree">
                    <el-input v-model="filterText" placeholder="请输入组织机构过滤"></el-input>
                    <div class="tree">
                        <el-tree ref="treeRef" :data="data" :props="propse" @node-click="handleNodeClick" :filter-node-method="filterNode" />
                    </div>
                </div>
            </el-col>
            <el-col :span="14" style="padding: 20px">
                <el-form ref="ruleFormRef" :model="ruleForm" status-icon>
                    <el-row>
                        <el-col :span="10" :offset="1">
                            <el-form-item size="default">
                                <el-input v-model="ruleForm.pass" placeholder="登录名" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="8" :offset="1">
                            <el-form-item>
                                <el-button size="default" type="primary" >查询</el-button>
                                <el-button size="default">重置</el-button>
                            </el-form-item>
                        </el-col>
                    </el-row>
                </el-form>
                <el-table :data="tableData" style="width: 100%; margin-top: 20px" @cell-click="radio">
                    <el-table-column align="center">
                        <template #default="scope">
                            <el-radio-group v-model="radio1">
                                <el-radio :label="scope.row.uid" size="large">{{ null }}</el-radio>
                            </el-radio-group>
                        </template>
                    </el-table-column>
                    <el-table-column align="center" prop="realName" label="登录名" />
                    <el-table-column align="center" prop="username" label="用户名" />
                    <el-table-column align="center" prop="address" label="所属机构" />
                    <el-table-column align="center" prop="address" label="所属部门" />
                    <el-table-column align="center" prop="type" label="状态" />
                </el-table>
                <el-pagination
                    style="padding: 20px 0; border-bottom: 1px solid #dedede"
                    v-model:currentPage="currentPage4"
                    v-model:page-size="pageSize4"
                    :page-sizes="[100, 200, 300, 400]"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="400"
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                />
            </el-col>
            <el-col :span="4">
            <div v-if="dynamicTags[0]==''?false:true">
                <el-tag
                    v-for="tag in dynamicTags"
                    :key="tag"
                    class="mx-1"
                    style="margin: 5px"
                    closable
                    :disable-transitions="false"
                    @close="handleClose(tag)"
                >
                    {{ tag.realName }}
                </el-tag>
                </div>
            </el-col>
        </el-row>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false" size="default">关闭</el-button>
                <el-button type="primary" @click="submitForm" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, reactive, watch } from 'vue';
import { FullScreen } from '@element-plus/icons-vue';
import { ElMessageBox, ElTree, ElMessage, ElButton, ElInput, TabsPaneContext } from 'element-plus';
import { goalManagementApi } from '/@/api/goalManagement';
interface Tree {
    label: string;
    children?: Tree[];
}
export default defineComponent({
    setup(props, { emit }) {
        //部门树
        const department = () => {
            goalManagementApi()
                .getTreedepartment()
                .then((res) => {
                    if (res.data.code == 200) {
                        data.value = res.data.data;
                    } else {
                        ElMessage.error(res.data.msg);
                    }
                });
        };
        const propse = {
            label: 'depName',
            children: 'children',
            value: 'depId',
        };
        //部门树查询
        const filterText = ref('');
        const treeRef = ref<InstanceType<typeof ElTree>>();
        watch(filterText, (val) => {
            treeRef.value!.filter(val);
        });
        const filterNode = (depName: string, data: Tree) => {
            if (!depName) return true;
            return data.depName.includes(depName);
        };
        onMounted(() => {
            department();
        });
        //左边树形部分点击获取回调
        const names = ref<any>();
        const handleNodeClick = (data: Tree) => {
            goalManagementApi()
                .getManName(data.depId)
                .then((res) => {
                    if (res.data.code == 200) {
                        tableData.value=res.data.data
                    }else{
                        ElMessage.error(res.data.msg);
                    }
                });
        };
        const data = ref();
        //中间表格
        // 搜索条件
        const ruleForm = reactive({
            pass: '',
            checkPass: '',
        });
        // 表格
        const tableData = ref();
        const currentPage4 = ref();
        const pageSize4 = ref();
        const handleSizeChange = (val: number) => {
            console.log(`${val} items per page`);
        };
        const handleCurrentChange = (val: number) => {
            console.log(`current page: ${val}`);
        };
        // 右方点击添加后显示标签
        const dynamicTags = ref(['']);
        const handleClose = (tag: any) => {
            dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
            radio1.value = '';
        };
        const radio1 = ref('');
        const radio = (event: any) => {
            dynamicTags.value[0] = event;
        };
        const types=ref()
        // 开启弹窗
        const dialogVisible = ref(false);
        const openDailog = (type:any) => {
            console.log(type)
            types.value=type
            dialogVisible.value = true;
        };
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        const submitForm = () => {
            emit('SearchUser', dynamicTags.value);
            dialogVisible.value = false;
        };
        return {
            types,
            filterText,
            treeRef,
            filterNode,
            propse,
            dialogVisible,
            names,
            data,
            handleNodeClick,
            openDailog,
            ruleForm,
            tableData,
            currentPage4,
            pageSize4,
            handleSizeChange,
            handleCurrentChange,
            radio1,
            dynamicTags,
            handleClose,
            FullScreen,
            full,
            toggleFullscreen,
            radio,
            submitForm,
        };
    },
});
</script>
<style scoped>
.userTree {
    border: 1px solid #ebeef5;
}
.userTree .el-input {
    padding: 10px;
    border-bottom: 1px solid #ebeef5;
}
.tree {
    height: 500px;
    overflow: hidden;
    overflow-y: auto;
}
</style>
src/components/auth/auth.vue
对比新文件
@@ -0,0 +1,30 @@
<template>
    <slot v-if="getUserAuthBtnList" />
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
import { storeToRefs } from 'pinia';
import { useUserInfo } from '/@/stores/userInfo';
export default defineComponent({
    name: 'auth',
    props: {
        value: {
            type: String,
            default: () => '',
        },
    },
    setup(props) {
        const stores = useUserInfo();
        const { userInfos } = storeToRefs(stores);
        // 获取 vuex 中的用户权限
        const getUserAuthBtnList = computed(() => {
            return userInfos.value.authBtnList.some((v: string) => v === props.value);
        });
        return {
            getUserAuthBtnList,
        };
    },
});
</script>
src/components/auth/authAll.vue
对比新文件
@@ -0,0 +1,31 @@
<template>
    <slot v-if="getUserAuthBtnList" />
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
import { storeToRefs } from 'pinia';
import { useUserInfo } from '/@/stores/userInfo';
import { judementSameArr } from '/@/utils/arrayOperation';
export default defineComponent({
    name: 'authAll',
    props: {
        value: {
            type: Array,
            default: () => [],
        },
    },
    setup(props) {
        const stores = useUserInfo();
        const { userInfos } = storeToRefs(stores);
        // 获取 pinia 中的用户权限
        const getUserAuthBtnList = computed(() => {
            return judementSameArr(props.value, userInfos.value.authBtnList);
        });
        return {
            getUserAuthBtnList,
        };
    },
});
</script>
src/components/auth/auths.vue
对比新文件
@@ -0,0 +1,36 @@
<template>
    <slot v-if="getUserAuthBtnList" />
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
import { storeToRefs } from 'pinia';
import { useUserInfo } from '/@/stores/userInfo';
export default defineComponent({
    name: 'auths',
    props: {
        value: {
            type: Array,
            default: () => [],
        },
    },
    setup(props) {
        const stores = useUserInfo();
        const { userInfos } = storeToRefs(stores);
        // 获取 vuex 中的用户权限
        const getUserAuthBtnList = computed(() => {
            let flag = false;
            userInfos.value.authBtnList.map((val: string) => {
                props.value.map((v) => {
                    if (val === v) flag = true;
                });
            });
            return flag;
        });
        return {
            getUserAuthBtnList,
        };
    },
});
</script>
src/components/checkTemplate/index.vue
对比新文件
@@ -0,0 +1,230 @@
<template>
    <el-dialog v-model="dialogVisible" title="选择应急队伍" width="900px" draggable :fullscreen="full">
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-row>
            <el-col :span="18">
                <el-row>
                    <el-col :span="24">
                        <el-form ref="ruleFormRef" :inline="true" status-icon>
                            <el-form-item>
                                <el-input size="default" v-model="listQuery.searchParams.teamName" placeholder="队伍名称" style="max-width: 215px; padding: 0 12px" />
                            </el-form-item>
                            <el-form-item>
                                <el-button size="default" type="primary" @click="onSubmit">查询</el-button>
                                <el-button size="default" @click="submitReset">重置</el-button>
                            </el-form-item>
                        </el-form>
                    </el-col>
                    <el-col :span="24">
                        <el-button size="default" :icon="Delete" style="margin-top: 15px" @click="submitReset">清除选择</el-button>
                    </el-col>
                </el-row>
                <el-table :data="tableData" ref="multipleTableRef" style="width: 100%; margin-top: 20px" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="55" v-if="types == 0">
                        <template #default="scope" v-if="types != 0">
                            <el-radio-group v-model="radio1">
                                <el-radio :label="scope.row.id" @click="radio(scope.row)" size="large">{{ null }}</el-radio>
                            </el-radio-group>
                        </template>
                    </el-table-column>
                    <el-table-column align="center" prop="id" label="id" />
                    <el-table-column align="center" prop="teamName" label="队伍名称" />
                </el-table>
                <div class="pages">
                    <el-pagination
                        v-model:currentPage="pageIndex"
                        v-model:page-size="pageSize"
                        :page-sizes="[10, 20, 30, 40]"
                        layout="total, sizes, prev, pager, next, jumper"
                        :total="total"
                        @size-change="handleSizeChange"
                        @current-change="handleCurrentChange"
                    />
                </div>
            </el-col>
            <el-col :span="6" style="padding-left: 15px">
                <div v-if="dynamicTags[0] == '' ? false : true">
                    <el-tag
                        v-for="tag in dynamicTags"
                        :key="tag"
                        class="mx-1"
                        style="margin: 5px"
                        closable
                        :disable-transitions="false"
                        @close="handleClose(tag)"
                    >
                        {{ tag.teamName }}
                    </el-tag>
                </div>
            </el-col>
        </el-row>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false" size="default">关闭</el-button>
                <el-button type="primary" @click="submitForm" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, onMounted } from 'vue';
import { Delete, FullScreen } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { contingencyApi } from '/@/api/contingencyManagement/contingency';
export default defineComponent({
    setup(props, { emit }) {
        const types = ref();
        const dialogVisible = ref<boolean>(false);
        const openDailog = (type: any) => {
            types.value = type;
            dialogVisible.value = true;
            // onSubmit();
        };
        // 搜索条件
        const listQuery = reactive({
            pageIndex: 1,
            pageSize: 10,
            searchParams: {
                teamName: '',
            },
        });
        // 列表数据请求
        const onSubmit = async () => {
            let res = await contingencyApi().getTeamManagementList(listQuery);
            if (res.data.code === '200') {
                tableData.value = res.data.data;
                pageIndex.value = res.data.pageIndex;
                pageSize.value = res.data.pageSize;
                total.value = res.data.total;
            } else {
                ElMessage({
                    showClose: true,
                    type: 'error',
                    message: res.data.msg,
                });
            }
        };
        const submitForm = () => {
            if (types.value == 0) {
                emit('SearchUser', dynamicTags.value, types.value);
            } else {
                emit('SearchUser', dynamicTags.value[0], types.value);
            }
            dialogVisible.value = false;
        };
        const handleSelectionChange = (val: any) => {
            dynamicTags.value = val;
        };
        // 重置
        const submitReset = () => {
            listQuery.searchParams.teamName = '';
            listQuery.searchParams.id = '';
            radio1.value = '';
            dynamicTags.value[0] = '';
            onSubmit();
        };
        // 表格
        const tableData = ref();
        // 分页
        const pageIndex = ref();
        const pageSize = ref();
        const total = ref();
        const handleSizeChange = (val: number) => {
            listQuery.pageSize = val;
            onSubmit();
        };
        const handleCurrentChange = (val: number) => {
            listQuery.pageIndex = val;
            onSubmit();
        };
        // 右方点击添加后显示标签
        const dynamicTags = ref(['']);
        const handleClose = (tag: string) => {
            dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
            radio1.value = '';
        };
        const radio1 = ref('');
        const radio = (event: any) => {
            console.log(event);
            dynamicTags.value[0] = event;
        };
        onMounted(() => {
            onSubmit();
        });
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        return {
            dialogVisible,
            openDailog,
            tableData,
            pageSize,
            pageIndex,
            handleSizeChange,
            handleCurrentChange,
            dynamicTags,
            handleClose,
            Delete,
            toggleFullscreen,
            FullScreen,
            full,
            onSubmit,
            listQuery,
            submitReset,
            total,
            radio,
            radio1,
            submitForm,
            types,
            handleSelectionChange,
        };
    },
});
</script>
<style scoped>
.el-form--inline .el-form-item {
    margin-bottom: 0;
    margin-right: 0;
}
/*分页*/
.pages {
    /*display: flex;*/
    /*justify-content: flex-end;*/
    margin-top: 15px;
}
::v-deep .el-pagination .el-pager li {
    margin: 0 5px;
    background-color: #f4f4f5;
    color: #606266;
    min-width: 30px;
    border-radius: 2px;
}
::v-deep .el-pagination .el-pager li.is-active {
    background-color: #409eff;
    color: #fff;
}
::v-deep .el-pagination .btn-prev {
    margin: 0 5px;
    background-color: #f4f4f5;
    color: #606266;
    min-width: 30px;
    border-radius: 2px;
}
::v-deep .el-pagination button:disabled {
    color: #c0c4cc;
}
::v-deep .el-pagination .btn-next {
    margin: 0 5px;
    background-color: #f4f4f5;
    color: #606266;
    min-width: 30px;
    border-radius: 2px;
}
</style>
src/components/cropper/index.vue
对比新文件
@@ -0,0 +1,149 @@
<template>
    <div>
        <el-dialog title="更换头像" v-model="isShowDialog" width="769px">
            <div class="cropper-warp">
                <div class="cropper-warp-left">
                    <img :src="cropperImg" class="cropper-warp-left-img" />
                </div>
                <div class="cropper-warp-right">
                    <div class="cropper-warp-right-title">预览</div>
                    <div class="cropper-warp-right-item">
                        <div class="cropper-warp-right-value">
                            <img :src="cropperImgBase64" class="cropper-warp-right-value-img" />
                        </div>
                        <div class="cropper-warp-right-label">100 x 100</div>
                    </div>
                    <div class="cropper-warp-right-item">
                        <div class="cropper-warp-right-value">
                            <img :src="cropperImgBase64" class="cropper-warp-right-value-img cropper-size" />
                        </div>
                        <div class="cropper-warp-right-label">50 x 50</div>
                    </div>
                </div>
            </div>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="onCancel" size="default">取 消</el-button>
                    <el-button type="primary" @click="onSubmit" size="default">更 换</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>
<script lang="ts">
import { reactive, toRefs, nextTick, defineComponent } from 'vue';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';
export default defineComponent({
    name: 'cropperIndex',
    setup() {
        const state = reactive({
            isShowDialog: false,
            cropperImg: '',
            cropperImgBase64: '',
            cropper: null,
        });
        // 打开弹窗
        const openDialog = (imgs: any) => {
            state.cropperImg = imgs;
            state.isShowDialog = true;
            nextTick(() => {
                initCropper();
            });
        };
        // 关闭弹窗
        const closeDialog = () => {
            state.isShowDialog = false;
        };
        // 取消
        const onCancel = () => {
            closeDialog();
        };
        // 更换
        const onSubmit = () => {
            // state.cropperImgBase64 = state.cropper.getCroppedCanvas().toDataURL('image/jpeg');
        };
        // 初始化cropperjs图片裁剪
        const initCropper = () => {
            const letImg: any = document.querySelector('.cropper-warp-left-img');
            (<any>state.cropper) = new Cropper(letImg, {
                viewMode: 1,
                dragMode: 'none',
                initialAspectRatio: 1,
                aspectRatio: 1,
                preview: '.before',
                background: false,
                autoCropArea: 0.6,
                zoomOnWheel: false,
                crop: () => {
                    state.cropperImgBase64 = (<any>state.cropper).getCroppedCanvas().toDataURL('image/jpeg');
                },
            });
        };
        return {
            openDialog,
            closeDialog,
            onCancel,
            onSubmit,
            initCropper,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.cropper-warp {
    display: flex;
    .cropper-warp-left {
        position: relative;
        display: inline-block;
        height: 350px;
        flex: 1;
        border: 1px solid var(--el-border-color);
        background: var(--el-color-white);
        overflow: hidden;
        background-repeat: no-repeat;
        cursor: move;
        border-radius: var(--el-border-radius-base);
        .cropper-warp-left-img {
            width: 100%;
            height: 100%;
        }
    }
    .cropper-warp-right {
        width: 150px;
        height: 350px;
        .cropper-warp-right-title {
            text-align: center;
            height: 20px;
            line-height: 20px;
        }
        .cropper-warp-right-item {
            margin: 15px 0;
            .cropper-warp-right-value {
                display: flex;
                .cropper-warp-right-value-img {
                    width: 100px;
                    height: 100px;
                    border-radius: var(--el-border-radius-circle);
                    margin: auto;
                }
                .cropper-size {
                    width: 50px;
                    height: 50px;
                }
            }
            .cropper-warp-right-label {
                text-align: center;
                font-size: 12px;
                color: var(--el-text-color-primary);
                height: 30px;
                line-height: 30px;
            }
        }
    }
}
</style>
src/components/editor/index.vue
对比新文件
@@ -0,0 +1,115 @@
<template>
    <div class="editor-container">
        <div ref="editorToolbar"></div>
        <div ref="editorContent" :style="{ height }"></div>
    </div>
</template>
<script lang="ts">
import { toRefs, reactive, onMounted, watch, defineComponent } from 'vue';
import { createEditor, createToolbar, IEditorConfig, IToolbarConfig, IDomEditor } from '@wangeditor/editor';
import '@wangeditor/editor/dist/css/style.css';
import { toolbarKeys } from './toolbar';
// 定义接口来定义对象的类型
interface WangeditorState {
    editorToolbar: HTMLDivElement | null;
    editorContent: HTMLDivElement | null;
    editor: any;
}
export default defineComponent({
    name: 'wngEditor',
    props: {
        // 节点 id
        id: {
            type: String,
            default: () => 'wangeditor',
        },
        // 是否禁用
        isDisable: {
            type: Boolean,
            default: () => false,
        },
        // 内容框默认 placeholder
        placeholder: {
            type: String,
            default: () => '请输入内容',
        },
        // 双向绑定:双向绑定值,字段名为固定,改了之后将不生效
        // 参考:https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5
        modelValue: String,
        // https://www.wangeditor.com/v5/getting-started.html#mode-%E6%A8%A1%E5%BC%8F
        // 模式,可选 <default|simple>,默认 default
        mode: {
            type: String,
            default: () => 'default',
        },
        // 高度
        height: {
            type: String,
            default: () => '310px',
        },
    },
    setup(props, { emit }) {
        const state = reactive<WangeditorState>({
            editorToolbar: null,
            editor: null,
            editorContent: null,
        });
        // 富文本配置
        const wangeditorConfig = () => {
            const editorConfig: Partial<IEditorConfig> = { MENU_CONF: {} };
            props.isDisable ? (editorConfig.readOnly = true) : (editorConfig.readOnly = false);
            editorConfig.placeholder = props.placeholder;
            editorConfig.onChange = (editor: IDomEditor) => {
                // console.log('content', editor.children);
                // console.log('html', editor.getHtml());
                emit('update:modelValue', editor.getHtml());
            };
            (<any>editorConfig).MENU_CONF['uploadImage'] = {
                base64LimitSize: 10 * 1024 * 1024,
            };
            return editorConfig;
        };
        //
        const toolbarConfig = () => {
            const toolbarConfig: Partial<IToolbarConfig> = {};
            toolbarConfig.toolbarKeys = toolbarKeys;
            return toolbarConfig;
        };
        // 初始化富文本
        // https://www.wangeditor.com/
        const initWangeditor = () => {
            state.editor = createEditor({
                html: props.modelValue,
                selector: state.editorContent!,
                config: wangeditorConfig(),
                mode: props.mode,
            });
            createToolbar({
                editor: state.editor,
                selector: state.editorToolbar!,
                mode: props.mode,
                config: toolbarConfig(),
            });
        };
        // 页面加载时
        onMounted(() => {
            initWangeditor();
        });
        // 监听双向绑定值的改变
        // https://gitee.com/lyt-top/vue-next-admin/issues/I4LM7I
        watch(
            () => props.modelValue,
            (value) => {
                state.editor.clear();
                state.editor.dangerouslyInsertHtml(value);
            }
        );
        return {
            ...toRefs(state),
        };
    },
});
</script>
src/components/editor/toolbar.ts
对比新文件
@@ -0,0 +1,60 @@
/**
 * 工具栏配置
 */
export const toolbarKeys = [
    'headerSelect',
    'blockquote',
    '|',
    'bold',
    'underline',
    'italic',
    {
        key: 'group-more-style',
        title: '更多',
        iconSvg:
            '<svg viewBox="0 0 1024 1024"><path d="M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path></svg>',
        menuKeys: ['through', 'code', 'sup', 'sub', 'clearStyle'],
    },
    'color',
    'bgColor',
    '|',
    'fontSize',
    'fontFamily',
    'lineHeight',
    '|',
    'bulletedList',
    'numberedList',
    'todo',
    {
        key: 'group-justify',
        title: '对齐',
        iconSvg:
            '<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>',
        menuKeys: ['justifyLeft', 'justifyRight', 'justifyCenter', 'justifyJustify'],
    },
    {
        key: 'group-indent',
        title: '缩进',
        iconSvg:
            '<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z"></path></svg>',
        menuKeys: ['indent', 'delIndent'],
    },
    '|',
    'emotion',
    'insertLink',
    {
        key: 'group-image',
        title: '图片',
        iconSvg:
            '<svg viewBox="0 0 1024 1024"><path d="M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z"></path></svg>',
        menuKeys: ['uploadImage'],
    },
    'insertTable',
    'codeBlock',
    'divider',
    '|',
    'undo',
    'redo',
    '|',
    'fullScreen',
];
src/components/emergencySupplies/index.vue
对比新文件
@@ -0,0 +1,215 @@
<template>
  <el-dialog
      v-model="dialogVisible"
      title="选择应急物资"
      width="900px"
      draggable
      :fullscreen="full"
  >
    <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
    <el-row>
      <el-col :span="18">
        <el-row>
          <el-form ref="ruleFormRef" :model="ruleForm" :inline="true" status-icon>
            <el-form-item>
              <el-input size="default" v-model="listQuery.searchParams.name" placeholder="物资名称"  style="max-width: 215px;margin-right: 12px;"/>
            </el-form-item>
            <el-form-item>
              <el-button size="default" type="primary" @click="onSubmit">查询</el-button>
              <el-button size="default" @click="submitReset">重置</el-button>
              <el-button size="default" :icon="Delete">清除选择</el-button>
            </el-form-item>
          </el-form>
        </el-row>
        <el-table :data="tableData" style="width: 100%;margin-top:20px">
          <el-table-column width="55">
            <template #default="scope">
              <el-radio-group v-model="radio1">
                <el-radio :label="scope.row" @click="radio(scope.row)" size="large">{{ null }}</el-radio>
              </el-radio-group>
            </template>
          </el-table-column>
          <el-table-column align="center" prop="name" label="物资名称"/>
        </el-table>
        <div class="pages">
          <el-pagination
              v-model:currentPage="pageIndex"
              v-model:page-size="pageSize"
              :page-sizes="[10, 20, 30]"
              layout="total, sizes, prev, pager, next, jumper"
              :total="total"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
          />
        </div>
      </el-col>
      <el-col :span="6">
        <div v-if="dynamicTags[0] == '' ? false : true">
          <el-tag
              v-for="tag in dynamicTags"
              :key="tag"
              class="mx-1"
              style="margin: 5px"
              closable
              :disable-transitions="false"
              @close="handleClose(tag)"
          >
            {{ tag.name }}
          </el-tag>
        </div>
      </el-col>
    </el-row>
    <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false" size="default">关闭</el-button>
                <el-button type="primary" @click="submitForm" size="default">确定</el-button>
            </span>
    </template>
  </el-dialog>
</template>
<script lang="ts">
import {
  defineComponent,
  reactive,
  ref
} from 'vue';
import {
  Delete,
  FullScreen
} from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import {emergencySuppliesApi} from "/@/api/contingencyManagement/emergencyResources";
export default defineComponent({
  setup(props, { emit }) {
    const dialogVisible = ref<boolean>(false);
    const openDailog = () => {
      dialogVisible.value = true;
      onSubmit()
    };
    // 搜索条件
    const listQuery = reactive({
      pageIndex: 1,
      pageSize: 10,
      searchParams:{
        name: '',
      }
    });
    // 定义表格数据
    const tableData = ref([]);
    // 列表请求数据
    const onSubmit = async () => {
      let res = await emergencySuppliesApi().getEmergencySuppliesList(listQuery);
      if (res.data.code === '200') {
        tableData.value = res.data.data;
        pageIndex.value = res.data.pageIndex;
        pageSize.value = res.data.pageSize;
        total.value = res.data.total;
      } else {
        ElMessage({
          showClose: true,
          type: 'error',
          message: res.data.msg,
        });
      }
    };
    // 重置
    const submitReset = () => {
      listQuery.searchParams.name = '';
      onSubmit();
    };
    const pageIndex = ref();
    const pageSize = ref();
    const total = ref();
    const handleSizeChange = (val: number) => {
      listQuery.pageSize = val;
    };
    const handleCurrentChange = (val: number) => {
      listQuery.pageIndex = val;
    };
    // 右方点击添加后显示标签
    const dynamicTags = ref(['']);
    const handleClose = (tag: string) => {
      dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
      radio1.value = '';
    };
    const radio1 = ref('');
    const radio = (event: any) => {
      dynamicTags.value[0] = event;
    };
    //全屏
    const full = ref(false);
    const toggleFullscreen = () => {
      if (full.value == false) {
        full.value = true;
      } else {
        full.value = false;
      }
    };
    const submitForm = () => {
      let obj = JSON.parse(JSON.stringify(dynamicTags.value));
      emit('SearchUser', obj[0]);
      dialogVisible.value = false;
    };
    return {
      dialogVisible,
      openDailog,
      listQuery,
      onSubmit,
      tableData,
      submitReset,
      handleSizeChange,
      handleCurrentChange,
      dynamicTags,
      handleClose,
      Delete,
      toggleFullscreen,
      FullScreen,
      full,
      pageIndex,
      pageSize,
      radio1,
      radio,
      submitForm,
      total,
    };
  },
});
</script>
<style scoped>
.el-form--inline .el-form-item{
  margin-bottom: 0;
  margin-right: 0;
}
/*分页*/
.pages{
  margin-top: 15px;
}
::v-deep .el-pagination .el-pager li {
  margin: 0 5px;
  background-color: #f4f4f5;
  color: #606266;
  min-width: 30px;
  border-radius: 2px;
}
::v-deep .el-pagination .el-pager li.is-active {
  background-color: #409eff;
  color: #fff;
}
::v-deep .el-pagination .btn-prev {
  margin: 0 5px;
  background-color: #f4f4f5;
  color: #606266;
  min-width: 30px;
  border-radius: 2px;
}
::v-deep .el-pagination button:disabled{
  color: #c0c4cc;
}
::v-deep .el-pagination .btn-next{
  margin: 0 5px;
  background-color: #f4f4f5;
  color: #606266;
  min-width: 30px;
  border-radius: 2px;
}
</style>
src/components/equipmentDailog/Dailog.vue
对比新文件
@@ -0,0 +1,903 @@
<template>
    <el-dialog v-model="dialogVisible" :fullscreen="full" @close="resetForm(ruleFormRef)" draggable :title="titles" width="60%">
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-form :model="form" ref="ruleFormRef" :rules="rules" :disabled="disabled" label-width="120px" class="formType">
            <el-form-item label="装置设施名称" size="default" prop="qName">
                <el-input v-model="form.qName" placeholder="请填写装置设施名称" />
            </el-form-item>
            <el-form-item label="装置设施位号" size="default" prop="positionNum">
                <el-input disabled v-model="form.positionNum" placeholder="请填写装置设施位号" />
            </el-form-item>
            <el-form-item label="装置设施用途" size="default" prop="qUsage">
                <el-input v-model="form.qUsage" placeholder="请填写装置设施用途" />
            </el-form-item>
            <el-form-item label="装置设施型号" size="default" prop="model">
                <el-input v-model="form.model" placeholder="请填写装置设施型号" />
            </el-form-item>
            <el-form-item label="类型/类别外键" size="default" prop="equipmentTypeName">
                <el-input v-model="form.equipmentTypeName" placeholder="请选择">
                    <template #append>
                        <el-button :icon="Search" @click="opencategory"></el-button>
                    </template>
                </el-input>
            </el-form-item>
            <!-- <el-form-item label="区域名称" size="default">
            <el-input v-model="form.name" placeholder="请选择">
              <template #append>
                <el-button :icon="Search" @click="openRegion"></el-button>
              </template>
            </el-input>
          </el-form-item> -->
            <el-form-item label="单位部门" size="default" prop="departmentId">
                <el-tree-select v-model="form.departmentId" :data="data" check-strictly="true" class="w100" :props="propse" placeholder="请选择" />
            </el-form-item>
            <el-form-item label="设置部位" size="default" prop="setPart">
                <el-input v-model="form.setPart" placeholder="请填写设置部位" />
            </el-form-item>
            <el-form-item label="生产日期" size="default" prop="produceTime">
                <el-date-picker v-model="form.produceTime" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="选择日期时间" style="width: 100%" />
            </el-form-item>
            <el-form-item label="使用期限(天)" size="default" prop="useEndDay">
                <el-input v-model="form.useEndDay" placeholder="请填写使用期限" />
            </el-form-item>
            <el-form-item label="生命周期" size="default" prop="lifeCycle">
                <el-select v-model="form.lifeCycle" placeholder="请选择" style="width: 100%">
                    <el-option label="已投用" :value="1" />
                    <el-option label="库存中" :value="2" />
                    <el-option label="报废" :value="3" />
                </el-select>
            </el-form-item>
            <el-form-item label="投用日期" size="default" prop="useDate">
                <el-date-picker v-model="form.useDate" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="选择日期时间" style="width: 100%" />
            </el-form-item>
            <el-form-item label="维修状态" size="default" prop="repairStatus">
                <el-select v-model="form.repairStatus" placeholder="请选择" style="width: 100%">
                    <el-option label="维修中" :value="1" />
                    <el-option label="已修好" :value="2" />
                </el-select>
            </el-form-item>
            <el-form-item label="停用状态" size="default" prop="stopStatus">
                <el-select v-model="form.stopStatus" placeholder="请选择" style="width: 100%">
                    <el-option label="停用" :value="1" />
                    <el-option label="在用" :value="2" />
                    <el-option label="维修" :value="3" />
                    <el-option label="报废" :value="4" />
                </el-select>
            </el-form-item>
            <el-form-item label="上次检查日期" size="default" prop="previousCheckDate">
                <el-date-picker
                    v-model="form.previousCheckDate"
                    format="YYYY-MM-DD HH:mm:ss"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    type="datetime"
                    placeholder="选择日期时间"
                    style="width: 100%"
                />
            </el-form-item>
            <el-form-item label="上次检测日期" size="default" prop="previousTestDate">
                <el-date-picker v-model="form.previousTestDate" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="选择日期时间" style="width: 100%" />
            </el-form-item>
            <el-form-item label="上次保养日期" size="default" prop="previousTakecareDate">
                <el-date-picker
                    v-model="form.previousTakecareDate"
                    format="YYYY-MM-DD HH:mm:ss"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    type="datetime"
                    placeholder="选择日期时间"
                    style="width: 100%"
                />
            </el-form-item>
            <el-form-item label="下次检查日期" size="default" prop="nextCheckDate">
                <el-date-picker v-model="form.nextCheckDate" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="选择日期时间" style="width: 100%" />
            </el-form-item>
            <el-form-item label="下次检测日期" size="default" prop="nextTestDate">
                <el-date-picker v-model="form.nextTestDate" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="选择日期时间" style="width: 100%" />
            </el-form-item>
            <el-form-item label="下次保养日期" size="default" prop="nextTakecareDate">
                <el-date-picker v-model="form.nextTakecareDate" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="选择日期时间" style="width: 100%" />
            </el-form-item>
            <el-form-item label="负责人" size="default" prop="leadingPersonName">
                <el-input v-model="form.leadingPersonName" placeholder="请选择">
                    <template #append>
                        <el-button :icon="Search" @click="openUser(1)"></el-button>
                    </template>
                </el-input>
            </el-form-item>
            <el-form-item label="负责人部门" size="default" prop="leadingPersonDepartmentId">
                <el-tree-select
                    v-model="form.leadingPersonDepartmentId"
                    :data="data"
                    check-strictly="true"
                    class="w100"
                    :props="propse"
                    placeholder="请选择"
                />
            </el-form-item>
            <el-form-item label="供应商" size="default" prop="supplyName">
                <el-input v-model="form.supplyName" placeholder="请填写供应商" />
            </el-form-item>
            <el-form-item label="使用说明" size="default" prop="useMemo">
                <el-input v-model="form.useMemo" placeholder="请填写使用说明" />
            </el-form-item>
            <el-form-item label="是否检查" size="default" prop="isNeedCheck">
                <el-select v-model="form.isNeedCheck" placeholder="请选择" style="width: 100%">
                    <el-option label="是" :value="1" />
                    <el-option label="否" :value="2" />
                </el-select>
            </el-form-item>
            <el-form-item label="检查周期" size="default" prop="checkCycle">
                <el-input v-model="form.checkCycle" placeholder="请填写检查周期" />
            </el-form-item>
            <el-form-item label="检查提前提醒" size="default" prop="checkWarn">
                <el-input v-model="form.checkWarn" placeholder="请填写检查提前提醒" />
            </el-form-item>
            <el-form-item label="是否检测" size="default" prop="isNeedTest">
                <el-select v-model="form.isNeedTest" placeholder="请选择" style="width: 100%">
                    <el-option label="是" :value="1" />
                    <el-option label="否" :value="2" />
                </el-select>
            </el-form-item>
            <el-form-item label="检测周期" size="default" prop="testCycle">
                <el-input v-model="form.testCycle" placeholder="请填写检测周期" />
            </el-form-item>
            <el-form-item label="检测提前提醒" size="default" prop="testWarn">
                <el-input v-model="form.testWarn" placeholder="请填写检测提前提醒" />
            </el-form-item>
            <el-form-item label="是否保养" size="default" prop="isNeedTakecare">
                <el-select v-model="form.isNeedTakecare" placeholder="请选择" style="width: 100%">
                    <el-option label="是" :value="1" />
                    <el-option label="否" :value="2" />
                </el-select>
            </el-form-item>
            <el-form-item label="检查内容" size="default" prop="checkContent">
                <el-input v-model="form.checkContent" placeholder="请填写检查内容" />
            </el-form-item>
            <el-form-item label="负责部门" size="default" prop="leadingDepartmentId">
                <el-tree-select v-model="form.leadingDepartmentId" :data="data" check-strictly="true" class="w100" :props="propse" placeholder="请选择" />
            </el-form-item>
            <el-form-item label="检查指标" size="default" prop="checkPoint">
                <el-input v-model="form.checkPoint" placeholder="请填写检查指标" />
            </el-form-item>
            <el-form-item label="预警值" size="default" prop="alertNum">
                <el-input v-model="form.alertNum" placeholder="请填写预警值" />
            </el-form-item>
            <el-form-item label="联锁值" size="default" prop="lockNum">
                <el-input v-model="form.lockNum" placeholder="请填写联锁值" />
            </el-form-item>
            <el-form-item label="停用理由" size="default" prop="stopReason">
                <el-input v-model="form.stopReason" placeholder="请填写停用理由" />
            </el-form-item>
            <el-form-item label="停用后措施" size="default" prop="afterStopStep">
                <el-input v-model="form.afterStopStep" placeholder="请填写停用后措施" />
            </el-form-item>
            <el-form-item label="实际停用日期" size="default" prop="actualStopDate">
                <el-date-picker v-model="form.actualStopDate" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="选择日期时间" style="width: 100%" />
            </el-form-item>
            <el-form-item label="停用提交人" size="default" prop="stopSubmitPersonName">
                <el-input v-model="form.stopSubmitPersonName" placeholder="请选择">
                    <template #append>
                        <el-button :icon="Search" @click="openUser(2)"></el-button>
                    </template>
                </el-input>
            </el-form-item>
            <el-form-item label="停用提交日期" size="default" prop="stopSubmitDate">
                <el-date-picker v-model="form.stopSubmitDate" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="选择日期时间" style="width: 100%" />
            </el-form-item>
            <el-form-item label="恢复理由" size="default" prop="recoveryReason">
                <el-input v-model="form.recoveryReason" placeholder="请填写恢复理由" />
            </el-form-item>
            <el-form-item label="恢复填报日期" size="default" prop="recoverySubmitDate">
                <el-date-picker
                    v-model="form.recoverySubmitDate"
                    format="YYYY-MM-DD HH:mm:ss"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    type="datetime"
                    placeholder="选择日期时间"
                    style="width: 100%"
                />
            </el-form-item>
            <el-form-item label="实际恢复日期" size="default" prop="actualRecoveryDate">
                <el-date-picker
                    v-model="form.actualRecoveryDate"
                    format="YYYY-MM-DD HH:mm:ss"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    type="datetime"
                    placeholder="选择日期时间"
                    style="width: 100%"
                />
            </el-form-item>
            <el-form-item label="报废理由" size="default" prop="destoryReason">
                <el-input v-model="form.destoryReason" placeholder="请填写报废理由" />
            </el-form-item>
            <el-form-item label="报废填报日期" size="default" prop="destorySubmitDate">
                <el-date-picker
                    v-model="form.destorySubmitDate"
                    format="YYYY-MM-DD HH:mm:ss"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    type="datetime"
                    placeholder="选择日期时间"
                    style="width: 100%"
                />
            </el-form-item>
            <el-form-item label="实际报废日期" size="default" prop="actualDestoryDate">
                <el-date-picker
                    v-model="form.actualDestoryDate"
                    format="YYYY-MM-DD HH:mm:ss"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    type="datetime"
                    placeholder="选择日期时间"
                    style="width: 100%"
                />
            </el-form-item>
            <el-form-item label="保养周期" size="default" prop="takecareCycle ">
                <el-input v-model="form.takecareCycle" placeholder="请填写保养周期" />
            </el-form-item>
        </el-form>
        <el-tabs v-model="activeName" class="demo-tabs">
            <el-tab-pane label="设备保养" name="first">
                <el-button type="primary" size="default" :disabled="disabled" @click="openMaintenance('新增', '')">新增</el-button>
                <el-table :data="form.takecareDetailList" style="width: 100%">
                    <el-table-column align="center" prop="takecareMemo" label="保养情况" />
                    <el-table-column align="center" prop="leadingPersonName" label="保养负责人" />
                    <el-table-column align="center" prop="takecareDate" :formatter="timeDate" label="保养日期" />
                    <el-table-column align="center" prop="leadingPersonDepartmentName" label="保养负责人单位" />
                    <el-table-column align="center" label="操作">
                        <template #default="scope">
                            <el-button link type="primary" @click="openMaintenance('查看', scope.row)" size="small">查看</el-button>
                            <el-button link type="primary" @click="openMaintenance('修改', scope.row)" size="small">修改</el-button>
                            <el-button link type="primary" @click="deleteA(scope.row)" size="small">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-tab-pane>
            <el-tab-pane label="设备检测" name="second">
                <el-button type="primary" size="default" :disabled="disabled" @click="openDetect('新增', '')">新增</el-button>
                <el-table :data="form.testDetailList" style="width: 100%">
                    <el-table-column align="center" prop="testPersonName" label="检测人" />
                    <el-table-column align="center" prop="testDate" :formatter="timeDate" label="检测日期" />
                    <el-table-column align="center" prop="testPersonDepartmentName" label="检测人单位" />
                    <el-table-column align="center" prop="testMemo" label="检测内容" />
                    <el-table-column align="center" label="检测结果" >
                        <template #default="scope">
                            <span v-if="scope.row.testResult==1">成功</span>
                            <span v-if="scope.row.testResult==2">失败</span>
                        </template>
                    </el-table-column>
                    <el-table-column align="center" prop="testStatus" label="检测状态" />
                    <el-table-column align="center" label="操作">
                        <template #default="scope">
                            <el-button link type="primary" @click="openDetect('查看', scope.row)" size="small">查看</el-button>
                            <el-button link type="primary" @click="openDetect('修改', scope.row)" size="small">修改</el-button>
                            <el-button link type="primary" @click="deleteB(scope.row)" size="small">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-tab-pane>
            <el-tab-pane label="设备维修" name="third">
                <el-button type="primary" size="default" :disabled="disabled" @click="openRepair('新增', '')">新增</el-button>
                <el-table :data="form.repaireDetailList" style="width: 100%">
                    <el-table-column align="center" prop="exceptionInfo" label="设施异常项" />
                    <el-table-column align="center"  label="维修状态">
                    <template #default="scope">
                            <span v-if="scope.row.repairStatus==1">维修中</span>
                            <span v-if="scope.row.repairStatus==2">已修好</span>
                        </template>
                    </el-table-column>
                    <el-table-column align="center" prop="repairMemo" label="维修情况" />
                    <el-table-column align="center" prop="repairPersonName" label="维修负责人" />
                    <el-table-column align="center" prop="repairPersonDepartmentName" label="维修负责人单位" />
                    <el-table-column align="center" prop="repairStartDate" :formatter="timeDate" label="维修开始日期" />
                    <el-table-column align="center" prop="repairEndDate" :formatter="timeDate" label="维修结束日期" />
                    <el-table-column align="center" label="操作">
                        <template #default="scope">
                            <el-button link type="primary" @click="openRepair('查看', scope.row)" size="small">查看</el-button>
                            <el-button link type="primary" @click="openRepair('修改', scope.row)" size="small">修改</el-button>
                            <el-button link type="primary" @click="deleteC(scope.row)" size="small">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-tab-pane>
            <el-tab-pane label="检查标准设置" name="fourth">
                <el-button type="primary" size="default" :disabled="disabled" @click="openStandard('新增', '')">新增</el-button>
                <el-table :data="form.checkStandardeDetailList" style="width: 100%">
                    <el-table-column align="center" prop="indexNum" label="序号" width="75" />
                    <el-table-column align="center" prop="checkContent" label="检查内容" />
                    <el-table-column align="center" prop="checkTarget" label="检查指标" />
                    <el-table-column align="center" prop="unit" label="单位" />
                    <el-table-column align="center" prop="checkPart" label="巡检部位" />
                    <el-table-column align="center" prop="rate" label="频次" />
                    <el-table-column align="center" label="操作">
                        <template #default="scope">
                            <el-button link type="primary" @click="openStandard('查看', scope.row)" size="small">查看</el-button>
                            <el-button link type="primary" @click="openStandard('修改', scope.row)" size="small">修改</el-button>
                            <el-button link type="primary" @click="deleteD(scope.row)" size="small">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-tab-pane>
            <el-tab-pane label="巡检记录" size="default" name="five">
                <el-table :data="name" style="width: 100%">
                    <el-table-column align="center" type="selection" width="75" />
                    <el-table-column align="center" sortable prop="name" label="任务编号" />
                    <el-table-column align="center" sortable prop="address" label="任务名称" />
                    <el-table-column align="center" sortable prop="address" label="点位类型" />
                    <el-table-column align="center" sortable prop="address" label="检查频次" />
                    <el-table-column align="center" sortable prop="address" :formatter="timeDate" label="巡检时间" />
                    <el-table-column align="center" sortable prop="address" label="巡检人" />
                </el-table>
            </el-tab-pane>
            <el-tab-pane label="保养维修标准" name="six" v-if="Dailogtype">
                <uploaderFile :fileList="fileList" :systemName="'EQUIPMENT'" :disabled="disabled"
                              @successUploader="successUploader"></uploaderFile>
            </el-tab-pane>
        </el-tabs>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="resetForm(ruleFormRef)">关闭</el-button>
                <el-button type="primary" @click="submitForm(ruleFormRef)">确定</el-button>
            </span>
        </template>
    </el-dialog>
    <categoryDailog ref="categoryShow"></categoryDailog>
    <categoryDailog ref="categoryShow" @typeId="Tid"></categoryDailog>
    <regionDailog ref="regionShow"></regionDailog>
    <DailogSearchUser ref="UserShow" @SearchUser="userId"></DailogSearchUser>
    <maintenanceDailog ref="maintenanceShow" @onMain="main"></maintenanceDailog>
    <detectDailog ref="detectShow" @onDelect="delect"></detectDailog>
    <repairDailog ref="repairShow" @onRepair="Repair"></repairDailog>
    <standardDailog ref="standardShow" @onStand="Stand"></standardDailog>
</template>
<script lang="ts">
import { defineComponent, ref, reactive } from 'vue';
import { Search, FullScreen } from '@element-plus/icons-vue';
import categoryDailog from './categoryDailog.vue';
import regionDailog from './regionDailog.vue';
import maintenanceDailog from './maintenanceDailog.vue';
import detectDailog from './detectDailog.vue';
import repairDailog from './repairDailog.vue';
import { timeDate } from '/@/assets/index.ts';
import standardDailog from './standardDailog.vue';
import DailogSearchUser from '/@/components/DailogSearchUser/index.vue';
import { ElMessage, ElMessageBox, FormInstance, FormRules } from 'element-plus';
import type { UploadProps, UploadUserFile } from 'element-plus';
import { facilityManagementApi } from '/@/api/facilityManagement';
import { goalManagementApi } from '/@/api/goalManagement';
import { deepClone } from '/@/utils/other';
import uploaderFile from '/@/components/uploaderFile/index.vue';
export default defineComponent({
    components: { categoryDailog, regionDailog, DailogSearchUser, maintenanceDailog,
        detectDailog, repairDailog, standardDailog,uploaderFile },
    setup(props, { emit }) {
        const dialogVisible = ref(false);
        const ruleFormRef = ref<FormInstance>();
        const form = ref({
            supplyName: '',
            nextTestDate: '',
            qUsage: '',
            departmentId: '',
            produceTime: '',
            actualStopDate: '',
            takecareDetailList: [],
            infoType: '',
            leadingDepartmentId: '',
            useEndDay: '',
            previousTakecareDate: '',
            previousCheckDate: '',
            model: '',
            stopStatus: '',
            testWarn: '',
            stopSubmitDate: '',
            repairStatus: '',
            takecareStardardeDetailList: [
            ],
            nextCheckDate: '',
            checkCycle: '',
            checkPoint: '',
            leadingPersonId: '',
            leadingPersonName: '',
            qName: '',
            nextTakecareDate: '',
            setPart: '',
            checkStandardeDetailList: [],
            actualDestoryDate: '',
            isNeedTest: '',
            alertNum: '',
            checkContent: '',
            useMemo: '',
            previousTestDate: '',
            isNeedTakecare: '',
            destoryReason: '',
            checkDetailList: [],
            positionNum: '',
            testCycle: '',
            recoveryReason: '',
            isNeedCheck: '',
            actualRecoveryDate: '',
            leadingPersonDepartmentId: '',
            stopReason: '',
            destorySubmitDate: '',
            testDetailList: [],
            checkWarn: '',
            repaireDetailList: [],
            equipmentTypeId: '',
            useDate: '',
            recoverySubmitDate: '',
            takecareCycle:"",
            lockNum: '',
            stopSubmitPersonId: '',
            stopSubmitPersonName: '',
            afterStopStep: '',
            lifeCycle: '',
            delCheckStandardeDetails: '',
            delTakecareStardardeDetails: '',
            delTakecareDetails: '',
            delRepaireDetails: '',
            delTestDetails: '',
        });
        const titles = ref();
        const titleT = ref();
        const disabled = ref(false);
        const Dailogtype = ref(false);
        const openDailog = (title: string, type: boolean, id: number, num: any) => {
            dialogVisible.value = true;
            titleT.value = title;
            department();
            Dailogtype.value = type;
            if (num == 0) {
                titles.value = `${title}仪表信息`;
                form.value.infoType = num;
            } else if (num == 1) {
                titles.value = `${title}设备设施`;
                form.value.infoType = num;
            } else if (num == 2) {
                titles.value = `${title}设备设施`;
                form.value.infoType = num;
            }
            disabled.value = title == '查看' ? true : false;
            if (title == '查看' || title == '修改')
                facilityManagementApi()
                    .getequipmentInfoDetail(id)
                    .then((res) => {
                        if (res.data.code == 200) {
                            form.value = res.data.data;
                            //初始化日期格式
                            form.value.actualDestoryDate = timeC(form.value.actualDestoryDate);
                            form.value.actualRecoveryDate = timeC(form.value.actualRecoveryDate);
                            form.value.actualStopDate = timeC(form.value.actualStopDate);
                            form.value.destorySubmitDate = timeC(form.value.destorySubmitDate);
                            form.value.nextCheckDate = timeC(form.value.nextCheckDate);
                            form.value.nextTakecareDate = timeC(form.value.nextTakecareDate);
                            form.value.nextTestDate = timeC(form.value.nextTestDate);
                            form.value.previousCheckDate = timeC(form.value.previousCheckDate);
                            form.value.previousTakecareDate = timeC(form.value.previousTakecareDate);
                            form.value.previousTestDate = timeC(form.value.previousTestDate);
                            form.value.produceTime = timeC(form.value.produceTime);
                            form.value.recoverySubmitDate = timeC(form.value.recoverySubmitDate);
                            form.value.stopSubmitDate = timeC(form.value.stopSubmitDate);
                            form.value.useDate = timeC(form.value.useDate);
                            fileList.value = (res.data.data.takecareStardardeDetailList?res.data.data.takecareStardardeDetailList:[])
                            initFileListData()
                        } else {
                            ElMessage.error(res.data.msg);
                        }
                    });
        };
        const timeC = (timestamp: any) => {
            let a = new Date(timestamp).getTime();
            const date = new Date(a);
            const Y = date.getFullYear() + '-';
            const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
            const D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + '  ';
            const h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
            const m = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
            const s = date.getSeconds(); // 秒
            const dateString = Y + M + D + h + m +`:${s}`;
            // console.log('dateString', dateString); // > dateString 2021-07-06 14:23
            return dateString;
        };
        const initFileListData = async () => {
            for(var a = 0;a<fileList.value.length;a++){
                fileList.value[a].name = fileList.value[a].filePath
            }
        }
        // 上传成功组装数据
        const successUploader = (list) =>{
            fileList.value = list
            const formFileList = []
            for(var a = 0;a<fileList.value.length;a++){
                formFileList.push(
                        {
                            filePath:fileList.value[a].fileName
                        }
                )
            }
            form.value.takecareStardardeDetailList = formFileList
        }
        const rules = reactive<FormRules>({
            qName: [],
            positionNum: [],
            qUsage: [],
            model: [],
            equipmentTypeId: [],
            equipmentTypeName: [{ required: true, message: '类型/类别外键不能为空', trigger: 'change' }],
            departmentId: [],
            setPart: [],
            produceTime: [],
            useEndDay: [],
            lifeCycle: [],
            useDate: [],
            repairStatus: [],
            stopStatus: [],
            previousCheckDate: [],
            previousTestDate: [],
            previousTakecareDate: [],
            nextCheckDate: [],
            nextTestDate: [],
            nextTakecareDate: [],
            leadingPersonName: [],
            leadingPersonDepartmentId: [],
            supplyName: [],
            useMemo: [],
            isNeedCheck: [],
            checkCycle: [],
            checkWarn: [],
            isNeedTest: [],
            testCycle: [],
            testWarn: [],
            isNeedTakecare: [],
            checkContent: [],
            leadingDepartmentId: [],
            checkPoint: [],
            alertNum: [],
            lockNum: [],
            stopReason: [],
            afterStopStep: [],
            actualStopDate: [],
            stopSubmitPersonName: [],
            stopSubmitDate: [],
            recoveryReason: [],
            recoverySubmitDate: [],
            actualRecoveryDate: [],
            destoryReason: [],
            destorySubmitDate: [],
            actualDestoryDate: [],
            takecareCycle :[]
        });
        // 提交
        const submitForm = async (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            await formEl.validate((valid, fields) => {
                if (valid) {
                    form.value.delTakecareDetails = deleteAId.value.toString();
                    form.value.delTestDetails = deleteBId.value.toString();
                    form.value.delRepaireDetails = deleteCId.value.toString();
                    form.value.delCheckStandardeDetails = deleteDId.value.toString();
                    dialogVisible.value = false;
                    delete form.value.equipmentTypeName;
                    delete form.value.departmentName;
                    delete form.value.leadingPersonDepartmentName;
                    delete form.value.leadingDepartmentName;
                    if (titleT.value == '新建') {
                        delete form.value.id;
                    }
                    facilityManagementApi()
                        .getequipmentInfoAddOrUpdate(form.value)
                        .then((res) => {
                            if (res.data.code == 200) {
                                ElMessage({
                                    message: res.data.msg,
                                    type: 'success',
                                });
                                emit('navAddorUpdata');
                            } else {
                                ElMessage.error(res.data.msg);
                            }
                        });
                }
            });
            form.value.takecareDetailList = [];
            form.value.testDetailList = [];
            form.value.repaireDetailList = [];
            form.value.checkStandardeDetailList = [];
        };
        //   取消
        const resetForm = (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            formEl.resetFields();
            form.value.takecareDetailList = [];
            form.value.testDetailList = [];
            form.value.repaireDetailList = [];
            form.value.checkStandardeDetailList = [];
            fileList.value = []
            dialogVisible.value = false;
        };
        const activeName = ref('first');
        const index = ref<any>();
        const categoryShow = ref();
        const opencategory = () => {
            categoryShow.value.openDailog();
        };
        const regionShow = ref();
        const openRegion = () => {
            regionShow.value.openDailog();
        };
        const UserShow = ref();
        const openUser = (type: any) => {
            UserShow.value.openDailog(type);
        };
        const maintenanceShow = ref();
        const openMaintenance = (title: string, data: any) => {
            index.value = form.value.takecareDetailList.indexOf(data);
            maintenanceShow.value.openDailog(title, data);
        };
        const detectShow = ref();
        const openDetect = (title: string, data: any) => {
            index.value = form.value.testDetailList.indexOf(data);
            detectShow.value.openDailog(title, data);
        };
        const repairShow = ref();
        const openRepair = (title: string, data: any) => {
            index.value = form.value.repaireDetailList.indexOf(data);
            repairShow.value.openDailog(title, data);
        };
        const standardShow = ref();
        const openStandard = (title: string, data: any) => {
            index.value = form.value.checkStandardeDetailList.indexOf(data);
            standardShow.value.openDailog(title, data);
        };
        // 上传
        const fileList = ref([]);
        const handleRemove: UploadProps['onRemove'] = (file, uploadFiles) => {
            console.log(file, uploadFiles);
        };
        const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
            console.log(uploadFile);
        };
        const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
            ElMessage.warning(`The limit is 3, you selected ${files.length} files this time, add up to ${files.length + uploadFiles.length} totally`);
        };
        const beforeRemove: UploadProps['beforeRemove'] = (uploadFile, uploadFiles) => {
            return ElMessageBox.confirm(`Cancel the transfert of ${uploadFile.name} ?`).then(
                () => true,
                () => false
            );
        };
        const deleteAId = ref([]);
        const deleteBId = ref([]);
        const deleteCId = ref([]);
        const deleteDId = ref([]);
        // 删除
        const deleteA = (tag: any) => {
            form.value.takecareDetailList.splice(form.value.takecareDetailList.indexOf(tag), 1);
            deleteAId.value.push(tag.id);
        };
        const deleteB = (tag: any) => {
            form.value.testDetailList.splice(form.value.testDetailList.indexOf(tag), 1);
            deleteBId.value.push(tag.id);
        };
        const deleteC = (tag: any) => {
            form.value.repaireDetailList.splice(form.value.repaireDetailList.indexOf(tag), 1);
            deleteCId.value.push(tag.id);
        };
        const deleteD = (tag: any) => {
            form.value.checkStandardeDetailList.splice(form.value.checkStandardeDetailList.indexOf(tag), 1);
            deleteDId.value.push(tag.id);
        };
        // 回传
        const main = (data: any) => {
            const val = deepClone(data);
            if (index.value == -1) {
                form.value.takecareDetailList.push(val);
            } else {
                form.value.takecareDetailList[index.value] = val;
            }
        };
        const delect = (data: any) => {
            const val = deepClone(data);
            if (index.value == -1) {
                form.value.testDetailList.push(val);
            } else  {
                form.value.testDetailList[index.value] = val;
            }
        };
        const Repair = (data: any) => {
            const val = deepClone(data);
            if (index.value == -1) {
                form.value.repaireDetailList.push(val);
            } else {
                form.value.repaireDetailList[index.value] = val;
            }
        };
        const Stand = (data: any) => {
            const val = deepClone(data);
            if (index.value == -1) {
                form.value.checkStandardeDetailList.push(val);
            } else {
                form.value.checkStandardeDetailList[index.value] = val;
            }
        };
        const userId = (val: any, type: number) => {
            console.log(val, type);
            if (type == 1) {
                form.value.leadingPersonId = val.uid;
                form.value.leadingPersonName = val.realName;
            } else if (type == 2) {
                form.value.stopSubmitPersonId = val.uid;
                form.value.stopSubmitPersonName = val.realName;
            }
        };
        const Tid = (data: any) => {
            form.value.equipmentTypeId = data.id;
            form.value.equipmentTypeName = data.typeName;
            form.value.positionNum = data.sortNum;
        };
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        //部门树
        const department = () => {
            goalManagementApi()
                .getTreedepartment()
                .then((res) => {
                    if (res.data.code == 200) {
                        data.value = res.data.data;
                    } else {
                        ElMessage.error(res.data.msg);
                    }
                });
        };
        const propse = {
            label: 'depName',
            children: 'children',
            value: 'depId',
        };
        const data = ref();
        return {
            Tid,
            deepClone,
            rules,
            userId,
            department,
            propse,
            data,
            deleteAId,
            deleteBId,
            deleteCId,
            deleteDId,
            deleteA,
            deleteB,
            deleteC,
            deleteD,
            main,
            index,
            delect,
            Repair,
            Stand,
            resetForm,
            submitForm,
            titles,
            dialogVisible,
            disabled,
            Dailogtype,
            form,
            openDailog,
            Search,
            activeName,
            categoryShow,
            opencategory,
            regionShow,
            openRegion,
            UserShow,
            openUser,
            maintenanceShow,
            openMaintenance,
            detectShow,
            openDetect,
            repairShow,
            openRepair,
            standardShow,
            openStandard,
            fileList,
            handleRemove,
            handlePreview,
            handleExceed,
            beforeRemove,
            full,
            toggleFullscreen,
            FullScreen,
            timeDate,
            ruleFormRef,
            successUploader,
            initFileListData,
            timeC
        };
    },
});
</script>
<style scoped>
.el-form-item {
    width: 25vw;
}
.formType:after {
    content: '';
    width: 400px;
}
.formType {
    padding: 20px 20px;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
}
.el-form .el-form-item:last-of-type {
    margin-bottom: 22px !important;
}
</style>
src/components/equipmentDailog/DailogS.vue
对比新文件
@@ -0,0 +1,701 @@
<template>
    <el-dialog :fullscreen="full" v-model="dialogVisible" draggable :title="titles" width="60%" @close="resetForm(ruleFormRef)" >
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-form :model="form" ref="ruleFormRef" label-width="130px" :rules="rules" :disabled="disabled">
            <el-row>
                <el-col :span="11">
                    <el-form-item label="类型/类别外键" size="default" prop="equipmentTypeId">
                        <el-input v-model="form.equipmentTypeName" placeholder="请选择">
                            <template #append>
                                <el-button :icon="Search" @click="opencategory"></el-button>
                            </template>
                        </el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="装置/部位名称" size="default">
                        <el-input v-model="form.name" placeholder="请填写装置/部位名称" />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="所属部门" size="default">
                        <el-tree-select v-model="form.departmentId" :data="data" check-strictly="true" placeholder="请选择" :props="propse" style="width: 100%">
                        </el-tree-select>
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="具体位置" size="default">
                        <el-input v-model="form.position" placeholder="请填写具体位置" />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="负责人姓名" size="default">
                        <el-input v-model="form.leadingPersonName" placeholder="请填写负责人姓名" />
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="联系人" size="default" prop="connectPersonName">
                        <el-input v-model="form.connectPersonName" placeholder="请选择">
                            <template #append>
                                <el-button :icon="Search" @click="openUser(1)"></el-button>
                            </template>
                        </el-input>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="录入人" size="default" prop="inputPersonName">
                        <el-input v-model="form.inputPersonName" placeholder="请选择">
                            <template #append>
                                <el-button :icon="Search" @click="openUser(2)"></el-button>
                            </template>
                        </el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="责任人" size="default" prop="responsibilityPersonName">
                        <el-input v-model="form.responsibilityPersonName" placeholder="请选择">
                            <template #append>
                                <el-button :icon="Search" @click="openUser(3)"></el-button>
                            </template>
                        </el-input>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="装置部位分类" size="default">
                        <el-select v-model="form.partType" placeholder="请选择" style="width: 100%">
                            <el-option label="关键装置" value="1" />
                            <el-option label="重点部位" value="2" />
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="检查周期" size="default">
                        <el-input v-model="form.checkCycle" placeholder="请填写检查周期" />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="相关应急预案" size="default">
                        <el-input v-model="form.emergencePlanName" placeholder="请选择">
                            <template #append>
                                <el-button :icon="Search" @click="openPlan"></el-button>
                            </template>
                        </el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="主要危险有害因素" size="default">
                        <el-input v-model="form.dangerousElement" placeholder="请填写主要危险有害因素" />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="易导致风险" size="default">
                        <el-input v-model="form.toDangerous" placeholder="请填写易导致风险" />
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="应急处置措施" size="default">
                        <el-input v-model="form.treatment" placeholder="请填写应急处置措施" />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="24">
                    <el-form-item label="现场图片">
                        <el-upload
                            v-model="form.scenePic"
                            class="avatar-uploader"
                            action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
                            :show-file-list="false"
                            :on-success="handleAvatarSuccess"
                            :before-upload="beforeAvatarUpload"
                        >
                            <img v-if="imageUrl" :src="imageUrl" class="avatar" />
                            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
                        </el-upload>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="备注信息" size="default"> <el-input v-model="form.memo" placeholder="请填写备注信息" /> </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <el-tabs v-model="activeName" class="demo-tabs">
            <el-tab-pane label="设备保养" name="first">
                <el-button type="primary" size="default" @click="openMaintenance('新增', '')" :disabled="disabled">新增</el-button>
                <el-table :data="form.takecareDetailList" style="width: 100%">
                    <el-table-column align="center" prop="takecareMemo" label="保养情况" />
                    <el-table-column align="center" prop="leadingPersonName" label="保养负责人" />
                    <el-table-column align="center" prop="takecareDate" :formatter="timeDate" label="保养日期" />
                    <el-table-column align="center" prop="leadingPersonDepartmentName" label="保养负责人单位" />
                    <el-table-column align="center" label="操作">
                        <template #default="scope">
                            <el-button link type="primary" @click="openMaintenance('查看', scope.row)" size="small" :disabled="disabled">查看</el-button>
                            <el-button link type="primary" @click="openMaintenance('修改', scope.row)" size="small" :disabled="disabled">修改</el-button>
                            <el-button link type="primary" @click="deleteA(scope.row)" size="small" :disabled="disabled">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-tab-pane>
            <el-tab-pane label="设备检测" name="second">
                <el-button type="primary" size="default" @click="openDetect('新增', '')" :disabled="disabled">新增</el-button>
                <el-table :data="form.checkDetailList" style="width: 100%">
                    <el-table-column align="center" prop="testPersonName" label="检测人" />
                    <el-table-column align="center" prop="testDate" :formatter="timeDate" label="检测日期" />
                    <el-table-column align="center" prop="testPersonDepartmentName" label="检测人单位" />
                    <el-table-column align="center" prop="testMemo" label="检测内容" />
                    <el-table-column align="center" prop="testResult" label="检测结果" >
                        <template #default="scope">
                            <span v-if="scope.row.testResult == 1">成功</span>
                            <span v-if="scope.row.testResult == 2">失败</span>
                        </template>
                    </el-table-column>
                    <el-table-column align="center" prop="testStatus" label="检测状态" />
                    <el-table-column align="center" label="操作">
                        <template #default="scope">
                            <el-button link type="primary" @click="openDetect('查看', scope.row)" size="small" :disabled="disabled">查看</el-button>
                            <el-button link type="primary" @click="openDetect('修改', scope.row)" size="small" :disabled="disabled">修改</el-button>
                            <el-button link type="primary" @click="deleteB(scope.row)" size="small" :disabled="disabled">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-tab-pane>
            <el-tab-pane label="设备维修" name="third">
                <el-button type="primary" size="default" @click="openRepair('新增', '')" :disabled="disabled">新增</el-button>
                <el-table :data="form.repaireDetailList" style="width: 100%">
                    <el-table-column align="center" prop="exceptionInfo" label="设施异常项" />
                    <el-table-column align="center" prop="repairStatus" label="维修状态" >
                        <template #default="scope">
                            <span v-if="scope.row.repairStatus == 1">维修中</span>
                            <span v-if="scope.row.repairStatus == 2">已维修</span>
                        </template>
                    </el-table-column>
                    <el-table-column align="center" prop="repairMemo" label="维修情况" />
                    <el-table-column align="center" prop="repairPersonName" label="维修负责人" />
                    <el-table-column align="center" prop="repairPersonDepartmentName" label="维修负责人单位" />
                    <el-table-column align="center" prop="repairStartDate" :formatter="timeDate" label="维修开始日期" />
                    <el-table-column align="center" prop="repairEndDate" :formatter="timeDate" label="维修结束日期" />
                    <el-table-column align="center" label="操作">
                        <template #default="scope">
                            <el-button link type="primary" @click="openRepair('查看', scope.row)" size="small" :disabled="disabled">查看</el-button>
                            <el-button link type="primary" @click="openRepair('修改', scope.row)" size="small" :disabled="disabled">修改</el-button>
                            <el-button link type="primary" @click="deleteC(scope.row)" size="small" :disabled="disabled">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-tab-pane>
            <el-tab-pane label="检查标准设置" name="fourth">
                <el-button type="primary" size="default" @click="openStandard('新增', '')" :disabled="disabled">新增</el-button>
                <el-table :data="form.checkStandardeDetailList" style="width: 100%">
                    <el-table-column align="center" prop="indexNum" label="序号" width="75" />
                    <el-table-column align="center" prop="checkContent" label="检查内容" />
                    <el-table-column align="center" prop="checkTarget" label="检查指标" />
                    <el-table-column align="center" prop="unit" label="单位" />
                    <el-table-column align="center" prop="checkPart" label="巡检部位" />
                    <el-table-column align="center" prop="rate" label="频次" />
                    <el-table-column align="center" label="操作">
                        <template #default="scope">
                            <el-button link type="primary" @click="openStandard('查看', scope.row)" size="small" :disabled="disabled">查看</el-button>
                            <el-button link type="primary" @click="openStandard('修改', scope.row)" size="small" :disabled="disabled">修改</el-button>
                            <el-button link type="primary" @click="deleteD(scope.row)" size="small" :disabled="disabled">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-tab-pane>
            <el-tab-pane label="巡检记录" name="five">
                <el-table :data="name" style="width: 100%">
                    <el-table-column align="center" type="selection" width="75" />
                    <el-table-column align="center" sortable prop="name" label="任务编号" />
                    <el-table-column align="center" sortable prop="address" label="任务名称" />
                    <el-table-column align="center" sortable prop="address" label="点位类型" />
                    <el-table-column align="center" sortable prop="address" label="检查频次" />
                    <el-table-column align="center" sortable prop="address" :formatter="timeDate" label="巡检时间" />
                    <el-table-column align="center" sortable prop="address" label="巡检人" />
                </el-table>
            </el-tab-pane>
            <el-tab-pane label="保养维修标准" name="six" v-if="Dailogtype">
                <el-upload
                    v-model:file-list="fileList"
                    class="upload-demo"
                    action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
                    multiple
                    :on-preview="handlePreview"
                    :on-remove="handleRemove"
                    :before-remove="beforeRemove"
                    :limit="3"
                    :on-exceed="handleExceed"
                >
                    <el-button type="primary">点击上传</el-button>
                    <template #tip>
                        <div class="el-upload__tip"></div>
                    </template>
                </el-upload>
            </el-tab-pane>
        </el-tabs>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="resetForm(ruleFormRef)">关闭</el-button>
                <el-button type="primary" @click="submitForm(ruleFormRef)">确定</el-button>
            </span>
        </template>
    </el-dialog>
    <categoryDailog ref="categoryShow" @typeId="Tid"></categoryDailog>
    <RegionsDialog ref="planShow" @SearchUser="onUser"></RegionsDialog>
    <DailogSearchUser ref="UserShow" @SearchUser="userId"></DailogSearchUser>
    <maintenanceDailog ref="maintenanceShow" @onMain="main"></maintenanceDailog>
    <detectDailog ref="detectShow" @onDelect="delect"></detectDailog>
    <repairDailog ref="repairShow" @onRepair="Repair"></repairDailog>
    <standardDailog ref="standardShow" @onStand="Stand"></standardDailog>
</template>
<script lang="ts">
import { defineComponent, ref ,reactive} from 'vue';
import { Search, Plus, FullScreen } from '@element-plus/icons-vue';
import { timeDate } from '/@/assets/index.ts';
import categoryDailog from './categoryDailog.vue';
import RegionsDialog from '../../views/contingencyManagement/emergencyDrill/releaseOfDrillPlan/component/regionsDialog.vue';
import maintenanceDailog from './maintenanceDailog.vue';
import detectDailog from './detectDailog.vue';
import repairDailog from './repairDailog.vue';
import standardDailog from './standardDailog.vue';
import DailogSearchUser from '/@/components/DailogSearchUser/index.vue';
import { ElMessage, ElMessageBox ,FormInstance ,FormRules,} from 'element-plus';
import type { UploadProps, UploadUserFile } from 'element-plus';
import { facilityManagementApi } from '/@/api/facilityManagement';
import { goalManagementApi } from '/@/api/goalManagement';
import {deepClone} from '/@/utils/other'
export default defineComponent({
    components: { categoryDailog,Plus, RegionsDialog, DailogSearchUser, maintenanceDailog, detectDailog, repairDailog, standardDailog },
    setup(props, { emit }) {
        const dialogVisible = ref(false);
        const form = ref({
            equipmentTypeId: 1,
      equipmentTypeName:"",
            treatment: '',
            inputPersonId: '',
      inputPersonName: '',
            departmentId: '',
            // delRepaireDetailList: [],
            // delTestDetailList: [],
            takecareDetailList: [],
            checkDetailList: [],
            responsibilityPersonId: '',
      responsibilityPersonName: '',
            // delTakecareStardardeDetailList: [],
            connectPersonId: '',
      connectPersonName: '',
            scenePic: '',
            partType: '',
            toDangerous: '',
            dangerousElement: '',
      memo:'',
            takecareStardardeDetailList: [
                {
                    filePath: '',
                },
            ],
            testDetailList: [],
            checkCycle: '',
            repaireDetailList: [],
            // delCheckStandardeDetailList: [],
            leadingPersonName: '',
            name: '',
            // delTakecareDetailList: [],
            position: '',
      emergencePlanId: '',
      emergencePlanName:'',
            checkStandardeDetailList: [],
            infoTpe: '',
            delCheckStandardeDetails: '',
            delTakecareStardardeDetails: '',
            delTakecareDetails: '',
            delRepaireDetails: '',
            delTestDetails: '',
        });
    const ruleFormRef = ref<FormInstance>();
        const titles = ref();
    const titleT = ref();
        const disabled = ref(false);
        const Dailogtype = ref(false);
        const openDailog = (title: string, type: boolean, id: number, num: any) => {
            dialogVisible.value = true;
      titleT.value = title;
            department();
            Dailogtype.value = type;
            if (num == 0) {
                titles.value = `${title}仪表信息`;
                form.value.infoTpe = num;
            } else if (num == 1) {
                titles.value = `${title}设备设施`;
                form.value.infoTpe = num;
            } else if (num == 2) {
                titles.value = `${title}设备设施`;
                form.value.infoTpe = num;
            }
            disabled.value = title == '查看' ? true : false;
            if (title == '查看' || title == '修改')
                facilityManagementApi()
                    .getkeypointEquipmentInfoDetail(id)
                    .then((res) => {
                        if (res.data.code == 200) {
                            form.value = res.data.data;
                        } else {
                            ElMessage.error(res.data.msg);
                        }
                    });
        };
        // 提交
        const submitForm = () => {
            form.value.delTakecareDetails = deleteAId.value.toString();
            form.value.delTestDetails = deleteBId.value.toString();
            form.value.delRepaireDetails = deleteCId.value.toString();
            form.value.delCheckStandardeDetails = deleteDId.value.toString();
            dialogVisible.value = false;
      if (titleT.value == '新建') {
        delete form.value.id;
        delete form.value.infoTpe
      }
            facilityManagementApi()
                .getkeypointEquipmentInfoAddOrUpdate(form.value)
                .then((res) => {
                    if (res.data.code == 200) {
                        ElMessage({
                            message: res.data.msg,
                            type: 'success',
                        });
                        emit('navAddorUpdata');
                    } else {
                        ElMessage.error(res.data.msg);
                    }
                });
            // form.value = null;
        };
        //   取消
        const resetForm = (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            formEl.resetFields();
            dialogVisible.value = false;
            form.value={}
        };
        const activeName = ref('first');
        const index = ref<any>();
        const categoryShow = ref();
        const opencategory = () => {
            categoryShow.value.openDailog();
        };
        // 应急预案弹窗
        const planShow = ref();
        const openPlan = () => {
            planShow.value.openDailog();
        };
        const onUser = (e: any) => {
            form.value.emergencePlanId = e.id;
      form.value.emergencePlanName=e.name
        };
        const UserShow = ref();
        const openUser = (type: any) => {
          UserShow.value.openDailog(type);
        };
        const userId = (val: any, type: number) => {
            if (type == 1) {
                form.value.connectPersonId = val.uid;
                form.value.connectPersonName = val.realName;
            } else if (type == 2) {
                form.value.inputPersonId = val.uid;
                form.value.inputPersonName = val.realName;
            } else if (type == 3) {
                form.value.responsibilityPersonId = val.id;
                form.value.responsibilityPersonName = val.realName;
            }
        };
    const Tid=(data:any)=>{
      form.value.equipmentTypeId=data.id
      form.value.equipmentTypeName=data.typeName
    }
        const maintenanceShow = ref();
        const openMaintenance = (title: string, data: any) => {
            index.value = form.value.takecareDetailList.indexOf(data);
            maintenanceShow.value.openDailog(title, data);
        };
        const detectShow = ref();
        const openDetect = (title: string, data: any) => {
            index.value = form.value.testDetailList.indexOf(data);
            detectShow.value.openDailog(title, data);
        };
        const repairShow = ref();
        const openRepair = (title: string, data: any) => {
            index.value = form.value.repaireDetailList.indexOf(data);
            repairShow.value.openDailog(title, data);
        };
        const standardShow = ref();
        const openStandard = (title: string, data: any) => {
            index.value = form.value.checkStandardeDetailList.indexOf(data);
            standardShow.value.openDailog(title, data);
        };
        // 上传
        const fileList = ref<UploadUserFile[]>([
            {
                name: 'element-plus-logo.svg',
                url: 'https://element-plus.org/images/element-plus-logo.svg',
            },
            {
                name: 'element-plus-logo2.svg',
                url: 'https://element-plus.org/images/element-plus-logo.svg',
            },
        ]);
        const handleRemove: UploadProps['onRemove'] = (file, uploadFiles) => {
            console.log(file, uploadFiles);
        };
        const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
            console.log(uploadFile);
        };
        const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
            ElMessage.warning(`The limit is 3, you selected ${files.length} files this time, add up to ${files.length + uploadFiles.length} totally`);
        };
        const beforeRemove: UploadProps['beforeRemove'] = (uploadFile, uploadFiles) => {
            return ElMessageBox.confirm(`Cancel the transfert of ${uploadFile.name} ?`).then(
                () => true,
                () => false
            );
        };
        const deleteAId = ref([]);
        const deleteBId = ref([]);
        const deleteCId = ref([]);
        const deleteDId = ref([]);
        // 删除
        const deleteA = (tag: any) => {
            form.value.takecareDetailList.splice(form.value.takecareDetailList.indexOf(tag), 1);
            deleteAId.value.push(tag.id);
        };
        const deleteB = (tag: any) => {
            form.value.testDetailList.splice(form.value.testDetailList.indexOf(tag), 1);
            deleteBId.value.push(tag.id);
        };
        const deleteC = (tag: any) => {
            form.value.repaireDetailList.splice(form.value.repaireDetailList.indexOf(tag), 1);
            deleteCId.value.push(tag.id);
        };
        const deleteD = (tag: any) => {
            form.value.checkStandardeDetailList.splice(form.value.checkStandardeDetailList.indexOf(tag), 1);
            deleteDId.value.push(tag.id);
        };
        // 回传
        const main = (data: any) => {
      let val=deepClone(data)
            if (index.value == -1) {
                form.value.takecareDetailList.push(val);
            } else {
                form.value.takecareDetailList[index.value] = val;
            }
        };
        const delect = (data: any) => {
      let val=deepClone(data)
            if (index.value == -1) {
                form.value.testDetailList.push(val);
            } else {
                form.value.testDetailList[index.value] = val;
            }
        };
        const Repair = (data: any) => {
      let val=deepClone(data)
            if (index.value == -1) {
                form.value.repaireDetailList.push(val);
            } else {
                form.value.repaireDetailList[index.value] = val;
            }
        };
        const Stand = (data: any) => {
      let val=deepClone(data)
            if (index.value == -1) {
                form.value.checkStandardeDetailList.push(val);
            } else {
                form.value.checkStandardeDetailList[index.value] = val;
            }
        };
    const rules = reactive<FormRules>({
      equipmentTypeId: [],
      equipmentTypeName:[],
    })
        //图片提交
        const imageUrl = ref('');
        const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
            imageUrl.value = URL.createObjectURL(uploadFile.raw!);
        };
        const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
            if (rawFile.type !== 'image/jpeg') {
                ElMessage.error('Avatar picture must be JPG format!');
                return false;
            } else if (rawFile.size / 1024 / 1024 > 2) {
                ElMessage.error('Avatar picture size can not exceed 2MB!');
                return false;
            }
            return true;
        };
        //部门树
        const department = () => {
            goalManagementApi()
                .getTreedepartment()
                .then((res) => {
                    if (res.data.code == 200) {
                        data.value = res.data.data;
                    } else {
                        ElMessage.error(res.data.msg);
                    }
                });
        };
        const propse = {
            label: 'depName',
            children: 'children',
            value: 'depId',
        };
        const data = ref();
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        return {
            propse,
            data,
            submitForm,
            dialogVisible,
            Dailogtype,
            form,
            openDailog,
            Search,
            main,
            delect,
            Repair,
            Stand,
      ruleFormRef,
            index,
            activeName,
            categoryShow,
            opencategory,
            planShow,
            onUser,
            openPlan,
      UserShow,
            openUser,
      rules,
            maintenanceShow,
            openMaintenance,
            detectShow,
            openDetect,
            repairShow,
            openRepair,
            standardShow,
            userId,
            openStandard,
            fileList,
            handleRemove,
            handlePreview,
            handleExceed,
            disabled,
            titles,
            beforeRemove,
            imageUrl,
            handleAvatarSuccess,
            beforeAvatarUpload,
            Plus,
            full,
            toggleFullscreen,
            FullScreen,
      Tid,
            resetForm,
            deleteAId,
            deleteBId,
            deleteCId,
            deleteDId,
            deleteA,
            deleteB,
            deleteC,
            deleteD,
            timeDate,
      titleT,
        };
    },
});
</script>
<style scoped>
.el-row {
    padding: 0 0 20px 0;
}
.avatar-uploader .avatar {
    width: 178px;
    height: 178px;
    display: block;
}
</style>
<style>
.avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    text-align: center;
}
</style>
src/components/equipmentDailog/categoryDailog.vue
对比新文件
@@ -0,0 +1,147 @@
<template>
    <el-dialog v-model="dialogVisible" :fullscreen="full" title="选择类型/类别外键" width="50%" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-row>
            <el-col :span="17">
                <!-- <el-form ref="ruleFormRef" :model="ruleForm" status-icon>
                    <el-row>
                        <el-col :span="12">
                            <el-form-item size="default">
                                <el-input v-model="ruleForm.pass" placeholder="类别名称" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="6" :offset="1">
                            <el-form-item>
                                <el-input v-model="ruleForm.checkPass" placeholder="目标指标编号" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="11" :offset="1">
                            <el-form-item>
                                <el-button size="default" type="primary" @click="submitForm(ruleFormRef)">查询</el-button>
                                <el-button size="default" @click="resetForm(ruleFormRef)">重置</el-button>
                            </el-form-item>
                        </el-col>
                    </el-row>
                </el-form> -->
                <el-button size="default" :icon="Delete" @click="clear">清除选择</el-button>
                <el-table :data="tableData" style="width: 100%; margin-top: 20px" row-key="id" :tree-props="propse">
                    <el-table-column align="center" width="100px">
                        <template #default="scope">
                            <el-radio-group v-model="radio1">
                                <el-radio :label="scope.row.id" @click="radio(scope.row)" size="large">{{ null }}</el-radio>
                            </el-radio-group>
                        </template>
                    </el-table-column>
                    <el-table-column align="center" prop="id" label="id" />
                    <el-table-column align="center" prop="typeName" label="类别名称" />
                </el-table>
            </el-col>
            <el-col :span="7">
            <div v-if="dynamicTags[0]==''?false:true">
                <el-tag
                    v-for="tag in dynamicTags"
                    :key="tag"
                    class="mx-1"
                    style="margin: 5px"
                    closable
                    :disable-transitions="false"
                    @close="handleClose(tag)"
                >
                    {{ tag.typeName }}
                </el-tag>
                </div>
            </el-col>
        </el-row>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false" size="default">关闭</el-button>
                <el-button type="primary" @click="submitForm" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts">
import { defineComponent, reactive, ref } from 'vue';
import { Delete, FullScreen } from '@element-plus/icons-vue';
import { facilityManagementApi } from '/@/api/facilityManagement';
import { ElMessage,ElMessageBox } from 'element-plus';
export default defineComponent({
    setup(props,{emit}) {
        const dialogVisible = ref<boolean>(false);
        const openDailog = () => {
            dialogVisible.value = true;
            listApi()
        };
            // 列表
        const listApi = () => {
            facilityManagementApi()
                .getequipmentTypeMngTreeData()
                .then((res) => {
                    if (res.data.code == 200) {
                        tableData.value = res.data.data;
                    } else {
                        ElMessage({
                            showClose: true,
                            message: res.data.msg,
                            type: 'error',
                        });
                    }
                });
        };
        // 表格
        const tableData = ref([])
        const propse = {
            children: 'childList',
        };
        // 右方点击添加后显示标签
        const dynamicTags = ref(['']);
        const handleClose = (tag: string) => {
            dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
            radio1.value = '';
        };
        const radio1 = ref('');
        const radio = (data: any) => {
            dynamicTags.value[0] = data
        };
        const clear=()=>{
            radio1.value=""
            dynamicTags.value=['']
        }
        const submitForm=()=>{
            emit('typeId',dynamicTags.value[0])
            dialogVisible.value=false
        }
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        return {
            submitForm,
            clear,
            dialogVisible,
            openDailog,
            listApi,
            propse,
            tableData,
            dynamicTags,
            handleClose,
            radio1,
            radio,
            Delete,
            full,
            toggleFullscreen,
            FullScreen,
        };
    },
});
</script>
<style scoped>
.el-row {
    padding: 0 0 20px 0;
}
</style>
src/components/equipmentDailog/detectDailog.vue
对比新文件
@@ -0,0 +1,194 @@
<template>
    <el-dialog v-model="dialogVisible" @close="resetForm(ruleFormRef)"  :fullscreen="full" :title="titles" width="50%" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-form :model="form" ref="ruleFormRef" :rules="rules" :disabled="disabled" label-width="120px">
            <el-row>
                <el-col :span="11">
                    <el-form-item label="检测人" size="default" prop="testPersonName">
                        <el-input v-model="form.testPersonName">
                            <template #append> <el-button :icon="Search" @click="openUser" /> </template
                        ></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="检测日期" size="default" prop="testDate">
                        <el-date-picker v-model="form.testDate" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" placeholder="选择日期时间" style="width: 100%" />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="检测人单位" size="default" prop="testPersonDepartmentId">
                        <el-tree-select
                            v-model="form.testPersonDepartmentId"
                            :data="data"
                            check-strictly="true"
                            class="w100"
                            :props="propse"
                            placeholder="请选择"
                        />
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="检测内容" size="default" prop="testMemo">
                        <el-input v-model="form.testMemo" placeholder="请填写检测内容" />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="检测结果" size="default" prop="testResult">
                        <el-select v-model="form.testResult" placeholder="请选择" style="width: 100%">
                            <el-option label="成功" value="1" />
                            <el-option label="失败" value="2" />
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="检测状态" size="default" prop="testStatus">
                        <el-input v-model="form.testStatus" placeholder="请填写检测状态" />
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <!-- <el-button type="primary" @click="dialogVisible = false" size="default">继续添加</el-button> -->
                <el-button @click="resetForm(ruleFormRef)" size="default">关闭</el-button>
                <el-button type="primary" @click="submitForm(ruleFormRef)" :disabled="disabled" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
    <DailogSearchUser ref="Show" @SearchUser="User"></DailogSearchUser>
</template>
<script lang="ts">
import { defineComponent, ref, reactive } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import type { FormInstance, FormRules } from 'element-plus';
import { Search, FullScreen } from '@element-plus/icons-vue';
import DailogSearchUser from '/@/components/DailogSearchUser/index.vue';
import { goalManagementApi } from '/@/api/goalManagement';
export default defineComponent({
    components: { DailogSearchUser },
    setup(props, { emit }) {
        const ruleFormRef = ref<FormInstance>();
        const form = ref({
            testPersonId: '',
            testPersonName: '',
            testDate: '',
            testPersonDepartmentId: '',
            testMemo: '',
            testResult: '',
            testStatus: '',
        });
        // 开启弹窗
        const titles = ref();
        const disabled = ref(false);
        const dialogVisible = ref(false);
        const openDailog = (title: string, data: any) => {
            department();
            dialogVisible.value = true;
            titles.value = `${title}设备检测`;
            if (title == '查看') {
                disabled.value = true;
                form.value = data;
            } else if (title == '修改') {
                disabled.value = false;
                form.value = data;
            }
        };
        // 开启用户弹窗
        const Show = ref();
        const openUser = () => {
            Show.value.openDailog();
        };
        const User = (val: any) => {
            form.value.testPersonId = val.uid;
            form.value.testPersonName = val.realName;
        };
        const rules = reactive<FormRules>({
            testPersonName: [{ required: true, message: '检测人不能为空', trigger: 'blur' }],
            testDate:[{ required: true, message: '检测日期不能为空', trigger: 'blur' }],
            testPersonDepartmentId:[],
            testMemo:[{ required: true, message: '检测内容不能为空', trigger: 'blur' }],
            testResult:[{ required: true, message: '检测结果不能为空', trigger: 'blur' }],
            testStatus:[{ required: true, message: '检测状态不能为空', trigger: 'blur' }],
        });
        // 提交
        const submitForm = async (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            await formEl.validate((valid, fields) => {
                if (valid) {
                    emit('onDelect', form.value);
                    dialogVisible.value = false;
                } else {
                    console.log('error submit!', fields);
                }
            });
            disabled.value = false;
        };
        //   取消
        const resetForm = (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            formEl.clearValidate();
            dialogVisible.value = false;
            disabled.value = false;
            form.value={}
        };
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        //部门树
        const department = () => {
            goalManagementApi()
                .getTreedepartment()
                .then((res) => {
                    if (res.data.code == 200) {
                        data.value = res.data.data;
                    } else {
                        ElMessage.error(res.data.msg);
                    }
                });
        };
        const propse = {
            label: 'depName',
            children: 'children',
            value: 'depId',
        };
        const data = ref();
        return {
            ruleFormRef,
            rules,
            department,
            propse,
            data,
            form,
            titles,
            User,
            disabled,
            dialogVisible,
            openDailog,
            submitForm,
            resetForm,
            Show,
            openUser,
            Search,
            full,
            toggleFullscreen,
            FullScreen,
        };
    },
});
</script>
<style scoped>
.el-row {
    padding: 0 0 20px 0;
}
</style>
src/components/equipmentDailog/maintenanceDailog.vue
对比新文件
@@ -0,0 +1,206 @@
<template>
    <el-dialog :fullscreen="full" v-model="dialogVisible" @close="resetForms(ruleFormRefs)" :title="titles" width="50%" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-form :model="form" ref="ruleFormRefs" :rules="rules" :disabled="disabled" label-width="120px">
            <el-row>
                <el-col :span="11">
                    <el-form-item label="保养情况" size="default" prop="takecareMemo">
                        <el-input v-model="form.takecareMemo" />
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="保养负责人" size="default" prop="leadingPersonName">
                        <el-input v-model="form.leadingPersonName">
                            <template #append> <el-button :icon="Search" @click="openUser" /> </template
                        ></el-input>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="保养日期" size="default" prop="takecareDate">
                        <el-date-picker
                            v-model="form.takecareDate"
                            format="YYYY-MM-DD HH:mm:ss"
                            value-format="YYYY-MM-DD HH:mm:ss"
                            type="datetime"
                            style="width: 100%"
                        />
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="保养负责人单位" size="default" prop="leadingPersonDepartmentId">
                        <el-tree-select
                            v-model="form.leadingPersonDepartmentId"
                            :data="data"
                            check-strictly="true"
                            class="w100"
                            :props="propse"
                            placeholder="请选择"
                        />
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <!-- <el-button type="primary" @click="dialogVisible = false" size="default">继续添加</el-button> -->
                <el-button @click="resetForms(ruleFormRefs)" size="default">关闭</el-button>
                <el-button type="primary" @click="submitForms(ruleFormRefs)" :disabled="disabled" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
    <DailogSearchUser ref="Show" @SearchUser="User"></DailogSearchUser>
</template>
<script lang="ts">
import { defineComponent, ref, reactive } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Search, FullScreen } from '@element-plus/icons-vue';
import type { FormInstance, FormRules } from 'element-plus';
import DailogSearchUser from '/@/components/DailogSearchUser/index.vue';
import { goalManagementApi } from '/@/api/goalManagement';
export default defineComponent({
    components: { DailogSearchUser },
    setup(props, { emit }) {
        const ruleFormRefs = ref<FormInstance>();
        const form = ref({
            takecareMemo: '',
            leadingPersonId: '',
            leadingPersonName: '',
            takecareDate: '',
            leadingPersonDepartmentId: '',
        });
        // 开启弹窗
        const titles = ref();
        const disabled = ref(false);
        const dialogVisible = ref(false);
        const openDailog = (title: string, data: any) => {
            department();
            dialogVisible.value = true;
            titles.value = `${title}仪器仪表`;
            if (title == '查看') {
                disabled.value = true;
                form.value = data;
            } else if (title == '修改') {
                disabled.value = false;
                form.value = data;
            }
        };
        const rules = reactive<FormRules>({
            takecareMemo: [
                {
                    required: true,
                    message: '保养情况不能为空',
                    trigger: 'blur',
                },
            ],
            leadingPersonName: [
                {
                    required: true,
                    message: '保养负责人不能为空',
                    trigger: 'blur',
                },
            ],
            takecareDate: [
                {
                    required: true,
                    message: '保养日期不能为空',
                    trigger: 'blur',
                },
            ],
            leadingPersonDepartmentId: [
                {
                    required: true,
                    message: '保养负责人单位不能为空',
                    trigger: 'blur',
                },
            ],
        });
        // 开启用户弹窗
        const Show = ref();
        const openUser = () => {
            Show.value.openDailog();
        };
        const User = (val: any) => {
            form.value.leadingPersonId = val.uid;
            form.value.leadingPersonName = val.realName;
        };
        // 提交
        const submitForms = async (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            await formEl.validate((valid, fields) => {
                if (valid) {
                    dialogVisible.value = false;
                    emit('onMain', form.value);
                } else {
                    console.log('error submit!', fields);
                }
            });
            disabled.value = false;
        };
        //   取消
        const resetForms = (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            formEl.clearValidate();
            disabled.value = false;
            form.value = {};
            dialogVisible.value = false;
        };
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        //部门树
        const department = () => {
            goalManagementApi()
                .getTreedepartment()
                .then((res) => {
                    if (res.data.code == 200) {
                        data.value = res.data.data;
                    } else {
                        ElMessage.error(res.data.msg);
                    }
                });
        };
        const propse = {
            label: 'depName',
            children: 'children',
            value: 'depId',
        };
        const data = ref();
        return {
            department,
            propse,
            data,
            disabled,
            rules,
            titles,
            submitForms,
            resetForms,
            form,
            User,
            dialogVisible,
            openDailog,
            ruleFormRefs,
            Show,
            openUser,
            Search,
            full,
            toggleFullscreen,
            FullScreen,
        };
    },
});
</script>
<style scoped>
.el-row {
    padding: 0 0 20px 0;
}
</style>
src/components/equipmentDailog/planDailog.vue
对比新文件
@@ -0,0 +1,156 @@
<template>
    <el-dialog v-model="dialogVisible" :fullscreen="full" title="选择所属重大危险源单元" width="50%" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-row>
            <el-col :span="17">
                <el-form ref="ruleFormRef" :model="ruleForm" status-icon>
                    <el-row>
                        <el-col :span="12">
                            <el-form-item size="default">
                                <el-input v-model="ruleForm.pass" placeholder="预案名称" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="11" :offset="1">
                            <el-form-item>
                                <el-button size="default" type="primary" @click="submitForm(ruleFormRef)">查询</el-button>
                                <el-button size="default" @click="resetForm(ruleFormRef)">重置</el-button>
                            </el-form-item>
                        </el-col>
                    </el-row>
                </el-form>
                <el-button size="default" :icon="Delete">清除选择</el-button>
                <el-table :data="tableData" style="width: 100%; margin-top: 20px">
                    <el-table-column align="center" width="80">
                        <template #default="scope">
                            <el-radio-group v-model="radio1" @change="radio">
                                <el-radio :label="scope.row.date" size="large">{{ null }}</el-radio>
                            </el-radio-group>
                        </template>
                    </el-table-column>
                    <!-- <el-table-column align="center" prop="date" label="id"/> -->
                    <el-table-column align="center" prop="name" label="预案名称" />
                </el-table>
                <el-pagination
                    style="padding: 20px 0; border-bottom: 1px solid #dedede"
                    v-model:currentPage="currentPage4"
                    v-model:page-size="pageSize4"
                    :page-sizes="[100, 200, 300, 400]"
                    :small="small"
                    :disabled="disabled"
                    :background="background"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="400"
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                />
            </el-col>
            <el-col :span="7">
                <el-tag
                    v-for="tag in dynamicTags"
                    :key="tag"
                    class="mx-1"
                    style="margin: 5px"
                    closable
                    :disable-transitions="false"
                    @close="handleClose(tag)"
                >
                    {{ tag }}
                </el-tag>
            </el-col>
        </el-row>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false" size="default">关闭</el-button>
                <el-button type="primary" @click="dialogVisible = false" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts">
import { defineComponent, reactive, ref } from 'vue';
import { Delete, FullScreen } from '@element-plus/icons-vue';
export default defineComponent({
    setup() {
        const dialogVisible = ref<boolean>(false);
        const openDailog = () => {
            dialogVisible.value = true;
        };
        // 搜索条件
        const ruleForm = reactive({
            pass: '',
            checkPass: '',
        });
        // 表格
        const tableData = [
            {
                date: '2016-05-03',
                name: 'Tom',
                address: 'No. 189, Grove St, Los Angeles',
            },
            {
                date: '2016-05-02',
                name: 'Tom',
                address: 'No. 189, Grove St, Los Angeles',
            },
            {
                date: '2016-05-04',
                name: 'Tom',
                address: 'No. 189, Grove St, Los Angeles',
            },
            {
                date: '2016-05-01',
                name: 'Tom',
                address: 'No. 189, Grove St, Los Angeles',
            },
        ];
        const pageSize4 = ref(100);
        const handleSizeChange = (val: number) => {
            console.log(`${val} items per page`);
        };
        const handleCurrentChange = (val: number) => {
            console.log(`current page: ${val}`);
        };
        // 右方点击添加后显示标签
        const dynamicTags = ref(['2016-05-03']);
        const handleClose = (tag: string) => {
            dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
            radio1.value = '';
        };
        const radio1 = ref('2016-05-03');
        const radio = (event: any) => {
            dynamicTags.value[0] = event;
        };
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        return {
            dialogVisible,
            openDailog,
            ruleForm,
            tableData,
            pageSize4,
            handleSizeChange,
            handleCurrentChange,
            dynamicTags,
            handleClose,
            radio1,
            radio,
            Delete,
            full,
            toggleFullscreen,
            FullScreen,
        };
    },
});
</script>
<style scoped>
.el-row {
    padding: 0 0 20px 0;
}
</style>
src/components/equipmentDailog/regionDailog.vue
对比新文件
@@ -0,0 +1,156 @@
<template>
    <el-dialog v-model="dialogVisible" :fullscreen="full" title="选择区域名称" width="50%" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-row>
            <el-col :span="17">
                <el-form ref="ruleFormRef" :model="ruleForm" status-icon>
                    <el-row>
                        <el-col :span="12">
                            <el-form-item size="default">
                                <el-input v-model="ruleForm.pass" placeholder="风险区域名称" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="11" :offset="1">
                            <el-form-item>
                                <el-button size="default" type="primary" @click="submitForm(ruleFormRef)">查询</el-button>
                                <el-button size="default" @click="resetForm(ruleFormRef)">重置</el-button>
                            </el-form-item>
                        </el-col>
                    </el-row>
                </el-form>
                <el-button size="default" :icon="Delete">清除选择</el-button>
                <el-table :data="tableData" style="width: 100%; margin-top: 20px">
                    <el-table-column align="center" width="80">
                        <template #default="scope">
                            <el-radio-group v-model="radio1" @change="radio">
                                <el-radio :label="scope.row.date" size="large">{{ null }}</el-radio>
                            </el-radio-group>
                        </template>
                    </el-table-column>
                    <!-- <el-table-column align="center" prop="date" label="id"/> -->
                    <el-table-column align="center" prop="name" label="风险区域名称" />
                </el-table>
                <el-pagination
                    style="padding: 20px 0; border-bottom: 1px solid #dedede"
                    v-model:currentPage="currentPage4"
                    v-model:page-size="pageSize4"
                    :page-sizes="[100, 200, 300, 400]"
                    :small="small"
                    :disabled="disabled"
                    :background="background"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="400"
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                />
            </el-col>
            <el-col :span="7">
                <el-tag
                    v-for="tag in dynamicTags"
                    :key="tag"
                    class="mx-1"
                    style="margin: 5px"
                    closable
                    :disable-transitions="false"
                    @close="handleClose(tag)"
                >
                    {{ tag }}
                </el-tag>
            </el-col>
        </el-row>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false" size="default">关闭</el-button>
                <el-button type="primary" @click="dialogVisible = false" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts">
import { defineComponent, reactive, ref } from 'vue';
import { Delete, FullScreen } from '@element-plus/icons-vue';
export default defineComponent({
    setup() {
        const dialogVisible = ref<boolean>(false);
        const openDailog = () => {
            dialogVisible.value = true;
        };
        // 搜索条件
        const ruleForm = reactive({
            pass: '',
            checkPass: '',
        });
        // 表格
        const tableData = [
            {
                date: '2016-05-03',
                name: 'Tom',
                address: 'No. 189, Grove St, Los Angeles',
            },
            {
                date: '2016-05-02',
                name: 'Tom',
                address: 'No. 189, Grove St, Los Angeles',
            },
            {
                date: '2016-05-04',
                name: 'Tom',
                address: 'No. 189, Grove St, Los Angeles',
            },
            {
                date: '2016-05-01',
                name: 'Tom',
                address: 'No. 189, Grove St, Los Angeles',
            },
        ];
        const pageSize4 = ref(100);
        const handleSizeChange = (val: number) => {
            console.log(`${val} items per page`);
        };
        const handleCurrentChange = (val: number) => {
            console.log(`current page: ${val}`);
        };
        // 右方点击添加后显示标签
        const dynamicTags = ref(['2016-05-03']);
        const handleClose = (tag: string) => {
            dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
            radio1.value = '';
        };
        const radio1 = ref('2016-05-03');
        const radio = (event: any) => {
            dynamicTags.value[0] = event;
        };
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        return {
            dialogVisible,
            openDailog,
            ruleForm,
            tableData,
            pageSize4,
            handleSizeChange,
            handleCurrentChange,
            dynamicTags,
            handleClose,
            radio1,
            radio,
            Delete,
            full,
            toggleFullscreen,
            FullScreen,
        };
    },
});
</script>
<style scoped>
.el-row {
    padding: 0 0 20px 0;
}
</style>
src/components/equipmentDailog/repairDailog.vue
对比新文件
@@ -0,0 +1,216 @@
<template>
    <el-dialog v-model="dialogVisible" :fullscreen="full" @close="resetForm(ruleFormRef)" :title="titles" width="50%" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-form :model="form"  ref="ruleFormRef" :rules="rules" :disabled="disabled" label-width="120px">
            <el-row>
                <el-col :span="11">
                    <el-form-item label="设施异常项" size="default" prop="exceptionInfo">
                        <el-input v-model="form.exceptionInfo" placeholder="请填写设施异常项" />
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="维修状态" size="default" prop="repairStatus">
                        <el-select v-model="form.repairStatus" placeholder="请选择" style="width: 100%">
                            <el-option label="维修中" :value="1" />
                            <el-option label="已修好" :value="2" />
                        </el-select>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="维修情况" size="default" prop="repairMemo">
                        <el-input v-model="form.repairMemo" placeholder="请填写维修情况" />
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="维修负责人" size="default" prop="repairPersonName">
                        <el-input v-model="form.repairPersonName" placeholder="请选择">
                            <template #append> <el-button :icon="Search" @click="openUser" /> </template
                        ></el-input>
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="维修负责人单位" size="default" prop="repairPersonDepartmentId">
                        <el-tree-select
                            v-model="form.repairPersonDepartmentId"
                            :data="data"
                            check-strictly="true"
                            class="w100"
                            :props="propse"
                            placeholder="请选择"
                        />
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="维修开始日期" size="default" prop="repairStartDate">
                        <el-date-picker
                            v-model="form.repairStartDate"
                            format="YYYY-MM-DD HH:mm:ss"
                            value-format="YYYY-MM-DD HH:mm:ss"
                            type="datetime"
                            placeholder="选择日期时间"
                            style="width: 100%"
                        />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="维修结束日期" size="default" prop="repairEndDate">
                        <el-date-picker
                            v-model="form.repairEndDate"
                            format="YYYY-MM-DD HH:mm:ss"
                            value-format="YYYY-MM-DD HH:mm:ss"
                            type="datetime"
                            placeholder="选择日期时间"
                            style="width: 100%"
                        />
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <!-- <el-button type="primary" @click="dialogVisible = false" size="default">继续添加</el-button> -->
                <el-button @click="resetForm(ruleFormRef)" size="default">关闭</el-button>
                <el-button type="primary"  @click="submitForm(ruleFormRef)" :disabled="disabled" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
    <DailogSearchUser ref="Show" @SearchUser="User"></DailogSearchUser>
</template>
<script lang="ts">
import { defineComponent, ref, reactive } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import type { FormInstance, FormRules } from 'element-plus';
import { Search, FullScreen } from '@element-plus/icons-vue';
import DailogSearchUser from '/@/components/DailogSearchUser/index.vue';
import { goalManagementApi } from '/@/api/goalManagement';
export default defineComponent({
    components: { DailogSearchUser },
    setup(props, { emit }) {
        const ruleFormRef = ref<FormInstance>();
        const form = ref({
            exceptionInfo: '',
            repairStatus: '',
            repairMemo: '',
            repairPersonId: '',
            repairPersonName: '',
            repairPersonDepartmentId: '',
            repairStartDate: '',
            repairEndDate: '',
        });
        // 开启弹窗
        const titles = ref();
        const disabled = ref(false);
        const dialogVisible = ref(false);
        const openDailog = (title: string, data: any) => {
            department();
            dialogVisible.value = true;
            titles.value = `${title}设备维修`;
            if (title == '查看') {
                disabled.value = true;
                form.value = data;
            } else if (title == '修改') {
                disabled.value = false;
                form.value = data;
            }
        };
        // 开启用户弹窗
        const Show = ref();
        const openUser = () => {
            Show.value.openDailog();
        };
        const User = (val: any) => {
            form.value.repairPersonId = val.uid;
            form.value.repairPersonName = val.realName;
        };
        const rules = reactive<FormRules>({
            exceptionInfo: [{ required: true, message: '设施异常项不能为空', trigger: 'blur' }],
            repairStatus: [{ required: true, message: '维修状态不能为空', trigger: 'blur' }],
            repairMemo: [{ required: true, message: '维修情况不能为空', trigger: 'blur' }],
            // repairPersonName: [{ required: true, message: '维修负责人不能为空', trigger: 'blur' }],
            repairPersonDepartmentId: [{ required: true, message: '维修负责人单位不能为空', trigger: 'blur' }],
            repairStartDate: [{ required: true, message: '维修开始日期不能为空', trigger: 'blur' }],
            repairEndDate: [{ required: true, message: '维修结束日期不能为空', trigger: 'blur' }],
        });
        // 提交
        const submitForm = async (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            await formEl.validate((valid, fields) => {
                if (valid) {
                    emit('onRepair', form.value);
                    dialogVisible.value = false;
                } else {
                    console.log('error submit!', fields);
                }
            });
            disabled.value = false;
        };
        //  取消
        const resetForm = (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            formEl.clearValidate();
            disabled.value = false;
            dialogVisible.value = false;
            form.value = {};
        };
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        //部门树
        const department = () => {
            goalManagementApi()
                .getTreedepartment()
                .then((res) => {
                    if (res.data.code == 200) {
                        data.value = res.data.data;
                    } else {
                        ElMessage.error(res.data.msg);
                    }
                });
        };
        const propse = {
            label: 'depName',
            children: 'children',
            value: 'depId',
        };
        const data = ref();
        return {
            rules,
            ruleFormRef,
            department,
            propse,
            data,
            form,
            titles,
            disabled,
            dialogVisible,
            openDailog,
            Show,
            User,
            openUser,
            submitForm,
            resetForm,
            Search,
            full,
            toggleFullscreen,
            FullScreen,
        };
    },
});
</script>
<style scoped>
.el-row {
    padding: 0 0 20px 0;
}
</style>
src/components/equipmentDailog/standardDailog.vue
对比新文件
@@ -0,0 +1,151 @@
<template>
    <el-dialog v-model="dialogVisible" :fullscreen="full" @close="resetForm(ruleFormRef)" :title="titles" width="50%" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-form :model="form" ref="ruleFormRef" :rules="rules" label-width="120px" :disabled="disabled">
            <el-row>
                <el-col :span="11">
                    <el-form-item label="序号" size="default" prop="indexNum">
                        <el-input v-model="form.indexNum" placeholder="请填写序号" />
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2" size="default" prop="checkContent">
                    <el-form-item label="检查内容">
                        <el-input v-model="form.checkContent" placeholder="请填写检查内容" />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="检查指标" size="default" prop="checkTarget">
                        <el-input v-model="form.checkTarget" placeholder="请填写检查指标" />
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="单位" size="default" prop="unit">
                        <el-input v-model="form.unit" placeholder="请填写单位" />
                    </el-form-item>
                </el-col>
            </el-row>
            <el-row>
                <el-col :span="11">
                    <el-form-item label="巡检部位" size="default" prop="checkPart">
                        <el-input v-model="form.checkPart" placeholder="请填写巡检部位" />
                    </el-form-item>
                </el-col>
                <el-col :span="11" :offset="2">
                    <el-form-item label="频次" size="default" prop="rate">
                        <el-input v-model="form.rate" placeholder="请填写频次" />
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <!-- <el-button type="primary" @click="dialogVisible = false" size="default">继续添加</el-button> -->
                <el-button @click="resetForm(ruleFormRef)" size="default">关闭</el-button>
                <el-button type="primary" @click="submitForm(ruleFormRef)" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
    <!-- <DailogSearchUser ref="Show"></DailogSearchUser> -->
</template>
<script lang="ts">
import { defineComponent, ref, reactive } from 'vue';
import type { FormInstance, FormRules } from 'element-plus';
import { Search, FullScreen } from '@element-plus/icons-vue';
import DailogSearchUser from '/@/components/DailogSearchUser/index.vue';
export default defineComponent({
    components: { DailogSearchUser },
    setup(props, { emit }) {
        const ruleFormRef = ref<FormInstance>();
        const form = ref({
            indexNum: '',
            checkContent: '',
            checkTarget: '',
            unit: '',
            checkPart: '',
            rate: '',
        });
        // 开启弹窗
        const titles = ref();
        const disabled = ref(false);
        const dialogVisible = ref(false);
        const openDailog = (title: string, data: any) => {
            dialogVisible.value = true;
            titles.value = `${title}检查标准设置`;
            if (title == '查看') {
                disabled.value = true;
                form.value = data;
            } else if (title == '修改') {
                disabled.value = false;
                form.value = data;
            }
        };
        // 开启用户弹窗
        const Show = ref();
        const openUser = () => {
            Show.value.openDailog();
        };
        const rules = reactive<FormRules>({
            indexNum: [{ required: true, message: '序号不能为空', trigger: 'blur' }],
            checkContent: [{ required: true, message: '检查内容不能为空', trigger: 'blur' }],
            checkTarget: [{ required: true, message: '检查指标不能为空', trigger: 'blur' }],
            unit: [{ required: true, message: '单位不能为空', trigger: 'blur' }],
            checkPart: [{ required: true, message: '巡检部位不能为空', trigger: 'blur' }],
            rate: [{ required: true, message: '频次不能为空', trigger: 'blur' }],
        });
        // 提交
        const submitForm = async (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            await formEl.validate((valid, fields) => {
                if (valid) {
                    emit('onStand', form.value);
                    dialogVisible.value = false;
                } else {
                    console.log('error submit!', fields);
                }
            });
            disabled.value = false;
        };
        //   取消
        const resetForm = (formEl: FormInstance | undefined) => {
            if (!formEl) return;
            formEl.clearValidate();
            dialogVisible.value = false;
            disabled.value = false;
            form.value = {};
        };
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            } else {
                full.value = false;
            }
        };
        return {
            rules,
            ruleFormRef,
            form,
            titles,
            disabled,
            dialogVisible,
            openDailog,
            submitForm,
            resetForm,
            Show,
            openUser,
            Search,
            full,
            toggleFullscreen,
            FullScreen,
        };
    },
});
</script>
<style scoped>
.el-row {
    padding: 0 0 20px 0;
}
</style>
src/components/iconSelector/index.vue
对比新文件
@@ -0,0 +1,252 @@
<template>
    <div class="icon-selector w100 h100">
        <el-popover
            placement="bottom"
            :width="fontIconWidth"
            trigger="click"
            transition="el-zoom-in-top"
            popper-class="icon-selector-popper"
            @show="onPopoverShow"
        >
            <template #reference>
                <el-input
                    v-model="fontIconSearch"
                    :placeholder="fontIconPlaceholder"
                    :clearable="clearable"
                    :disabled="disabled"
                    :size="size"
                    ref="inputWidthRef"
                    @clear="onClearFontIcon"
                    @focus="onIconFocus"
                    @blur="onIconBlur"
                >
                    <template #prepend>
                        <SvgIcon
                            :name="fontIconPrefix === '' ? prepend : fontIconPrefix"
                            class="font14"
                            v-if="fontIconPrefix === '' ? prepend?.indexOf('ele-') > -1 : fontIconPrefix?.indexOf('ele-') > -1"
                        />
                        <i v-else :class="fontIconPrefix === '' ? prepend : fontIconPrefix" class="font14"></i>
                    </template>
                </el-input>
            </template>
            <template #default>
                <div class="icon-selector-warp">
                    <div class="icon-selector-warp-title flex">
                        <div class="flex-auto">{{ title }}</div>
                        <div class="icon-selector-warp-title-tab" v-if="type === 'all'">
                            <span :class="{ 'span-active': fontIconType === 'ali' }" @click="onIconChange('ali')" class="ml10" title="iconfont 图标">ali</span>
                            <span :class="{ 'span-active': fontIconType === 'ele' }" @click="onIconChange('ele')" class="ml10" title="elementPlus 图标">ele</span>
                            <span :class="{ 'span-active': fontIconType === 'awe' }" @click="onIconChange('awe')" class="ml10" title="fontawesome 图标">awe</span>
                        </div>
                    </div>
                    <div class="icon-selector-warp-row">
                        <el-scrollbar ref="selectorScrollbarRef">
                            <el-row :gutter="10" v-if="fontIconSheetsFilterList.length > 0">
                                <el-col :xs="6" :sm="4" :md="4" :lg="4" :xl="4" @click="onColClick(v)" v-for="(v, k) in fontIconSheetsFilterList" :key="k">
                                    <div class="icon-selector-warp-item" :class="{ 'icon-selector-active': fontIconPrefix === v }">
                                        <div class="flex-margin">
                                            <div class="icon-selector-warp-item-value">
                                                <SvgIcon :name="v" />
                                            </div>
                                        </div>
                                    </div>
                                </el-col>
                            </el-row>
                            <el-empty :image-size="100" v-if="fontIconSheetsFilterList.length <= 0" :description="emptyDescription"></el-empty>
                        </el-scrollbar>
                    </div>
                </div>
            </template>
        </el-popover>
    </div>
</template>
<script lang="ts">
import { ref, toRefs, reactive, onMounted, nextTick, computed, watch, defineComponent } from 'vue';
import initIconfont from '/@/utils/getStyleSheets';
export default defineComponent({
    name: 'iconSelector',
    emits: ['update:modelValue', 'get', 'clear'],
    props: {
        // 输入框前置内容
        prepend: {
            type: String,
            default: () => 'ele-Pointer',
        },
        // 输入框占位文本
        placeholder: {
            type: String,
            default: () => '请输入内容搜索图标或者选择图标',
        },
        // 输入框占位文本
        size: {
            type: String,
            default: () => 'default',
        },
        // 弹窗标题
        title: {
            type: String,
            default: () => '请选择图标',
        },
        // icon 图标类型
        type: {
            type: String,
            default: () => 'ele',
        },
        // 禁用
        disabled: {
            type: Boolean,
            default: () => false,
        },
        // 是否可清空
        clearable: {
            type: Boolean,
            default: () => true,
        },
        // 自定义空状态描述文字
        emptyDescription: {
            type: String,
            default: () => '无相关图标',
        },
        // 双向绑定值,默认为 modelValue,
        // 参考:https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5
        // 参考:https://v3.cn.vuejs.org/guide/component-custom-events.html#%E5%A4%9A%E4%B8%AA-v-model-%E7%BB%91%E5%AE%9A
        modelValue: String,
    },
    setup(props, { emit }) {
        const inputWidthRef = ref();
        const selectorScrollbarRef = ref();
        const state = reactive({
            fontIconPrefix: '',
            fontIconWidth: 0,
            fontIconSearch: '',
            fontIconTabsIndex: 0,
            fontIconSheetsList: [],
            fontIconPlaceholder: '',
            fontIconType: 'ali',
            fontIconShow: true,
        });
        // 处理 input 获取焦点时,modelValue 有值时,改变 input 的 placeholder 值
        const onIconFocus = () => {
            if (!props.modelValue) return false;
            state.fontIconSearch = '';
            state.fontIconPlaceholder = props.modelValue;
        };
        // 处理 input 失去焦点时,为空将清空 input 值,为点击选中图标时,将取原先值
        const onIconBlur = () => {
            setTimeout(() => {
                const icon = state.fontIconSheetsList.filter((icon: string) => icon === state.fontIconSearch);
                if (icon.length <= 0) state.fontIconSearch = '';
            }, 300);
        };
        // 处理 icon 双向绑定数值回显
        const initModeValueEcho = () => {
            if (props.modelValue === '') return ((<string | undefined>state.fontIconPlaceholder) = props.placeholder);
            (<string | undefined>state.fontIconPlaceholder) = props.modelValue;
            (<string | undefined>state.fontIconPrefix) = props.modelValue;
        };
        // 处理 icon type 类型为 all 时,类型 ali、ele、awe 回显问题
        const initFontIconTypeEcho = () => {
            if ((<any>props.modelValue)?.indexOf('iconfont') > -1) onIconChange('ali');
            else if ((<any>props.modelValue)?.indexOf('ele-') > -1) onIconChange('ele');
            else if ((<any>props.modelValue)?.indexOf('fa') > -1) onIconChange('awe');
            else onIconChange('ali');
        };
        // 图标搜索及图标数据显示
        const fontIconSheetsFilterList = computed(() => {
            if (!state.fontIconSearch) return state.fontIconSheetsList;
            let search = state.fontIconSearch.trim().toLowerCase();
            return state.fontIconSheetsList.filter((item: any) => {
                if (item.toLowerCase().indexOf(search) !== -1) return item;
            });
        });
        // 获取 input 的宽度
        const getInputWidth = () => {
            nextTick(() => {
                state.fontIconWidth = inputWidthRef.value.$el.offsetWidth;
            });
        };
        // 监听页面宽度改变
        const initResize = () => {
            window.addEventListener('resize', () => {
                getInputWidth();
            });
        };
        // 初始化数据
        const initFontIconData = async (type: string) => {
            state.fontIconSheetsList = [];
            if (type === 'ali') {
                await initIconfont.ali().then((res: any) => {
                    // 阿里字体图标使用 `iconfont xxx`
                    state.fontIconSheetsList = res.map((i: string) => `iconfont ${i}`);
                });
            } else if (type === 'ele') {
                await initIconfont.ele().then((res: any) => {
                    state.fontIconSheetsList = res;
                });
            } else if (type === 'awe') {
                await initIconfont.awe().then((res: any) => {
                    // fontawesome字体图标使用 `fa xxx`
                    state.fontIconSheetsList = res.map((i: string) => `fa ${i}`);
                });
            }
            // 初始化 input 的 placeholder
            // 参考(单项数据流):https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81
            state.fontIconPlaceholder = props.placeholder;
            // 初始化双向绑定回显
            initModeValueEcho();
        };
        // 图标点击切换
        const onIconChange = (type: string) => {
            state.fontIconType = type;
            initFontIconData(type);
        };
        // 获取当前点击的 icon 图标
        const onColClick = (v: any) => {
            state.fontIconPlaceholder = v;
            state.fontIconPrefix = v;
            emit('get', state.fontIconPrefix);
            emit('update:modelValue', state.fontIconPrefix);
        };
        // 清空当前点击的 icon 图标
        const onClearFontIcon = () => {
            state.fontIconPrefix = '';
            emit('clear', state.fontIconPrefix);
            emit('update:modelValue', state.fontIconPrefix);
        };
        // 监听 Popover 打开,用于双向绑定值回显
        const onPopoverShow = () => {
            initModeValueEcho();
            initFontIconTypeEcho();
        };
        // 页面加载时
        onMounted(() => {
            initModeValueEcho();
            initResize();
            getInputWidth();
        });
        // 监听双向绑定 modelValue 的变化
        watch(
            () => props.modelValue,
            () => {
                initModeValueEcho();
            }
        );
        return {
            inputWidthRef,
            selectorScrollbarRef,
            fontIconSheetsFilterList,
            onColClick,
            onIconChange,
            onClearFontIcon,
            onIconFocus,
            onIconBlur,
            onPopoverShow,
            ...toRefs(state),
        };
    },
});
</script>
src/components/noticeBar/index.vue
对比新文件
@@ -0,0 +1,195 @@
<template>
    <div class="notice-bar" :style="{ background, height: `${height}px` }" v-show="!isMode">
        <div class="notice-bar-warp" :style="{ color, fontSize: `${size}px` }">
            <i v-if="leftIcon" class="notice-bar-warp-left-icon" :class="leftIcon"></i>
            <div class="notice-bar-warp-text-box" ref="noticeBarWarpRef">
                <div class="notice-bar-warp-text" ref="noticeBarTextRef" v-if="!scrollable">{{ text }}</div>
                <div class="notice-bar-warp-slot" v-else><slot /></div>
            </div>
            <SvgIcon :name="rightIcon" v-if="rightIcon" class="notice-bar-warp-right-icon" @click="onRightIconClick" />
        </div>
    </div>
</template>
<script lang="ts">
import { toRefs, reactive, defineComponent, ref, onMounted, nextTick } from 'vue';
export default defineComponent({
    name: 'noticeBar',
    props: {
        // 通知栏模式,可选值为 closeable link
        mode: {
            type: String,
            default: () => '',
        },
        // 通知文本内容
        text: {
            type: String,
            default: () => '',
        },
        // 通知文本颜色
        color: {
            type: String,
            default: () => 'var(--el-color-warning)',
        },
        // 通知背景色
        background: {
            type: String,
            default: () => 'var(--el-color-warning-light-9)',
        },
        // 字体大小,单位px
        size: {
            type: [Number, String],
            default: () => 14,
        },
        // 通知栏高度,单位px
        height: {
            type: Number,
            default: () => 40,
        },
        // 动画延迟时间 (s)
        delay: {
            type: Number,
            default: () => 1,
        },
        // 滚动速率 (px/s)
        speed: {
            type: Number,
            default: () => 100,
        },
        // 是否开启垂直滚动
        scrollable: {
            type: Boolean,
            default: () => false,
        },
        // 自定义左侧图标
        leftIcon: {
            type: String,
            default: () => '',
        },
        // 自定义右侧图标
        rightIcon: {
            type: String,
            default: () => '',
        },
    },
    setup(props, { emit }) {
        const noticeBarWarpRef = ref();
        const noticeBarTextRef = ref();
        const state = reactive({
            order: 1,
            oneTime: 0,
            twoTime: 0,
            warpOWidth: 0,
            textOWidth: 0,
            isMode: false,
        });
        // 初始化 animation 各项参数
        const initAnimation = () => {
            nextTick(() => {
                state.warpOWidth = noticeBarWarpRef.value.offsetWidth;
                state.textOWidth = noticeBarTextRef.value.offsetWidth;
                document.styleSheets[0].insertRule(`@keyframes oneAnimation {0% {left: 0px;} 100% {left: -${state.textOWidth}px;}}`);
                document.styleSheets[0].insertRule(`@keyframes twoAnimation {0% {left: ${state.warpOWidth}px;} 100% {left: -${state.textOWidth}px;}}`);
                computeAnimationTime();
                setTimeout(() => {
                    changeAnimation();
                }, props.delay * 1000);
            });
        };
        // 计算 animation 滚动时长
        const computeAnimationTime = () => {
            state.oneTime = state.textOWidth / props.speed;
            state.twoTime = (state.textOWidth + state.warpOWidth) / props.speed;
        };
        // 改变 animation 动画调用
        const changeAnimation = () => {
            if (state.order === 1) {
                noticeBarTextRef.value.style.cssText = `animation: oneAnimation ${state.oneTime}s linear; opactity: 1;}`;
                state.order = 2;
            } else {
                noticeBarTextRef.value.style.cssText = `animation: twoAnimation ${state.twoTime}s linear infinite; opacity: 1;`;
            }
        };
        // 监听 animation 动画的结束
        const listenerAnimationend = () => {
            noticeBarTextRef.value.addEventListener(
                'animationend',
                () => {
                    changeAnimation();
                },
                false
            );
        };
        // 右侧 icon 图标点击
        const onRightIconClick = () => {
            if (!props.mode) return false;
            if (props.mode === 'closeable') {
                state.isMode = true;
                emit('close');
            } else if (props.mode === 'link') {
                emit('link');
            }
        };
        // 页面加载时
        onMounted(() => {
            if (props.scrollable) return false;
            initAnimation();
            listenerAnimationend();
        });
        return {
            noticeBarWarpRef,
            noticeBarTextRef,
            onRightIconClick,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.notice-bar {
    padding: 0 15px;
    width: 100%;
    border-radius: 4px;
    .notice-bar-warp {
        display: flex;
        align-items: center;
        width: 100%;
        height: inherit;
        .notice-bar-warp-text-box {
            flex: 1;
            height: inherit;
            display: flex;
            align-items: center;
            overflow: hidden;
            position: relative;
            .notice-bar-warp-text {
                white-space: nowrap;
                position: absolute;
                left: 0;
            }
            .notice-bar-warp-slot {
                width: 100%;
                white-space: nowrap;
                ::v-deep(.el-carousel__item) {
                    display: flex;
                    align-items: center;
                }
            }
        }
        .notice-bar-warp-left-icon {
            width: 24px;
            font-size: inherit !important;
        }
        .notice-bar-warp-right-icon {
            width: 24px;
            text-align: right;
            font-size: inherit !important;
            &:hover {
                cursor: pointer;
            }
        }
    }
}
</style>
src/components/regionsDialog/index.vue
对比新文件
@@ -0,0 +1,129 @@
<template>
    <el-dialog v-model="dialogVisible" title="选择区域" width="900px" draggable :fullscreen="full">
    <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-row>
            <el-col :span="18">
        <el-form :inline="true" ref="ruleFormRef" :model="ruleForm" status-icon>
            <el-form-item>
                <el-input size="default" v-model="ruleForm.checkPass" placeholder="风险区域名称" style="max-width: 215px;" />
            </el-form-item>
            <el-form-item>
                <el-button size="default" type="primary" @click="submitForm(ruleFormRef)" style="margin-left: 12px;">查询</el-button>
                <el-button size="default" @click="resetForm(ruleFormRef)">重置</el-button>
            </el-form-item>
      <el-button size="default" :icon="Delete" style="margin-left: 12px;">清除选择</el-button>
        </el-form>
        <el-table :data="tableData" style="width: 100%;margin-top:20px;">
      <el-table-column type="selection" width="55" />
            <el-table-column align="center" prop="name" label="风险区域名称"/>
        </el-table>
        <el-pagination
            style="padding:20px 0;"
            v-model:currentPage="currentPage4"
            v-model:page-size="pageSize4"
            :page-sizes="[100, 200, 300, 400]"
            :small="small"
            :disabled="disabled"
            :background="background"
            layout="total, sizes, prev, pager, next, jumper"
            :total="400"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
        />
        </el-col>
        <el-col :span="6" style="padding-left: 15px;">
            <el-tag v-for="tag in dynamicTags" :key="tag" class="mx-1" style="margin:5px" closable :disable-transitions="false" @close="handleClose(tag)">
                    {{ tag }}
                </el-tag>
        </el-col>
        </el-row>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false" size="default">关闭</el-button>
                <el-button type="primary" @click="dialogVisible = false" size="default">确定</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts">
import {
  defineComponent,
  reactive,
  ref
} from 'vue';
import {
  Delete,
  FullScreen
} from '@element-plus/icons-vue';
export default defineComponent({
    setup() {
        const dialogVisible = ref<boolean>(false);
        const openDailog = () => {
            dialogVisible.value = true;
        };
        // 搜索条件
        const ruleForm = reactive({
            checkPass: '',
        });
        // 表格
        const tableData = [
            {
                name: '1#LNG储罐单元',
            },
            {
                name: 'LNG装车区',
            },
            {
                name: '丙烷储罐区',
            },
            {
                name: '4#LNG储罐单元',
            },
        ];
        const pageSize4 = ref(100);
        const handleSizeChange = (val: number) => {
            console.log(`${val} items per page`);
        };
        const handleCurrentChange = (val: number) => {
            console.log(`current page: ${val}`);
        };
        // 右方点击添加后显示标签
        const dynamicTags = ref(['应急救援组', '工艺抢险组', '后勤保障组']);
        const handleClose = (tag: string) => {
            dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
        };
    //全屏
    const full = ref(false);
    const toggleFullscreen = () => {
      if (full.value == false) {
        full.value = true;
      } else {
        full.value = false;
      }
    };
        return {
            dialogVisible,
            openDailog,
            ruleForm,
            tableData,
            pageSize4,
            handleSizeChange,
            handleCurrentChange,
            dynamicTags,
            handleClose,
            Delete,
      toggleFullscreen,
      FullScreen,
      full,
        };
    },
});
</script>
<style scoped>
.el-row {
    padding: 0 0 20px 0;
}
.el-form--inline .el-form-item{
  margin: 0;
}
</style>
src/components/svgIcon/index.vue
对比新文件
@@ -0,0 +1,73 @@
<template>
    <i v-if="isShowIconSvg" class="el-icon" :style="setIconSvgStyle">
        <component :is="getIconName" />
    </i>
    <div v-else-if="isShowIconImg" :style="setIconImgOutStyle">
        <img :src="getIconName" :style="setIconSvgInsStyle" />
    </div>
    <i v-else :class="getIconName" :style="setIconSvgStyle" />
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
export default defineComponent({
    name: 'svgIcon',
    props: {
        // svg 图标组件名字
        name: {
            type: String,
        },
        // svg 大小
        size: {
            type: Number,
            default: () => 14,
        },
        // svg 颜色
        color: {
            type: String,
        },
    },
    setup(props) {
        // 在线链接、本地引入地址前缀
        const linesString = ['https', 'http', '/src', '/assets', import.meta.env.VITE_PUBLIC_PATH];
        // 获取 icon 图标名称
        const getIconName = computed(() => {
            return props?.name;
        });
        // 用于判断 element plus 自带 svg 图标的显示、隐藏
        const isShowIconSvg = computed(() => {
            return props?.name?.startsWith('ele-');
        });
        // 用于判断在线链接、本地引入等图标显示、隐藏
        const isShowIconImg = computed(() => {
            return linesString.find((str) => props.name?.startsWith(str));
        });
        // 设置图标样式
        const setIconSvgStyle = computed(() => {
            return `font-size: ${props.size}px;color: ${props.color};`;
        });
        // 设置图片样式
        const setIconImgOutStyle = computed(() => {
            return `width: ${props.size}px;height: ${props.size}px;display: inline-block;overflow: hidden;`;
        });
        // 设置图片样式
        // https://gitee.com/lyt-top/vue-next-admin/issues/I59ND0
        const setIconSvgInsStyle = computed(() => {
            const filterStyle: string[] = [];
            const compatibles: string[] = ['-webkit', '-ms', '-o', '-moz'];
            compatibles.forEach((j) => filterStyle.push(`${j}-filter: drop-shadow(${props.color} 30px 0);`));
            return `width: ${props.size}px;height: ${props.size}px;position: relative;left: -${props.size}px;${filterStyle.join('')}`;
        });
        return {
            getIconName,
            isShowIconSvg,
            isShowIconImg,
            setIconSvgStyle,
            setIconImgOutStyle,
            setIconSvgInsStyle,
        };
    },
});
</script>
src/components/updata/updata.vue
对比新文件
@@ -0,0 +1,89 @@
<template>
    <el-dialog v-model="dialogVisible" title="导入Excel" width="50%" :fullscreen="full" draggable>
        <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
        <el-upload
            v-model:file-list="fileList"
            class="upload-demo"
            action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
            multiple
            :on-preview="handlePreview"
            :on-remove="handleRemove"
            :before-remove="beforeRemove"
            :limit="3"
            :on-exceed="handleExceed"
        >
            <el-button>下载模板</el-button>
            <el-button type="primary">点击上传</el-button>
            <template #tip>
                <div class="el-upload__tip">只允许导入“xls”或“xlsx”格式文件!</div>
            </template>
        </el-upload>
    </el-dialog>
</template>
<script lang="ts">
import { ref, toRefs, reactive, defineComponent, computed } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import type { UploadProps, UploadUserFile } from 'element-plus';
import { FullScreen } from '@element-plus/icons-vue';
export default defineComponent({
    setup() {
        let dialogVisible = ref<boolean>(false);
        const fileList = ref<UploadUserFile[]>([
            {
                name: 'element-plus-logo.svg',
                url: 'https://element-plus.org/images/element-plus-logo.svg',
            },
            {
                name: 'element-plus-logo2.svg',
                url: 'https://element-plus.org/images/element-plus-logo.svg',
            },
        ]);
        const handleRemove: UploadProps['onRemove'] = (file, uploadFiles) => {
            console.log(file, uploadFiles);
        };
        const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
            console.log(uploadFile);
        };
        const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
            ElMessage.warning(`The limit is 3, you selected ${files.length} files this time, add up to ${files.length + uploadFiles.length} totally`);
        };
        const beforeRemove: UploadProps['beforeRemove'] = (uploadFile, uploadFiles) => {
            return ElMessageBox.confirm(`Cancel the transfert of ${uploadFile.name} ?`).then(
                () => true,
                () => false
            );
        };
        // 打开弹窗
        const openDialog = (type: string, value: any, projectList: any, projectId: string) => {
            dialogVisible.value = true;
        };
        //全屏
        const full = ref(false);
        const toggleFullscreen = () => {
            if (full.value == false) {
                full.value = true;
            }else{
        full.value = false;
      }
        };
        return {
            dialogVisible,
            fileList,
            handleRemove,
            handlePreview,
            handleExceed,
            beforeRemove,
            openDialog,
      full,
      toggleFullscreen,
      FullScreen
        };
    },
});
</script>
<style scoped>
</style>
src/components/uploaderFile/index.vue
对比新文件
@@ -0,0 +1,183 @@
<template>
    <el-upload
        v-model:file-list="fileList"
        multiple
        :disabled="disabled"
        class="upload-demo"
        :http-request="uploadSectionFile"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :on-success="successFile"
        :on-error="errorFile"
    >
        <el-button type="primary">点击上传</el-button>
        <template #tip>
            <div class="el-upload__tip">
                请上传文件
                <!--jpg/png files with a size less than 500KB.-->
            </div>
            <slot name="file">
            </slot>
        </template>
    </el-upload>
    <!--<el-dialog v-model="dialogVisible">-->
        <!--<img w-full :src="dialogImageUrl" alt="Preview Image" />-->
    <!--</el-dialog>-->
</template>
<script lang="ts">
import axios from 'axios';
import { ref, defineComponent,onMounted,watch } from 'vue';
import { Plus } from '@element-plus/icons-vue';
import type { UploadProps, UploadUserFile } from 'element-plus';
import { ElMessage } from 'element-plus';
import { goalManagementApi } from '/@/api/goalManagement';
export default defineComponent({
    props: {
        fileList: {
            type: Array,
        },
        disabled: {
            type: Boolean,
            default: () => false,
        },
        systemName: {
            type: String,
            default: () => '',
        },
    },
    components: {
        Plus,
    },
    setup(props, { emit }) {
        const dialogImageUrl = ref('');
        const dialogVisible = ref(false);
        const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
            console.log(uploadFile, uploadFiles);
            emit('deleteFile',uploadFiles);
        };
        const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
            console.log(uploadFile)
            goalManagementApi()
                    .searchFile(uploadFile.name)
                    .then((res) => {
                        window.open(res.data, "_blank");
                    })
            dialogImageUrl.value = uploadFile.url!;
            // dialogVisible.value = true;
        };
        const successFile = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
            console.log(response, uploadFile, uploadFiles);
        };
        const errorFile = (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
            console.log(error, uploadFile, uploadFiles);
        };
        watch(props.fileList, (val) => {
            viewList.value = val
            // searchFile()
        });
        onMounted(() => {
            if(props.fileList){
                viewList.value = props.fileList
                // searchFile()
            }else {
                viewList.value = []
            }
        });
        const newFileList = ref([])
        const viewList = ref([])
        const searchFile = async () => {
            for(var a = 0;a<props.fileList.length;a++){
                await goalManagementApi()
                        .searchFile(props.fileList[a].fileName)
                        .then((res) => {
                            props.fileList[a].url = res.data
                        })
            }
        };
        const uploadSectionFile = (param) => {
            let form = new FormData();
            form.append('file', param.file);
            //组装文件名(传入后缀名)
            console.log(param)
            var fileNameList = param.file.name.split('.')
            var typeFile = param.file.name.split('.')[fileNameList.length-1]
            var fileName1 = getFileName(param.file.type.split('/')[1], 1);
            // var fileName2 = getFileName(param.file.type.split('/')[1], 2);
            var fileName2 = '.'+typeFile;
            goalManagementApi()
                .beforeUploadFile(fileName1, fileName2)
                .then((res) => {
                    // 转换形式
                    const reader = new FileReader();
                    reader.readAsArrayBuffer(param.file);
                    // 上传图片
                    reader.onload = () => { // 上传图片接口 url:上传图片地址 修改请求头
                        axios.put(res.data.uploadUrl, reader.result,
                            {
                                header:
                                    { "Content-Type": "multipart/form-data" }
                            }
                        )
                        .then(res1 =>
                        {
                            props.fileList[props.fileList.length-1].fileName=res.data.fileName
                            props.fileList[props.fileList.length-1].name=res.data.fileName
                            props.fileList[props.fileList.length-1].fileUrl=''
                            emit('successUploader',props.fileList);
                            ElMessage({
                                showClose: true,
                                message: '上传成功',
                                type: 'success',
                            });
                        })
                    };
                });
        };
        const getFileName = (suffix, type) => {
            var projectName = props.systemName;
            var date = getNowDate();
            var fileName1 = projectName + '/' + date + '_';
            var fileName2 = '.' + suffix;
            if (type == 1) {
                return fileName1;
            } else if (type == 2) {
                return fileName2;
            }
            return '';
        };
        //获取当前年月日
        const getNowDate = () => {
            var a = new Date().getTime(); //获取到当前时间戳
            var now = new Date(a); //创建一个指定的日期对象
            var year = now.getFullYear(); //年份
            var month = now.getMonth() + 1; //月份(0-11)
            var date = now.getDate(); //天数(1到31)
            return year + '-' + month + '-' + date;
        };
        return {
            dialogImageUrl,
            dialogVisible,
            handleRemove,
            handlePictureCardPreview,
            successFile,
            errorFile,
            uploadSectionFile,
            viewList
        };
    },
});
</script>
<style scoped>
    .upload-demo{
        width: 100%;
    }
</style>
src/components/uploaderImg/index.vue
对比新文件
@@ -0,0 +1,158 @@
<template>
    <el-upload
        v-model:file-list="fileList"
        :disabled="disabled"
        :http-request="uploadSectionFile"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :on-success="successFile"
        :on-error="errorFile"
    >
        <el-icon><Plus /></el-icon>
    </el-upload>
    <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
</template>
<script lang="ts">
import axios from 'axios';
import { ref, defineComponent,onMounted,watch } from 'vue';
import { Plus } from '@element-plus/icons-vue';
import type { UploadProps, UploadUserFile } from 'element-plus';
import { ElMessage } from 'element-plus';
import { goalManagementApi } from '/@/api/goalManagement';
export default defineComponent({
    props: {
        // svg 图标组件名字
        fileList: {
            type: Array,
        },
        disabled: {
            type: Boolean,
            default: () => false,
        },
        systemName: {
            type: String,
            default: () => '',
        },
    },
    components: {
        Plus,
    },
    setup(props, { emit }) {
        const dialogImageUrl = ref('');
        const dialogVisible = ref(false);
        const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
            console.log(uploadFile, uploadFiles);
        };
        const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
            alert(1)
            dialogImageUrl.value = uploadFile.url;
            dialogVisible.value = true;
        };
        const successFile = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
            console.log(response, uploadFile, uploadFiles);
        };
        const errorFile = (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
            console.log(error, uploadFile, uploadFiles);
        };
        watch(props.fileList, (val) => {
            viewList.value = val
            // searchFile()
        });
        onMounted(() => {
            if(props.fileList){
                viewList.value = props.fileList
                // searchFile()
            }else {
                viewList.value = []
            }
        });
        const newFileList = ref([])
        const viewList = ref([])
        const searchFile = async () => {
            for(var a = 0;a<props.fileList.length;a++){
                await goalManagementApi()
                        .searchFile(props.fileList[a].fileName)
                        .then((res) => {
                            props.fileList[a].url = res.data
                        })
            }
        };
        const uploadSectionFile = (param) => {
            let form = new FormData();
            form.append('file', param.file);
            //组装文件名(传入后缀名)
            var fileName1 = getFileName(param.file.type.split('/')[1], 1);
            var fileName2 = getFileName(param.file.type.split('/')[1], 2);
            goalManagementApi()
                .beforeUploadFile(fileName1, fileName2)
                .then((res) => {
                    // 转换形式
                    const reader = new FileReader();
                    reader.readAsArrayBuffer(param.file);
                    // 上传图片
                    reader.onload = () => { // 上传图片接口 url:上传图片地址 修改请求头
                        axios.put(res.data.uploadUrl, reader.result,
                            {
                                header:
                                    { "Content-Type": "multipart/form-data" }
                            }
                        )
                        .then(res1 =>
                        {
                            props.fileList[props.fileList.length-1].fileName=res.data.fileName
                            props.fileList[props.fileList.length-1].fileUrl=''
                            emit('successUploader',props.fileList);
                            ElMessage({
                                showClose: true,
                                message: '上传成功',
                                type: 'success',
                            });
                        })
                    };
                });
        };
        const getFileName = (suffix, type) => {
            var projectName = props.systemName;
            var date = getNowDate();
            var fileName1 = projectName + '/' + date + '_';
            var fileName2 = '.' + suffix;
            if (type == 1) {
                return fileName1;
            } else if (type == 2) {
                return fileName2;
            }
            return '';
        };
        //获取当前年月日
        const getNowDate = () => {
            var a = new Date().getTime(); //获取到当前时间戳
            var now = new Date(a); //创建一个指定的日期对象
            var year = now.getFullYear(); //年份
            var month = now.getMonth() + 1; //月份(0-11)
            var date = now.getDate(); //天数(1到31)
            return year + '-' + month + '-' + date;
        };
        return {
            dialogImageUrl,
            dialogVisible,
            handleRemove,
            handlePictureCardPreview,
            successFile,
            errorFile,
            uploadSectionFile,
            viewList
        };
    },
});
</script>
src/components/userCheckbox/index.vue
对比新文件
@@ -0,0 +1,422 @@
<template>
  <div class="system-edit-user-container">
    <el-dialog
        title="用户选择"
        v-model="isShowDialog"
        width="1000px"
        draggable
        :fullscreen="full"
    >
      <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
      <el-container class="layout-container-demo" style="height: 500px;overflow: auto;min-width: 960px">
        <el-aside width="200px">
          <el-input v-model="filterText" placeholder="请输入组织机构过滤" />
          <el-tree
              ref="treeRef"
              class="filter-tree"
              :data="data"
              :props="defaultProps"
              default-expand-all
              @node-click="handleNodeClick"
              :filter-node-method="filterNode"
          />
        </el-aside>
        <el-container style="margin: 0 15px;min-width:560px;">
          <el-header style="font-size: 12px">
            <el-form :inline="true" :model="ruleForm" class="demo-form-inline">
              <el-form-item>
                <el-input size="default" v-model="ruleForm.name" placeholder="登录名"> </el-input>
              </el-form-item>
              <el-form-item>
                <el-button size="default" type="primary" class="ml10" @click="onSubmit">
                  查询
                </el-button>
                <el-button size="default" class="ml10" @click="submitReset">
                  重置
                </el-button>
              </el-form-item>
            </el-form>
          </el-header>
          <el-main style="position: relative;">
            <el-table
                :data="tableData"
                :header-cell-style="{background:'#f6f7fa',color:'#909399',fontWeight:400}"
                @cell-click="checkbox"
            >
              <el-table-column type="selection"  width="55">
                <template #default="scope">
                  <el-checkbox-group v-model="checkbox1">
                    <el-checkbox :label="scope.row.uid" size="large">{{ null }}</el-checkbox>
                  </el-checkbox-group>
                </template>
              </el-table-column>
              <el-table-column prop="realName" label="登录名" width="100" show-overflow-tooltip sortable />
              <el-table-column prop="username" label="用户名" width="100" show-overflow-tooltip sortable />
              <el-table-column prop="address" label="所属机构" width="115"  show-overflow-tooltip sortable />
              <el-table-column prop="address" label="所属部门" width="115" show-overflow-tooltip sortable/>
              <el-table-column align="center" prop="type" label="状态" />
<!--              <el-table-column  label="状态"-->
<!--                                width="80"-->
<!--                                prop="tag"-->
<!--                                :filters="[-->
<!--                     { text: '正常', value: 'Home' },-->
<!--                     { text: '不正常', value: 'Office' },-->
<!--                   ]"-->
<!--                                :filter-method="filterTag"-->
<!--                                filter-placement="bottom-end">-->
<!--                <template #default="scope">-->
<!--                  <el-tag-->
<!--                      :type="scope.row.tag === 'Home' ? '' : 'success'"-->
<!--                      disable-transitions-->
<!--                  >{{ scope.row.tag }}</el-tag-->
<!--                  >-->
<!--                </template>-->
<!--              </el-table-column>-->
            </el-table>
            <div class="pages">
              <el-pagination
                  v-model:currentPage="pageIndex"
                  v-model:page-size="pageSize"
                  :page-sizes="[10, 20, 30]"
                  :pager-count="5"
                  layout="total, sizes, prev, pager, next, jumper"
                  :total="total"
                  @size-change="handleSizeChange"
                  @current-change="handleCurrentChange"
              />
            </div>
          </el-main>
        </el-container>
        <div style="width: 200px;">
          <div v-if="dynamicTags[0]==''?false:true">
            <el-tag
                v-for="tag in dynamicTags"
                :key="tag"
                class="mx-1"
                style="margin: 5px"
                closable
                :disable-transitions="false"
                @close="handleClose(tag)"
            >
              {{ tag.realName }}
            </el-tag>
          </div>
        </div>
      </el-container>
      <template #footer>
                <span class="dialog-footer">
                    <el-button size="default" type="primary"  @click="onCancel">确定</el-button>
          <el-button size="default" @click="onCancel">关闭</el-button>
                </span>
      </template>
    </el-dialog>
  </div>
</template>
<script lang="ts">
import {
  ref,
  defineComponent,
  watch,
  reactive,
  onMounted,
} from 'vue';
import type {
  ElTree,
  // ElTable,
} from 'element-plus'
import {
  ElMessage,
} from 'element-plus';
import {
  FullScreen
} from '@element-plus/icons-vue'
import {goalManagementApi} from "/@/api/goalManagement";
interface Tree {
  id: number
  label: string
  children?: Tree[]
}
// interface User {
//   date: string
//   name: string
//   address: string
// }
export default defineComponent({
  name: 'userSelections',
  components: {
    // Search,
  },
  setup(props, { emit }) {
    const isShowDialog = ref(false)
    // 打开弹窗
    const openDialog = (type:any) => {
      types.value=type
      isShowDialog.value = true;
    };
    // 关闭弹窗
    const closeDialog = () => {
      isShowDialog.value = false;
    };
    // 取消
    const onCancel = () => {
      closeDialog();
    };
    //部门树
    const department = () => {
      goalManagementApi()
          .getTreedepartment()
          .then((res) => {
            if (res.data.code == 200) {
              data.value = res.data.data;
            } else {
              ElMessage.error(res.data.msg);
            }
          });
    };
    const defaultProps = {
      label: 'depName',
      children: 'children',
      value: 'depId',
    }
    //部门树查询
    const filterText = ref('')
    const treeRef = ref<InstanceType<typeof ElTree>>()  //实例化
    watch(filterText, (val) => {
      treeRef.value!.filter(val);
    });
    // 节点过滤模糊搜索
    const filterNode = (depName: string, data: Tree) => {
      if (!depName) return true
      return data.depName.includes(depName)
    }
    onMounted(() => {
      department();
    });
    //左边树形部分点击获取回调
    const names = ref<any>();
    const handleNodeClick = (data: Tree) => {
      goalManagementApi()
          .getManName(data.depId)
          .then((res) => {
            if (res.data.code == 200) {
              tableData.value=res.data.data
            }else{
              ElMessage.error(res.data.msg);
            }
          });
    };
    // 监听搜索关键字改变
    watch(filterText, (val) => {
      treeRef.value!.filter(val)
    })
    // 树形结构内容
    const data = ref()
    // const item = {
    //   date: '孙刚',
    //   name: '龚赛健',
    //   address: '综合办公室',
    //   tag: '正常',
    // }
    // const tableData = ref(Array.from({ length: 7 }).fill(item))
    // 定义表单搜索
    const ruleForm = reactive({
      name: '',
    })
    const types=ref()
    // 搜索按钮
    const onSubmit = () => {
      let obj = JSON.parse(JSON.stringify(dynamicTags.value));
      emit('SearchUser', obj[0],types.value);
      isShowDialog.value = false;
    }
    // const multipleTableRef = ref<InstanceType<typeof ElTable>>()
    // 右方点击添加后显示标签
    const dynamicTags = ref(['']);
    const handleClose = () => {
      dynamicTags.value.push(checkbox1.value)
      // dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
      checkbox1.value = '';
    };
    const checkbox1 = ref('');
    const checkbox = (event: any) => {
      dynamicTags.value[0] = event;
    };
    const tableData = ref();
    // 分页
    const pageIndex = ref(4);
    const pageSize = ref(10);
    // 分页改变
    const handleSizeChange = (val: number) => {
      console.log(`${val} items per page`);
    };
    // 分页未改变
    const handleCurrentChange = (val: number) => {
      console.log(`current page: ${val}`);
    };
    //全屏
    const full = ref(false);
    const toggleFullscreen = () => {
      if (full.value == false) {
        full.value = true;
      } else {
        full.value = false;
      }
    };
    return {
      openDialog,
      closeDialog,
      isShowDialog,
      onCancel,
      defaultProps,
      filterNode,
      data,
      tableData,
      ruleForm,
      onSubmit,
      // multipleTableRef,
      handleClose,
      dynamicTags,
      handleSizeChange,
      handleCurrentChange,
      pageIndex,
      pageSize,
      toggleFullscreen,
      FullScreen,
      full,
      names,
      handleNodeClick,
      types,
      checkbox1,
      checkbox,
    };
  },
});
</script>
<style scoped lang="scss">
.layout-container-demo .el-header {
  position: relative;
  color: var(--el-text-color-primary);
  line-height: 32px;
  --el-header-height: 45px;
  padding: 0;
}
.layout-container-demo .el-aside {
  padding: 10px;
  border: 1px solid #ebeef5;
  color: var(--el-text-color-primary);
}
::v-deep .el-input--large .el-input__inner {
  height: 32px!important;
  line-height: 32px!important;
}
.layout-container-demo .el-menu {
  border-right: none;
}
.layout-container-demo .el-main {
  padding: 0;
}
.layout-container-demo .toolbar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  right: 20px;
}
.el-input--large{
  //width: 178px;
  height: 32px;
}
.el-tree{
  overflow: auto;
}
::-webkit-scrollbar {
  height: 1px;
}
::-webkit-scrollbar-thumb {
  background-color: transparent;
}
// 鼠标悬浮样式
:hover::-webkit-scrollbar-thumb {
  border-radius: 15px;
  background-color: #d8d9db;
}
::v-deep .el-input__wrapper{
  width: 215px;
}
::v-deep .el-form-item{
  margin-bottom: 0;
  margin-right: 0;
}
//弹窗底部边框线
::v-deep .el-dialog__footer{
  border-top: 1px solid #e8e8e8;
  border-radius: 0 0 4px 4px;
}
//弹窗顶部边框线
::v-deep .el-dialog__header {
  border-bottom: 1px solid #e8e8e8;
  margin-right: 0;
  border-radius: 4px 4px 0 0;
}
//单选框圆形
//::v-deep .el-table__header .el-table-column--selection .cell .el-checkbox {
//  display:none
//}
//::v-deep .el-table-column--selection .cell{
//  text-align: center;
//}
//::v-deep .el-checkbox__input .el-checkbox__inner{
//  border-radius: 50%;
//}
/*分页*/
.pages{
  display: flex;
  justify-content: flex-end;
  margin-top: 15px;
  align-items: center;
  //position: absolute;
  //bottom: 0;
}
::v-deep .el-pagination{
  width: 100%;
}
::v-deep .el-pagination .el-pager li {
  margin: 0 5px;
  background-color: #f4f4f5;
  color: #606266;
  min-width: 30px;
  border-radius: 2px;
}
::v-deep .el-pagination .el-pager li.is-active {
  background-color: #409eff;
  color: #fff;
}
::v-deep .el-pagination .btn-prev {
  margin: 0 5px;
  background-color: #f4f4f5;
  color: #606266;
  min-width: 30px;
  border-radius: 2px;
}
::v-deep .el-pagination button:disabled{
  color: #c0c4cc;
}
::v-deep .el-pagination .btn-next{
  margin: 0 5px;
  background-color: #f4f4f5;
  color: #606266;
  min-width: 30px;
  border-radius: 2px;
}
</style>
src/components/userSelections/index.vue
对比新文件
@@ -0,0 +1,446 @@
<template>
  <div class="system-edit-user-container">
    <el-dialog
        title="用户选择"
        v-model="isShowDialog"
        width="1000px"
        draggable
        :fullscreen="full"
    >
      <el-button @click="toggleFullscreen" size="small" class="pot" :icon="FullScreen"></el-button>
      <el-container class="layout-container-demo" style="height: 500px;overflow: auto;min-width: 960px">
        <el-aside width="200px">
          <el-input v-model="filterText" placeholder="请输入组织机构过滤" />
          <el-tree
            ref="treeRef"
            class="filter-tree"
            :data="data"
            :props="defaultProps"
            default-expand-all
            :filter-node-method="filterNode"
          />
        </el-aside>
        <el-container style="margin: 0 15px;min-width:560px;">
          <el-header style="font-size: 12px">
            <el-form :inline="true" :model="formInline" class="demo-form-inline">
              <el-form-item>
                <el-input size="default" v-model="formInline.name" placeholder="登录名"> </el-input>
              </el-form-item>
              <el-form-item>
                <el-button size="default" type="primary" class="ml10" @click="onSubmit">
                  查询
                </el-button>
                <el-button size="default" class="ml10" @click="submitReset">
                  重置
                </el-button>
              </el-form-item>
            </el-form>
          </el-header>
          <el-main style="position: relative;">
              <el-table
                  :data="tableData"
                  :header-cell-style="{background:'#f6f7fa',color:'#909399',fontWeight:400}"
                  @cell-click="radio"
              >
                <el-table-column align="center" width="55">
                  <template #default="scope">
                    <el-radio-group v-model="radio1">
                      <el-radio :label="scope.row.id" size="large">{{ null }}</el-radio>
                    </el-radio-group>
                  </template>
                </el-table-column>
                <el-table-column prop="date" label="登录名" width="100" show-overflow-tooltip sortable />
                <el-table-column prop="name" label="用户名" width="100" show-overflow-tooltip sortable />
                <el-table-column prop="address" label="所属机构" width="115"  show-overflow-tooltip sortable />
                <el-table-column prop="department" label="所属部门" width="115" show-overflow-tooltip sortable/>
                <el-table-column  label="状态"
                                  width="80"
                  prop="tag"
                  :filters="[
                     { text: '正常', value: 'Home' },
                     { text: '不正常', value: 'Office' },
                   ]"
                        :filter-method="filterTag"
                        filter-placement="bottom-end">
                  <template #default="scope">
                    <el-tag
                        :type="scope.row.tag === 'Home' ? '' : 'success'"
                        disable-transitions
                    >{{ scope.row.tag }}</el-tag
                    >
                  </template>
                </el-table-column>
              </el-table>
            <div class="pages">
              <el-pagination
                  v-model:currentPage="pageIndex"
                  v-model:page-size="pageSize"
                  :page-sizes="[10, 20, 30]"
                  :pager-count="5"
                  :small="small"
                  :disabled="disabled"
                  :background="background"
                  layout="total, sizes, prev, pager, next, jumper"
                  :total="40"
                  @size-change="handleSizeChange"
                  @current-change="handleCurrentChange"
              />
            </div>
          </el-main>
        </el-container>
        <div style="width: 200px;">
          <el-tag
              v-for="tag in dynamicTags"
              :key="tag"
              class="mx-1"
              style="margin: 5px"
              closable
              :disable-transitions="false"
              @close="handleClose(tag)"
          >
            {{ tag }}
          </el-tag>
        </div>
      </el-container>
      <template #footer>
                <span class="dialog-footer">
                    <el-button size="default" type="primary"  @click="onCancel">确定</el-button>
          <el-button size="default" @click="onCancel">关闭</el-button>
                </span>
      </template>
    </el-dialog>
  </div>
</template>
<script lang="ts">
import {
  ref,
  defineComponent,
  watch,
  reactive,
} from 'vue';
import type {
  ElTree,
  // ElTable,
} from 'element-plus'
import {
  FullScreen
} from '@element-plus/icons-vue'
interface Tree {
  id: number
  label: string
  children?: Tree[]
}
// interface User {
//   date: string
//   name: string
//   address: string
// }
export default defineComponent({
  name: 'userSelections',
  components: {
    // Search,
  },
  setup(props,{emit}) {
    const isShowDialog = ref(false)
    // 打开弹窗
    const openDialog = () => {
      isShowDialog.value = true;
    };
    // 关闭弹窗
    const closeDialog = () => {
      isShowDialog.value = false;
    };
    // 取消
    const onCancel = () => {
      let obj=JSON.parse(JSON.stringify(dynamicTags.value))
      emit("SearchUser",obj[0])
      closeDialog();
    };
    const filterText = ref('')
    const treeRef = ref<InstanceType<typeof ElTree>>()  //实例化
    const defaultProps = {
      children: 'children',
      label: 'label',
    }
    // 监听搜索关键字改变
    watch(filterText, (val) => {
      treeRef.value!.filter(val)
    })
    // 节点过滤模糊搜索
    const filterNode = (value: string, data: Tree) => {
      if (!value) return true
      return data.label.includes(value)
    }
    // 树形结构内容
    const data: Tree[] = [
      {
        id: 1,
        label: '广汇能源综合物流发展有限责任公司',
        children: [
          {
            id: 4,
            label: '经营班子',
            children: []
          },
        ],
      },
      {
        id: 2,
        label: '生产运行部',
        children: [
          {
            id: 5,
            label: '工艺二班',
          },
          {
            id: 6,
            label: '灌装一班',
          },
        ],
      },
      {
        id: 3,
        label: '设备部',
        children: [
          {
            id: 7,
            label: '仪表班',
          },
          {
            id: 8,
            label: '机修班',
          },
        ],
      },
    ]
    // const item = {
    //   date: '孙刚',
    //   name: '龚赛健',
    //   address: '综合办公室',
    //   tag: '正常',
    // }
    // const tableData = ref(Array.from({ length: 7 }).fill(item))
    const tableData = [
      {
        date: '孙刚',
        name: '孙刚',
        address: '',
        department: '经营班子',
        tag: '正常',
      },
      {
        date: '谭柏',
        name: '谭柏',
        address: '',
        department: '经营班子',
        tag: '正常',
      },
      {
        date: '倪威',
        name: '倪威',
        address: '',
        department: '经营班子',
        tag: '正常',
      },
      {
        date: '倪玲婕',
        name: '倪玲婕',
        address: '',
        department: '经营班子',
        tag: '正常',
      },
    ];
    // 定义表单搜索
    const formInline = reactive({
      name: '',
    })
    // 搜索按钮
    const onSubmit = () => {
      console.log('submit!')
    }
    // const multipleTableRef = ref<InstanceType<typeof ElTable>>()
    // 右方点击添加后显示标签
    const dynamicTags = ref(['胡海涛']);
    const handleClose = (tag: string) => {
      dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
      radio1.value=""
    };
    const radio1=ref('')
    const radio=(event:any)=>{
      dynamicTags.value[0]=event
    }
    // 分页
    const pageIndex = ref(4);
    const pageSize = ref(10);
    // 分页改变
    const handleSizeChange = (val: number) => {
      console.log(`${val} items per page`);
    };
    // 分页未改变
    const handleCurrentChange = (val: number) => {
      console.log(`current page: ${val}`);
    };
    //全屏
    const full = ref(false);
    const toggleFullscreen = () => {
      if (full.value == false) {
        full.value = true;
      } else {
        full.value = false;
      }
    };
    return {
      openDialog,
      closeDialog,
      isShowDialog,
      onCancel,
      defaultProps,
      filterNode,
      data,
      tableData,
      formInline,
      onSubmit,
      // multipleTableRef,
      handleClose,
      dynamicTags,
      handleSizeChange,
      handleCurrentChange,
      pageIndex,
      pageSize,
      radio1,
      radio,
      toggleFullscreen,
      FullScreen,
      full,
    };
  },
});
</script>
<style scoped lang="scss">
.layout-container-demo .el-header {
  position: relative;
  color: var(--el-text-color-primary);
  line-height: 32px;
  --el-header-height: 45px;
  padding: 0;
}
.layout-container-demo .el-aside {
  padding: 10px;
  border: 1px solid #ebeef5;
  color: var(--el-text-color-primary);
}
::v-deep .el-input--large .el-input__inner {
  height: 32px!important;
  line-height: 32px!important;
}
.layout-container-demo .el-menu {
  border-right: none;
}
.layout-container-demo .el-main {
  padding: 0;
}
.layout-container-demo .toolbar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  right: 20px;
}
.el-input--large{
  //width: 178px;
  height: 32px;
}
.el-tree{
  overflow: auto;
}
::-webkit-scrollbar {
  height: 1px;
}
::-webkit-scrollbar-thumb {
  background-color: transparent;
}
// 鼠标悬浮样式
:hover::-webkit-scrollbar-thumb {
  border-radius: 15px;
  background-color: #d8d9db;
}
::v-deep .el-input__wrapper{
  width: 215px;
}
::v-deep .el-form-item{
  margin-bottom: 0;
  margin-right: 0;
}
//弹窗底部边框线
::v-deep .el-dialog__footer{
  border-top: 1px solid #e8e8e8;
  border-radius: 0 0 4px 4px;
}
//弹窗顶部边框线
::v-deep .el-dialog__header {
  border-bottom: 1px solid #e8e8e8;
  margin-right: 0;
  border-radius: 4px 4px 0 0;
}
//单选框圆形
::v-deep .el-table__header .el-table-column--selection .cell .el-checkbox {
  display:none
}
::v-deep .el-table-column--selection .cell{
  text-align: center;
}
::v-deep .el-checkbox__input .el-checkbox__inner{
  border-radius: 50%;
}
/*分页*/
.pages{
  display: flex;
  justify-content: flex-end;
  margin-top: 15px;
  align-items: center;
  //position: absolute;
  //bottom: 0;
}
::v-deep .el-pagination{
  width: 100%;
}
::v-deep .el-pagination .el-pager li {
  margin: 0 5px;
  background-color: #f4f4f5;
  color: #606266;
  min-width: 30px;
  border-radius: 2px;
}
::v-deep .el-pagination .el-pager li.is-active {
  background-color: #409eff;
  color: #fff;
}
::v-deep .el-pagination .btn-prev {
  margin: 0 5px;
  background-color: #f4f4f5;
  color: #606266;
  min-width: 30px;
  border-radius: 2px;
}
::v-deep .el-pagination button:disabled{
  color: #c0c4cc;
}
::v-deep .el-pagination .btn-next{
  margin: 0 5px;
  background-color: #f4f4f5;
  color: #606266;
  min-width: 30px;
  border-radius: 2px;
}
</style>
src/i18n/index.ts
对比新文件
@@ -0,0 +1,67 @@
import { createI18n } from 'vue-i18n';
import pinia from '/@/stores/index';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import zhcnLocale from 'element-plus/lib/locale/lang/zh-cn';
import enLocale from 'element-plus/lib/locale/lang/en';
import zhtwLocale from 'element-plus/lib/locale/lang/zh-tw';
import nextZhcn from '/@/i18n/lang/zh-cn';
import nextEn from '/@/i18n/lang/en';
import nextZhtw from '/@/i18n/lang/zh-tw';
import pagesLoginZhcn from '/@/i18n/pages/login/zh-cn';
import pagesLoginEn from '/@/i18n/pages/login/en';
import pagesLoginZhtw from '/@/i18n/pages/login/zh-tw';
import pagesFormI18nZhcn from '/@/i18n/pages/formI18n/zh-cn';
import pagesFormI18nEn from '/@/i18n/pages/formI18n/en';
import pagesFormI18nZhtw from '/@/i18n/pages/formI18n/zh-tw';
// 定义语言国际化内容
/**
 * 说明:
 * /src/i18n/lang 下的 ts 为框架的国际化内容
 * /src/i18n/pages 下的 ts 为各界面的国际化内容
 */
const messages = {
    [zhcnLocale.name]: {
        ...zhcnLocale,
        message: {
            ...nextZhcn,
            ...pagesLoginZhcn,
            ...pagesFormI18nZhcn,
        },
    },
    [enLocale.name]: {
        ...enLocale,
        message: {
            ...nextEn,
            ...pagesLoginEn,
            ...pagesFormI18nEn,
        },
    },
    [zhtwLocale.name]: {
        ...zhtwLocale,
        message: {
            ...nextZhtw,
            ...pagesLoginZhtw,
            ...pagesFormI18nZhtw,
        },
    },
};
// 读取 pinia 默认语言
const stores = useThemeConfig(pinia);
const { themeConfig } = storeToRefs(stores);
// 导出语言国际化
// https://vue-i18n.intlify.dev/guide/essentials/fallback.html#explicit-fallback-with-one-locale
export const i18n = createI18n({
    silentTranslationWarn: true,
    missingWarn: false,
    silentFallbackWarn: true,
    fallbackWarn: false,
    locale: themeConfig.value.globalI18n,
    fallbackLocale: zhcnLocale.name,
    messages,
});
src/i18n/lang/en.ts
对比新文件
@@ -0,0 +1,180 @@
// 定义内容
export default {
    router: {
        home: 'home',
        system: 'system',
        systemMenu: 'systemMenu',
        systemRole: 'systemRole',
        systemUser: 'systemUser',
        systemDept: 'systemDept',
        systemDic: 'systemDic',
        limits: 'limits',
        limitsFrontEnd: 'FrontEnd',
        limitsFrontEndPage: 'FrontEndPage',
        limitsFrontEndBtn: 'FrontEndBtn',
        limitsBackEnd: 'BackEnd',
        limitsBackEndEndPage: 'BackEndEndPage',
        menu: 'menu',
        menu1: 'menu1',
        menu11: 'menu11',
        menu12: 'menu12',
        menu121: 'menu121',
        menu122: 'menu122',
        menu13: 'menu13',
        menu2: 'menu2',
        funIndex: 'function',
        funTagsView: 'funTagsView',
        funCountup: 'countup',
        funWangEditor: 'wangEditor',
        funCropper: 'cropper',
        funQrcode: 'qrcode',
        funEchartsMap: 'EchartsMap',
        funPrintJs: 'PrintJs',
        funClipboard: 'Copy cut',
        funGridLayout: 'Drag layout',
        funSplitpanes: 'Pane splitter',
        funDragVerify: 'Validator',
        pagesIndex: 'pages',
        pagesFiltering: 'Filtering',
        pagesFilteringDetails: 'FilteringDetails',
        pagesFilteringDetails1: 'FilteringDetails1',
        pagesIocnfont: 'iconfont icon',
        pagesElement: 'element icon',
        pagesAwesome: 'awesome icon',
        pagesFormAdapt: 'FormAdapt',
        pagesTableRules: 'pagesTableRules',
        pagesFormI18n: 'FormI18n',
        pagesFormRules: 'Multi form validation',
        pagesDynamicForm: 'Dynamic complex form',
        pagesWorkflow: 'Workflow',
        pagesListAdapt: 'ListAdapt',
        pagesWaterfall: 'Waterfall',
        pagesSteps: 'Steps',
        pagesPreview: 'Large preview',
        pagesWaves: 'Wave effect',
        pagesTree: 'tree alter table',
        pagesDrag: 'Drag command',
        pagesLazyImg: 'Image lazy loading',
        makeIndex: 'makeIndex',
        makeSelector: 'Icon selector',
        makeNoticeBar: 'notification bar',
        makeSvgDemo: 'Svgicon demo',
        paramsIndex: 'Routing parameters',
        paramsCommon: 'General routing',
        paramsDynamic: 'Dynamic routing',
        paramsCommonDetails: 'General routing details',
        paramsDynamicDetails: 'Dynamic routing details',
        chartIndex: 'chartIndex',
        visualizingIndex: 'visualizingIndex',
        visualizingLinkDemo1: 'visualizingLinkDemo1',
        visualizingLinkDemo2: 'visualizingLinkDemo2',
        personal: 'personal',
        tools: 'tools',
        layoutLinkView: 'LinkView',
        layoutIfameView: 'IfameView',
    },
    staticRoutes: {
        signIn: 'signIn',
        notFound: 'notFound',
        noPower: 'noPower',
    },
    user: {
        title0: 'Component size',
        title1: 'Language switching',
        title2: 'Menu search',
        title3: 'Layout configuration',
        title4: 'news',
        title5: 'Full screen on',
        title6: 'Full screen off',
        dropdownLarge: 'large',
        dropdownDefault: 'default',
        dropdownSmall: 'small',
        dropdown1: 'home page',
        dropdown2: 'Personal Center',
        dropdown3: '404',
        dropdown4: '401',
        dropdown5: 'Log out',
        dropdown6: 'Code warehouse',
        searchPlaceholder: 'Menu search: support Chinese, routing path',
        newTitle: 'notice',
        newBtn: 'All read',
        newGo: 'Go to the notification center',
        newDesc: 'No notice',
        logOutTitle: 'Tips',
        logOutMessage: 'This operation will log out. Do you want to continue?',
        logOutConfirm: 'determine',
        logOutCancel: 'cancel',
        logOutExit: 'Exiting',
    },
    tagsView: {
        refresh: 'refresh',
        close: 'close',
        closeOther: 'closeOther',
        closeAll: 'closeAll',
        fullscreen: 'fullscreen',
        closeFullscreen: 'closeFullscreen',
    },
    notFound: {
        foundTitle: 'Wrong address input, please re-enter the address~',
        foundMsg: 'You can check the web address first, and then re-enter or give us feedback.',
        foundBtn: 'Back to home page',
    },
    noAccess: {
        accessTitle: 'You are not authorized to operate~',
        accessMsg: 'Contact information: add QQ group discussion 665452019',
        accessBtn: 'Reauthorization',
    },
    layout: {
        configTitle: 'Layout configuration',
        oneTitle: 'Global Themes',
        twoTopTitle: 'top bar set up',
        twoMenuTitle: 'Menu set up',
        twoColumnsTitle: 'Columns set up',
        twoTopBar: 'Top bar background',
        twoTopBarColor: 'Top bar default font color',
        twoIsTopBarColorGradual: 'Top bar gradient',
        twoMenuBar: 'Menu background',
        twoMenuBarColor: 'Menu default font color',
        twoIsMenuBarColorGradual: 'Menu gradient',
        twoColumnsMenuBar: 'Column menu background',
        twoColumnsMenuBarColor: 'Default font color bar menu',
        twoIsColumnsMenuBarColorGradual: 'Column gradient',
        threeTitle: 'Interface settings',
        threeIsCollapse: 'Menu horizontal collapse',
        threeIsUniqueOpened: 'Menu accordion',
        threeIsFixedHeader: 'Fixed header',
        threeIsClassicSplitMenu: 'Classic layout split menu',
        threeIsLockScreen: 'Open the lock screen',
        threeLockScreenTime: 'screen locking(s/s)',
        fourTitle: 'Interface display',
        fourIsShowLogo: 'Sidebar logo',
        fourIsBreadcrumb: 'Open breadcrumb',
        fourIsBreadcrumbIcon: 'Open breadcrumb icon',
        fourIsTagsview: 'Open tagsview',
        fourIsTagsviewIcon: 'Open tagsview Icon',
        fourIsCacheTagsView: 'Enable tagsview cache',
        fourIsSortableTagsView: 'Enable tagsview drag',
        fourIsShareTagsView: 'Enable tagsview sharing',
        fourIsFooter: 'Open footer',
        fourIsGrayscale: 'Grey model',
        fourIsInvert: 'Color weak mode',
        fourIsDark: 'Dark Mode',
        fourIsWartermark: 'Turn on watermark',
        fourWartermarkText: 'Watermark copy',
        fiveTitle: 'Other settings',
        fiveTagsStyle: 'Tagsview style',
        fiveAnimation: 'page animation',
        fiveColumnsAsideStyle: 'Column style',
        fiveColumnsAsideLayout: 'Column layout',
        sixTitle: 'Layout switch',
        sixDefaults: 'One',
        sixClassic: 'Two',
        sixTransverse: 'Three',
        sixColumns: 'Four',
        tipText: 'Click the button below to copy the layout configuration to `/src/stores/themeConfig.ts` It has been modified in.',
        copyText: 'replication configuration',
        resetText: 'restore default',
        copyTextSuccess: 'Copy succeeded!',
        copyTextError: 'Copy failed!',
    },
};
src/i18n/lang/zh-cn.ts
对比新文件
@@ -0,0 +1,180 @@
// 定义内容
export default {
    router: {
        home: '首页',
        system: '系统设置',
        systemMenu: '菜单管理',
        systemRole: '角色管理',
        systemUser: '用户管理',
        systemDept: '部门管理',
        systemDic: '字典管理',
        limits: '权限管理',
        limitsFrontEnd: '前端控制',
        limitsFrontEndPage: '页面权限',
        limitsFrontEndBtn: '按钮权限',
        limitsBackEnd: '后端控制',
        limitsBackEndEndPage: '页面权限',
        menu: '菜单嵌套',
        menu1: '菜单1',
        menu11: '菜单11',
        menu12: '菜单12',
        menu121: '菜单121',
        menu122: '菜单122',
        menu13: '菜单13',
        menu2: '菜单2',
        funIndex: '功能',
        funTagsView: 'tagsView 操作',
        funCountup: '数字滚动',
        funWangEditor: 'Editor 编辑器',
        funCropper: '图片裁剪',
        funQrcode: '二维码生成',
        funEchartsMap: '地理坐标/地图',
        funPrintJs: '页面打印',
        funClipboard: '复制剪切',
        funGridLayout: '拖拽布局',
        funSplitpanes: '窗格拆分器',
        funDragVerify: '验证器',
        pagesIndex: '页面',
        pagesFiltering: '过滤筛选组件',
        pagesFilteringDetails: '过滤筛选组件详情',
        pagesFilteringDetails1: '过滤筛选组件详情111',
        pagesIocnfont: 'ali 字体图标',
        pagesElement: 'ele 字体图标',
        pagesAwesome: 'awe 字体图标',
        pagesFormAdapt: '表单自适应',
        pagesTableRules: '表单表格验证',
        pagesFormI18n: '表单国际化',
        pagesFormRules: '多表单验证',
        pagesDynamicForm: '动态复杂表单',
        pagesWorkflow: '工作流',
        pagesListAdapt: '列表自适应',
        pagesWaterfall: '瀑布屏',
        pagesSteps: '步骤条',
        pagesPreview: '大图预览',
        pagesWaves: '波浪效果',
        pagesTree: '树形改表格',
        pagesDrag: '拖动指令',
        pagesLazyImg: '图片懒加载',
        makeIndex: '组件封装',
        makeSelector: '图标选择器',
        makeNoticeBar: '滚动通知栏',
        makeSvgDemo: 'svgIcon 演示',
        paramsIndex: '路由参数',
        paramsCommon: '普通路由',
        paramsDynamic: '动态路由',
        paramsCommonDetails: '普通路由详情',
        paramsDynamicDetails: '动态路由详情',
        chartIndex: '大数据图表',
        visualizingIndex: '数据可视化',
        visualizingLinkDemo1: '数据可视化演示1',
        visualizingLinkDemo2: '数据可视化演示2',
        personal: '个人中心',
        tools: '工具类集合',
        layoutLinkView: '外链',
        layoutIfameView: '内嵌 iframe',
    },
    staticRoutes: {
        signIn: '登录',
        notFound: '找不到此页面',
        noPower: '没有权限',
    },
    user: {
        title0: '组件大小',
        title1: '语言切换',
        title2: '菜单搜索',
        title3: '布局配置',
        title4: '消息',
        title5: '开全屏',
        title6: '关全屏',
        dropdownLarge: '大型',
        dropdownDefault: '默认',
        dropdownSmall: '小型',
        dropdown1: '首页',
        dropdown2: '个人中心',
        dropdown3: '404',
        dropdown4: '401',
        dropdown5: '退出登录',
        dropdown6: '代码仓库',
        searchPlaceholder: '菜单搜索:支持中文、路由路径',
        newTitle: '通知',
        newBtn: '全部已读',
        newGo: '前往通知中心',
        newDesc: '暂无通知',
        logOutTitle: '提示',
        logOutMessage: '此操作将退出登录, 是否继续?',
        logOutConfirm: '确定',
        logOutCancel: '取消',
        logOutExit: '退出中',
    },
    tagsView: {
        refresh: '刷新',
        close: '关闭',
        closeOther: '关闭其它',
        closeAll: '全部关闭',
        fullscreen: '当前页全屏',
        closeFullscreen: '关闭全屏',
    },
    notFound: {
        foundTitle: '地址输入错误,请重新输入地址~',
        foundMsg: '您可以先检查网址,然后重新输入或给我们反馈问题。',
        foundBtn: '返回首页',
    },
    noAccess: {
        accessTitle: '您未被授权,没有操作权限~',
        accessMsg: '联系方式:加QQ群探讨 665452019',
        accessBtn: '重新授权',
    },
    layout: {
        configTitle: '布局配置',
        oneTitle: '全局主题',
        twoTopTitle: '顶栏设置',
        twoMenuTitle: '菜单设置',
        twoColumnsTitle: '分栏设置',
        twoTopBar: '顶栏背景',
        twoTopBarColor: '顶栏默认字体颜色',
        twoIsTopBarColorGradual: '顶栏背景渐变',
        twoMenuBar: '菜单背景',
        twoMenuBarColor: '菜单默认字体颜色',
        twoIsMenuBarColorGradual: '菜单背景渐变',
        twoColumnsMenuBar: '分栏菜单背景',
        twoColumnsMenuBarColor: '分栏菜单默认字体颜色',
        twoIsColumnsMenuBarColorGradual: '分栏菜单背景渐变',
        threeTitle: '界面设置',
        threeIsCollapse: '菜单水平折叠',
        threeIsUniqueOpened: '菜单手风琴',
        threeIsFixedHeader: '固定 Header',
        threeIsClassicSplitMenu: '经典布局分割菜单',
        threeIsLockScreen: '开启锁屏',
        threeLockScreenTime: '自动锁屏(s/秒)',
        fourTitle: '界面显示',
        fourIsShowLogo: '侧边栏 Logo',
        fourIsBreadcrumb: '开启 Breadcrumb',
        fourIsBreadcrumbIcon: '开启 Breadcrumb 图标',
        fourIsTagsview: '开启 Tagsview',
        fourIsTagsviewIcon: '开启 Tagsview 图标',
        fourIsCacheTagsView: '开启 TagsView 缓存',
        fourIsSortableTagsView: '开启 TagsView 拖拽',
        fourIsShareTagsView: '开启 TagsView 共用',
        fourIsFooter: '开启 Footer',
        fourIsGrayscale: '灰色模式',
        fourIsInvert: '色弱模式',
        fourIsDark: '深色模式',
        fourIsWartermark: '开启水印',
        fourWartermarkText: '水印文案',
        fiveTitle: '其它设置',
        fiveTagsStyle: 'Tagsview 风格',
        fiveAnimation: '主页面切换动画',
        fiveColumnsAsideStyle: '分栏高亮风格',
        fiveColumnsAsideLayout: '分栏布局风格',
        sixTitle: '布局切换',
        sixDefaults: '默认',
        sixClassic: '经典',
        sixTransverse: '横向',
        sixColumns: '分栏',
        tipText: '点击下方按钮,复制布局配置去 `src/stores/themeConfig.ts` 中修改。',
        copyText: '一键复制配置',
        resetText: '一键恢复默认',
        copyTextSuccess: '复制成功!',
        copyTextError: '复制失败!',
    },
};
src/i18n/lang/zh-tw.ts
对比新文件
@@ -0,0 +1,180 @@
// 定义内容
export default {
    router: {
        home: '首頁',
        system: '系統設置',
        systemMenu: '選單管理',
        systemRole: '角色管理',
        systemUser: '用戶管理',
        systemDept: '部門管理',
        systemDic: '字典管理',
        limits: '許可權管理',
        limitsFrontEnd: '前端控制',
        limitsFrontEndPage: '頁面許可權',
        limitsFrontEndBtn: '按鈕許可權',
        limitsBackEnd: '後端控制',
        limitsBackEndEndPage: '頁面許可權',
        menu: '選單嵌套',
        menu1: '選單1',
        menu11: '選單11',
        menu12: '選單12',
        menu121: '選單121',
        menu122: '選單122',
        menu13: '選單13',
        menu2: '選單2',
        funIndex: '功能',
        funTagsView: 'tagsView 操作',
        funCountup: '數位滾動',
        funWangEditor: 'Editor 編輯器',
        funCropper: '圖片裁剪',
        funQrcode: '二維碼生成',
        funEchartsMap: '地理座標/地圖',
        funPrintJs: '頁面列印',
        funClipboard: '複製剪切',
        funGridLayout: '拖拽佈局',
        funSplitpanes: '窗格折開器',
        funDragVerify: '驗證器',
        pagesIndex: '頁面',
        pagesFiltering: '過濾篩選組件',
        pagesFilteringDetails: '過濾篩選組件詳情',
        pagesFilteringDetails1: '過濾篩選組件詳情111',
        pagesIocnfont: 'ali 字體圖標',
        pagesElement: 'ele 字體圖標',
        pagesAwesome: 'awe 字體圖標',
        pagesFormAdapt: '表單自我調整',
        pagesTableRules: '表單表格驗證',
        pagesFormI18n: '表單國際化',
        pagesFormRules: '多表單驗證',
        pagesDynamicForm: '動態複雜表單',
        pagesWorkflow: '工作流',
        pagesListAdapt: '清單自我調整',
        pagesWaterfall: '瀑布屏',
        pagesSteps: '步驟條',
        pagesPreview: '大圖預覽',
        pagesWaves: '波浪效果',
        pagesTree: '樹形改表格',
        pagesDrag: '拖動指令',
        pagesLazyImg: '圖片懶加載',
        makeIndex: '組件封裝',
        makeSelector: '圖標選擇器',
        makeNoticeBar: '滾動通知欄',
        makeSvgDemo: 'svgIcon 演示',
        paramsIndex: '路由參數',
        paramsCommon: '普通路由',
        paramsDynamic: '動態路由',
        paramsCommonDetails: '普通路由詳情',
        paramsDynamicDetails: '動態路由詳情',
        chartIndex: '大資料圖表',
        visualizingIndex: '數據視覺化',
        visualizingLinkDemo1: '數據視覺化演示1',
        visualizingLinkDemo2: '數據視覺化演示2',
        personal: '個人中心',
        tools: '工具類集合',
        layoutLinkView: '外鏈',
        layoutIfameView: '内嵌 iframe',
    },
    staticRoutes: {
        signIn: '登入',
        notFound: '找不到此頁面',
        noPower: '沒有許可權',
    },
    user: {
        title0: '組件大小',
        title1: '語言切換',
        title2: '選單蒐索',
        title3: '佈局配寘',
        title4: '消息',
        title5: '開全屏',
        title6: '關全屏',
        dropdownLarge: '大型',
        dropdownDefault: '默認',
        dropdownSmall: '小型',
        dropdown1: '首頁',
        dropdown2: '個人中心',
        dropdown3: '404',
        dropdown4: '401',
        dropdown5: '登出',
        dropdown6: '程式碼倉庫',
        searchPlaceholder: '選單蒐索:支援中文、路由路徑',
        newTitle: '通知',
        newBtn: '全部已讀',
        newGo: '前往通知中心',
        newDesc: '暫無通知',
        logOutTitle: '提示',
        logOutMessage: '此操作將登出,是否繼續?',
        logOutConfirm: '確定',
        logOutCancel: '取消',
        logOutExit: '退出中',
    },
    tagsView: {
        refresh: '重繪',
        close: '關閉',
        closeOther: '關閉其它',
        closeAll: '全部關閉',
        fullscreen: '當前頁全屏',
        closeFullscreen: '關閉全屏',
    },
    notFound: {
        foundTitle: '地址輸入錯誤,請重新輸入地址~',
        foundMsg: '您可以先檢查網址,然後重新輸入或給我們迴響問題。',
        foundBtn: '返回首頁',
    },
    noAccess: {
        accessTitle: '您未被授權,沒有操作許可權~',
        accessMsg: '聯繫方式:加QQ群探討665452019',
        accessBtn: '重新授權',
    },
    layout: {
        configTitle: '佈局配寘',
        oneTitle: '全域主題',
        twoTopTitle: '頂欄設定',
        twoMenuTitle: '選單設定',
        twoColumnsTitle: '分欄設定',
        twoTopBar: '頂欄背景',
        twoTopBarColor: '頂欄默認字體顏色',
        twoIsTopBarColorGradual: '頂欄背景漸變',
        twoMenuBar: '選單背景',
        twoMenuBarColor: '選單默認字體顏色',
        twoIsMenuBarColorGradual: '選單背景漸變',
        twoColumnsMenuBar: '分欄選單背景',
        twoColumnsMenuBarColor: '分欄選單默認字體顏色',
        twoIsColumnsMenuBarColorGradual: '分欄選單背景漸變',
        threeTitle: '介面設定',
        threeIsCollapse: '選單水准折疊',
        threeIsUniqueOpened: '選單手風琴',
        threeIsFixedHeader: '固定 Header',
        threeIsClassicSplitMenu: '經典佈局分割選單',
        threeIsLockScreen: '開啟鎖屏',
        threeLockScreenTime: '自動鎖屏(s/秒)',
        fourTitle: '介面顯示',
        fourIsShowLogo: '側邊欄 Logo',
        fourIsBreadcrumb: '開啟 Breadcrumb',
        fourIsBreadcrumbIcon: '開啟 Breadcrumb 圖標',
        fourIsTagsview: '開啟 Tagsview',
        fourIsTagsviewIcon: '開啟 Tagsview 圖標',
        fourIsCacheTagsView: '開啟 TagsView 緩存',
        fourIsSortableTagsView: '開啟 TagsView 拖拽',
        fourIsShareTagsView: '開啟 TagsView 共用',
        fourIsFooter: '開啟 Footer',
        fourIsGrayscale: '灰色模式',
        fourIsInvert: '色弱模式',
        fourIsDark: '深色模式',
        fourIsWartermark: '開啟浮水印',
        fourWartermarkText: '浮水印文案',
        fiveTitle: '其它設定',
        fiveTagsStyle: 'Tagsview 風格',
        fiveAnimation: '主頁面切換動畫',
        fiveColumnsAsideStyle: '分欄高亮風格',
        fiveColumnsAsideLayout: '分欄佈局風格',
        sixTitle: '佈局切換',
        sixDefaults: '默認',
        sixClassic: '經典',
        sixTransverse: '橫向',
        sixColumns: '分欄',
        tipText: '點擊下方按鈕,複製佈局配寘去`src/stores/themeConfig.ts`中修改。',
        copyText: '一鍵複製配寘',
        resetText: '一鍵恢復默認',
        copyTextSuccess: '複製成功!',
        copyTextError: '複製失敗!',
    },
};
src/i18n/pages/formI18n/en.ts
对比新文件
@@ -0,0 +1,13 @@
// 定义内容
export default {
    formI18nLabel: {
        name: 'name',
        email: 'email',
        autograph: 'autograph',
    },
    formI18nPlaceholder: {
        name: 'Please enter your name',
        email: 'Please enter the users Department',
        autograph: 'Please enter the login account name',
    },
};
src/i18n/pages/formI18n/zh-cn.ts
对比新文件
@@ -0,0 +1,13 @@
// 定义内容
export default {
    formI18nLabel: {
        name: '姓名',
        email: '用户归属部门',
        autograph: '登陆账户名',
    },
    formI18nPlaceholder: {
        name: '请输入姓名',
        email: '请输入用户归属部门',
        autograph: '请输入登陆账户名',
    },
};
src/i18n/pages/formI18n/zh-tw.ts
对比新文件
@@ -0,0 +1,13 @@
// 定义内容
export default {
    formI18nLabel: {
        name: '姓名',
        email: '用戶歸屬部門',
        autograph: '登入帳戶名',
    },
    formI18nPlaceholder: {
        name: '請輸入姓名',
        email: '請輸入用戶歸屬部門',
        autograph: '請輸入登入帳戶名',
    },
};
src/i18n/pages/login/en.ts
对比新文件
@@ -0,0 +1,29 @@
// 定义内容
export default {
    label: {
        one1: 'User name login',
        two2: 'Mobile number',
    },
    link: {
        one3: 'Third party login',
        two4: 'Links',
    },
    account: {
        accountPlaceholder1: 'The user name admin or not is common',
        accountPlaceholder2: 'Password: 123456',
        accountPlaceholder3: 'Please enter the verification code',
        accountBtnText: 'Sign in',
    },
    mobile: {
        placeholder1: 'Please input mobile phone number',
        placeholder2: 'Please enter the verification code',
        codeText: 'Get code',
        btnText: 'Sign in',
        msgText:
            'Warm tip: it is recommended to use Google, Microsoft edge, version 79.0.1072.62 and above browsers, and 360 browser, please use speed mode',
    },
    scan: {
        text: 'Open the mobile phone to scan and quickly log in / register',
    },
    signInText: 'welcome back!',
};
src/i18n/pages/login/zh-cn.ts
对比新文件
@@ -0,0 +1,28 @@
// 定义内容
export default {
    label: {
        one1: '用户名登录',
        two2: '手机号登录',
    },
    link: {
        one3: '第三方登录',
        two4: '友情链接',
    },
    account: {
        accountPlaceholder1: '用户名 admin 或不输均为 common',
        accountPlaceholder2: '密码:123456',
        accountPlaceholder3: '请输入验证码',
        accountBtnText: '登 录',
    },
    mobile: {
        placeholder1: '请输入手机号',
        placeholder2: '请输入验证码',
        codeText: '获取验证码',
        btnText: '登 录',
        msgText: '* 温馨提示:建议使用谷歌、Microsoft Edge,版本 79.0.1072.62 及以上浏览器,360浏览器请使用极速模式',
    },
    scan: {
        text: '打开手机扫一扫,快速登录/注册',
    },
    signInText: '欢迎回来!',
};
src/i18n/pages/login/zh-tw.ts
对比新文件
@@ -0,0 +1,28 @@
// 定义内容
export default {
    label: {
        one1: '用戶名登入',
        two2: '手機號登入',
    },
    link: {
        one3: '協力廠商登入',
        two4: '友情連結',
    },
    account: {
        accountPlaceholder1: '用戶名admin或不輸均為common',
        accountPlaceholder2: '密碼:123456',
        accountPlaceholder3: '請輸入驗證碼',
        accountBtnText: '登入',
    },
    mobile: {
        placeholder1: '請輸入手機號',
        placeholder2: '請輸入驗證碼',
        codeText: '獲取驗證碼',
        btnText: '登入',
        msgText: '* 溫馨提示:建議使用穀歌、Microsoft Edge,版本79.0.1072.62及以上瀏覽器,360瀏覽器請使用極速模式',
    },
    scan: {
        text: '打開手機掃一掃,快速登錄/注册',
    },
    signInText: '歡迎回來!',
};
src/layout/component/aside.vue
对比新文件
@@ -0,0 +1,164 @@
<template>
    <div class="h100" v-show="!isTagsViewCurrenFull">
        <el-aside class="layout-aside" :class="setCollapseStyle">
<!--            <Logo v-if="setShowLogo" />-->
            <el-scrollbar class="flex-auto" ref="layoutAsideScrollbarRef" @mouseenter="onAsideEnterLeave(true)" @mouseleave="onAsideEnterLeave(false)">
                <Vertical :menuList="menuList" />
            </el-scrollbar>
            <div style="font-size: 9px;color: rgba(255,255,255,.4);padding: 10px 20px">技术支持:<br/>苏州国科鸿宇智能科技有限公司</div>
        </el-aside>
    </div>
</template>
<script lang="ts">
import { toRefs, reactive, computed, watch, getCurrentInstance, onBeforeMount, defineComponent } from 'vue';
import { storeToRefs } from 'pinia';
import pinia from '/@/stores/index';
import { useRoutesList } from '/@/stores/routesList';
import { useThemeConfig } from '/@/stores/themeConfig';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import Logo from '/@/layout/logo/index.vue';
import Vertical from '/@/layout/navMenu/vertical.vue';
export default defineComponent({
    name: 'layoutAside',
    components: { Logo, Vertical },
    setup() {
        const { proxy } = <any>getCurrentInstance();
        const stores = useRoutesList();
        const storesThemeConfig = useThemeConfig();
        const storesTagsViewRoutes = useTagsViewRoutes();
        const { routesList } = storeToRefs(stores);
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const { isTagsViewCurrenFull } = storeToRefs(storesTagsViewRoutes);
        const state = reactive({
            menuList: [],
            clientWidth: 0,
        });
        // 设置菜单展开/收起时的宽度
        const setCollapseStyle = computed(() => {
            const { layout, isCollapse, menuBar } = themeConfig.value;
            const asideBrTheme = ['#FFFFFF', '#FFF', '#fff', '#ffffff'];
            const asideBrColor = asideBrTheme.includes(menuBar) ? 'layout-el-aside-br-color' : '';
            // 判断是否是手机端
            if (state.clientWidth <= 1000) {
                if (isCollapse) {
                    document.body.setAttribute('class', 'el-popup-parent--hidden');
                    const asideEle = document.querySelector('.layout-container') as HTMLElement;
                    const modeDivs = document.createElement('div');
                    modeDivs.setAttribute('class', 'layout-aside-mobile-mode');
                    asideEle.appendChild(modeDivs);
                    modeDivs.addEventListener('click', closeLayoutAsideMobileMode);
                    return [asideBrColor, 'layout-aside-mobile', 'layout-aside-mobile-open'];
                } else {
                    // 关闭弹窗
                    closeLayoutAsideMobileMode();
                    return [asideBrColor, 'layout-aside-mobile', 'layout-aside-mobile-close'];
                }
            } else {
                if (layout === 'columns') {
                    // 分栏布局,菜单收起时宽度给 1px
                    if (isCollapse) return [asideBrColor, 'layout-aside-pc-1'];
                    else return [asideBrColor, 'layout-aside-pc-220'];
                } else {
                    // 其它布局给 64px
                    if (isCollapse) return [asideBrColor, 'layout-aside-pc-64'];
                    else return [asideBrColor, 'layout-aside-pc-220'];
                }
            }
        });
        // 关闭移动端蒙版
        const closeLayoutAsideMobileMode = () => {
            const el = document.querySelector('.layout-aside-mobile-mode');
            el?.setAttribute('style', 'animation: error-img-two 0.3s');
            setTimeout(() => {
                el?.parentNode?.removeChild(el);
            }, 300);
            const clientWidth = document.body.clientWidth;
            if (clientWidth < 1000) themeConfig.value.isCollapse = false;
            document.body.setAttribute('class', '');
        };
        // 设置显示/隐藏 logo
        const setShowLogo = computed(() => {
            let { layout, isShowLogo } = themeConfig.value;
            return (isShowLogo && layout === 'defaults') || (isShowLogo && layout === 'columns');
        });
        // 设置/过滤路由(非静态路由/是否显示在菜单中)
        const setFilterRoutes = () => {
            if (themeConfig.value.layout === 'columns') return false;
            (state.menuList as any) = filterRoutesFun(routesList.value);
        };
        // 路由过滤递归函数
        const filterRoutesFun = (arr: Array<string>) => {
            return arr
                .filter((item: any) => !item.meta.isHide)
                .map((item: any) => {
                    item = Object.assign({}, item);
                    if (item.children) item.children = filterRoutesFun(item.children);
                    return item;
                });
        };
        // 设置菜单导航是否固定(移动端)
        const initMenuFixed = (clientWidth: number) => {
            state.clientWidth = clientWidth;
        };
        // 鼠标移入、移出
        const onAsideEnterLeave = (bool: Boolean) => {
            let { layout } = themeConfig.value;
            if (layout !== 'columns') return false;
            if (!bool) proxy.mittBus.emit('restoreDefault');
            stores.setColumnsMenuHover(bool);
        };
        // 监听 themeConfig 配置文件的变化,更新菜单 el-scrollbar 的高度
        watch(themeConfig.value, (val) => {
            if (val.isShowLogoChange !== val.isShowLogo) {
                if (!proxy.$refs.layoutAsideScrollbarRef) return false;
                proxy.$refs.layoutAsideScrollbarRef.update();
            }
        });
        // 监听vuex值的变化,动态赋值给菜单中
        watch(
            pinia.state,
            (val) => {
                let { layout, isClassicSplitMenu } = val.themeConfig.themeConfig;
                if (layout === 'classic' && isClassicSplitMenu) return false;
                setFilterRoutes();
            },
            {
                deep: true,
            }
        );
        // 页面加载前
        onBeforeMount(() => {
            initMenuFixed(document.body.clientWidth);
            setFilterRoutes();
            // 此界面不需要取消监听(proxy.mittBus.off('setSendColumnsChildren))
            // 因为切换布局时有的监听需要使用,取消了监听,某些操作将不生效
            proxy.mittBus.on('setSendColumnsChildren', (res: any) => {
                state.menuList = res.children;
            });
            proxy.mittBus.on('setSendClassicChildren', (res: any) => {
                let { layout, isClassicSplitMenu } = themeConfig.value;
                if (layout === 'classic' && isClassicSplitMenu) {
                    state.menuList = [];
                    state.menuList = res.children;
                }
            });
            proxy.mittBus.on('getBreadcrumbIndexSetFilterRoutes', () => {
                setFilterRoutes();
            });
            proxy.mittBus.on('layoutMobileResize', (res: any) => {
                initMenuFixed(res.clientWidth);
                closeLayoutAsideMobileMode();
            });
        });
        return {
            setCollapseStyle,
            setShowLogo,
            isTagsViewCurrenFull,
            onAsideEnterLeave,
            ...toRefs(state),
        };
    },
});
</script>
src/layout/component/columnsAside.vue
对比新文件
@@ -0,0 +1,292 @@
<template>
    <div class="layout-columns-aside">
        <el-scrollbar>
            <ul @mouseleave="onColumnsAsideMenuMouseleave()">
                <li
                    v-for="(v, k) in columnsAsideList"
                    :key="k"
                    @click="onColumnsAsideMenuClick(v, k)"
                    @mouseenter="onColumnsAsideMenuMouseenter(v, k)"
                    :ref="
                        (el) => {
                            if (el) columnsAsideOffsetTopRefs[k] = el;
                        }
                    "
                    :class="{ 'layout-columns-active': liIndex === k, 'layout-columns-hover': liHoverIndex === k }"
                    :title="$t(v.meta.title)"
                >
                    <div :class="themeConfig.columnsAsideLayout" v-if="!v.meta.isLink || (v.meta.isLink && v.meta.isIframe)">
                        <SvgIcon :name="v.meta.icon" />
                        <div class="columns-vertical-title font12">
                            {{
                                $t(v.meta.title) && $t(v.meta.title).length >= 4
                                    ? $t(v.meta.title).substr(0, themeConfig.columnsAsideLayout === 'columns-vertical' ? 4 : 3)
                                    : $t(v.meta.title)
                            }}
                        </div>
                    </div>
                    <div :class="themeConfig.columnsAsideLayout" v-else>
                        <a :href="v.meta.isLink" target="_blank">
                            <SvgIcon :name="v.meta.icon" />
                            <div class="columns-vertical-title font12">
                                {{
                                    $t(v.meta.title) && $t(v.meta.title).length >= 4
                                        ? $t(v.meta.title).substr(0, themeConfig.columnsAsideLayout === 'columns-vertical' ? 4 : 3)
                                        : $t(v.meta.title)
                                }}
                            </div>
                        </a>
                    </div>
                </li>
                <div ref="columnsAsideActiveRef" :class="themeConfig.columnsAsideStyle"></div>
            </ul>
        </el-scrollbar>
    </div>
</template>
<script lang="ts">
import { reactive, toRefs, ref, onMounted, nextTick, getCurrentInstance, watch, onUnmounted, defineComponent } from 'vue';
import { useRoute, useRouter, onBeforeRouteUpdate, RouteRecordRaw } from 'vue-router';
import { storeToRefs } from 'pinia';
import pinia from '/@/stores/index';
import { useRoutesList } from '/@/stores/routesList';
import { useThemeConfig } from '/@/stores/themeConfig';
// 定义接口来定义对象的类型
interface ColumnsAsideState {
    columnsAsideList: any[];
    liIndex: number;
    liOldIndex: null | number;
    liHoverIndex: null | number;
    liOldPath: null | string;
    difference: number;
    routeSplit: string[];
}
export default defineComponent({
    name: 'layoutColumnsAside',
    setup() {
        const columnsAsideOffsetTopRefs: any = ref([]);
        const columnsAsideActiveRef = ref();
        const { proxy } = <any>getCurrentInstance();
        const stores = useRoutesList();
        const storesThemeConfig = useThemeConfig();
        const { routesList, isColumnsMenuHover, isColumnsNavHover } = storeToRefs(stores);
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const route = useRoute();
        const router = useRouter();
        const state = reactive<ColumnsAsideState>({
            columnsAsideList: [],
            liIndex: 0,
            liOldIndex: null,
            liHoverIndex: null,
            liOldPath: null,
            difference: 0,
            routeSplit: [],
        });
        // 设置菜单高亮位置移动
        const setColumnsAsideMove = (k: number) => {
            state.liIndex = k;
            columnsAsideActiveRef.value.style.top = `${columnsAsideOffsetTopRefs.value[k].offsetTop + state.difference}px`;
        };
        // 菜单高亮点击事件
        const onColumnsAsideMenuClick = (v: Object, k: number) => {
            setColumnsAsideMove(k);
            let { path, redirect } = v as any;
            if (redirect) router.push(redirect);
            else router.push(path);
        };
        // 鼠标移入时,显示当前的子级菜单
        const onColumnsAsideMenuMouseenter = (v: RouteRecordRaw, k: number) => {
            let { path } = v;
            state.liOldPath = path;
            state.liOldIndex = k;
            state.liHoverIndex = k;
            proxy.mittBus.emit('setSendColumnsChildren', setSendChildren(path));
            stores.setColumnsMenuHover(false);
            stores.setColumnsNavHover(true);
        };
        // 鼠标移走时,显示原来的子级菜单
        const onColumnsAsideMenuMouseleave = async () => {
            await stores.setColumnsNavHover(false);
            // 添加延时器,防止拿到的 store.state.routesList 值不是最新的
            setTimeout(() => {
                if (!isColumnsMenuHover && !isColumnsNavHover) proxy.mittBus.emit('restoreDefault');
            }, 100);
        };
        // 设置高亮动态位置
        const onColumnsAsideDown = (k: number) => {
            nextTick(() => {
                setColumnsAsideMove(k);
            });
        };
        // 设置/过滤路由(非静态路由/是否显示在菜单中)
        const setFilterRoutes = () => {
            state.columnsAsideList = filterRoutesFun(routesList.value);
            const resData: any = setSendChildren(route.path);
            if (Object.keys(resData).length <= 0) return false;
            onColumnsAsideDown(resData.item[0].k);
            proxy.mittBus.emit('setSendColumnsChildren', resData);
        };
        // 传送当前子级数据到菜单中
        const setSendChildren = (path: string) => {
            const currentPathSplit = path.split('/');
            let currentData: any = {};
            state.columnsAsideList.map((v: any, k: number) => {
                if (v.path === `/${currentPathSplit[1]}`) {
                    v['k'] = k;
                    currentData['item'] = [{ ...v }];
                    currentData['children'] = [{ ...v }];
                    if (v.children) currentData['children'] = v.children;
                }
            });
            return currentData;
        };
        // 路由过滤递归函数
        const filterRoutesFun = (arr: Array<string>) => {
            return arr
                .filter((item: any) => !item.meta.isHide)
                .map((item: any) => {
                    item = Object.assign({}, item);
                    if (item.children) item.children = filterRoutesFun(item.children);
                    return item;
                });
        };
        // tagsView 点击时,根据路由查找下标 columnsAsideList,实现左侧菜单高亮
        const setColumnsMenuHighlight = (path: string) => {
            state.routeSplit = path.split('/');
            state.routeSplit.shift();
            const routeFirst = `/${state.routeSplit[0]}`;
            const currentSplitRoute = state.columnsAsideList.find((v: any) => v.path === routeFirst);
            if (!currentSplitRoute) return false;
            // 延迟拿值,防止取不到
            setTimeout(() => {
                onColumnsAsideDown((<any>currentSplitRoute).k);
            }, 0);
        };
        // 监听布局配置信息的变化,动态增加菜单高亮位置移动像素
        watch(
            pinia.state,
            (val) => {
                val.themeConfig.themeConfig.columnsAsideStyle === 'columnsRound' ? (state.difference = 3) : (state.difference = 0);
                if (!val.routesList.isColumnsMenuHover && !val.routesList.isColumnsNavHover) {
                    state.liHoverIndex = null;
                    proxy.mittBus.emit('setSendColumnsChildren', setSendChildren(route.path));
                } else {
                    state.liHoverIndex = state.liOldIndex;
                    if (!state.liOldPath) return false;
                    proxy.mittBus.emit('setSendColumnsChildren', setSendChildren(state.liOldPath));
                }
            },
            {
                deep: true,
            }
        );
        // 页面加载时
        onMounted(() => {
            setFilterRoutes();
            // 销毁变量,防止鼠标再次移入时,保留了上次的记录
            proxy.mittBus.on('restoreDefault', () => {
                state.liOldIndex = null;
                state.liOldPath = null;
            });
        });
        // 页面卸载时
        onUnmounted(() => {
            proxy.mittBus.off('restoreDefault', () => {});
        });
        // 路由更新时
        onBeforeRouteUpdate((to) => {
            setColumnsMenuHighlight(to.path);
            proxy.mittBus.emit('setSendColumnsChildren', setSendChildren(to.path));
        });
        return {
            themeConfig,
            columnsAsideOffsetTopRefs,
            columnsAsideActiveRef,
            onColumnsAsideDown,
            onColumnsAsideMenuClick,
            onColumnsAsideMenuMouseenter,
            onColumnsAsideMenuMouseleave,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.layout-columns-aside {
    width: 70px;
    height: 100%;
    background: var(--next-bg-columnsMenuBar);
    ul {
        position: relative;
        li {
            color: var(--next-bg-columnsMenuBarColor);
            width: 100%;
            height: 50px;
            text-align: center;
            display: flex;
            cursor: pointer;
            position: relative;
            z-index: 1;
            .columns-vertical {
                margin: auto;
                .columns-vertical-title {
                    padding-top: 1px;
                }
            }
            .columns-horizontal {
                display: flex;
                height: 50px;
                width: 100%;
                align-items: center;
                padding: 0 5px;
                i {
                    margin-right: 3px;
                }
                a {
                    display: flex;
                    .columns-horizontal-title {
                        padding-top: 1px;
                    }
                }
            }
            a {
                text-decoration: none;
                color: var(--next-bg-columnsMenuBarColor);
            }
        }
        .layout-columns-active {
            color: var(--next-bg-columnsMenuBarColor) !important;
            transition: 0.3s ease-in-out;
        }
        .layout-columns-hover {
            color: var(--el-color-primary);
            a {
                color: var(--el-color-primary);
            }
        }
        .columns-round {
            background: var(--el-color-primary);
            color: var(--el-color-white);
            position: absolute;
            left: 50%;
            top: 2px;
            height: 44px;
            width: 65px;
            transform: translateX(-50%);
            z-index: 0;
            transition: 0.3s ease-in-out;
            border-radius: 5px;
        }
        .columns-card {
            @extend .columns-round;
            top: 0;
            height: 50px;
            width: 100%;
            border-radius: 0;
        }
    }
}
</style>
src/layout/component/header.vue
对比新文件
@@ -0,0 +1,34 @@
<template>
    <el-header class="layout-header" :height="setHeaderHeight" v-show="!isTagsViewCurrenFull">
        <NavBarsIndex />
    </el-header>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import NavBarsIndex from '/@/layout/navBars/index.vue';
export default defineComponent({
    name: 'layoutHeader',
    components: { NavBarsIndex },
    setup() {
        const storesTagsViewRoutes = useTagsViewRoutes();
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const { isTagsViewCurrenFull } = storeToRefs(storesTagsViewRoutes);
        // 设置 header 的高度
        const setHeaderHeight = computed(() => {
            let { isTagsview, layout } = themeConfig.value;
            if (isTagsview && layout !== 'classic') return '84px';
            else return '80px';
        });
        return {
            setHeaderHeight,
            isTagsViewCurrenFull,
        };
    },
});
</script>
src/layout/component/main.vue
对比新文件
@@ -0,0 +1,101 @@
<template>
    <el-main class="layout-main">
        <el-scrollbar
            ref="layoutScrollbarRef"
            :class="{
                'layout-scrollbar':
                    (!isClassicOrTransverse && !currentRouteMeta.isLink && !currentRouteMeta.isIframe) ||
                    (!isClassicOrTransverse && currentRouteMeta.isLink && !currentRouteMeta.isIframe),
            }"
        >
            <LayoutParentView
                :style="{
                    padding: !isClassicOrTransverse || (currentRouteMeta.isLink && currentRouteMeta.isIframe) ? '0' : '15px',
                    transition: 'padding 0.3s ease-in-out',
                }"
            />
            <Footer v-if="themeConfig.isFooter" />
        </el-scrollbar>
    </el-main>
</template>
<script lang="ts">
import { defineComponent, toRefs, reactive, getCurrentInstance, watch, onMounted, computed } from 'vue';
import { useRoute } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import { NextLoading } from '/@/utils/loading';
import LayoutParentView from '/@/layout/routerView/parent.vue';
import Footer from '/@/layout/footer/index.vue';
// 定义接口来定义对象的类型
interface MainState {
    headerHeight: string | number;
    currentRouteMeta: any;
}
export default defineComponent({
    name: 'layoutMain',
    components: { LayoutParentView, Footer },
    setup() {
        const { proxy } = <any>getCurrentInstance();
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const route = useRoute();
        const state = reactive<MainState>({
            headerHeight: '',
            currentRouteMeta: {},
        });
        // 判断布局
        const isClassicOrTransverse = computed(() => {
            const { layout } = themeConfig.value;
            return layout === 'classic' || layout === 'transverse';
        });
        // 设置 main 的高度
        const initHeaderHeight = () => {
            const bool = state.currentRouteMeta.isLink && state.currentRouteMeta.isIframe;
            let { isTagsview } = themeConfig.value;
            if (isTagsview) return (state.headerHeight = bool ? `86px` : `115px`);
            else return (state.headerHeight = `80px`);
        };
        // 初始化获取当前路由 meta,用于设置 iframes padding
        const initGetMeta = () => {
            state.currentRouteMeta = route.meta;
        };
        // 页面加载前
        onMounted(async () => {
            await initGetMeta();
            initHeaderHeight();
            NextLoading.done();
        });
        // 监听路由变化
        watch(
            () => route.path,
            () => {
                state.currentRouteMeta = route.meta;
                const bool = state.currentRouteMeta.isLink && state.currentRouteMeta.isIframe;
                state.headerHeight = bool ? `86px` : `115px`;
                proxy.$refs.layoutScrollbarRef.update();
            }
        );
        // 监听 themeConfig 配置文件的变化,更新菜单 el-scrollbar 的高度
        watch(
            themeConfig,
            (val) => {
                state.currentRouteMeta = route.meta;
                const bool = state.currentRouteMeta.isLink && state.currentRouteMeta.isIframe;
                state.headerHeight = val.isTagsview ? (bool ? `86px` : `115px`) : '51px';
                proxy.$refs?.layoutScrollbarRef?.update();
            },
            {
                deep: true,
            }
        );
        return {
            themeConfig,
            isClassicOrTransverse,
            ...toRefs(state),
        };
    },
});
</script>
src/layout/footer/index.vue
对比新文件
@@ -0,0 +1,47 @@
<template>
    <div class="layout-footer mt15" v-show="isDelayFooter">
        <div class="layout-footer-warp">
            <div>vue-next-admin,Made by lyt with ❤️</div>
            <div class="mt5">深圳市 xxx 公司版权所有</div>
        </div>
    </div>
</template>
<script lang="ts">
import { toRefs, reactive, defineComponent } from 'vue';
import { onBeforeRouteUpdate } from 'vue-router';
export default defineComponent({
    name: 'layoutFooter',
    setup() {
        const state = reactive({
            isDelayFooter: true,
        });
        // 路由改变时,等主界面动画加载完毕再显示 footer
        onBeforeRouteUpdate(() => {
            setTimeout(() => {
                state.isDelayFooter = false;
                setTimeout(() => {
                    state.isDelayFooter = true;
                }, 800);
            }, 0);
        });
        return {
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.layout-footer {
    width: 100%;
    display: flex;
    &-warp {
        margin: auto;
        color: var(--el-text-color-secondary);
        text-align: center;
        animation: error-num 1s ease-in-out;
    }
}
</style>
src/layout/index.vue
对比新文件
@@ -0,0 +1,54 @@
<template>
    <component :is="themeConfig.layout" />
</template>
<script lang="ts">
import { onBeforeMount, onUnmounted, getCurrentInstance, defineComponent, defineAsyncComponent } from 'vue';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import { Local } from '/@/utils/storage';
export default defineComponent({
    name: 'layout',
    components: {
        defaults: defineAsyncComponent(() => import('/@/layout/main/defaults.vue')),
        classic: defineAsyncComponent(() => import('/@/layout/main/classic.vue')),
        transverse: defineAsyncComponent(() => import('/@/layout/main/transverse.vue')),
        columns: defineAsyncComponent(() => import('/@/layout/main/columns.vue')),
    },
    setup() {
        const { proxy } = <any>getCurrentInstance();
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        // 窗口大小改变时(适配移动端)
        const onLayoutResize = () => {
            if (!Local.get('oldLayout')) Local.set('oldLayout', themeConfig.value.layout);
            const clientWidth = document.body.clientWidth;
            if (clientWidth < 1000) {
                themeConfig.value.isCollapse = false;
                proxy.mittBus.emit('layoutMobileResize', {
                    layout: 'defaults',
                    clientWidth,
                });
            } else {
                proxy.mittBus.emit('layoutMobileResize', {
                    layout: Local.get('oldLayout') ? Local.get('oldLayout') : themeConfig.value.layout,
                    clientWidth,
                });
            }
        };
        // 页面加载前
        onBeforeMount(() => {
            onLayoutResize();
            window.addEventListener('resize', onLayoutResize);
        });
        // 页面卸载时
        onUnmounted(() => {
            window.removeEventListener('resize', onLayoutResize);
        });
        return {
            themeConfig,
        };
    },
});
</script>
src/layout/lockScreen/index.vue
对比新文件
@@ -0,0 +1,372 @@
<template>
    <div v-show="isShowLockScreen">
        <div class="layout-lock-screen-mask"></div>
        <div class="layout-lock-screen-img" :class="{ 'layout-lock-screen-filter': isShowLoockLogin }"></div>
        <div class="layout-lock-screen">
            <div
                class="layout-lock-screen-date"
                ref="layoutLockScreenDateRef"
                @mousedown="onDown"
                @mousemove="onMove"
                @mouseup="onEnd"
                @touchstart.stop="onDown"
                @touchmove.stop="onMove"
                @touchend.stop="onEnd"
            >
                <div class="layout-lock-screen-date-box">
                    <div class="layout-lock-screen-date-box-time">
                        {{ time.hm }}<span class="layout-lock-screen-date-box-minutes">{{ time.s }}</span>
                    </div>
                    <div class="layout-lock-screen-date-box-info">{{ time.mdq }}</div>
                </div>
                <div class="layout-lock-screen-date-top">
                    <SvgIcon name="ele-Top" />
                    <div class="layout-lock-screen-date-top-text">上滑解锁</div>
                </div>
            </div>
            <transition name="el-zoom-in-center">
                <div v-show="isShowLoockLogin" class="layout-lock-screen-login">
                    <div class="layout-lock-screen-login-box">
                        <div class="layout-lock-screen-login-box-img">
                            <img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1813762643,1914315241&fm=26&gp=0.jpg" />
                        </div>
                        <div class="layout-lock-screen-login-box-name">Administrator</div>
                        <div class="layout-lock-screen-login-box-value">
                            <el-input
                                placeholder="请输入密码"
                                ref="layoutLockScreenInputRef"
                                v-model="lockScreenPassword"
                                @keyup.enter.native.stop="onLockScreenSubmit()"
                            >
                                <template #append>
                                    <el-button @click="onLockScreenSubmit">
                                        <el-icon class="el-input__icon">
                                            <ele-Right />
                                        </el-icon>
                                    </el-button>
                                </template>
                            </el-input>
                        </div>
                    </div>
                    <div class="layout-lock-screen-login-icon">
                        <SvgIcon name="ele-Microphone" :size="20" />
                        <SvgIcon name="ele-AlarmClock" :size="20" />
                        <SvgIcon name="ele-SwitchButton" :size="20" />
                    </div>
                </div>
            </transition>
        </div>
    </div>
</template>
<script lang="ts">
import { nextTick, onMounted, reactive, toRefs, ref, onUnmounted, getCurrentInstance, defineComponent } from 'vue';
import { formatDate } from '/@/utils/formatTime';
import { Local } from '/@/utils/storage';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
// 定义接口来定义对象的类型
interface LockScreenState {
    transparency: number;
    downClientY: number;
    moveDifference: number;
    isShowLoockLogin: boolean;
    isFlags: boolean;
    querySelectorEl: HTMLElement | string;
    time: {
        hm: string;
        s: string;
        mdq: string;
    };
    setIntervalTime: number;
    isShowLockScreen: boolean;
    isShowLockScreenIntervalTime: number;
    lockScreenPassword: string;
}
export default defineComponent({
    name: 'layoutLockScreen',
    setup() {
        const { proxy } = <any>getCurrentInstance();
        const layoutLockScreenInputRef = ref();
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const state = reactive<LockScreenState>({
            transparency: 1,
            downClientY: 0,
            moveDifference: 0,
            isShowLoockLogin: false,
            isFlags: false,
            querySelectorEl: '',
            time: {
                hm: '',
                s: '',
                mdq: '',
            },
            setIntervalTime: 0,
            isShowLockScreen: false,
            isShowLockScreenIntervalTime: 0,
            lockScreenPassword: '',
        });
        // 鼠标按下
        const onDown = (down: any) => {
            state.isFlags = true;
            state.downClientY = down.touches ? down.touches[0].clientY : down.clientY;
        };
        // 鼠标移动
        const onMove = (move: any) => {
            if (state.isFlags) {
                const el = <HTMLElement>state.querySelectorEl;
                const opacitys = (state.transparency -= 1 / 200);
                if (move.touches) {
                    state.moveDifference = move.touches[0].clientY - state.downClientY;
                } else {
                    state.moveDifference = move.clientY - state.downClientY;
                }
                if (state.moveDifference >= 0) return false;
                el.setAttribute('style', `top:${state.moveDifference}px;cursor:pointer;opacity:${opacitys};`);
                if (state.moveDifference < -400) {
                    el.setAttribute('style', `top:${-el.clientHeight}px;cursor:pointer;transition:all 0.3s ease;`);
                    state.moveDifference = -el.clientHeight;
                    setTimeout(() => {
                        el && el.parentNode?.removeChild(el);
                    }, 300);
                }
                if (state.moveDifference === -el.clientHeight) {
                    state.isShowLoockLogin = true;
                    layoutLockScreenInputRef.value.focus();
                }
            }
        };
        // 鼠标松开
        const onEnd = () => {
            state.isFlags = false;
            state.transparency = 1;
            if (state.moveDifference >= -400) {
                (<HTMLElement>state.querySelectorEl).setAttribute('style', `top:0px;opacity:1;transition:all 0.3s ease;`);
            }
        };
        // 获取要拖拽的初始元素
        const initGetElement = () => {
            nextTick(() => {
                state.querySelectorEl = proxy.$refs.layoutLockScreenDateRef;
            });
        };
        // 时间初始化
        const initTime = () => {
            state.time.hm = formatDate(new Date(), 'HH:MM');
            state.time.s = formatDate(new Date(), 'SS');
            state.time.mdq = formatDate(new Date(), 'mm月dd日,WWW');
        };
        // 时间初始化定时器
        const initSetTime = () => {
            initTime();
            state.setIntervalTime = window.setInterval(() => {
                initTime();
            }, 1000);
        };
        // 锁屏时间定时器
        const initLockScreen = () => {
            if (themeConfig.value.isLockScreen) {
                state.isShowLockScreenIntervalTime = window.setInterval(() => {
                    if (themeConfig.value.lockScreenTime <= 1) {
                        state.isShowLockScreen = true;
                        setLocalThemeConfig();
                        return false;
                    }
                    themeConfig.value.lockScreenTime--;
                }, 1000);
            } else {
                clearInterval(state.isShowLockScreenIntervalTime);
            }
        };
        // 存储布局配置
        const setLocalThemeConfig = () => {
            themeConfig.value.isDrawer = false;
            Local.set('themeConfig', themeConfig.value);
        };
        // 密码输入点击事件
        const onLockScreenSubmit = () => {
            themeConfig.value.isLockScreen = false;
            themeConfig.value.lockScreenTime = 30;
            setLocalThemeConfig();
        };
        // 页面加载时
        onMounted(() => {
            initGetElement();
            initSetTime();
            initLockScreen();
        });
        // 页面卸载时
        onUnmounted(() => {
            window.clearInterval(state.setIntervalTime);
            window.clearInterval(state.isShowLockScreenIntervalTime);
        });
        return {
            layoutLockScreenInputRef,
            onDown,
            onMove,
            onEnd,
            onLockScreenSubmit,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.layout-lock-screen-fixed {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
.layout-lock-screen-filter {
    filter: blur(1px);
}
.layout-lock-screen-mask {
    background: var(--el-color-white);
    @extend .layout-lock-screen-fixed;
    z-index: 9999990;
}
.layout-lock-screen-img {
    @extend .layout-lock-screen-fixed;
    background-image: url('https://img-blog.csdnimg.cn/afa9c317667f47d5bea34b85af45979e.png#pic_center');
    background-size: 100% 100%;
    z-index: 9999991;
}
.layout-lock-screen {
    @extend .layout-lock-screen-fixed;
    z-index: 9999992;
    &-date {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        color: var(--el-color-white);
        z-index: 9999993;
        user-select: none;
        &-box {
            position: absolute;
            left: 30px;
            bottom: 50px;
            &-time {
                font-size: 100px;
                color: var(--el-color-white);
            }
            &-info {
                font-size: 40px;
                color: var(--el-color-white);
            }
            &-minutes {
                font-size: 16px;
            }
        }
        &-top {
            width: 40px;
            height: 40px;
            line-height: 40px;
            border-radius: 100%;
            border: 1px solid var(--el-border-color-light, #ebeef5);
            background: rgba(255, 255, 255, 0.1);
            color: var(--el-color-white);
            opacity: 0.8;
            position: absolute;
            right: 30px;
            bottom: 50px;
            text-align: center;
            overflow: hidden;
            transition: all 0.3s ease;
            i {
                transition: all 0.3s ease;
            }
            &-text {
                opacity: 0;
                position: absolute;
                top: 150%;
                font-size: 12px;
                color: var(--el-color-white);
                left: 50%;
                line-height: 1.2;
                transform: translate(-50%, -50%);
                transition: all 0.3s ease;
                width: 35px;
            }
            &:hover {
                border: 1px solid rgba(255, 255, 255, 0.5);
                background: rgba(255, 255, 255, 0.2);
                box-shadow: 0 0 12px 0 rgba(255, 255, 255, 0.5);
                color: var(--el-color-white);
                opacity: 1;
                transition: all 0.3s ease;
                i {
                    transform: translateY(-40px);
                    transition: all 0.3s ease;
                }
                .layout-lock-screen-date-top-text {
                    opacity: 1;
                    top: 50%;
                    transition: all 0.3s ease;
                }
            }
        }
    }
    &-login {
        position: relative;
        z-index: 9999994;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        display: flex;
        flex-direction: column;
        justify-content: center;
        color: var(--el-color-white);
        &-box {
            text-align: center;
            margin: auto;
            &-img {
                width: 180px;
                height: 180px;
                margin: auto;
                img {
                    width: 100%;
                    height: 100%;
                    border-radius: 100%;
                }
            }
            &-name {
                font-size: 26px;
                margin: 15px 0 30px;
            }
        }
        &-icon {
            position: absolute;
            right: 30px;
            bottom: 30px;
            i {
                font-size: 20px;
                margin-left: 15px;
                cursor: pointer;
                opacity: 0.8;
                &:hover {
                    opacity: 1;
                }
            }
        }
    }
}
::v-deep(.el-input-group__append) {
    background: var(--el-color-white);
    padding: 0px 15px;
}
::v-deep(.el-input__inner) {
    border-right-color: var(--el-border-color-extra-light);
    &:hover {
        border-color: var(--el-border-color-extra-light);
    }
}
</style>
src/layout/logo/index.vue
对比新文件
@@ -0,0 +1,85 @@
<template>
    <div class="layout-logo" v-if="setShowLogo" @click="onThemeConfigChange">
        <img :src="logoMini" class="layout-logo-medium-img" />
        <span>{{ themeConfig.globalTitle }}</span>
    </div>
    <div class="layout-logo-size" v-else @click="onThemeConfigChange">
        <img :src="logoMini" class="layout-logo-size-img" />
    </div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import logoMini from '/@/assets/logo-mini.svg';
export default defineComponent({
    name: 'layoutLogo',
    setup() {
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        // 设置 logo 的显示。classic 经典布局默认显示 logo
        const setShowLogo = computed(() => {
            let { isCollapse, layout } = themeConfig.value;
            return !isCollapse || layout === 'classic' || document.body.clientWidth < 1000;
        });
        // logo 点击实现菜单展开/收起
        const onThemeConfigChange = () => {
            if (themeConfig.value.layout === 'transverse') return false;
            themeConfig.value.isCollapse = !themeConfig.value.isCollapse;
        };
        return {
            logoMini,
            setShowLogo,
            themeConfig,
            onThemeConfigChange,
        };
    },
});
</script>
<style scoped lang="scss">
.layout-logo {
    width: 220px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: rgb(0 21 41 / 2%) 0px 1px 4px;
    color: var(--el-color-primary);
    font-size: 16px;
    cursor: pointer;
    animation: logoAnimation 0.3s ease-in-out;
    span {
        white-space: nowrap;
        display: inline-block;
    }
    &:hover {
        span {
            color: var(--color-primary-light-2);
        }
    }
    &-medium-img {
        width: 20px;
        margin-right: 5px;
    }
}
.layout-logo-size {
    width: 100%;
    height: 50px;
    display: flex;
    cursor: pointer;
    animation: logoAnimation 0.3s ease-in-out;
    &-img {
        width: 20px;
        margin: auto;
    }
    &:hover {
        img {
            animation: logoAnimation 0.3s ease-in-out;
        }
    }
}
</style>
src/layout/main/classic.vue
对比新文件
@@ -0,0 +1,35 @@
<template>
    <el-container class="layout-container flex-center">
        <Header />
        <el-container class="layout-mian-height-50">
            <Aside />
            <div class="flex-center layout-backtop">
                <TagsView v-if="themeConfig.isTagsview" />
                <Main />
            </div>
        </el-container>
        <el-backtop target=".layout-backtop .el-main .el-scrollbar__wrap"></el-backtop>
    </el-container>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import Aside from '/@/layout/component/aside.vue';
import Header from '/@/layout/component/header.vue';
import Main from '/@/layout/component/main.vue';
import TagsView from '/@/layout/navBars/tagsView/tagsView.vue';
export default defineComponent({
    name: 'layoutClassic',
    components: { Aside, Header, Main, TagsView },
    setup() {
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        return {
            themeConfig,
        };
    },
});
</script>
src/layout/main/columns.vue
对比新文件
@@ -0,0 +1,41 @@
<template>
    <el-container class="layout-container">
        <ColumnsAside />
        <div class="layout-columns-warp">
            <Aside />
            <el-container class="flex-center layout-backtop" :class="{ 'layout-backtop': !isFixedHeader }">
                <Header v-if="isFixedHeader" />
                <el-scrollbar :class="{ 'layout-backtop': isFixedHeader }">
                    <Header v-if="!isFixedHeader" />
                    <Main />
                </el-scrollbar>
            </el-container>
        </div>
        <el-backtop target=".layout-backtop .el-scrollbar__wrap"></el-backtop>
    </el-container>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import Aside from '/@/layout/component/aside.vue';
import Header from '/@/layout/component/header.vue';
import Main from '/@/layout/component/main.vue';
import ColumnsAside from '/@/layout/component/columnsAside.vue';
export default defineComponent({
    name: 'layoutColumns',
    components: { Aside, Header, Main, ColumnsAside },
    setup() {
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const isFixedHeader = computed(() => {
            return themeConfig.value.isFixedHeader;
        });
        return {
            isFixedHeader,
        };
    },
});
</script>
src/layout/main/defaults.vue
对比新文件
@@ -0,0 +1,47 @@
<template>
    <el-container class="layout-container">
        <Aside />
        <el-container class="flex-center" :class="{ 'layout-backtop': !isFixedHeader }">
            <Header v-if="isFixedHeader" />
            <el-scrollbar ref="layoutDefaultsScrollbarRef" :class="{ 'layout-backtop': isFixedHeader }">
                <Header v-if="!isFixedHeader" />
                <Main />
            </el-scrollbar>
        </el-container>
        <el-backtop target=".layout-backtop .el-scrollbar__wrap"></el-backtop>
    </el-container>
</template>
<script lang="ts">
import { computed, getCurrentInstance, watch, defineComponent } from 'vue';
import { useRoute } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import Aside from '/@/layout/component/aside.vue';
import Header from '/@/layout/component/header.vue';
import Main from '/@/layout/component/main.vue';
export default defineComponent({
    name: 'layoutDefaults',
    components: { Aside, Header, Main },
    setup() {
        const { proxy } = <any>getCurrentInstance();
        const route = useRoute();
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const isFixedHeader = computed(() => {
            return themeConfig.value.isFixedHeader;
        });
        // 监听路由的变化
        watch(
            () => route.path,
            () => {
                proxy.$refs.layoutDefaultsScrollbarRef.wrap$.scrollTop = 0;
            }
        );
        return {
            isFixedHeader,
        };
    },
});
</script>
src/layout/main/transverse.vue
对比新文件
@@ -0,0 +1,17 @@
<template>
    <el-container class="layout-container flex-center layout-backtop">
        <Header />
        <Main />
        <el-backtop target=".layout-backtop .el-main .el-scrollbar__wrap"></el-backtop>
    </el-container>
</template>
<script lang="ts">
import Header from '/@/layout/component/header.vue';
import Main from '/@/layout/component/main.vue';
export default {
    name: 'layoutTransverse',
    components: { Header, Main },
};
</script>
src/layout/navBars/breadcrumb/breadcrumb.vue
对比新文件
@@ -0,0 +1,162 @@
<template>
    <div v-if="isShowBreadcrumb" class="layout-navbars-breadcrumb">
        <SvgIcon
            class="layout-navbars-breadcrumb-icon"
            :name="themeConfig.isCollapse ? 'ele-Expand' : 'ele-Fold'"
            :size="16"
            @click="onThemeConfigChange"
        />
        <el-breadcrumb class="layout-navbars-breadcrumb-hide">
            <transition-group name="breadcrumb">
                <el-breadcrumb-item v-for="(v, k) in breadcrumbList" :key="!v.meta.tagsViewName ? v.meta.title : v.meta.tagsViewName">
                    <span v-if="k === breadcrumbList.length - 1" class="layout-navbars-breadcrumb-span">
                        <SvgIcon :name="v.meta.icon" class="layout-navbars-breadcrumb-iconfont" v-if="themeConfig.isBreadcrumbIcon" />
                        <div v-if="!v.meta.tagsViewName">{{ $t(v.meta.title) }}</div>
                        <div v-else>{{ v.meta.tagsViewName }}</div>
                    </span>
                    <a v-else @click.prevent="onBreadcrumbClick(v)">
                        <SvgIcon :name="v.meta.icon" class="layout-navbars-breadcrumb-iconfont" v-if="themeConfig.isBreadcrumbIcon" />{{ $t(v.meta.title) }}
                    </a>
                </el-breadcrumb-item>
            </transition-group>
        </el-breadcrumb>
    </div>
</template>
<script lang="ts">
import { toRefs, reactive, computed, onMounted, defineComponent } from 'vue';
import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router';
import { Local } from '/@/utils/storage';
import other from '/@/utils/other';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import { useRoutesList } from '/@/stores/routesList';
// 定义接口来定义对象的类型
interface BreadcrumbState {
    breadcrumbList: Array<any>;
    routeSplit: Array<string>;
    routeSplitFirst: string;
    routeSplitIndex: number;
}
export default defineComponent({
    name: 'layoutBreadcrumb',
    setup() {
        const stores = useRoutesList();
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const { routesList } = storeToRefs(stores);
        const route = useRoute();
        const router = useRouter();
        const state = reactive<BreadcrumbState>({
            breadcrumbList: [],
            routeSplit: [],
            routeSplitFirst: '',
            routeSplitIndex: 1,
        });
        // 动态设置经典、横向布局不显示
        const isShowBreadcrumb = computed(() => {
            initRouteSplit(route.path);
            const { layout, isBreadcrumb } = themeConfig.value;
            if (layout === 'classic' || layout === 'transverse') return false;
            else return isBreadcrumb ? true : false;
        });
        // 面包屑点击时
        const onBreadcrumbClick = (v: any) => {
            const { redirect, path } = v;
            if (redirect) router.push(redirect);
            else router.push(path);
        };
        // 展开/收起左侧菜单点击
        const onThemeConfigChange = () => {
            themeConfig.value.isCollapse = !themeConfig.value.isCollapse;
            setLocalThemeConfig();
        };
        // 存储布局配置
        const setLocalThemeConfig = () => {
            Local.remove('themeConfig');
            Local.set('themeConfig', themeConfig.value);
        };
        // 处理面包屑数据
        const getBreadcrumbList = (arr: Array<string>) => {
            arr.forEach((item: any) => {
                state.routeSplit.forEach((v: any, k: number, arrs: any) => {
                    if (state.routeSplitFirst === item.path) {
                        state.routeSplitFirst += `/${arrs[state.routeSplitIndex]}`;
                        state.breadcrumbList.push(item);
                        state.routeSplitIndex++;
                        if (item.children) getBreadcrumbList(item.children);
                    }
                });
            });
        };
        // 当前路由字符串切割成数组,并删除第一项空内容
        const initRouteSplit = (path: string) => {
            if (!themeConfig.value.isBreadcrumb) return false;
            state.breadcrumbList = [routesList.value[0]];
            state.routeSplit = path.split('/');
            state.routeSplit.shift();
            state.routeSplitFirst = `/${state.routeSplit[0]}`;
            state.routeSplitIndex = 1;
            getBreadcrumbList(routesList.value);
            if (route.name === 'home' || (route.name === 'notFound' && state.breadcrumbList.length > 1)) state.breadcrumbList.shift();
            if (state.breadcrumbList.length > 0) state.breadcrumbList[state.breadcrumbList.length - 1].meta.tagsViewName = other.setTagsViewNameI18n(route);
        };
        // 页面加载时
        onMounted(() => {
            initRouteSplit(route.path);
        });
        // 路由更新时
        onBeforeRouteUpdate((to) => {
            initRouteSplit(to.path);
        });
        return {
            onThemeConfigChange,
            isShowBreadcrumb,
            themeConfig,
            onBreadcrumbClick,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.layout-navbars-breadcrumb {
    height: inherit;
    display: flex;
    align-items: center;
    .layout-navbars-breadcrumb-icon {
        cursor: pointer;
        font-size: 18px;
        color: var(--next-bg-topBarColor);
        height: 100%;
        width: 40px;
        opacity: 0.8;
        &:hover {
            opacity: 1;
        }
    }
    .layout-navbars-breadcrumb-span {
        display: flex;
        opacity: 0.7;
        color: var(--next-bg-topBarColor);
    }
    .layout-navbars-breadcrumb-iconfont {
        font-size: 14px;
        margin-right: 5px;
    }
    ::v-deep(.el-breadcrumb__separator) {
        opacity: 0.7;
        color: var(--next-bg-topBarColor);
    }
    ::v-deep(.el-breadcrumb__inner a, .el-breadcrumb__inner.is-link) {
        font-weight: unset !important;
        color: var(--next-bg-topBarColor);
        &:hover {
            color: var(--el-color-primary) !important;
        }
    }
}
</style>
src/layout/navBars/breadcrumb/closeFull.vue
对比新文件
@@ -0,0 +1,61 @@
<template>
    <div class="layout-navbars-close-full" v-if="isTagsViewCurrenFull">
        <div class="layout-navbars-close-full-icon">
            <SvgIcon name="ele-Close" :title="$t('message.tagsView.closeFullscreen')" @click="onCloseFullscreen" />
        </div>
    </div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { storeToRefs } from 'pinia';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
export default defineComponent({
    name: 'layoutCloseFull',
    setup() {
        const stores = useTagsViewRoutes();
        const { isTagsViewCurrenFull } = storeToRefs(stores);
        // 关闭当前全屏
        const onCloseFullscreen = () => {
            stores.setCurrenFullscreen(false);
        };
        return {
            isTagsViewCurrenFull,
            onCloseFullscreen,
        };
    },
});
</script>
<style scoped lang="scss">
.layout-navbars-close-full {
    position: fixed;
    z-index: 9999999999;
    right: -30px;
    top: -30px;
    .layout-navbars-close-full-icon {
        width: 60px;
        height: 60px;
        border-radius: 100%;
        cursor: pointer;
        background: rgba(0, 0, 0, 0.1);
        transition: all 0.3s ease;
        position: relative;
        ::v-deep(i) {
            position: absolute;
            left: 10px;
            top: 35px;
            color: #333333;
            transition: all 0.3s ease;
        }
    }
    &:hover {
        transition: all 0.3s ease;
        ::v-deep(i) {
            color: var(--el-color-primary);
            transition: all 0.3s ease;
        }
    }
}
</style>
src/layout/navBars/breadcrumb/index.vue
对比新文件
@@ -0,0 +1,119 @@
<template>
    <div class="layout-navbars-breadcrumb-index">
        <Logo v-if="setIsShowLogo" />
        <Breadcrumb />
        <Horizontal :menuList="menuList" v-if="isLayoutTransverse" />
        <User />
    </div>
</template>
<script lang="ts">
import { computed, reactive, toRefs, onMounted, onUnmounted, getCurrentInstance, defineComponent } from 'vue';
import { useRoute } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useRoutesList } from '/@/stores/routesList';
import { useThemeConfig } from '/@/stores/themeConfig';
import Breadcrumb from '/@/layout/navBars/breadcrumb/breadcrumb.vue';
import User from '/@/layout/navBars/breadcrumb/user.vue';
import Logo from '/@/layout/logo/index.vue';
import Horizontal from '/@/layout/navMenu/horizontal.vue';
// 定义接口来定义对象的类型
interface IndexState {
    menuList: object[];
}
export default defineComponent({
    name: 'layoutBreadcrumbIndex',
    components: { Breadcrumb, User, Logo, Horizontal },
    setup() {
        const { proxy } = <any>getCurrentInstance();
        const stores = useRoutesList();
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const { routesList } = storeToRefs(stores);
        const route = useRoute();
        const state = reactive<IndexState>({
            menuList: [],
        });
        // 设置 logo 显示/隐藏
        const setIsShowLogo = computed(() => {
            let { isShowLogo, layout } = themeConfig.value;
            return (isShowLogo && layout === 'classic') || (isShowLogo && layout === 'transverse');
        });
        // 设置是否显示横向导航菜单
        const isLayoutTransverse = computed(() => {
            let { layout, isClassicSplitMenu } = themeConfig.value;
            return layout === 'transverse' || (isClassicSplitMenu && layout === 'classic');
        });
        // 设置/过滤路由(非静态路由/是否显示在菜单中)
        const setFilterRoutes = () => {
            let { layout, isClassicSplitMenu } = themeConfig.value;
            if (layout === 'classic' && isClassicSplitMenu) {
                state.menuList = delClassicChildren(filterRoutesFun(routesList.value));
                const resData = setSendClassicChildren(route.path);
                proxy.mittBus.emit('setSendClassicChildren', resData);
            } else {
                state.menuList = filterRoutesFun(routesList.value);
            }
        };
        // 设置了分割菜单时,删除底下 children
        const delClassicChildren = (arr: Array<object>) => {
            arr.map((v: any) => {
                if (v.children) delete v.children;
            });
            return arr;
        };
        // 路由过滤递归函数
        const filterRoutesFun = (arr: Array<string>) => {
            return arr
                .filter((item: any) => !item.meta.isHide)
                .map((item: any) => {
                    item = Object.assign({}, item);
                    if (item.children) item.children = filterRoutesFun(item.children);
                    return item;
                });
        };
        // 传送当前子级数据到菜单中
        const setSendClassicChildren = (path: string) => {
            const currentPathSplit = path.split('/');
            let currentData: any = {};
            filterRoutesFun(routesList.value).map((v, k) => {
                if (v.path === `/${currentPathSplit[1]}`) {
                    v['k'] = k;
                    currentData['item'] = [{ ...v }];
                    currentData['children'] = [{ ...v }];
                    if (v.children) currentData['children'] = v.children;
                }
            });
            return currentData;
        };
        // 页面加载时
        onMounted(() => {
            setFilterRoutes();
            proxy.mittBus.on('getBreadcrumbIndexSetFilterRoutes', () => {
                setFilterRoutes();
            });
        });
        // 页面卸载时
        onUnmounted(() => {
            proxy.mittBus.off('getBreadcrumbIndexSetFilterRoutes', () => {});
        });
        return {
            setIsShowLogo,
            isLayoutTransverse,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.layout-navbars-breadcrumb-index {
    height: 80px;
    display: flex;
    align-items: center;
    background: var(--next-bg-topBar);
    border-bottom: 1px solid var(--next-border-color-light);
}
</style>
src/layout/navBars/breadcrumb/search.vue
对比新文件
@@ -0,0 +1,138 @@
<template>
    <div class="layout-search-dialog">
        <el-dialog v-model="isShowSearch" width="300px" destroy-on-close :modal="false" fullscreen :show-close="false">
            <el-autocomplete
                v-model="menuQuery"
                :fetch-suggestions="menuSearch"
                :placeholder="$t('message.user.searchPlaceholder')"
                ref="layoutMenuAutocompleteRef"
                @select="onHandleSelect"
                @blur="onSearchBlur"
            >
                <template #prefix>
                    <el-icon class="el-input__icon">
                        <ele-Search />
                    </el-icon>
                </template>
                <template #default="{ item }">
                    <div>
                        <SvgIcon :name="item.meta.icon" class="mr5" />
                        {{ $t(item.meta.title) }}
                    </div>
                </template>
            </el-autocomplete>
        </el-dialog>
    </div>
</template>
<script lang="ts">
import { reactive, toRefs, defineComponent, ref, nextTick } from 'vue';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { storeToRefs } from 'pinia';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
// 定义接口来定义对象的类型
interface SearchState {
    isShowSearch: boolean;
    menuQuery: string;
    tagsViewList: object[];
}
interface Restaurant {
    path: string;
    meta: {
        title: string;
    };
}
export default defineComponent({
    name: 'layoutBreadcrumbSearch',
    setup() {
        const storesTagsViewRoutes = useTagsViewRoutes();
        const { tagsViewRoutes } = storeToRefs(storesTagsViewRoutes);
        const layoutMenuAutocompleteRef = ref();
        const { t } = useI18n();
        const router = useRouter();
        const state = reactive<SearchState>({
            isShowSearch: false,
            menuQuery: '',
            tagsViewList: [],
        });
        // 搜索弹窗打开
        const openSearch = () => {
            state.menuQuery = '';
            state.isShowSearch = true;
            initTageView();
            nextTick(() => {
                setTimeout(() => {
                    layoutMenuAutocompleteRef.value.focus();
                });
            });
        };
        // 搜索弹窗关闭
        const closeSearch = () => {
            state.isShowSearch = false;
        };
        // 菜单搜索数据过滤
        const menuSearch = (queryString: string, cb: Function) => {
            let results = queryString ? state.tagsViewList.filter(createFilter(queryString)) : state.tagsViewList;
            cb(results);
        };
        // 菜单搜索过滤
        const createFilter: any = (queryString: string) => {
            return (restaurant: Restaurant) => {
                return (
                    restaurant.path.toLowerCase().indexOf(queryString.toLowerCase()) > -1 ||
                    restaurant.meta.title.toLowerCase().indexOf(queryString.toLowerCase()) > -1 ||
                    t(restaurant.meta.title).indexOf(queryString.toLowerCase()) > -1
                );
            };
        };
        // 初始化菜单数据
        const initTageView = () => {
            if (state.tagsViewList.length > 0) return false;
            tagsViewRoutes.value.map((v: any) => {
                if (!v.meta.isHide) state.tagsViewList.push({ ...v });
            });
        };
        // 当前菜单选中时
        const onHandleSelect = (item: any) => {
            let { path, redirect } = item;
            if (item.meta.isLink && !item.meta.isIframe) window.open(item.meta.isLink);
            else if (redirect) router.push(redirect);
            else router.push(path);
            closeSearch();
        };
        // input 失去焦点时
        const onSearchBlur = () => {
            closeSearch();
        };
        return {
            layoutMenuAutocompleteRef,
            openSearch,
            closeSearch,
            menuSearch,
            onHandleSelect,
            onSearchBlur,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.layout-search-dialog {
    ::v-deep(.el-dialog) {
        box-shadow: unset !important;
        border-radius: 0 !important;
        background: rgba(0, 0, 0, 0.5);
    }
    ::v-deep(.el-autocomplete) {
        width: 560px;
        position: absolute;
        top: 100px;
        left: 50%;
        transform: translateX(-50%);
    }
}
</style>
src/layout/navBars/breadcrumb/setings.vue
对比新文件
@@ -0,0 +1,816 @@
<template>
    <div class="layout-breadcrumb-seting">
        <el-drawer
            :title="$t('message.layout.configTitle')"
            v-model="getThemeConfig.isDrawer"
            direction="rtl"
            destroy-on-close
            size="260px"
            @close="onDrawerClose"
        >
            <el-scrollbar class="layout-breadcrumb-seting-bar">
                <!-- 全局主题 -->
                <el-divider content-position="left">{{ $t('message.layout.oneTitle') }}</el-divider>
                <div class="layout-breadcrumb-seting-bar-flex">
                    <div class="layout-breadcrumb-seting-bar-flex-label">primary</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-color-picker v-model="getThemeConfig.primary" size="default" @change="onColorPickerChange"> </el-color-picker>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsDark') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isIsDark" size="small" @change="onAddDarkChange"></el-switch>
                    </div>
                </div>
                <!-- 顶栏设置 -->
                <el-divider content-position="left">{{ $t('message.layout.twoTopTitle') }}</el-divider>
                <div class="layout-breadcrumb-seting-bar-flex">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoTopBar') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-color-picker v-model="getThemeConfig.topBar" size="default" @change="onBgColorPickerChange('topBar')"> </el-color-picker>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoTopBarColor') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-color-picker v-model="getThemeConfig.topBarColor" size="default" @change="onBgColorPickerChange('topBarColor')"> </el-color-picker>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt10">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoIsTopBarColorGradual') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isTopBarColorGradual" size="small" @change="onTopBarGradualChange"></el-switch>
                    </div>
                </div>
                <!-- 菜单设置 -->
                <el-divider content-position="left">{{ $t('message.layout.twoMenuTitle') }}</el-divider>
                <div class="layout-breadcrumb-seting-bar-flex">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoMenuBar') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-color-picker v-model="getThemeConfig.menuBar" size="default" @change="onBgColorPickerChange('menuBar')"> </el-color-picker>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoMenuBarColor') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-color-picker v-model="getThemeConfig.menuBarColor" size="default" @change="onBgColorPickerChange('menuBarColor')"> </el-color-picker>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt14">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoIsMenuBarColorGradual') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isMenuBarColorGradual" size="small" @change="onMenuBarGradualChange"></el-switch>
                    </div>
                </div>
                <!-- 分栏设置 -->
                <el-divider content-position="left" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">{{
                    $t('message.layout.twoColumnsTitle')
                }}</el-divider>
                <div class="layout-breadcrumb-seting-bar-flex" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoColumnsMenuBar') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-color-picker
                            v-model="getThemeConfig.columnsMenuBar"
                            size="default"
                            @change="onBgColorPickerChange('columnsMenuBar')"
                            :disabled="getThemeConfig.layout !== 'columns'"
                        >
                        </el-color-picker>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoColumnsMenuBarColor') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-color-picker
                            v-model="getThemeConfig.columnsMenuBarColor"
                            size="default"
                            @change="onBgColorPickerChange('columnsMenuBarColor')"
                            :disabled="getThemeConfig.layout !== 'columns'"
                        >
                        </el-color-picker>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt14" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.twoIsColumnsMenuBarColorGradual') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch
                            v-model="getThemeConfig.isColumnsMenuBarColorGradual"
                            size="small"
                            @change="onColumnsMenuBarGradualChange"
                            :disabled="getThemeConfig.layout !== 'columns'"
                        ></el-switch>
                    </div>
                </div>
                <!-- 界面设置 -->
                <el-divider content-position="left">{{ $t('message.layout.threeTitle') }}</el-divider>
                <div class="layout-breadcrumb-seting-bar-flex" :style="{ opacity: getThemeConfig.layout === 'transverse' ? 0.5 : 1 }">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeIsCollapse') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch
                            v-model="getThemeConfig.isCollapse"
                            :disabled="getThemeConfig.layout === 'transverse'"
                            size="small"
                            @change="onThemeConfigChange"
                        ></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15" :style="{ opacity: getThemeConfig.layout === 'transverse' ? 0.5 : 1 }">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeIsUniqueOpened') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch
                            v-model="getThemeConfig.isUniqueOpened"
                            :disabled="getThemeConfig.layout === 'transverse'"
                            size="small"
                            @change="setLocalThemeConfig"
                        ></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeIsFixedHeader') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isFixedHeader" size="small" @change="onIsFixedHeaderChange"></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15" :style="{ opacity: getThemeConfig.layout !== 'classic' ? 0.5 : 1 }">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeIsClassicSplitMenu') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch
                            v-model="getThemeConfig.isClassicSplitMenu"
                            :disabled="getThemeConfig.layout !== 'classic'"
                            size="small"
                            @change="onClassicSplitMenuChange"
                        >
                        </el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeIsLockScreen') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isLockScreen" size="small" @change="setLocalThemeConfig"></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt11">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.threeLockScreenTime') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-input-number
                            v-model="getThemeConfig.lockScreenTime"
                            controls-position="right"
                            :min="1"
                            :max="9999"
                            @change="setLocalThemeConfig"
                            size="default"
                            style="width: 90px"
                        >
                        </el-input-number>
                    </div>
                </div>
                <!-- 界面显示 -->
                <el-divider content-position="left">{{ $t('message.layout.fourTitle') }}</el-divider>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsShowLogo') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isShowLogo" size="small" @change="onIsShowLogoChange"></el-switch>
                    </div>
                </div>
                <div
                    class="layout-breadcrumb-seting-bar-flex mt15"
                    :style="{ opacity: getThemeConfig.layout === 'classic' || getThemeConfig.layout === 'transverse' ? 0.5 : 1 }"
                >
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsBreadcrumb') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch
                            v-model="getThemeConfig.isBreadcrumb"
                            :disabled="getThemeConfig.layout === 'classic' || getThemeConfig.layout === 'transverse'"
                            size="small"
                            @change="onIsBreadcrumbChange"
                        ></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsBreadcrumbIcon') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isBreadcrumbIcon" size="small" @change="setLocalThemeConfig"></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsTagsview') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isTagsview" size="small" @change="setLocalThemeConfig"></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsTagsviewIcon') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isTagsviewIcon" size="small" @change="setLocalThemeConfig"></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsCacheTagsView') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isCacheTagsView" size="small" @change="setLocalThemeConfig"></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15" :style="{ opacity: isMobile ? 0.5 : 1 }">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsSortableTagsView') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch
                            v-model="getThemeConfig.isSortableTagsView"
                            :disabled="isMobile ? true : false"
                            size="small"
                            @change="onSortableTagsViewChange"
                        ></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsShareTagsView') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isShareTagsView" size="small" @change="onShareTagsViewChange"></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsFooter') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isFooter" size="small" @change="setLocalThemeConfig"></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsGrayscale') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isGrayscale" size="small" @change="onAddFilterChange('grayscale')"></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsInvert') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isInvert" size="small" @change="onAddFilterChange('invert')"></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourIsWartermark') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-switch v-model="getThemeConfig.isWartermark" size="small" @change="onWartermarkChange"></el-switch>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt14">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fourWartermarkText') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-input v-model="getThemeConfig.wartermarkText" size="default" style="width: 90px" @input="onWartermarkTextInput($event)"></el-input>
                    </div>
                </div>
                <!-- 其它设置 -->
                <el-divider content-position="left">{{ $t('message.layout.fiveTitle') }}</el-divider>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fiveTagsStyle') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-select v-model="getThemeConfig.tagsStyle" placeholder="请选择" size="default" style="width: 90px" @change="setLocalThemeConfig">
                            <el-option label="风格1" value="tags-style-one"></el-option>
                            <el-option label="风格4" value="tags-style-four"></el-option>
                            <el-option label="风格5" value="tags-style-five"></el-option>
                        </el-select>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fiveAnimation') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-select v-model="getThemeConfig.animation" placeholder="请选择" size="default" style="width: 90px" @change="setLocalThemeConfig">
                            <el-option label="slide-right" value="slide-right"></el-option>
                            <el-option label="slide-left" value="slide-left"></el-option>
                            <el-option label="opacitys" value="opacitys"></el-option>
                        </el-select>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fiveColumnsAsideStyle') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-select
                            v-model="getThemeConfig.columnsAsideStyle"
                            placeholder="请选择"
                            size="default"
                            style="width: 90px"
                            :disabled="getThemeConfig.layout !== 'columns' ? true : false"
                            @change="setLocalThemeConfig"
                        >
                            <el-option label="圆角" value="columns-round"></el-option>
                            <el-option label="卡片" value="columns-card"></el-option>
                        </el-select>
                    </div>
                </div>
                <div class="layout-breadcrumb-seting-bar-flex mt15 mb27" :style="{ opacity: getThemeConfig.layout !== 'columns' ? 0.5 : 1 }">
                    <div class="layout-breadcrumb-seting-bar-flex-label">{{ $t('message.layout.fiveColumnsAsideLayout') }}</div>
                    <div class="layout-breadcrumb-seting-bar-flex-value">
                        <el-select
                            v-model="getThemeConfig.columnsAsideLayout"
                            placeholder="请选择"
                            size="default"
                            style="width: 90px"
                            :disabled="getThemeConfig.layout !== 'columns' ? true : false"
                            @change="setLocalThemeConfig"
                        >
                            <el-option label="水平" value="columns-horizontal"></el-option>
                            <el-option label="垂直" value="columns-vertical"></el-option>
                        </el-select>
                    </div>
                </div>
                <!-- 布局切换 -->
                <el-divider content-position="left">{{ $t('message.layout.sixTitle') }}</el-divider>
                <div class="layout-drawer-content-flex">
                    <!-- defaults 布局 -->
                    <div class="layout-drawer-content-item" @click="onSetLayout('defaults')">
                        <section class="el-container el-circular" :class="{ 'drawer-layout-active': getThemeConfig.layout === 'defaults' }">
                            <aside class="el-aside" style="width: 20px"></aside>
                            <section class="el-container is-vertical">
                                <header class="el-header" style="height: 10px"></header>
                                <main class="el-main"></main>
                            </section>
                        </section>
                        <div class="layout-tips-warp" :class="{ 'layout-tips-warp-active': getThemeConfig.layout === 'defaults' }">
                            <div class="layout-tips-box">
                                <p class="layout-tips-txt">{{ $t('message.layout.sixDefaults') }}</p>
                            </div>
                        </div>
                    </div>
                    <!-- classic 布局 -->
                    <div class="layout-drawer-content-item" @click="onSetLayout('classic')">
                        <section class="el-container is-vertical el-circular" :class="{ 'drawer-layout-active': getThemeConfig.layout === 'classic' }">
                            <header class="el-header" style="height: 10px"></header>
                            <section class="el-container">
                                <aside class="el-aside" style="width: 20px"></aside>
                                <section class="el-container is-vertical">
                                    <main class="el-main"></main>
                                </section>
                            </section>
                        </section>
                        <div class="layout-tips-warp" :class="{ 'layout-tips-warp-active': getThemeConfig.layout === 'classic' }">
                            <div class="layout-tips-box">
                                <p class="layout-tips-txt">{{ $t('message.layout.sixClassic') }}</p>
                            </div>
                        </div>
                    </div>
                    <!-- transverse 布局 -->
                    <div class="layout-drawer-content-item" @click="onSetLayout('transverse')">
                        <section class="el-container is-vertical el-circular" :class="{ 'drawer-layout-active': getThemeConfig.layout === 'transverse' }">
                            <header class="el-header" style="height: 10px"></header>
                            <section class="el-container">
                                <section class="el-container is-vertical">
                                    <main class="el-main"></main>
                                </section>
                            </section>
                        </section>
                        <div class="layout-tips-warp" :class="{ 'layout-tips-warp-active': getThemeConfig.layout === 'transverse' }">
                            <div class="layout-tips-box">
                                <p class="layout-tips-txt">{{ $t('message.layout.sixTransverse') }}</p>
                            </div>
                        </div>
                    </div>
                    <!-- columns 布局 -->
                    <div class="layout-drawer-content-item" @click="onSetLayout('columns')">
                        <section class="el-container el-circular" :class="{ 'drawer-layout-active': getThemeConfig.layout === 'columns' }">
                            <aside class="el-aside-dark" style="width: 10px"></aside>
                            <aside class="el-aside" style="width: 20px"></aside>
                            <section class="el-container is-vertical">
                                <header class="el-header" style="height: 10px"></header>
                                <main class="el-main"></main>
                            </section>
                        </section>
                        <div class="layout-tips-warp" :class="{ 'layout-tips-warp-active': getThemeConfig.layout === 'columns' }">
                            <div class="layout-tips-box">
                                <p class="layout-tips-txt">{{ $t('message.layout.sixColumns') }}</p>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="copy-config">
                    <el-alert :title="$t('message.layout.tipText')" type="warning" :closable="false"> </el-alert>
                    <el-button size="default" class="copy-config-btn" type="primary" ref="copyConfigBtnRef" @click="onCopyConfigClick">
                        <el-icon class="mr5">
                            <ele-CopyDocument />
                        </el-icon>
                        {{ $t('message.layout.copyText') }}
                    </el-button>
                    <el-button size="default" class="copy-config-btn-reset" type="info" @click="onResetConfigClick">
                        <el-icon class="mr5">
                            <ele-RefreshRight />
                        </el-icon>
                        {{ $t('message.layout.resetText') }}
                    </el-button>
                </div>
            </el-scrollbar>
        </el-drawer>
    </div>
</template>
<script lang="ts">
import { nextTick, onUnmounted, onMounted, getCurrentInstance, defineComponent, computed, reactive, toRefs } from 'vue';
import { ElMessage } from 'element-plus';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import { getLightColor, getDarkColor } from '/@/utils/theme';
import { verifyAndSpace } from '/@/utils/toolsValidate';
import { Local } from '/@/utils/storage';
import Watermark from '/@/utils/wartermark';
import commonFunction from '/@/utils/commonFunction';
import other from '/@/utils/other';
export default defineComponent({
    name: 'layoutBreadcrumbSeting',
    setup() {
        const { proxy } = <any>getCurrentInstance();
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const { copyText } = commonFunction();
        const state = reactive({
            isMobile: false,
        });
        // 获取布局配置信息
        const getThemeConfig = computed(() => {
            return themeConfig.value;
        });
        // 1、全局主题
        const onColorPickerChange = () => {
            if (!getThemeConfig.value.primary) return ElMessage.warning('全局主题 primary 颜色值不能为空');
            // 颜色加深
            document.documentElement.style.setProperty('--el-color-primary-dark-2', `${getDarkColor(getThemeConfig.value.primary, 0.1)}`);
            document.documentElement.style.setProperty('--el-color-primary', getThemeConfig.value.primary);
            // 颜色变浅
            for (let i = 1; i <= 9; i++) {
                document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(getThemeConfig.value.primary, i / 10)}`);
            }
            setDispatchThemeConfig();
        };
        // 2、菜单 / 顶栏
        const onBgColorPickerChange = (bg: string) => {
            document.documentElement.style.setProperty(`--next-bg-${bg}`, (<any>getThemeConfig.value)[bg]);
            if (bg === 'menuBar') {
                document.documentElement.style.setProperty(`--next-bg-menuBar-light-1`, <any>getLightColor(getThemeConfig.value.menuBar, 0.05));
            }
            onTopBarGradualChange();
            onMenuBarGradualChange();
            onColumnsMenuBarGradualChange();
            setDispatchThemeConfig();
        };
        // 2、菜单 / 顶栏 --> 顶栏背景渐变
        const onTopBarGradualChange = () => {
            setGraduaFun('.layout-navbars-breadcrumb-index', getThemeConfig.value.isTopBarColorGradual, getThemeConfig.value.topBar);
        };
        // 2、菜单 / 顶栏 --> 菜单背景渐变
        const onMenuBarGradualChange = () => {
            setGraduaFun('.layout-container .el-aside', getThemeConfig.value.isMenuBarColorGradual, getThemeConfig.value.menuBar);
        };
        // 2、菜单 / 顶栏 --> 分栏菜单背景渐变
        const onColumnsMenuBarGradualChange = () => {
            setGraduaFun('.layout-container .layout-columns-aside', getThemeConfig.value.isColumnsMenuBarColorGradual, getThemeConfig.value.columnsMenuBar);
        };
        // 2、菜单 / 顶栏 --> 背景渐变函数
        const setGraduaFun = (el: string, bool: boolean, color: string) => {
            setTimeout(() => {
                let els = document.querySelector(el);
                if (!els) return false;
                document.documentElement.style.setProperty('--el-menu-bg-color', document.documentElement.style.getPropertyValue('--next-bg-menuBar'));
                if (bool) els.setAttribute('style', `background:linear-gradient(to bottom left , ${color}, ${getLightColor(color, 0.6)}) !important;`);
                else els.setAttribute('style', ``);
                setLocalThemeConfig();
            }, 200);
        };
        // 3、界面设置 --> 菜单水平折叠
        const onThemeConfigChange = () => {
            setDispatchThemeConfig();
        };
        // 3、界面设置 --> 固定 Header
        const onIsFixedHeaderChange = () => {
            getThemeConfig.value.isFixedHeaderChange = getThemeConfig.value.isFixedHeader ? false : true;
            setLocalThemeConfig();
        };
        // 3、界面设置 --> 经典布局分割菜单
        const onClassicSplitMenuChange = () => {
            getThemeConfig.value.isBreadcrumb = false;
            setLocalThemeConfig();
            proxy.mittBus.emit('getBreadcrumbIndexSetFilterRoutes');
        };
        // 4、界面显示 --> 侧边栏 Logo
        const onIsShowLogoChange = () => {
            getThemeConfig.value.isShowLogoChange = getThemeConfig.value.isShowLogo ? false : true;
            setLocalThemeConfig();
        };
        // 4、界面显示 --> 面包屑 Breadcrumb
        const onIsBreadcrumbChange = () => {
            if (getThemeConfig.value.layout === 'classic') {
                getThemeConfig.value.isClassicSplitMenu = false;
            }
            setLocalThemeConfig();
        };
        // 4、界面显示 --> 开启 TagsView 拖拽
        const onSortableTagsViewChange = () => {
            proxy.mittBus.emit('openOrCloseSortable');
            setLocalThemeConfig();
        };
        // 4、界面显示 --> 开启 TagsView 共用
        const onShareTagsViewChange = () => {
            proxy.mittBus.emit('openShareTagsView');
            setLocalThemeConfig();
        };
        // 4、界面显示 --> 灰色模式/色弱模式
        const onAddFilterChange = (attr: string) => {
            if (attr === 'grayscale') {
                if (getThemeConfig.value.isGrayscale) getThemeConfig.value.isInvert = false;
            } else {
                if (getThemeConfig.value.isInvert) getThemeConfig.value.isGrayscale = false;
            }
            const cssAttr =
                attr === 'grayscale' ? `grayscale(${getThemeConfig.value.isGrayscale ? 1 : 0})` : `invert(${getThemeConfig.value.isInvert ? '80%' : '0%'})`;
            const appEle: any = document.body;
            appEle.setAttribute('style', `filter: ${cssAttr}`);
            setLocalThemeConfig();
        };
        // 4、界面显示 --> 深色模式
        const onAddDarkChange = () => {
            const body = document.documentElement as HTMLElement;
            if (getThemeConfig.value.isIsDark) body.setAttribute('data-theme', 'dark');
            else body.setAttribute('data-theme', '');
        };
        // 4、界面显示 --> 开启水印
        const onWartermarkChange = () => {
            getThemeConfig.value.isWartermark ? Watermark.set(getThemeConfig.value.wartermarkText) : Watermark.del();
            setLocalThemeConfig();
        };
        // 4、界面显示 --> 水印文案
        const onWartermarkTextInput = (val: any) => {
            getThemeConfig.value.wartermarkText = verifyAndSpace(val);
            if (getThemeConfig.value.wartermarkText === '') return false;
            if (getThemeConfig.value.isWartermark) Watermark.set(getThemeConfig.value.wartermarkText);
            setLocalThemeConfig();
        };
        // 5、布局切换
        const onSetLayout = (layout: string) => {
            Local.set('oldLayout', layout);
            if (getThemeConfig.value.layout === layout) return false;
            if (layout === 'transverse') getThemeConfig.value.isCollapse = false;
            getThemeConfig.value.layout = layout;
            getThemeConfig.value.isDrawer = false;
            initLayoutChangeFun();
        };
        // 设置布局切换函数
        const initLayoutChangeFun = () => {
            onBgColorPickerChange('menuBar');
            onBgColorPickerChange('menuBarColor');
            onBgColorPickerChange('topBar');
            onBgColorPickerChange('topBarColor');
            onBgColorPickerChange('columnsMenuBar');
            onBgColorPickerChange('columnsMenuBarColor');
        };
        // 关闭弹窗时,初始化变量。变量用于处理 proxy.$refs.layoutScrollbarRef.update()
        const onDrawerClose = () => {
            getThemeConfig.value.isFixedHeaderChange = false;
            getThemeConfig.value.isShowLogoChange = false;
            getThemeConfig.value.isDrawer = false;
            setLocalThemeConfig();
        };
        // 布局配置弹窗打开
        const openDrawer = () => {
            getThemeConfig.value.isDrawer = true;
        };
        // 触发 store 布局配置更新
        const setDispatchThemeConfig = () => {
            setLocalThemeConfig();
            setLocalThemeConfigStyle();
        };
        // 存储布局配置
        const setLocalThemeConfig = () => {
            Local.remove('themeConfig');
            Local.set('themeConfig', getThemeConfig.value);
        };
        // 存储布局配置全局主题样式(html根标签)
        const setLocalThemeConfigStyle = () => {
            Local.set('themeConfigStyle', document.documentElement.style.cssText);
        };
        // 一键复制配置
        const onCopyConfigClick = () => {
            let copyThemeConfig = Local.get('themeConfig');
            copyThemeConfig.isDrawer = false;
            copyText(JSON.stringify(copyThemeConfig)).then(() => {
                getThemeConfig.value.isDrawer = false;
            });
        };
        // 一键恢复默认
        const onResetConfigClick = () => {
            Local.clear();
            window.location.reload();
        };
        // 初始化菜单样式等
        const initSetStyle = () => {
            // 2、菜单 / 顶栏 --> 顶栏背景渐变
            onTopBarGradualChange();
            // 2、菜单 / 顶栏 --> 菜单背景渐变
            onMenuBarGradualChange();
            // 2、菜单 / 顶栏 --> 分栏菜单背景渐变
            onColumnsMenuBarGradualChange();
        };
        onMounted(() => {
            nextTick(() => {
                // 判断当前布局是否不相同,不相同则初始化当前布局的样式,防止监听窗口大小改变时,布局配置logo、菜单背景等部分布局失效问题
                if (!Local.get('frequency')) initLayoutChangeFun();
                Local.set('frequency', 1);
                // 监听窗口大小改变,非默认布局,设置成默认布局(适配移动端)
                proxy.mittBus.on('layoutMobileResize', (res: any) => {
                    getThemeConfig.value.layout = res.layout;
                    getThemeConfig.value.isDrawer = false;
                    initLayoutChangeFun();
                    state.isMobile = other.isMobile();
                });
                setTimeout(() => {
                    // 默认样式
                    onColorPickerChange();
                    // 灰色模式
                    if (getThemeConfig.value.isGrayscale) onAddFilterChange('grayscale');
                    // 色弱模式
                    if (getThemeConfig.value.isInvert) onAddFilterChange('invert');
                    // 深色模式
                    if (getThemeConfig.value.isIsDark) onAddDarkChange();
                    // 开启水印
                    onWartermarkChange();
                    // 语言国际化
                    if (Local.get('themeConfig')) proxy.$i18n.locale = Local.get('themeConfig').globalI18n;
                    // 初始化菜单样式等
                    initSetStyle();
                }, 100);
            });
        });
        onUnmounted(() => {
            proxy.mittBus.off('layoutMobileResize', () => {});
        });
        return {
            openDrawer,
            onColorPickerChange,
            onBgColorPickerChange,
            onTopBarGradualChange,
            onMenuBarGradualChange,
            onColumnsMenuBarGradualChange,
            onThemeConfigChange,
            onIsFixedHeaderChange,
            onIsShowLogoChange,
            getThemeConfig,
            onDrawerClose,
            onAddFilterChange,
            onAddDarkChange,
            onWartermarkChange,
            onWartermarkTextInput,
            onSetLayout,
            setLocalThemeConfig,
            onClassicSplitMenuChange,
            onIsBreadcrumbChange,
            onSortableTagsViewChange,
            onShareTagsViewChange,
            onCopyConfigClick,
            onResetConfigClick,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.layout-breadcrumb-seting-bar {
    height: calc(100vh - 50px);
    padding: 0 15px;
    ::v-deep(.el-scrollbar__view) {
        overflow-x: hidden !important;
    }
    .layout-breadcrumb-seting-bar-flex {
        display: flex;
        align-items: center;
        margin-bottom: 5px;
        &-label {
            flex: 1;
            color: var(--el-text-color-primary);
        }
    }
    .layout-drawer-content-flex {
        overflow: hidden;
        display: flex;
        flex-wrap: wrap;
        align-content: flex-start;
        margin: 0 -5px;
        .layout-drawer-content-item {
            width: 50%;
            height: 70px;
            cursor: pointer;
            border: 1px solid transparent;
            position: relative;
            padding: 5px;
            .el-container {
                height: 100%;
                .el-aside-dark {
                    background-color: var(--next-color-seting-header);
                }
                .el-aside {
                    background-color: var(--next-color-seting-aside);
                }
                .el-header {
                    background-color: var(--next-color-seting-header);
                }
                .el-main {
                    background-color: var(--next-color-seting-main);
                }
            }
            .el-circular {
                border-radius: 2px;
                overflow: hidden;
                border: 1px solid transparent;
                transition: all 0.3s ease-in-out;
            }
            .drawer-layout-active {
                border: 1px solid;
                border-color: var(--el-color-primary);
            }
            .layout-tips-warp,
            .layout-tips-warp-active {
                transition: all 0.3s ease-in-out;
                position: absolute;
                left: 50%;
                top: 50%;
                transform: translate(-50%, -50%);
                border: 1px solid;
                border-color: var(--el-color-primary-light-5);
                border-radius: 100%;
                padding: 4px;
                .layout-tips-box {
                    transition: inherit;
                    width: 30px;
                    height: 30px;
                    z-index: 9;
                    border: 1px solid;
                    border-color: var(--el-color-primary-light-5);
                    border-radius: 100%;
                    .layout-tips-txt {
                        transition: inherit;
                        position: relative;
                        top: 5px;
                        font-size: 12px;
                        line-height: 1;
                        letter-spacing: 2px;
                        white-space: nowrap;
                        color: var(--el-color-primary-light-5);
                        text-align: center;
                        transform: rotate(30deg);
                        left: -1px;
                        background-color: var(--next-color-seting-main);
                        width: 32px;
                        height: 17px;
                        line-height: 17px;
                    }
                }
            }
            .layout-tips-warp-active {
                border: 1px solid;
                border-color: var(--el-color-primary);
                .layout-tips-box {
                    border: 1px solid;
                    border-color: var(--el-color-primary);
                    .layout-tips-txt {
                        color: var(--el-color-primary) !important;
                        background-color: var(--next-color-seting-main) !important;
                    }
                }
            }
            &:hover {
                .el-circular {
                    transition: all 0.3s ease-in-out;
                    border: 1px solid;
                    border-color: var(--el-color-primary);
                }
                .layout-tips-warp {
                    transition: all 0.3s ease-in-out;
                    border-color: var(--el-color-primary);
                    .layout-tips-box {
                        transition: inherit;
                        border-color: var(--el-color-primary);
                        .layout-tips-txt {
                            transition: inherit;
                            color: var(--el-color-primary) !important;
                            background-color: var(--next-color-seting-main) !important;
                        }
                    }
                }
            }
        }
    }
    .copy-config {
        margin: 10px 0;
        .copy-config-btn {
            width: 100%;
            margin-top: 15px;
        }
        .copy-config-btn-reset {
            width: 100%;
            margin: 10px 0 0;
        }
    }
}
</style>
src/layout/navBars/breadcrumb/user.vue
对比新文件
@@ -0,0 +1,430 @@
<template>
    <div class="layout-navbars-breadcrumb-user pr15" :style="{ flex: layoutUserFlexNum }">
        <div class="logo">
            <img @click="toHome" src="../../../assets/menu/companyLogo.png" />
            <span>{{ systemName }}</span>
        </div>
        <div style="display: flex; align-items: center; padding-right: 5px">
            <div @click="backToMenu()" class="backBtn">返回首页</div>
            <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onComponentSizeChange">
                <div class="layout-navbars-breadcrumb-user-icon">
                    <i class="iconfont icon-ziti" :title="$t('message.user.title0')"></i>
                </div>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item command="large" :disabled="disabledSize === 'large'">{{ $t('message.user.dropdownLarge') }}</el-dropdown-item>
                        <el-dropdown-item command="default" :disabled="disabledSize === 'default'">{{ $t('message.user.dropdownDefault') }}</el-dropdown-item>
                        <el-dropdown-item command="small" :disabled="disabledSize === 'small'">{{ $t('message.user.dropdownSmall') }}</el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
            <!--        <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onLanguageChange">-->
            <!--            <div class="layout-navbars-breadcrumb-user-icon">-->
            <!--                <i class="iconfont" :class="disabledI18n === 'en' ? 'icon-fuhao-yingwen' : 'icon-fuhao-zhongwen'" :title="$t('message.user.title1')"></i>-->
            <!--            </div>-->
            <!--            <template #dropdown>-->
            <!--                <el-dropdown-menu>-->
            <!--                    <el-dropdown-item command="zh-cn" :disabled="disabledI18n === 'zh-cn'">简体中文</el-dropdown-item>-->
            <!--                    <el-dropdown-item command="en" :disabled="disabledI18n === 'en'">English</el-dropdown-item>-->
            <!--                    <el-dropdown-item command="zh-tw" :disabled="disabledI18n === 'zh-tw'">繁體中文</el-dropdown-item>-->
            <!--                </el-dropdown-menu>-->
            <!--            </template>-->
            <!--        </el-dropdown>-->
            <!--        <div class="layout-navbars-breadcrumb-user-icon" @click="onSearchClick">-->
            <!--            <el-icon :title="$t('message.user.title2')">-->
            <!--                <ele-Search />-->
            <!--            </el-icon>-->
            <!--        </div>-->
            <!--        <div class="layout-navbars-breadcrumb-user-icon" @click="onLayoutSetingClick">-->
            <!--            <i class="icon-skin iconfont" :title="$t('message.user.title3')"></i>-->
            <!--        </div>-->
            <!--        <div class="layout-navbars-breadcrumb-user-icon">-->
            <!--            <el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false">-->
            <!--                <template #reference>-->
            <!--                    <el-badge :is-dot="true">-->
            <!--                        <el-icon :title="$t('message.user.title4')">-->
            <!--                            <ele-Bell />-->
            <!--                        </el-icon>-->
            <!--                    </el-badge>-->
            <!--                </template>-->
            <!--                <template #default>-->
            <!--                    <UserNews />-->
            <!--                </template>-->
            <!--            </el-popover>-->
            <!--        </div>-->
            <div class="layout-navbars-breadcrumb-user-icon mr10" @click="onScreenfullClick">
                <i class="iconfont" :title="isScreenfull ? $t('message.user.title6') : $t('message.user.title5')" :class="!isScreenfull ? 'icon-fullscreen' : 'icon-tuichuquanping'"></i>
            </div>
            <el-dropdown :show-timeout="70" :hide-timeout="50" @command="onHandleCommandClick">
                <span class="layout-navbars-breadcrumb-user-link">
                    <img src="../../../assets/avator.png" class="layout-navbars-breadcrumb-user-link-photo mr5" style="width: 24px;height: 24px"/>
                    {{ userInfos.userName }}
                    <el-icon class="el-icon--right">
                        <ele-ArrowDown />
                    </el-icon>
                </span>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item command="/newMenu">{{ $t('message.user.dropdown1') }}</el-dropdown-item>
                        <!--                    <el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item>-->
                        <!--                    <el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item>-->
                        <!--                    <el-dropdown-item command="/404">{{ $t('message.user.dropdown3') }}</el-dropdown-item>-->
                        <!--                    <el-dropdown-item command="/401">{{ $t('message.user.dropdown4') }}</el-dropdown-item>-->
                        <el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
            <Search ref="searchRef" />
        </div>
    </div>
</template>
<script lang="ts">
import { ref, getCurrentInstance, computed, reactive, toRefs, onMounted, defineComponent } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessageBox, ElMessage } from 'element-plus';
import screenfull from 'screenfull';
import { useI18n } from 'vue-i18n';
import { storeToRefs } from 'pinia';
import { useUserInfo } from '/@/stores/userInfo';
import { useThemeConfig } from '/@/stores/themeConfig';
import other from '/@/utils/other';
import { Session, Local } from '/@/utils/storage';
import UserNews from '/@/layout/navBars/breadcrumb/userNews.vue';
import Search from '/@/layout/navBars/breadcrumb/search.vue';
import { useLoginApi } from '/@/api/login';
import { useMenuApi } from '/@/api/systemManage/menu/index';
const menuApi = useMenuApi();
import { backEndComponent, getBackEndControlRoutes, initBackEndControlRoutes, setAddRoute, setFilterMenuAndCacheTagsViewRoutes } from '../../../router/backEnd';
import { NextLoading } from '/@/utils/loading';
import { useRequestOldRoutes } from '/@/stores/requestOldRoutes';
import { dynamicRoutes } from '/@/router/route';
import Cookies from 'js-cookie';
import {useRoutesList} from "/@/stores/routesList";
export default defineComponent({
    name: 'layoutBreadcrumbUser',
    components: { UserNews, Search },
    setup() {
        const { t } = useI18n();
        const { proxy } = <any>getCurrentInstance();
        const router = useRouter();
        const stores = useUserInfo();
        const routeList = storeToRefs(useRoutesList())
        const storesThemeConfig = useThemeConfig();
        const { userInfos } = storeToRefs(stores);
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const searchRef = ref();
        const state = reactive({
            isScreenfull: false,
            disabledI18n: 'zh-cn',
            disabledSize: 'large',
            systemName: ''
        });
        // 设置分割样式
        const layoutUserFlexNum = computed(() => {
            let num: string | number = '';
            const { layout, isClassicSplitMenu } = themeConfig.value;
            const layoutArr: string[] = ['defaults', 'columns'];
            if (layoutArr.includes(layout) || (layout === 'classic' && !isClassicSplitMenu)) num = '1';
            else num = '';
            return num;
        });
        // 全屏点击时
        const onScreenfullClick = () => {
            if (!screenfull.isEnabled) {
                ElMessage.warning('暂不不支持全屏');
                return false;
            }
            screenfull.toggle();
            screenfull.on('change', () => {
                if (screenfull.isFullscreen) state.isScreenfull = true;
                else state.isScreenfull = false;
            });
        };
        // 布局配置 icon 点击时
        const onLayoutSetingClick = () => {
            proxy.mittBus.emit('openSetingsDrawer');
        };
        // 下拉菜单点击时
        const onHandleCommandClick = (path: string) => {
            if (path === 'logOut') {
                ElMessageBox({
                    closeOnClickModal: false,
                    closeOnPressEscape: false,
                    title: t('message.user.logOutTitle'),
                    message: t('message.user.logOutMessage'),
                    showCancelButton: true,
                    confirmButtonText: t('message.user.logOutConfirm'),
                    cancelButtonText: t('message.user.logOutCancel'),
                    buttonSize: 'default',
                    beforeClose: (action, instance, done) => {
                        if (action === 'confirm') {
                            instance.confirmButtonLoading = true;
                            instance.confirmButtonText = t('message.user.logOutExit');
                            setTimeout(() => {
                                done();
                                setTimeout(() => {
                                    instance.confirmButtonLoading = false;
                                }, 300);
                            }, 700);
                        } else {
                            done();
                        }
                    }
                })
                    .then(async () => {
                        let res = await useLoginApi().signOut();
                        if (res.data.code === '200') {
                            Session.clear(); // 清除缓存/token等
                            // 使用 reload 时,不需要调用 resetRoute() 重置路由
                            window.location.reload();
                        } else {
                            ElMessage({
                                type: 'warning',
                                message: res.data.msg
                            });
                        }
                    })
                    .catch(() => {});
            } else if (path === 'wareHouse') {
                window.open('https://gitee.com/lyt-top/vue-next-admin');
            } else {
                router.push(path);
            }
        };
        // 菜单搜索点击
        const onSearchClick = () => {
            searchRef.value.openSearch();
        };
        // 组件大小改变
        const onComponentSizeChange = (size: string) => {
            Local.remove('themeConfig');
            themeConfig.value.globalComponentSize = size;
            Local.set('themeConfig', themeConfig.value);
            initComponentSize();
            window.location.reload();
        };
        // 语言切换
        const onLanguageChange = (lang: string) => {
            Local.remove('themeConfig');
            themeConfig.value.globalI18n = lang;
            Local.set('themeConfig', themeConfig.value);
            proxy.$i18n.locale = lang;
            initI18n();
            other.useTitle();
        };
        // 设置 element plus 组件的国际化
        const setI18nConfig = (locale: string) => {
            proxy.mittBus.emit('getI18nConfig', proxy.$i18n.messages[locale]);
        };
        // 初始化言语国际化
        const initI18n = () => {
            switch (Local.get('themeConfig').globalI18n) {
                case 'zh-cn':
                    state.disabledI18n = 'zh-cn';
                    setI18nConfig('zh-cn');
                    break;
                case 'en':
                    state.disabledI18n = 'en';
                    setI18nConfig('en');
                    break;
                case 'zh-tw':
                    state.disabledI18n = 'zh-tw';
                    setI18nConfig('zh-tw');
                    break;
            }
        };
        // 初始化全局组件大小
        const initComponentSize = () => {
            switch (Local.get('themeConfig').globalComponentSize) {
                case 'large':
                    state.disabledSize = 'large';
                    break;
                case 'default':
                    state.disabledSize = 'default';
                    break;
                case 'small':
                    state.disabledSize = 'small';
                    break;
            }
        };
        const getSysName = async () => {
            if (window.nextLoading === undefined) NextLoading.start();
            if (!Cookies.get('token')) return false;
            const res = await menuApi.getMenuAdmin(Cookies.get('projectId') === null ? '' : Cookies.get('projectId'));
            if (res.data.code === '200') {
                state.systemName = res.data.data[1].project.projectName;
                console.log(state.systemName);
            } else {
                console.log('有问题');
            }
        };
        const backToMenu = () => {
            router.push({ path: 'newMenu' }).then(()=>{
                routeList.routesList.value = []
                console.log(routeList);
            });
        };
        const toHome = () => {
            router.push({ path: 'newMenu' });
        };
        // 页面加载时
        onMounted(() => {
            if (Local.get('themeConfig')) {
                initI18n();
                initComponentSize();
            }
            getSysName();
        });
        return {
            userInfos,
            backToMenu,
            toHome,
            onLayoutSetingClick,
            onHandleCommandClick,
            onScreenfullClick,
            onSearchClick,
            onComponentSizeChange,
            onLanguageChange,
            searchRef,
            layoutUserFlexNum,
            ...toRefs(state)
        };
    }
});
</script>
<style scoped lang="scss">
    @media screen and (min-width: 1400px) {
        .logo{
            img {
                height: 100%;
                cursor: pointer;
            }
            span{
                font-size: 32px;
                color: #409eff;
                font-weight: bolder;
                border-left: 2px solid #409eff;
                padding-left: 10px
            }
        }
        .backBtn {
            font-size: 16px;
            cursor: pointer;
            margin-right: 20px;
            &:hover {
                color: #409eff;
                font-weight: bolder;
            }
        }
    }
    @media screen and (min-width: 1200px) and (max-width: 1400px) {
        .logo{
            img {
                height: 90%;
                cursor: pointer;
            }
            span{
                font-size: 28px;
                color: #409eff;
                font-weight: bolder;
                border-left: 2px solid #409eff;
                padding-left: 10px
            }
        }
        .backBtn {
            font-size: 14px;
            cursor: pointer;
            margin-right: 20px;
            &:hover {
                color: #409eff;
                font-weight: bolder;
            }
        }
    }
    @media screen and (max-width: 1024px) {
        .logo{
            img {
                width: 60%;
                height: auto;
                cursor: pointer;
            }
            span{
                font-size: 22px;
                color: #409eff;
                font-weight: bolder;
                border-left: 2px solid #409eff;
                padding-left: 10px
            }
        }
        .backBtn {
            font-size: 12px;
            cursor: pointer;
            margin-right: 20px;
            &:hover {
                color: #409eff;
                font-weight: bolder;
            }
        }
    }
    .layout-navbars-breadcrumb-user {
        display: flex;
        align-items: center;
        justify-content: space-between;
        .logo {
            height: 75%;
            padding: 5px 10px;
            display: flex;
            align-items: center;
            overflow: hidden;
            box-sizing: border-box;
        }
        &-link {
            height: 100%;
            display: flex;
            align-items: center;
            white-space: nowrap;
            &-photo {
                width: 25px;
                height: 25px;
                border-radius: 100%;
            }
        }
        &-icon {
            padding: 0 10px;
            cursor: pointer;
            color: var(--next-bg-topBarColor);
            height: 80px;
            line-height: 80px;
            display: flex;
            align-items: center;
            &:hover {
                background: var(--next-color-user-hover);
                i {
                    display: inline-block;
                    animation: logoAnimation 0.3s ease-in-out;
                }
            }
        }
        ::v-deep(.el-dropdown) {
            color: var(--next-bg-topBarColor);
        }
        ::v-deep(.el-badge) {
            height: 40px;
            line-height: 40px;
            display: flex;
            align-items: center;
        }
        ::v-deep(.el-badge__content.is-fixed) {
            top: 12px;
        }
    }
</style>
src/layout/navBars/breadcrumb/userNews.vue
对比新文件
@@ -0,0 +1,115 @@
<template>
    <div class="layout-navbars-breadcrumb-user-news">
        <div class="head-box">
            <div class="head-box-title">{{ $t('message.user.newTitle') }}</div>
            <div class="head-box-btn" v-if="newsList.length > 0" @click="onAllReadClick">{{ $t('message.user.newBtn') }}</div>
        </div>
        <div class="content-box">
            <template v-if="newsList.length > 0">
                <div class="content-box-item" v-for="(v, k) in newsList" :key="k">
                    <div>{{ v.label }}</div>
                    <div class="content-box-msg">
                        {{ v.value }}
                    </div>
                    <div class="content-box-time">{{ v.time }}</div>
                </div>
            </template>
            <el-empty :description="$t('message.user.newDesc')" v-else></el-empty>
        </div>
        <div class="foot-box" @click="onGoToGiteeClick" v-if="newsList.length > 0">{{ $t('message.user.newGo') }}</div>
    </div>
</template>
<script lang="ts">
import { reactive, toRefs, defineComponent } from 'vue';
export default defineComponent({
    name: 'layoutBreadcrumbUserNews',
    setup() {
        const state = reactive({
            newsList: [
                {
                    label: '关于版本发布的通知',
                    value: 'vue-next-admin,基于 vue3 + CompositionAPI + typescript + vite + element plus,正式发布时间:2021年02月28日!',
                    time: '2020-12-08',
                },
                {
                    label: '关于学习交流的通知',
                    value: 'QQ群号码 665452019,欢迎小伙伴入群学习交流探讨!',
                    time: '2020-12-08',
                },
            ],
        });
        // 全部已读点击
        const onAllReadClick = () => {
            state.newsList = [];
        };
        // 前往通知中心点击
        const onGoToGiteeClick = () => {
            window.open('https://gitee.com/lyt-top/vue-next-admin');
        };
        return {
            onAllReadClick,
            onGoToGiteeClick,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.layout-navbars-breadcrumb-user-news {
    .head-box {
        display: flex;
        border-bottom: 1px solid var(--el-border-color-lighter);
        box-sizing: border-box;
        color: var(--el-text-color-primary);
        justify-content: space-between;
        height: 35px;
        align-items: center;
        .head-box-btn {
            color: var(--el-color-primary);
            font-size: 13px;
            cursor: pointer;
            opacity: 0.8;
            &:hover {
                opacity: 1;
            }
        }
    }
    .content-box {
        font-size: 13px;
        .content-box-item {
            padding-top: 12px;
            &:last-of-type {
                padding-bottom: 12px;
            }
            .content-box-msg {
                color: var(--el-text-color-secondary);
                margin-top: 5px;
                margin-bottom: 5px;
            }
            .content-box-time {
                color: var(--el-text-color-secondary);
            }
        }
    }
    .foot-box {
        height: 35px;
        color: var(--el-color-primary);
        font-size: 13px;
        cursor: pointer;
        opacity: 0.8;
        display: flex;
        align-items: center;
        justify-content: center;
        border-top: 1px solid var(--el-border-color-lighter);
        &:hover {
            opacity: 1;
        }
    }
    ::v-deep(.el-empty__description p) {
        font-size: 13px;
    }
}
</style>
src/layout/navBars/index.vue
对比新文件
@@ -0,0 +1,40 @@
<template>
    <div class="layout-navbars-container">
        <BreadcrumbIndex />
        <TagsView v-if="setShowTagsView" />
    </div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import BreadcrumbIndex from '/@/layout/navBars/breadcrumb/index.vue';
import TagsView from '/@/layout/navBars/tagsView/tagsView.vue';
export default defineComponent({
    name: 'layoutNavBars',
    components: { BreadcrumbIndex, TagsView },
    setup() {
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        // 是否显示 tagsView
        const setShowTagsView = computed(() => {
            let { layout, isTagsview } = themeConfig.value;
            return layout !== 'classic' && isTagsview;
        });
        return {
            setShowTagsView,
        };
    },
});
</script>
<style scoped lang="scss">
.layout-navbars-container {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
}
</style>
src/layout/navBars/tagsView/contextmenu.vue
对比新文件
@@ -0,0 +1,138 @@
<template>
    <transition name="el-zoom-in-center">
        <div
            aria-hidden="true"
            class="el-dropdown__popper el-popper is-light is-pure custom-contextmenu"
            role="tooltip"
            data-popper-placement="bottom"
            :style="`top: ${dropdowns.y + 5}px;left: ${dropdowns.x}px;`"
            :key="Math.random()"
            v-show="isShow"
        >
            <ul class="el-dropdown-menu">
                <template v-for="(v, k) in dropdownList">
                    <li
                        class="el-dropdown-menu__item"
                        aria-disabled="false"
                        tabindex="-1"
                        :key="k"
                        v-if="!v.affix"
                        @click="onCurrentContextmenuClick(v.contextMenuClickId)"
                    >
                        <SvgIcon :name="v.icon" />
                        <span>{{ $t(v.txt) }}</span>
                    </li>
                </template>
            </ul>
            <div class="el-popper__arrow" :style="{ left: `${arrowLeft}px` }"></div>
        </div>
    </transition>
</template>
<script lang="ts">
import { computed, defineComponent, reactive, toRefs, onMounted, onUnmounted, watch } from 'vue';
export default defineComponent({
    name: 'layoutTagsViewContextmenu',
    props: {
        dropdown: {
            type: Object,
            default: () => {
                return {
                    x: 0,
                    y: 0,
                };
            },
        },
    },
    setup(props, { emit }) {
        const state = reactive({
            isShow: false,
            dropdownList: [
                { contextMenuClickId: 0, txt: 'message.tagsView.refresh', affix: false, icon: 'ele-RefreshRight' },
                { contextMenuClickId: 1, txt: 'message.tagsView.close', affix: false, icon: 'ele-Close' },
                { contextMenuClickId: 2, txt: 'message.tagsView.closeOther', affix: false, icon: 'ele-CircleClose' },
                { contextMenuClickId: 3, txt: 'message.tagsView.closeAll', affix: false, icon: 'ele-FolderDelete' },
                {
                    contextMenuClickId: 4,
                    txt: 'message.tagsView.fullscreen',
                    affix: false,
                    icon: 'iconfont icon-fullscreen',
                },
            ],
            item: {},
            arrowLeft: 10,
        });
        // 父级传过来的坐标 x,y 值
        const dropdowns = computed(() => {
            // 117 为 `Dropdown 下拉菜单` 的宽度
            if (props.dropdown.x + 117 > document.documentElement.clientWidth) {
                return {
                    x: document.documentElement.clientWidth - 117 - 5,
                    y: props.dropdown.y,
                };
            } else {
                return props.dropdown;
            }
        });
        // 当前项菜单点击
        const onCurrentContextmenuClick = (contextMenuClickId: number) => {
            emit('currentContextmenuClick', Object.assign({}, { contextMenuClickId }, state.item));
        };
        // 打开右键菜单:判断是否固定,固定则不显示关闭按钮
        const openContextmenu = (item: any) => {
            state.item = item;
            item.meta.isAffix ? (state.dropdownList[1].affix = true) : (state.dropdownList[1].affix = false);
            closeContextmenu();
            setTimeout(() => {
                state.isShow = true;
            }, 10);
        };
        // 关闭右键菜单
        const closeContextmenu = () => {
            state.isShow = false;
        };
        // 监听页面监听进行右键菜单的关闭
        onMounted(() => {
            document.body.addEventListener('click', closeContextmenu);
        });
        // 页面卸载时,移除右键菜单监听事件
        onUnmounted(() => {
            document.body.removeEventListener('click', closeContextmenu);
        });
        // 监听下拉菜单位置
        watch(
            () => props.dropdown,
            ({ x }) => {
                if (x + 117 > document.documentElement.clientWidth) state.arrowLeft = 117 - (document.documentElement.clientWidth - x);
                else state.arrowLeft = 10;
            },
            {
                deep: true,
            }
        );
        return {
            dropdowns,
            openContextmenu,
            closeContextmenu,
            onCurrentContextmenuClick,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.custom-contextmenu {
    transform-origin: center top;
    z-index: 2190;
    position: fixed;
    .el-dropdown-menu__item {
        font-size: 12px !important;
        white-space: nowrap;
        i {
            font-size: 12px !important;
        }
    }
}
</style>
src/layout/navBars/tagsView/tagsView.vue
对比新文件
@@ -0,0 +1,734 @@
<template>
    <div class="layout-navbars-tagsview" :class="{ 'layout-navbars-tagsview-shadow': getThemeConfig.layout === 'classic' }">
        <el-scrollbar ref="scrollbarRef" @wheel.prevent="onHandleScroll">
            <ul class="layout-navbars-tagsview-ul" :class="setTagsStyle" ref="tagsUlRef">
                <li
                    v-for="(v, k) in tagsViewList"
                    :key="k"
                    class="layout-navbars-tagsview-ul-li"
                    :data-url="v.url"
                    :class="{ 'is-active': isActive(v) }"
                    @contextmenu.prevent="onContextmenu(v, $event)"
                    @click="onTagsClick(v, k)"
                    :ref="
                        (el) => {
                            if (el) tagsRefs[k] = el;
                        }
                    "
                >
                    <i class="iconfont icon-webicon318 layout-navbars-tagsview-ul-li-iconfont" v-if="isActive(v)"></i>
                    <SvgIcon :name="v.meta.icon" v-if="!isActive(v) && getThemeConfig.isTagsviewIcon" class="pr5" />
                    <span>{{ setTagsViewNameI18n(v) }}</span>
                    <template v-if="isActive(v)">
                        <SvgIcon
                            name="ele-RefreshRight"
                            class="ml5 layout-navbars-tagsview-ul-li-refresh"
                            @click.stop="refreshCurrentTagsView($route.fullPath)"
                        />
                        <SvgIcon
                            name="ele-Close"
                            class="layout-navbars-tagsview-ul-li-icon layout-icon-active"
                            v-if="!v.meta.isAffix"
                            @click.stop="closeCurrentTagsView(getThemeConfig.isShareTagsView ? v.path : v.url)"
                        />
                    </template>
                    <SvgIcon
                        name="ele-Close"
                        class="layout-navbars-tagsview-ul-li-icon layout-icon-three"
                        v-if="!v.meta.isAffix"
                        @click.stop="closeCurrentTagsView(getThemeConfig.isShareTagsView ? v.path : v.url)"
                    />
                </li>
            </ul>
        </el-scrollbar>
        <Contextmenu :dropdown="dropdown" ref="contextmenuRef" @currentContextmenuClick="onCurrentContextmenuClick" />
    </div>
</template>
<script lang="ts">
import {
    toRefs,
    reactive,
    onMounted,
    computed,
    ref,
    nextTick,
    onBeforeUpdate,
    onBeforeMount,
    onUnmounted,
    getCurrentInstance,
    watch,
    defineComponent,
} from 'vue';
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
import Sortable from 'sortablejs';
import { ElMessage } from 'element-plus';
import { storeToRefs } from 'pinia';
import pinia from '/@/stores/index';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { useThemeConfig } from '/@/stores/themeConfig';
import { useKeepALiveNames } from '/@/stores/keepAliveNames';
import { Session } from '/@/utils/storage';
import { isObjectValueEqual } from '/@/utils/arrayOperation';
import other from '/@/utils/other';
import Contextmenu from '/@/layout/navBars/tagsView/contextmenu.vue';
// 定义接口来定义对象的类型
interface TagsViewState {
    routeActive: string;
    routePath: string | unknown;
    dropdown: {
        x: string | number;
        y: string | number;
    };
    sortable: any;
    tagsRefsIndex: number;
    tagsViewList: any[];
    tagsViewRoutesList: any[];
}
interface RouteParams {
    path: string;
    url: string;
    query: object;
    params: object;
}
interface CurrentContextmenu {
    meta: {
        isDynamic: boolean;
    };
    params: any;
    query: any;
    path: string;
    contextMenuClickId: string | number;
}
export default defineComponent({
    name: 'layoutTagsView',
    components: { Contextmenu },
    setup() {
        const { proxy } = <any>getCurrentInstance();
        const tagsRefs = ref<any[]>([]);
        const scrollbarRef = ref();
        const contextmenuRef = ref();
        const tagsUlRef = ref();
        const stores = useTagsViewRoutes();
        const storesThemeConfig = useThemeConfig();
        const storesTagsViewRoutes = useTagsViewRoutes();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const { tagsViewRoutes } = storeToRefs(storesTagsViewRoutes);
        const storesKeepALiveNames = useKeepALiveNames();
        const route = useRoute();
        const router = useRouter();
        const state = reactive<TagsViewState>({
            routeActive: '',
            routePath: route.path,
            dropdown: { x: '', y: '' },
            sortable: '',
            tagsRefsIndex: 0,
            tagsViewList: [],
            tagsViewRoutesList: [],
        });
        // 动态设置 tagsView 风格样式
        const setTagsStyle = computed(() => {
            return themeConfig.value.tagsStyle;
        });
        // 获取布局配置信息
        const getThemeConfig = computed(() => {
            return themeConfig.value;
        });
        // 设置 自定义 tagsView 名称、 自定义 tagsView 名称国际化
        const setTagsViewNameI18n = computed(() => {
            return (v: any) => {
                return other.setTagsViewNameI18n(v);
            };
        });
        // 设置 tagsView 高亮
        const isActive = (v: RouteParams) => {
            if (getThemeConfig.value.isShareTagsView) {
                return v.path === state.routePath;
            } else {
                if ((v.query && Object.keys(v.query).length) || (v.params && Object.keys(v.params).length)) {
                    // 普通传参
                    return v.url ? v.url === state.routeActive : v.path === state.routeActive;
                } else {
                    // 通过 name 传参,params 取值,刷新页面参数消失
                    // https://gitee.com/lyt-top/vue-next-admin/issues/I51RS9
                    return v.path === state.routePath;
                }
            }
        };
        // 存储 tagsViewList 到浏览器临时缓存中,页面刷新时,保留记录
        const addBrowserSetSession = (tagsViewList: Array<object>) => {
            Session.set('tagsViewList', tagsViewList);
        };
        // 获取 vuex 中的 tagsViewRoutes 列表
        const getTagsViewRoutes = async () => {
            state.routeActive = await setTagsViewHighlight(route);
            state.routePath = (await route.meta.isDynamic) ? route.meta.isDynamicPath : route.path;
            state.tagsViewList = [];
            state.tagsViewRoutesList = tagsViewRoutes.value;
            initTagsView();
        };
        // vuex 中获取路由信息:如果是设置了固定的(isAffix),进行初始化显示
        const initTagsView = async () => {
            if (Session.get('tagsViewList') && getThemeConfig.value.isCacheTagsView) {
                state.tagsViewList = await Session.get('tagsViewList');
            } else {
                await state.tagsViewRoutesList.map((v: any) => {
                    if (v.meta.isAffix && !v.meta.isHide) {
                        v.url = setTagsViewHighlight(v);
                        state.tagsViewList.push({ ...v });
                        storesKeepALiveNames.addCachedView(v);
                    }
                });
                await addTagsView(route.path, route);
            }
            // 初始化当前元素(li)的下标
            getTagsRefsIndex(getThemeConfig.value.isShareTagsView ? state.routePath : state.routeActive);
        };
        // 处理可开启多标签详情,单标签详情(动态路由(xxx/:id/:name"),普通路由处理)
        const solveAddTagsView = async (path: string, to?: any) => {
            let isDynamicPath = to.meta.isDynamic ? to.meta.isDynamicPath : path;
            let current = state.tagsViewList.filter(
                (v: any) =>
                    v.path === isDynamicPath &&
                    isObjectValueEqual(
                        to.meta.isDynamic ? (v.params ? v.params : null) : v.query ? v.query : null,
                        to.meta.isDynamic ? (to?.params ? to?.params : null) : to?.query ? to?.query : null
                    )
            );
            if (current.length <= 0) {
                // 防止:Avoid app logic that relies on enumerating keys on a components instance. The keys will be empty in production mode to avoid performance overhead.
                let findItem = state.tagsViewRoutesList.find((v: any) => v.path === isDynamicPath);
                if (!findItem) return false;
                if (findItem.meta.isAffix) return false;
                if (findItem.meta.isLink && !findItem.meta.isIframe) return false;
                to.meta.isDynamic ? (findItem.params = to.params) : (findItem.query = to.query);
                findItem.url = setTagsViewHighlight(findItem);
                state.tagsViewList.push({ ...findItem });
                await storesKeepALiveNames.addCachedView(findItem);
                addBrowserSetSession(state.tagsViewList);
            }
        };
        // 处理单标签时,第二次的值未覆盖第一次的 tagsViewList 值(Session Storage)
        const singleAddTagsView = (path: string, to?: any) => {
            let isDynamicPath = to.meta.isDynamic ? to.meta.isDynamicPath : path;
            state.tagsViewList.forEach((v) => {
                if (
                    v.path === isDynamicPath &&
                    !isObjectValueEqual(
                        to.meta.isDynamic ? (v.params ? v.params : null) : v.query ? v.query : null,
                        to.meta.isDynamic ? (to?.params ? to?.params : null) : to?.query ? to?.query : null
                    )
                ) {
                    to.meta.isDynamic ? (v.params = to.params) : (v.query = to.query);
                    v.url = setTagsViewHighlight(v);
                    addBrowserSetSession(state.tagsViewList);
                }
            });
        };
        // 1、添加 tagsView:未设置隐藏(isHide)也添加到在 tagsView 中(可开启多标签详情,单标签详情)
        const addTagsView = (path: string, to?: any) => {
            // 防止拿取不到路由信息
            nextTick(async () => {
                // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
                let item: any = '';
                if (to && to.meta.isDynamic) {
                    // 动态路由(xxx/:id/:name"):参数不同,开启多个 tagsview
                    if (!getThemeConfig.value.isShareTagsView) await solveAddTagsView(path, to);
                    else await singleAddTagsView(path, to);
                    if (state.tagsViewList.some((v: any) => v.path === to.meta.isDynamicPath)) return false;
                    item = state.tagsViewRoutesList.find((v: any) => v.path === to.meta.isDynamicPath);
                } else {
                    // 普通路由:参数不同,开启多个 tagsview
                    if (!getThemeConfig.value.isShareTagsView) await solveAddTagsView(path, to);
                    else await singleAddTagsView(path, to);
                    if (state.tagsViewList.some((v: any) => v.path === path)) return false;
                    item = state.tagsViewRoutesList.find((v: any) => v.path === path);
                }
                if (!item) return false;
                if (item.meta.isLink && !item.meta.isIframe) return false;
                if (to && to.meta.isDynamic) item.params = to?.params ? to?.params : route.params;
                else item.query = to?.query ? to?.query : route.query;
                item.url = setTagsViewHighlight(item);
                await storesKeepALiveNames.addCachedView(item);
                await state.tagsViewList.push({ ...item });
                await addBrowserSetSession(state.tagsViewList);
            });
        };
        // 2、刷新当前 tagsView:
        const refreshCurrentTagsView = async (fullPath: string) => {
            const item = state.tagsViewList.find((v: any) => (getThemeConfig.value.isShareTagsView ? v.path === fullPath : v.url === fullPath));
            if (item != null) {
                await storesKeepALiveNames.delCachedView(item);
                proxy.mittBus.emit('onTagsViewRefreshRouterView', fullPath);
                if (item.meta.isKeepAlive) storesKeepALiveNames.addCachedView(item);
            }
        };
        // 3、关闭当前 tagsView:如果是设置了固定的(isAffix),不可以关闭
        const closeCurrentTagsView = (path: string) => {
            state.tagsViewList.map((v: any, k: number, arr: any) => {
                if (!v.meta.isAffix) {
                    if (getThemeConfig.value.isShareTagsView ? v.path === path : v.url === path) {
                        storesKeepALiveNames.delCachedView(v);
                        state.tagsViewList.splice(k, 1);
                        setTimeout(() => {
                            if (state.tagsViewList.length === k && getThemeConfig.value.isShareTagsView ? state.routePath === path : state.routeActive === path) {
                                // 最后一个且高亮时
                                if (arr[arr.length - 1].meta.isDynamic) {
                                    // 动态路由(xxx/:id/:name")
                                    if (k !== arr.length) router.push({ name: arr[k].name, params: arr[k].params });
                                    else router.push({ name: arr[arr.length - 1].name, params: arr[arr.length - 1].params });
                                } else {
                                    // 普通路由
                                    if (k !== arr.length) router.push({ path: arr[k].path, query: arr[k].query });
                                    else router.push({ path: arr[arr.length - 1].path, query: arr[arr.length - 1].query });
                                }
                            } else {
                                // 非最后一个且高亮时,跳转到下一个
                                if (state.tagsViewList.length !== k && getThemeConfig.value.isShareTagsView ? state.routePath === path : state.routeActive === path) {
                                    if (arr[k].meta.isDynamic) {
                                        // 动态路由(xxx/:id/:name")
                                        router.push({ name: arr[k].name, params: arr[k].params });
                                    } else {
                                        // 普通路由
                                        router.push({ path: arr[k].path, query: arr[k].query });
                                    }
                                }
                            }
                        }, 0);
                    }
                }
            });
            addBrowserSetSession(state.tagsViewList);
        };
        // 4、关闭其它 tagsView:如果是设置了固定的(isAffix),不进行关闭
        const closeOtherTagsView = (path: string) => {
            if (Session.get('tagsViewList')) {
                state.tagsViewList = [];
                Session.get('tagsViewList').map((v: any) => {
                    if (v.meta.isAffix && !v.meta.isHide) {
                        v.url = setTagsViewHighlight(v);
                        storesKeepALiveNames.delOthersCachedViews(v);
                        state.tagsViewList.push({ ...v });
                    }
                });
                addTagsView(path, route);
                addBrowserSetSession(state.tagsViewList);
            }
        };
        // 5、关闭全部 tagsView:如果是设置了固定的(isAffix),不进行关闭
        const closeAllTagsView = () => {
            if (Session.get('tagsViewList')) {
                storesKeepALiveNames.delAllCachedViews();
                state.tagsViewList = [];
                Session.get('tagsViewList').map((v: any) => {
                    if (v.meta.isAffix && !v.meta.isHide) {
                        v.url = setTagsViewHighlight(v);
                        state.tagsViewList.push({ ...v });
                        router.push({ path: state.tagsViewList[state.tagsViewList.length - 1].path });
                    }
                });
                addBrowserSetSession(state.tagsViewList);
            }
        };
        // 6、开启当前页面全屏
        const openCurrenFullscreen = async (path: string) => {
            const item = state.tagsViewList.find((v: any) => (getThemeConfig.value.isShareTagsView ? v.path === path : v.url === path));
            if (item.meta.isDynamic) await router.push({ name: item.name, params: item.params });
            else await router.push({ name: item.name, query: item.query });
            stores.setCurrenFullscreen(true);
        };
        // 当前项右键菜单点击,拿当前点击的路由路径对比 浏览器缓存中的 tagsView 路由数组,取当前点击项的详细路由信息
        // 防止 tagsView 非当前页演示时,操作异常
        const getCurrentRouteItem = (path: string, cParams: any) => {
            const itemRoute = Session.get('tagsViewList') ? Session.get('tagsViewList') : state.tagsViewList;
            return itemRoute.find((v: any) => {
                if (
                    v.path === path &&
                    isObjectValueEqual(
                        v.meta.isDynamic ? (v.params ? v.params : null) : v.query ? v.query : null,
                        cParams && Object.keys(cParams ? cParams : {}).length > 0 ? cParams : null
                    )
                ) {
                    return v;
                } else if (v.path === path && Object.keys(cParams ? cParams : {}).length <= 0) {
                    return v;
                }
            });
        };
        // 当前项右键菜单点击
        const onCurrentContextmenuClick = async (item: CurrentContextmenu) => {
            const cParams = item.meta.isDynamic ? item.params : item.query;
            if (!getCurrentRouteItem(item.path, cParams)) return ElMessage({ type: 'warning', message: '请正确输入路径及完整参数(query、params)' });
            const { path, name, params, query, meta, url } = getCurrentRouteItem(item.path, cParams);
            switch (item.contextMenuClickId) {
                case 0:
                    // 刷新当前
                    if (meta.isDynamic) await router.push({ name, params });
                    else await router.push({ path, query });
                    refreshCurrentTagsView(route.fullPath);
                    break;
                case 1:
                    // 关闭当前
                    closeCurrentTagsView(getThemeConfig.value.isShareTagsView ? path : url);
                    break;
                case 2:
                    // 关闭其它
                    if (meta.isDynamic) await router.push({ name, params });
                    else await router.push({ path, query });
                    closeOtherTagsView(path);
                    break;
                case 3:
                    // 关闭全部
                    closeAllTagsView();
                    break;
                case 4:
                    // 开启当前页面全屏
                    openCurrenFullscreen(getThemeConfig.value.isShareTagsView ? path : url);
                    break;
            }
        };
        // 右键点击时:传 x,y 坐标值到子组件中(props)
        const onContextmenu = (v: any, e: any) => {
            const { clientX, clientY } = e;
            state.dropdown.x = clientX;
            state.dropdown.y = clientY;
            contextmenuRef.value.openContextmenu(v);
        };
        // 当前的 tagsView 项点击时
        const onTagsClick = (v: any, k: number) => {
            state.tagsRefsIndex = k;
            router.push(v);
        };
        // 处理 tagsView 高亮(多标签详情时使用,单标签详情未使用)
        const setTagsViewHighlight = (v: any) => {
            let params = v.query && Object.keys(v.query).length > 0 ? v.query : v.params;
            if (!params || Object.keys(params).length <= 0) return v.path;
            let path = '';
            for (let i in params) {
                path += params[i];
            }
            // 判断是否是动态路由(xxx/:id/:name")
            return `${v.meta.isDynamic ? v.meta.isDynamicPath : v.path}-${path}`;
        };
        // 更新滚动条显示
        const updateScrollbar = () => {
            proxy.$refs.scrollbarRef.update();
        };
        // 鼠标滚轮滚动
        const onHandleScroll = (e: any) => {
            proxy.$refs.scrollbarRef.$refs.wrap$.scrollLeft += e.wheelDelta / 4;
        };
        // tagsView 横向滚动
        const tagsViewmoveToCurrentTag = () => {
            nextTick(() => {
                if (tagsRefs.value.length <= 0) return false;
                // 当前 li 元素
                let liDom = tagsRefs.value[state.tagsRefsIndex];
                // 当前 li 元素下标
                let liIndex = state.tagsRefsIndex;
                // 当前 ul 下 li 元素总长度
                let liLength = tagsRefs.value.length;
                // 最前 li
                let liFirst: any = tagsRefs.value[0];
                // 最后 li
                let liLast: any = tagsRefs.value[tagsRefs.value.length - 1];
                // 当前滚动条的值
                let scrollRefs = proxy.$refs.scrollbarRef.$refs.wrap$;
                // 当前滚动条滚动宽度
                let scrollS = scrollRefs.scrollWidth;
                // 当前滚动条偏移宽度
                let offsetW = scrollRefs.offsetWidth;
                // 当前滚动条偏移距离
                let scrollL = scrollRefs.scrollLeft;
                // 上一个 tags li dom
                let liPrevTag: any = tagsRefs.value[state.tagsRefsIndex - 1];
                // 下一个 tags li dom
                let liNextTag: any = tagsRefs.value[state.tagsRefsIndex + 1];
                // 上一个 tags li dom 的偏移距离
                let beforePrevL: any = '';
                // 下一个 tags li dom 的偏移距离
                let afterNextL: any = '';
                if (liDom === liFirst) {
                    // 头部
                    scrollRefs.scrollLeft = 0;
                } else if (liDom === liLast) {
                    // 尾部
                    scrollRefs.scrollLeft = scrollS - offsetW;
                } else {
                    // 非头/尾部
                    if (liIndex === 0) beforePrevL = liFirst.offsetLeft - 5;
                    else beforePrevL = liPrevTag?.offsetLeft - 5;
                    if (liIndex === liLength) afterNextL = liLast.offsetLeft + liLast.offsetWidth + 5;
                    else afterNextL = liNextTag.offsetLeft + liNextTag.offsetWidth + 5;
                    if (afterNextL > scrollL + offsetW) {
                        scrollRefs.scrollLeft = afterNextL - offsetW;
                    } else if (beforePrevL < scrollL) {
                        scrollRefs.scrollLeft = beforePrevL;
                    }
                }
                // 更新滚动条,防止不出现
                updateScrollbar();
            });
        };
        // 获取 tagsView 的下标:用于处理 tagsView 点击时的横向滚动
        const getTagsRefsIndex = (path: string | unknown) => {
            nextTick(async () => {
                // await 使用该写法,防止拿取不到 tagsViewList 列表数据不完整
                let tagsViewList = await state.tagsViewList;
                state.tagsRefsIndex = tagsViewList.findIndex((v: any) => {
                    if (getThemeConfig.value.isShareTagsView) {
                        return v.path === path;
                    } else {
                        return v.url === path;
                    }
                });
                // 添加初始化横向滚动条移动到对应位置
                tagsViewmoveToCurrentTag();
            });
        };
        // 设置 tagsView 可以进行拖拽
        const initSortable = async () => {
            const el = <HTMLElement>document.querySelector('.layout-navbars-tagsview-ul');
            if (!el) return false;
            state.sortable.el && state.sortable.destroy();
            state.sortable = Sortable.create(el, {
                animation: 300,
                dataIdAttr: 'data-url',
                disabled: getThemeConfig.value.isSortableTagsView ? false : true,
                onEnd: () => {
                    const sortEndList: any = [];
                    state.sortable.toArray().map((val: any) => {
                        state.tagsViewList.map((v: any) => {
                            if (v.url === val) sortEndList.push({ ...v });
                        });
                    });
                    addBrowserSetSession(sortEndList);
                },
            });
        };
        // 拖动问题,https://gitee.com/lyt-top/vue-next-admin/issues/I3ZRRI
        const onSortableResize = async () => {
            await initSortable();
            if (other.isMobile()) state.sortable.el && state.sortable.destroy();
        };
        // 页面加载前
        onBeforeMount(() => {
            // 初始化,防止手机端直接访问时还可以拖拽
            onSortableResize();
            // 拖动问题,https://gitee.com/lyt-top/vue-next-admin/issues/I3ZRRI
            window.addEventListener('resize', onSortableResize);
            // 监听非本页面调用 0 刷新当前,1 关闭当前,2 关闭其它,3 关闭全部 4 当前页全屏
            proxy.mittBus.on('onCurrentContextmenuClick', (data: CurrentContextmenu) => {
                onCurrentContextmenuClick(data);
            });
            // 监听布局配置界面开启/关闭拖拽
            proxy.mittBus.on('openOrCloseSortable', () => {
                initSortable();
            });
            // 监听布局配置开启 TagsView 共用,为了演示还原默认值
            proxy.mittBus.on('openShareTagsView', () => {
                if (getThemeConfig.value.isShareTagsView) {
                    router.push('/home');
                    state.tagsViewList = [];
                    state.tagsViewRoutesList.map((v: any) => {
                        if (v.meta.isAffix && !v.meta.isHide) {
                            v.url = setTagsViewHighlight(v);
                            state.tagsViewList.push({ ...v });
                        }
                    });
                }
            });
        });
        // 页面卸载时
        onUnmounted(() => {
            // 取消非本页面调用监听
            proxy.mittBus.off('onCurrentContextmenuClick', () => {});
            // 取消监听布局配置界面开启/关闭拖拽
            proxy.mittBus.off('openOrCloseSortable', () => {});
            // 取消监听布局配置开启 TagsView 共用
            proxy.mittBus.off('openShareTagsView', () => {});
            // 取消窗口 resize 监听
            window.removeEventListener('resize', onSortableResize);
        });
        // 页面更新时
        onBeforeUpdate(() => {
            tagsRefs.value = [];
        });
        // 页面加载时
        onMounted(() => {
            // 初始化 pinia 中的 tagsViewRoutes 列表
            getTagsViewRoutes();
            initSortable();
        });
        // 路由更新时(组件内生命钩子)
        onBeforeRouteUpdate(async (to) => {
            state.routeActive = setTagsViewHighlight(to);
            state.routePath = to.meta.isDynamic ? to.meta.isDynamicPath : to.path;
            await addTagsView(to.path, to);
            getTagsRefsIndex(getThemeConfig.value.isShareTagsView ? state.routePath : state.routeActive);
        });
        // 监听路由的变化,动态赋值给 tagsView
        watch(
            pinia.state,
            (val) => {
                if (val.tagsViewRoutes.tagsViewRoutes.length === state.tagsViewRoutesList.length) return false;
                getTagsViewRoutes();
            },
            {
                deep: true,
            }
        );
        return {
            isActive,
            onContextmenu,
            onTagsClick,
            tagsRefs,
            contextmenuRef,
            scrollbarRef,
            tagsUlRef,
            onHandleScroll,
            getThemeConfig,
            setTagsStyle,
            setTagsViewNameI18n,
            refreshCurrentTagsView,
            closeCurrentTagsView,
            onCurrentContextmenuClick,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.layout-navbars-tagsview {
    background-color: var(--el-color-white);
    border-bottom: 1px solid var(--next-border-color-light);
    position: relative;
    z-index: 4;
    ::v-deep(.el-scrollbar__wrap) {
        overflow-x: auto !important;
    }
    &-ul {
        list-style: none;
        margin: 0;
        padding: 0;
        height: 34px;
        display: flex;
        align-items: center;
        color: var(--el-text-color-regular);
        font-size: 12px;
        white-space: nowrap;
        padding: 0 15px;
        &-li {
            height: 26px;
            line-height: 26px;
            display: flex;
            align-items: center;
            border: 1px solid var(--el-border-color-lighter);
            padding: 0 15px;
            margin-right: 5px;
            border-radius: 2px;
            position: relative;
            z-index: 0;
            cursor: pointer;
            justify-content: space-between;
            &:hover {
                background-color: var(--el-color-primary-light-9);
                color: var(--el-color-primary);
                border-color: var(--el-color-primary-light-5);
            }
            &-iconfont {
                position: relative;
                left: -5px;
                font-size: 12px;
            }
            &-icon {
                border-radius: 100%;
                position: relative;
                height: 14px;
                width: 14px;
                text-align: center;
                line-height: 14px;
                right: -5px;
                &:hover {
                    color: var(--el-color-white);
                    background-color: var(--el-color-primary-light-3);
                }
            }
            .layout-icon-active {
                display: block;
            }
            .layout-icon-three {
                display: none;
            }
        }
        .is-active {
            color: var(--el-color-white);
            background: var(--el-color-primary);
            border-color: var(--el-color-primary);
            transition: border-color 3s ease;
        }
    }
    // 风格4
    .tags-style-four {
        .layout-navbars-tagsview-ul-li {
            margin-right: 0 !important;
            border: none !important;
            position: relative;
            border-radius: 3px !important;
            .layout-icon-active {
                display: none;
            }
            .layout-icon-three {
                display: block;
            }
            &:hover {
                background: none !important;
            }
        }
        .is-active {
            background: none !important;
            color: var(--el-color-primary) !important;
        }
    }
    // 风格5
    .tags-style-five {
        align-items: flex-end;
        .tags-style-five-svg {
            -webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='68' height='34' viewBox='0 0 68 34' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='m27,0c-7.99582,0 -11.95105,0.00205 -12,12l0,6c0,8.284 -0.48549,16.49691 -8.76949,16.49691l54.37857,-0.11145c-8.284,0 -8.60908,-8.10146 -8.60908,-16.38546l0,-6c0.11145,-12.08445 -4.38441,-12 -12,-12l-13,0z' fill='%23409eff'/%3E%3C/svg%3E")
                12 27 15;
        }
        .layout-navbars-tagsview-ul-li {
            padding: 0 5px;
            border-width: 15px 27px 15px;
            border-style: solid;
            border-color: transparent;
            margin: 0 -15px;
            .layout-icon-active,
            .layout-navbars-tagsview-ul-li-iconfont,
            .layout-navbars-tagsview-ul-li-refresh {
                display: none;
            }
            .layout-icon-three {
                display: block;
            }
            &:hover {
                @extend .tags-style-five-svg;
                background: var(--el-color-primary-light-9);
                color: unset;
            }
        }
        .is-active {
            @extend .tags-style-five-svg;
            background: var(--el-color-primary-light-9) !important;
            color: var(--el-color-primary) !important;
            z-index: 1;
        }
    }
}
.layout-navbars-tagsview-shadow {
    box-shadow: rgb(0 21 41 / 4%) 0px 1px 4px;
}
</style>
src/layout/navMenu/horizontal.vue
对比新文件
@@ -0,0 +1,157 @@
<template>
    <div class="el-menu-horizontal-warp">
        <el-scrollbar @wheel.native.prevent="onElMenuHorizontalScroll" ref="elMenuHorizontalScrollRef">
            <el-menu router :default-active="defaultActive" :ellipsis="false" background-color="transparent" mode="horizontal">
                <template v-for="val in menuLists">
                    <el-sub-menu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
                        <template #title>
                            <SvgIcon :name="val.meta.icon" />
                            <span>{{ $t(val.meta.title) }}</span>
                        </template>
                        <SubItem :chil="val.children" />
                    </el-sub-menu>
                    <template v-else>
                        <el-menu-item :index="val.path" :key="val.path">
                            <template #title v-if="!val.meta.isLink || (val.meta.isLink && val.meta.isIframe)">
                                <SvgIcon :name="val.meta.icon" />
                                {{ $t(val.meta.title) }}
                            </template>
                            <template #title v-else>
                                <a :href="val.meta.isLink" target="_blank" rel="opener" class="w100">
                                    <SvgIcon :name="val.meta.icon" />
                                    {{ $t(val.meta.title) }}
                                </a>
                            </template>
                        </el-menu-item>
                    </template>
                </template>
            </el-menu>
        </el-scrollbar>
    </div>
</template>
<script lang="ts">
import { toRefs, reactive, computed, defineComponent, getCurrentInstance, onMounted, nextTick, onBeforeMount } from 'vue';
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useRoutesList } from '/@/stores/routesList';
import { useThemeConfig } from '/@/stores/themeConfig';
import SubItem from '/@/layout/navMenu/subItem.vue';
export default defineComponent({
    name: 'navMenuHorizontal',
    components: { SubItem },
    props: {
        menuList: {
            type: Array,
            default: () => [],
        },
    },
    setup(props) {
        const { proxy } = <any>getCurrentInstance();
        const stores = useRoutesList();
        const storesThemeConfig = useThemeConfig();
        const { routesList } = storeToRefs(stores);
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const route = useRoute();
        const state = reactive({
            defaultActive: null,
        });
        // 获取父级菜单数据
        const menuLists = computed(() => {
            return <any>props.menuList;
        });
        // 设置横向滚动条可以鼠标滚轮滚动
        const onElMenuHorizontalScroll = (e: any) => {
            const eventDelta = e.wheelDelta || -e.deltaY * 40;
            proxy.$refs.elMenuHorizontalScrollRef.$refs.wrap$.scrollLeft = proxy.$refs.elMenuHorizontalScrollRef.$refs.wrap$.scrollLeft + eventDelta / 4;
        };
        // 初始化数据,页面刷新时,滚动条滚动到对应位置
        const initElMenuOffsetLeft = () => {
            nextTick(() => {
                let els: any = document.querySelector('.el-menu.el-menu--horizontal li.is-active');
                if (!els) return false;
                proxy.$refs.elMenuHorizontalScrollRef.$refs.wrap$.scrollLeft = els.offsetLeft;
            });
        };
        // 路由过滤递归函数
        const filterRoutesFun = (arr: Array<string>) => {
            return arr
                .filter((item: any) => !item.meta.isHide)
                .map((item: any) => {
                    item = Object.assign({}, item);
                    if (item.children) item.children = filterRoutesFun(item.children);
                    return item;
                });
        };
        // 传送当前子级数据到菜单中
        const setSendClassicChildren = (path: string) => {
            const currentPathSplit = path.split('/');
            let currentData: any = {};
            filterRoutesFun(routesList.value).map((v, k) => {
                if (v.path === `/${currentPathSplit[1]}`) {
                    v['k'] = k;
                    currentData['item'] = [{ ...v }];
                    currentData['children'] = [{ ...v }];
                    if (v.children) currentData['children'] = v.children;
                }
            });
            return currentData;
        };
        // 设置页面当前路由高亮
        const setCurrentRouterHighlight = (currentRoute: any) => {
            const { path, meta } = currentRoute;
            if (themeConfig.value.layout === 'classic') {
                (<any>state.defaultActive) = `/${path.split('/')[1]}`;
            } else {
                const pathSplit = meta.isDynamic ? meta.isDynamicPath.split('/') : path.split('/');
                if (pathSplit.length >= 4 && meta.isHide) state.defaultActive = pathSplit.splice(0, 3).join('/');
                else state.defaultActive = path;
            }
        };
        // 页面加载前
        onBeforeMount(() => {
            setCurrentRouterHighlight(route);
        });
        // 页面加载时
        onMounted(() => {
            initElMenuOffsetLeft();
        });
        // 路由更新时
        onBeforeRouteUpdate((to) => {
            // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
            setCurrentRouterHighlight(to);
            // 修复经典布局开启切割菜单时,点击tagsView后左侧导航菜单数据不变的问题
            let { layout, isClassicSplitMenu } = themeConfig.value;
            if (layout === 'classic' && isClassicSplitMenu) {
                proxy.mittBus.emit('setSendClassicChildren', setSendClassicChildren(to.path));
            }
        });
        return {
            menuLists,
            onElMenuHorizontalScroll,
            ...toRefs(state),
        };
    },
});
</script>
<style scoped lang="scss">
.el-menu-horizontal-warp {
    flex: 1;
    overflow: hidden;
    margin-right: 30px;
    ::v-deep(.el-scrollbar__bar.is-vertical) {
        display: none;
    }
    ::v-deep(a) {
        width: 100%;
    }
    .el-menu.el-menu--horizontal {
        display: flex;
        height: 100%;
        width: 100%;
        box-sizing: border-box;
    }
}
</style>
src/layout/navMenu/subItem.vue
对比新文件
@@ -0,0 +1,48 @@
<template>
    <template v-for="val in chils">
        <el-sub-menu :index="val.path" :key="val.path" v-if="val.children && val.children.length > 0">
            <template #title>
                <SvgIcon :name="val.meta.icon" />
                <span>{{ $t(val.meta.title) }}</span>
            </template>
            <sub-item :chil="val.children" />
        </el-sub-menu>
        <template v-else>
            <el-menu-item :index="val.path" :key="val.path">
                <template v-if="!val.meta.isLink || (val.meta.isLink && val.meta.isIframe)">
                    <SvgIcon :name="val.meta.icon" />
                    <span>{{ $t(val.meta.title) }}</span>
                </template>
                <template v-else>
                    <a :href="val.meta.isLink" target="_blank" rel="opener" class="w100">
                        <SvgIcon :name="val.meta.icon" />
                        {{ $t(val.meta.title) }}
                    </a>
                </template>
            </el-menu-item>
        </template>
    </template>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
export default defineComponent({
    name: 'navMenuSubItem',
    props: {
        chil: {
            type: Array,
            default: () => [],
        },
    },
    setup(props) {
        // 获取父级菜单数据
        const chils = computed(() => {
            return <any>props.chil;
        });
        return {
            chils,
        };
    },
});
</script>
src/layout/navMenu/vertical.vue
对比新文件
@@ -0,0 +1,101 @@
<template>
    <el-menu
        router
        :default-active="defaultActive"
        background-color="transparent"
        :collapse="isCollapse"
        :unique-opened="true"
        :collapse-transition="false"
    >
        <template v-for="val in menuLists">
            <el-sub-menu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
                <template #title>
                    <SvgIcon :name="val.meta.icon" />
                    <span>{{ $t(val.meta.title) }}</span>
                </template>
                <SubItem :chil="val.children" />
            </el-sub-menu>
            <template v-else>
                <el-menu-item :index="val.path" :key="val.path">
                    <SvgIcon :name="val.meta.icon" />
                    <template #title v-if="!val.meta.isLink || (val.meta.isLink && val.meta.isIframe)">
                        <span>{{ $t(val.meta.title) }}</span>
                    </template>
                    <template #title v-else>
                        <a :href="val.meta.isLink" target="_blank" rel="opener" class="w100">{{ $t(val.meta.title) }}</a>
                    </template>
                </el-menu-item>
            </template>
        </template>
    </el-menu>
</template>
<script lang="ts">
import { toRefs, reactive, computed, defineComponent, onMounted, watch } from 'vue';
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import SubItem from '/@/layout/navMenu/subItem.vue';
export default defineComponent({
    name: 'navMenuVertical',
    components: { SubItem },
    props: {
        menuList: {
            type: Array,
            default: () => [],
        },
    },
    setup(props) {
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const route = useRoute();
        const state = reactive({
            // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
            defaultActive: route.meta.isDynamic ? route.meta.isDynamicPath : route.path,
            isCollapse: false,
        });
        // 获取父级菜单数据
        const menuLists = computed(() => {
            return <any>props.menuList;
        });
        // 获取布局配置信息
        const getThemeConfig = computed(() => {
            return themeConfig.value;
        });
        // 菜单高亮(详情时,父级高亮)
        const setParentHighlight = (currentRoute: any) => {
            const { path, meta } = currentRoute;
            const pathSplit = meta.isDynamic ? meta.isDynamicPath.split('/') : path.split('/');
            if (pathSplit.length >= 4 && meta.isHide) return pathSplit.splice(0, 3).join('/');
            else return path;
        };
        // 设置菜单的收起/展开
        watch(
            themeConfig.value,
            () => {
                document.body.clientWidth <= 1000 ? (state.isCollapse = false) : (state.isCollapse = themeConfig.value.isCollapse);
            },
            {
                immediate: true,
            }
        );
        // 页面加载时
        onMounted(() => {
            state.defaultActive = setParentHighlight(route);
        });
        // 路由更新时
        onBeforeRouteUpdate((to) => {
            // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
            state.defaultActive = setParentHighlight(to);
            const clientWidth = document.body.clientWidth;
            if (clientWidth < 1000) themeConfig.value.isCollapse = false;
        });
        return {
            menuLists,
            getThemeConfig,
            ...toRefs(state),
        };
    },
});
</script>
src/layout/routerView/iframes.vue
对比新文件
@@ -0,0 +1,66 @@
<template>
    <div class="layout-view-bg-white flex mt1" :style="{ height: `calc(100vh - ${setIframeHeight}`, border: 'none' }" v-loading="iframeLoading">
        <iframe :src="iframeUrl" frameborder="0" height="100%" width="100%" ref="iframeDom" v-show="!iframeLoading"></iframe>
    </div>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs, onMounted, nextTick, watch, computed } from 'vue';
import { storeToRefs } from 'pinia';
import { useRoute } from 'vue-router';
import { useThemeConfig } from '/@/stores/themeConfig';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
export default defineComponent({
    name: 'layoutIfameView',
    setup() {
        const storesThemeConfig = useThemeConfig();
        const storesTagsViewRoutes = useTagsViewRoutes();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const { isTagsViewCurrenFull } = storeToRefs(storesTagsViewRoutes);
        const route = useRoute();
        const state = reactive({
            iframeDom: null as HTMLIFrameElement | null,
            iframeLoading: true,
            iframeUrl: '',
        });
        // 初始化页面加载 loading
        const initIframeLoad = () => {
            state.iframeUrl = <any>route.meta.isLink;
            nextTick(() => {
                state.iframeLoading = true;
                const iframe = state.iframeDom;
                if (!iframe) return false;
                iframe.onload = () => {
                    state.iframeLoading = false;
                };
            });
        };
        // 设置 iframe 的高度
        const setIframeHeight = computed(() => {
            let { isTagsview } = themeConfig.value;
            if (isTagsViewCurrenFull.value) {
                return `1px`;
            } else {
                if (isTagsview) return `86px`;
                else return `51px`;
            }
        });
        // 页面加载时
        onMounted(() => {
            initIframeLoad();
        });
        // 监听路由变化,多个 iframe 时使用
        watch(
            () => route.path,
            () => {
                initIframeLoad();
            }
        );
        return {
            setIframeHeight,
            ...toRefs(state),
        };
    },
});
</script>
src/layout/routerView/link.vue
对比新文件
@@ -0,0 +1,59 @@
<template>
    <div class="layout-view-bg-white flex layout-view-link" :style="{ height: `calc(100vh - ${setLinkHeight}` }">
        <a :href="currentRouteMeta.isLink" target="_blank" rel="opener" class="flex-margin"> {{ $t(currentRouteMeta.title) }}:{{ currentRouteMeta.isLink }} </a>
    </div>
</template>
<script lang="ts">
import { defineComponent, toRefs, reactive, computed, watch } from 'vue';
import { useRoute, RouteMeta } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
// 定义接口来定义对象的类型
interface LinkViewState {
    currentRouteMeta: {
        isLink: string;
        title: string;
    };
}
interface LinkViewRouteMeta extends RouteMeta {
    isLink: string;
    title: string;
}
export default defineComponent({
    name: 'layoutLinkView',
    setup() {
        const storesThemeConfig = useThemeConfig();
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const route = useRoute();
        const state = reactive<LinkViewState>({
            currentRouteMeta: {
                isLink: '',
                title: ''
            }
        });
        // 设置 link 的高度
        const setLinkHeight = computed(() => {
            let { isTagsview } = themeConfig.value;
            if (isTagsview) return `115px`;
            else return `80px`;
        });
        // 监听路由的变化,设置内容
        watch(
            () => route.path,
            () => {
                state.currentRouteMeta = <LinkViewRouteMeta>route.meta;
            },
            {
                immediate: true
            }
        );
        return {
            setLinkHeight,
            ...toRefs(state)
        };
    }
});
</script>
src/layout/routerView/parent.vue
对比新文件
@@ -0,0 +1,88 @@
<template>
    <div class="h100">
        <router-view v-slot="{ Component }">
            <transition :name="setTransitionName" mode="out-in">
                <keep-alive :include="getKeepAliveNames">
                    <component :is="Component" :key="refreshRouterViewKey" class="w100" />
                </keep-alive>
            </transition>
        </router-view>
    </div>
</template>
<script lang="ts">
import { computed, defineComponent, toRefs, reactive, getCurrentInstance, onBeforeMount, onUnmounted, nextTick, watch, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useKeepALiveNames } from '/@/stores/keepAliveNames';
import { useThemeConfig } from '/@/stores/themeConfig';
import { Session } from '/@/utils/storage';
// 定义接口来定义对象的类型
interface ParentViewState {
    refreshRouterViewKey: null | string;
    keepAliveNameList: string[];
}
export default defineComponent({
    name: 'layoutParentView',
    setup() {
        const { proxy } = <any>getCurrentInstance();
        const route = useRoute();
        const storesKeepAliveNames = useKeepALiveNames();
        const storesThemeConfig = useThemeConfig();
        const { keepAliveNames, cachedViews } = storeToRefs(storesKeepAliveNames);
        const { themeConfig } = storeToRefs(storesThemeConfig);
        const state = reactive<ParentViewState>({
            refreshRouterViewKey: null,
            keepAliveNameList: [],
        });
        // 设置主界面切换动画
        const setTransitionName = computed(() => {
            return themeConfig.value.animation;
        });
        // 获取组件缓存列表(name值)
        const getKeepAliveNames = computed(() => {
            return themeConfig.value.isTagsview ? cachedViews.value : state.keepAliveNameList;
        });
        // 页面加载前,处理缓存,页面刷新时路由缓存处理
        onBeforeMount(() => {
            state.keepAliveNameList = keepAliveNames.value;
            proxy.mittBus.on('onTagsViewRefreshRouterView', (fullPath: string) => {
                state.keepAliveNameList = keepAliveNames.value.filter((name: string) => route.name !== name);
                state.refreshRouterViewKey = null;
                nextTick(() => {
                    state.refreshRouterViewKey = fullPath;
                    state.keepAliveNameList = keepAliveNames.value;
                });
            });
        });
        // 页面加载时
        onMounted(() => {
            // https://gitee.com/lyt-top/vue-next-admin/issues/I58U75
            // https://gitee.com/lyt-top/vue-next-admin/issues/I59RXK
            nextTick(() => {
                setTimeout(() => {
                    if (themeConfig.value.isCacheTagsView) cachedViews.value = Session.get('tagsViewList')?.map((item: any) => item.name);
                }, 0);
            });
        });
        // 页面卸载时
        onUnmounted(() => {
            proxy.mittBus.off('onTagsViewRefreshRouterView', () => {});
        });
        // 监听路由变化,防止 tagsView 多标签时,切换动画消失
        watch(
            () => route.fullPath,
            () => {
                state.refreshRouterViewKey = decodeURI(route.fullPath);
            }
        );
        return {
            setTransitionName,
            getKeepAliveNames,
            ...toRefs(state),
        };
    },
});
</script>
src/main.ts
对比新文件
@@ -0,0 +1,27 @@
import { createApp } from 'vue';
import pinia from '/@/stores/index';
import App from './App.vue';
import router from './router';
import { directive } from '/@/utils/directive';
import { i18n } from '/@/i18n/index';
import other from '/@/utils/other';
import '/@/assets/style/index.scss';
import ElementPlus from 'element-plus';
import * as ElementPlusIconsVue from '@element-plus/icons-vue';
import 'element-plus/dist/index.css';
import '/@/theme/index.scss';
import mitt from 'mitt';
import VueGridLayout from 'vue-grid-layout';
import zhCn from 'element-plus/lib/locale/lang/zh-cn';
import DataVVue3 from '@kjgl77/datav-vue3'
const app = createApp(App);
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component);
}
directive(app);
other.elSvg(app);
app.use(pinia).use(router).use(ElementPlus, { i18n: i18n.global.t, locale: zhCn }).use(i18n).use(DataVVue3).use(VueGridLayout).mount('#app');
app.config.globalProperties.mittBus = mitt();
src/router/backEnd.ts
对比新文件
@@ -0,0 +1,98 @@
import { RouteRecordRaw } from 'vue-router';
import { storeToRefs } from 'pinia';
import pinia from '/@/stores/index';
import { useUserInfo } from '/@/stores/userInfo';
import { useRequestOldRoutes } from '/@/stores/requestOldRoutes';
import { NextLoading } from '/@/utils/loading';
import { dynamicRoutes, notFoundAndNoPower } from '/@/router/route';
import { formatTwoStageRoutes, formatFlatteningRoutes, router } from '/@/router/index';
import { useRoutesList } from '/@/stores/routesList';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { useMenuApi } from '/@/api/systemManage/menu/index';
import { ElMessage } from 'element-plus';
import Cookies from 'js-cookie';
const menuApi = useMenuApi();
const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}');
const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}');
/**
 * 获取目录下的 .vue、.tsx 全部文件
 * @method import.meta.glob
 * @link 参考:https://cn.vitejs.dev/guide/features.html#json
 */
const dynamicViewsModules: Record<string, Function> = Object.assign({}, { ...layouModules }, { ...viewsModules });
export async function initBackEndControlRoutes() {
    if (window.nextLoading === undefined) NextLoading.start();
    if (!Cookies.get('token')) return false;
    const res = await getBackEndControlRoutes(Cookies.get('projectId') === null ? '' : Cookies.get('projectId'));
    await useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data.data)));
    dynamicRoutes[0].children = await backEndComponent(res.data.data);
    await setAddRoute();
    await setFilterMenuAndCacheTagsViewRoutes();
}
export function setFilterMenuAndCacheTagsViewRoutes() {
    const storesRoutesList = useRoutesList(pinia);
    storesRoutesList.setRoutesList(dynamicRoutes[0].children as any);
    setCacheTagsViewRoutes();
}
export function setCacheTagsViewRoutes() {
    const storesTagsView = useTagsViewRoutes(pinia);
    storesTagsView.setTagsViewRoutes(formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes))[0].children);
}
export function setFilterRouteEnd() {
    let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes));
    filterRouteEnd[0].children = [...filterRouteEnd[0].children, ...notFoundAndNoPower];
    return filterRouteEnd;
}
export async function setAddRoute() {
    await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
        router.addRoute(route);
    });
}
export async function getBackEndControlRoutes(value: string) {
    // const stores = useUserInfo(pinia);
    // const { userInfos } = storeToRefs(stores);
    // const auth = userInfos.value.roles[0];
    return menuApi.getMenuAdmin(value);
}
/**
 * 重新请求后端路由菜单接口
 * @description 用于菜单管理界面刷新菜单(未进行测试)
 * @description 路径:/src/views/system/homeMenu/components/menuDialog.vue
 */
export function setBackEndControlRefreshRoutes() {
    getBackEndControlRoutes(Cookies.get('projectId'));
}
export function backEndComponent(routes: any) {
    if (!routes) return;
    return routes.map((item: any) => {
        if (item.component) item.component = dynamicImport(dynamicViewsModules, item.component as string);
        item.children && backEndComponent(item.children);
        return item;
    });
}
export function dynamicImport(dynamicViewsModules: Record<string, Function>, component: string) {
    const keys = Object.keys(dynamicViewsModules);
    const matchKeys = keys.filter((key) => {
        const k = key.replace(/..\/views|../, '');
        return k.startsWith(`${component}`) || k.startsWith(`/${component}`);
    });
    if (matchKeys?.length === 1) {
        const matchKey = matchKeys[0];
        return dynamicViewsModules[matchKey];
    }
    if (matchKeys?.length > 1) {
        return false;
    }
}
src/router/frontEnd.ts
对比新文件
@@ -0,0 +1,97 @@
import { RouteRecordRaw } from 'vue-router';
import { storeToRefs } from 'pinia';
import { formatTwoStageRoutes, formatFlatteningRoutes, router } from '/@/router/index';
import { dynamicRoutes, notFoundAndNoPower } from '/@/router/route';
import pinia from '/@/stores/index';
import { Session } from '/@/utils/storage';
import { useUserInfo } from '/@/stores/userInfo';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { useRoutesList } from '/@/stores/routesList';
import { NextLoading } from '/@/utils/loading';
export async function initFrontEndControlRoutes() {
    if (window.nextLoading === undefined) NextLoading.start();
    if (!Session.get('token')) return false;
    // useUserInfo(pinia).setUserInfos();
    await setAddRoute();
    await setFilterMenuAndCacheTagsViewRoutes();
}
export async function setAddRoute() {
    await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
        router.addRoute(route);
    });
}
export async function frontEndsResetRoute() {
    await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
        const routeName: any = route.name;
        router.hasRoute(routeName) && router.removeRoute(routeName);
    });
}
export function setFilterRouteEnd() {
    let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes));
    filterRouteEnd[0].children = [...setFilterRoute(filterRouteEnd[0].children), ...notFoundAndNoPower];
    return filterRouteEnd;
}
export function setFilterRoute(chil: any) {
    const stores = useUserInfo(pinia);
    const { userInfos } = storeToRefs(stores);
    let filterRoute: any = [];
    chil.forEach((route: any) => {
        if (route.meta.roles) {
            route.meta.roles.forEach((metaRoles: any) => {
                userInfos.value.roles.forEach((roles: any) => {
                    if (metaRoles === roles) filterRoute.push({ ...route });
                });
            });
        }
    });
    return filterRoute;
}
export function setCacheTagsViewRoutes() {
    // 获取有权限的路由,否则 tagsView、菜单搜索中无权限的路由也将显示
    const stores = useUserInfo(pinia);
    const storesTagsView = useTagsViewRoutes(pinia);
    const { userInfos } = storeToRefs(stores);
    let rolesRoutes = setFilterHasRolesMenu(dynamicRoutes, userInfos.value.roles);
    // 添加到 pinia setTagsViewRoutes 中
    storesTagsView.setTagsViewRoutes(formatTwoStageRoutes(formatFlatteningRoutes(rolesRoutes))[0].children);
}
export function setFilterMenuAndCacheTagsViewRoutes() {
    const stores = useUserInfo(pinia);
    const storesRoutesList = useRoutesList(pinia);
    const { userInfos } = storeToRefs(stores);
    storesRoutesList.setRoutesList(setFilterHasRolesMenu(dynamicRoutes[0].children, userInfos.value.roles));
    setCacheTagsViewRoutes();
}
export function hasRoles(roles: any, route: any) {
    if (route.meta && route.meta.roles) return roles.some((role: any) => route.meta.roles.includes(role));
    else return true;
}
export function setFilterHasRolesMenu(routes: any, roles: any) {
    const menu: any = [];
    routes.forEach((route: any) => {
        const item = { ...route };
        if (hasRoles(roles, item)) {
            if (item.children) item.children = setFilterHasRolesMenu(item.children, roles);
            menu.push(item);
        }
    });
    return menu;
}
src/router/index.ts
对比新文件
@@ -0,0 +1,106 @@
import { createRouter, createWebHashHistory } from 'vue-router';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import pinia from '/@/stores/index';
import { storeToRefs } from 'pinia';
import { useKeepALiveNames } from '/@/stores/keepAliveNames';
import { useRoutesList } from '/@/stores/routesList';
import { useThemeConfig } from '/@/stores/themeConfig';
import { Session } from '/@/utils/storage';
import { staticRoutes } from '/@/router/route';
import { initFrontEndControlRoutes } from '/@/router/frontEnd';
import { initBackEndControlRoutes } from '/@/router/backEnd';
import { useUserInfo } from '/@/stores/userInfo';
import { nextTick } from 'vue';
// 读取 `/src/stores/themeConfig.ts` 是否开启后端控制路由配置
const storesThemeConfig = useThemeConfig(pinia);
const { themeConfig } = storeToRefs(storesThemeConfig);
const { isRequestRoutes } = themeConfig.value;
if (isRequestRoutes) staticRoutes.splice(0, 1);
export const router = createRouter({
    history: createWebHashHistory(),
    routes: staticRoutes
});
export function formatFlatteningRoutes(arr: any) {
    if (arr.length <= 0) return false;
    for (let i = 0; i < arr.length; i++) {
        if (arr[i].children) {
            arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1));
        }
    }
    return arr;
}
export function formatTwoStageRoutes(arr: any) {
    if (arr.length <= 0) return false;
    const newArr: any = [];
    const cacheList: Array<string> = [];
    arr.forEach((v: any) => {
        if (v.path === '/') {
            newArr.push({ component: v.component, name: v.name, path: v.path, redirect: v.redirect, meta: v.meta, children: [] });
        } else {
            // 判断是否是动态路由(xx/:id/:name),用于 tagsView 等中使用
            // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G
            if (v.path.indexOf('/:') > -1) {
                v.meta['isDynamic'] = true;
                v.meta['isDynamicPath'] = v.path;
            }
            newArr[0].children.push({ ...v });
            // 存 name 值,keep-alive 中 include 使用,实现路由的缓存
            // 路径:/@/layout/routerView/parent.vue
            if (newArr[0].meta.isKeepAlive && v.meta.isKeepAlive) {
                cacheList.push(v.name);
                const stores = useKeepALiveNames(pinia);
                stores.setCacheKeepAlive(cacheList);
            }
        }
    });
    return newArr;
}
// // isRequestRoutes 为 true,则开启后端控制路由,路径:`/src/stores/themeConfig.ts`
// if (!isRequestRoutes) initFrontEndControlRoutes();
// 路由加载前
router.beforeEach(async (to, from, next) => {
    NProgress.configure({ showSpinner: false });
    if (to.meta.title) NProgress.start();
    const token = Session.get('token');
    if (to.path === '/login' && !token) {
        next();
        NProgress.done();
    } else {
        if (!token) {
            next(`/login?redirect=${to.path}&params=${JSON.stringify(to.query ? to.query : to.params)}`);
            Session.clear();
            NProgress.done();
        } else if (token && to.path === '/login') {
            next('/home');
            NProgress.done();
        } else {
            const storesRoutesList = useRoutesList(pinia);
            const { routesList } = storeToRefs(storesRoutesList);
            if (routesList.value.length === 0) {
                // 后端控制路由:路由数据初始化,防止刷新时丢失
                await initBackEndControlRoutes();
                // 动态添加路由:防止非首页刷新时跳转回首页的问题
                // 确保 addRoute() 时动态添加的路由已经被完全加载上去
                next({ ...to, replace: true });
            } else {
                next();
            }
        }
    }
});
// 路由加载后
router.afterEach(() => {
    NProgress.done();
});
// 导出路由
export default router;
src/router/route.ts
对比新文件
@@ -0,0 +1,115 @@
import { RouteRecordRaw } from 'vue-router';
export const dynamicRoutes: Array<RouteRecordRaw> = [
    {
        path: '/',
        name: '/',
        component: () => import('/@/layout/index.vue'),
        redirect: '/home',
        meta: {
            isKeepAlive: false
        },
        children: [
            {
                path: '/home',
                name: 'home',
                component: () => import('/@/views/newHome/index.vue'),
                meta: {
                    title: '首页',
                    isLink: '',
                    isHide: false,
                    isKeepAlive: true,
                    isAffix: true,
                    isIframe: false,
                    roles: ['admin', 'common'],
                    icon: 'iconfont icon-shouye'
                }
            }
        ]
    }
];
export const notFoundAndNoPower = [
    {
        path: '/:path(.*)*',
        name: 'notFound',
        component: () => import('/@/views/error/404.vue'),
        meta: {
            title: 'message.staticRoutes.notFound',
            isHide: true
        }
    },
    {
        path: '/401',
        name: 'noPower',
        component: () => import('/@/views/error/401.vue'),
        meta: {
            title: 'message.staticRoutes.noPower',
            isHide: true
        }
    }
];
export const staticRoutes: Array<RouteRecordRaw> = [
    {
        path: '/',
        name: '/',
        component: () => import('/@/layout/index.vue'),
        meta: {
            title: '布局界面'
        },
        children: [
            // 请不要往这里 `children` 中添加内容,此内容为了防止 No match found for location with path "xxx" 问题
            ...notFoundAndNoPower
        ]
    },
    {
        path: '/login',
        name: 'login',
        component: () => import('/@/views/loginPage/loginPage.vue'),
        meta: {
            title: '登录'
        }
    },
    {
        path: '/newMenu',
        name: 'newMenu',
        component: () => import('/@/views/newHome/index.vue'),
        meta: {
            title: '首页',
            isKeepAlive: false
        }
    },
    {
        path: '/warningScreen',
        name: 'warningScreen',
        component: () => import('/@/views/riskWarningSys/warningBigScreen/index.vue'),
        meta: {
            title: '预警预报'
        }
    },
    {
        path: '/msgDetail',
        name: 'msgDetail',
        component: () => import('/@/views/riskWarningSys/warningBigScreen/indexs/msgDetail.vue'),
        meta: {
            title: 'spi报告详情'
        }
    },
    {
        path: '/screenPage',
        name: 'screenPage',
        component: () => import('/@/views/riskWarningSys/warningBigScreen/indexs/index.vue'),
        meta: {
            title: '预警预报'
        }
    },
    {
        path: '/securities',
        name: 'securities',
        component: () => import('/@/views/facilityManagement/securities/index.vue'),
        meta: {
            title: '安全物资与设备'
        }
    }
];
src/stores/index.ts
对比新文件
@@ -0,0 +1,15 @@
// https://pinia.vuejs.org/
import { createPinia } from 'pinia';
import { createPersistedState } from 'pinia-plugin-persistedstate'
// 创建
const pinia = createPinia();
pinia.use(createPersistedState({
    serializer:{
        serialize:JSON.stringify,
        deserialize:JSON.parse,
    }
}))
// 导出
export default pinia;
src/stores/interface/index.ts
对比新文件
@@ -0,0 +1,109 @@
/**
 * 定义接口来定义对象的类型
 * `stores` 全部类型定义在这里
 */
// 用户信息
export interface UserInfosState {
    authBtnList: string[];
    photo: string;
    roles: string[];
    time: number;
    userName: string;
    uid: string;
    depId: null | number;
    projectId: string;
    dataList: [];
}
export interface UserInfosStates {
    userInfos: UserInfosState;
}
// 路由缓存列表
export interface KeepAliveNamesState {
    keepAliveNames: string[];
    cachedViews: string[];
}
// 后端返回原始路由(未处理时)
export interface RequestOldRoutesState {
    requestOldRoutes: string[];
}
// TagsView 路由列表
export interface TagsViewRoutesState {
    tagsViewRoutes: string[];
    isTagsViewCurrenFull: Boolean;
}
// 路由列表
export interface RoutesListState {
    routesList: string[];
    isColumnsMenuHover: Boolean;
    isColumnsNavHover: Boolean;
    projectId: string;
}
export interface loginInfoState {
    loginUser: {
        projectId: string;
        token: string;
        uid: string;
    };
}
export interface screenThemeState {
    screenTheme: {
        isDark: boolean
    }
}
// 布局配置
export interface ThemeConfigState {
    isDrawer: boolean;
    primary: string;
    topBar: string;
    topBarColor: string;
    isTopBarColorGradual: boolean;
    menuBar: string;
    menuBarColor: string;
    isMenuBarColorGradual: boolean;
    columnsMenuBar: string;
    columnsMenuBarColor: string;
    isColumnsMenuBarColorGradual: boolean;
    isCollapse: boolean;
    isUniqueOpened: boolean;
    isFixedHeader: boolean;
    isFixedHeaderChange: boolean;
    isClassicSplitMenu: boolean;
    isLockScreen: boolean;
    lockScreenTime: number;
    isShowLogo: boolean;
    isShowLogoChange: boolean;
    isBreadcrumb: boolean;
    isTagsview: boolean;
    isBreadcrumbIcon: boolean;
    isTagsviewIcon: boolean;
    isCacheTagsView: boolean;
    isSortableTagsView: boolean;
    isShareTagsView: boolean;
    isFooter: boolean;
    isGrayscale: boolean;
    isInvert: boolean;
    isIsDark: boolean;
    isWartermark: boolean;
    wartermarkText: string;
    tagsStyle: string;
    animation: string;
    columnsAsideStyle: string;
    columnsAsideLayout: string;
    layout: string;
    isRequestRoutes: boolean;
    globalTitle: string;
    globalViceTitle: string;
    globalI18n: string;
    globalComponentSize: string;
}
export interface ThemeConfigStates {
    themeConfig: ThemeConfigState;
}
src/stores/keepAliveNames.ts
对比新文件
@@ -0,0 +1,37 @@
import { defineStore } from 'pinia';
import { KeepAliveNamesState } from './interface';
/**
 * 路由缓存列表
 * @methods setCacheKeepAlive 设置要缓存的路由 names(开启 Tagsview)
 * @methods addCachedView 添加要缓存的路由 names(关闭 Tagsview)
 * @methods delCachedView 删除要缓存的路由 names(关闭 Tagsview)
 * @methods delOthersCachedViews 右键菜单`关闭其它`,删除要缓存的路由 names(关闭 Tagsview)
 * @methods delAllCachedViews 右键菜单`全部关闭`,删除要缓存的路由 names(关闭 Tagsview)
 */
export const useKeepALiveNames = defineStore('keepALiveNames', {
    state: (): KeepAliveNamesState => ({
        keepAliveNames: [],
        cachedViews: [],
    }),
    actions: {
        async setCacheKeepAlive(data: Array<string>) {
            this.keepAliveNames = data;
        },
        async addCachedView(view: any) {
            if (this.cachedViews.includes(view.name)) return;
            if (view.meta.isKeepAlive) this.cachedViews.push(view.name);
        },
        async delCachedView(view: any) {
            const index = this.cachedViews.indexOf(view.name);
            index > -1 && this.cachedViews.splice(index, 1);
        },
        async delOthersCachedViews(view: any) {
            if (view.meta.isKeepAlive) this.cachedViews = [view.name];
            else this.cachedViews = [];
        },
        async delAllCachedViews() {
            this.cachedViews = [];
        },
    },
});
src/stores/loginInfo.ts
对比新文件
@@ -0,0 +1,20 @@
import { defineStore } from 'pinia';
import { loginInfoState } from './interface';
/**
 * 路由列表
 * @methods setRoutesList 设置路由数据
 * @methods setColumnsMenuHover 设置分栏布局菜单鼠标移入 boolean
 * @methods setColumnsNavHover 设置分栏布局最左侧导航鼠标移入 boolean
 */
export const useLoginInfo = defineStore('loginInfo', {
    state: (): loginInfoState => ({
        loginUser:{
            projectId:'',
            token:'',
            uid:'',
        }
    }),
    actions: {
    },
});
src/stores/requestOldRoutes.ts
对比新文件
@@ -0,0 +1,17 @@
import { defineStore } from 'pinia';
import { RequestOldRoutesState } from './interface';
/**
 * 后端返回原始路由(未处理时)
 * @methods setCacheKeepAlive 设置接口原始路由数据
 */
export const useRequestOldRoutes = defineStore('requestOldRoutes', {
    state: (): RequestOldRoutesState => ({
        requestOldRoutes: [],
    }),
    actions: {
        async setRequestOldRoutes(routes: Array<string>) {
            this.requestOldRoutes = routes;
        },
    },
});
src/stores/routesList.ts
对比新文件
@@ -0,0 +1,28 @@
import { defineStore } from 'pinia';
import { RoutesListState } from './interface';
/**
 * 路由列表
 * @methods setRoutesList 设置路由数据
 * @methods setColumnsMenuHover 设置分栏布局菜单鼠标移入 boolean
 * @methods setColumnsNavHover 设置分栏布局最左侧导航鼠标移入 boolean
 */
export const useRoutesList = defineStore('routesList', {
    state: (): RoutesListState => ({
        routesList: [],
        isColumnsMenuHover: false,
        isColumnsNavHover: false,
        projectId:'',
    }),
    actions: {
        async setRoutesList(data: Array<string>) {
            this.routesList = data;
        },
        async setColumnsMenuHover(bool: Boolean) {
            this.isColumnsMenuHover = bool;
        },
        async setColumnsNavHover(bool: Boolean) {
            this.isColumnsNavHover = bool;
        },
    },
});
src/stores/screenTheme.ts
对比新文件
@@ -0,0 +1,21 @@
import { defineStore } from 'pinia';
import { screenThemeState } from './interface';
/**
 * 路由列表
 * @methods setRoutesList 设置路由数据
 * @methods setColumnsMenuHover 设置分栏布局菜单鼠标移入 boolean
 * @methods setColumnsNavHover 设置分栏布局最左侧导航鼠标移入 boolean
 */
export const useScreenTheme = defineStore('screenTheme', {
    state: (): screenThemeState => ({
        screenTheme:{
            isDark: true
        }
    }),
    actions: {
        async setScreenTheme(value: any) {
            this.screenTheme.isDark = value;
        }
    },
});
src/stores/tagsViewRoutes.ts
对比新文件
@@ -0,0 +1,24 @@
import { defineStore } from 'pinia';
import { TagsViewRoutesState } from './interface';
import { Session } from '/@/utils/storage';
/**
 * TagsView 路由列表
 * @methods setTagsViewRoutes 设置 TagsView 路由列表
 * @methods setCurrenFullscreen 设置开启/关闭全屏时的 boolean 状态
 */
export const useTagsViewRoutes = defineStore('tagsViewRoutes', {
    state: (): TagsViewRoutesState => ({
        tagsViewRoutes: [],
        isTagsViewCurrenFull: false,
    }),
    actions: {
        async setTagsViewRoutes(data: Array<string>) {
            this.tagsViewRoutes = data;
        },
        setCurrenFullscreen(bool: Boolean) {
            Session.set('isTagsViewCurrenFull', bool);
            this.isTagsViewCurrenFull = bool;
        },
    },
});
src/stores/themeConfig.ts
对比新文件
@@ -0,0 +1,146 @@
import { defineStore } from 'pinia';
import { ThemeConfigStates, ThemeConfigState } from './interface';
/**
 * 布局配置
 * 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I567R1,感谢@lanbao123
 * 2020.05.28 by lyt 优化。开发时配置不生效问题
 * 修改配置时:
 * 1、需要每次都清理 `window.localStorage` 浏览器永久缓存
 * 2、或者点击布局配置最底部 `一键恢复默认` 按钮即可看到效果
 */
export const useThemeConfig = defineStore('themeConfig', {
    state: (): ThemeConfigStates => ({
        themeConfig: {
            // 是否开启布局配置抽屉
            isDrawer: false,
            /**
             * 全局主题
             */
            // 默认 primary 主题颜色
            primary: '#409eff',
            // 是否开启深色模式
            isIsDark: false,
            /**
             * 菜单 / 顶栏
             * 注意:v1.0.17 版本去除设置布局切换,重置主题样式(initSetLayoutChange),
             * 切换布局需手动设置样式,设置的样式自动同步各布局,
             * 代码位置:/@/layout/navBars/breadcrumb/setings.vue
             */
            // 默认顶栏导航背景颜色
            topBar: '#ffffff',
            // 默认顶栏导航字体颜色
            topBarColor: '#606266',
            // 是否开启顶栏背景颜色渐变
            isTopBarColorGradual: false,
            // 默认菜单导航背景颜色
            menuBar: '#545c64',
            // 默认菜单导航字体颜色
            menuBarColor: '#eaeaea',
            // 是否开启菜单背景颜色渐变
            isMenuBarColorGradual: false,
            // 默认分栏菜单背景颜色
            columnsMenuBar: '#545c64',
            // 默认分栏菜单字体颜色
            columnsMenuBarColor: '#e6e6e6',
            // 是否开启分栏菜单背景颜色渐变
            isColumnsMenuBarColorGradual: false,
            /**
             * 界面设置
             */
            // 是否开启菜单水平折叠效果
            isCollapse: false,
            // 是否开启菜单手风琴效果
            isUniqueOpened: false,
            // 是否开启固定 Header
            isFixedHeader: false,
            // 初始化变量,用于更新菜单 el-scrollbar 的高度,请勿删除
            isFixedHeaderChange: false,
            // 是否开启经典布局分割菜单(仅经典布局生效)
            isClassicSplitMenu: false,
            // 是否开启自动锁屏
            isLockScreen: false,
            // 开启自动锁屏倒计时(s/秒)
            lockScreenTime: 30,
            /**
             * 界面显示
             */
            // 是否开启侧边栏 Logo
            isShowLogo: false,
            // 初始化变量,用于 el-scrollbar 的高度更新,请勿删除
            isShowLogoChange: false,
            // 是否开启 Breadcrumb,强制经典、横向布局不显示
            isBreadcrumb: true,
            // 是否开启 Tagsview
            isTagsview: true,
            // 是否开启 Breadcrumb 图标
            isBreadcrumbIcon: false,
            // 是否开启 Tagsview 图标
            isTagsviewIcon: false,
            // 是否开启 TagsView 缓存
            isCacheTagsView: false,
            // 是否开启 TagsView 拖拽
            isSortableTagsView: true,
            // 是否开启 TagsView 共用
            isShareTagsView: false,
            // 是否开启 Footer 底部版权信息
            isFooter: false,
            // 是否开启灰色模式
            isGrayscale: false,
            // 是否开启色弱模式
            isInvert: false,
            // 是否开启水印
            isWartermark: false,
            // 水印文案
            wartermarkText: 'small@小柒',
            /**
             * 其它设置
             */
            // Tagsview 风格:可选值"<tags-style-one|tags-style-four|tags-style-five>",默认 tags-style-five
            // 定义的值与 `/src/layout/navBars/tagsView/tagsView.vue` 中的 class 同名
            tagsStyle: 'tags-style-five',
            // 主页面切换动画:可选值"<slide-right|slide-left|opacitys>",默认 slide-right
            animation: 'slide-right',
            // 分栏高亮风格:可选值"<columns-round|columns-card>",默认 columns-round
            columnsAsideStyle: 'columns-round',
            // 分栏布局风格:可选值"<columns-horizontal|columns-vertical>",默认 columns-horizontal
            columnsAsideLayout: 'columns-vertical',
            /**
             * 布局切换
             * 注意:为了演示,切换布局时,颜色会被还原成默认,代码位置:/@/layout/navBars/breadcrumb/setings.vue
             * 中的 `initSetLayoutChange(设置布局切换,重置主题样式)` 方法
             */
            // 布局切换:可选值"<defaults|classic|transverse|columns>",默认 defaults
            layout: 'classic',
            /**
             * 后端控制路由
             */
            // 是否开启后端控制路由
            isRequestRoutes: true,
            /**
             * 全局网站标题 / 副标题
             */
            // 网站主标题(菜单导航、浏览器当前网页标题)
            globalTitle: 'vue-next-admin',
            // 网站副标题(登录页顶部文字)
            globalViceTitle: 'vueNextAdmin',
            // 默认初始语言,可选值"<zh-cn|en|zh-tw>",默认 zh-cn
            globalI18n: 'zh-cn',
            // 默认全局组件大小,可选值"<large|'default'|small>",默认 'large'
            globalComponentSize: 'large'
        }
    }),
    actions: {
        setThemeConfig(data: ThemeConfigState) {
            this.themeConfig = data;
        }
    }
});
src/stores/userInfo.ts
对比新文件
@@ -0,0 +1,73 @@
import { defineStore } from 'pinia';
import Cookies from 'js-cookie';
import { UserInfosStates } from './interface';
/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfo = defineStore('userInfo', {
    state: (): UserInfosStates => ({
        userInfos: {
            userName: '',
            photo: 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=317673774,2961727727&fm=26&gp=0.jpg',
            time: 0,
            roles: [],
            authBtnList: [],
            uid: '',
            depId: null,
            projectId: '',
            dataList: []
        }
    }),
    persist:true,
    actions: {
        async setUserInfos(value: any) {
            this.userInfos.userName = value.realName;
            this.userInfos.uid = value.uid;
            this.userInfos.roles = value.role;
            this.userInfos.depId = value.depId
            // const userName = Cookies.get('userName');
            // // 模拟数据
            // let defaultRoles: Array<string> = [];
            // let defaultAuthBtnList: Array<string> = [];
            // // admin 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
            // let adminRoles: Array<string> = ['admin'];
            // // admin 按钮权限标识
            // let adminAuthBtnList: Array<string> = ['btn.add', 'btn.del', 'btn.edit', 'btn.link'];
            // // test 页面权限标识,对应路由 meta.roles,用于控制路由的显示/隐藏
            // let testRoles: Array<string> = ['common'];
            // // test 按钮权限标识
            // let testAuthBtnList: Array<string> = ['btn.add', 'btn.link'];
            // // 不同用户模拟不同的用户权限
            // if (userName === 'admin') {
            //     defaultRoles = adminRoles;
            //     defaultAuthBtnList = adminAuthBtnList;
            // } else {
            //     defaultRoles = testRoles;
            //     defaultAuthBtnList = testAuthBtnList;
            // }
            // // 用户信息模拟数据
            // const userInfos = {
            //     userName: userName,
            //     photo:
            //         userName === 'admin'
            //             ? 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1813762643,1914315241&fm=26&gp=0.jpg'
            //             : 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=317673774,2961727727&fm=26&gp=0.jpg',
            //     time: new Date().getTime(),
            //     roles: defaultRoles,
            //     authBtnList: defaultAuthBtnList,
            //     uid:'',
            //     projectId:'',
            // };
            // // 存储用户信息到浏览器缓存
            // Session.set('userInfo', userInfos);
            //
            // if (Session.get('userInfo')) {
            //     this.userInfos = Session.get('userInfo');
            // } else {
            //     this.userInfos = userInfos;
            // }
        }
    }
});
src/theme/app.scss
对比新文件
@@ -0,0 +1,281 @@
/* 初始化样式
------------------------------- */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    outline: none !important;
}
:root {
    --next-color-white: #ffffff;
    --next-bg-main-color: #f8f8f8;
    --next-bg-color: #f5f5ff;
    --next-border-color-light: #f1f2f3;
    --next-color-primary-lighter: #ecf5ff;
    --next-color-success-lighter: #f0f9eb;
    --next-color-warning-lighter: #fdf6ec;
    --next-color-danger-lighter: #fef0f0;
    --next-color-dark-hover: #0000001a;
    --next-color-menu-hover: rgba(0, 0, 0, 0.2);
    --next-color-user-hover: rgba(0, 0, 0, 0.04);
    --next-color-seting-main: #e9eef3;
    --next-color-seting-aside: #d3dce6;
    --next-color-seting-header: #b3c0d1;
}
html,
body,
#app {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
    font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: transparent;
    background-color: var(--next-bg-main-color);
    font-size: 14px;
    overflow: hidden;
    position: relative;
}
/* 主布局样式
------------------------------- */
.layout-container {
    width: 100%;
    height: 100%;
    .layout-aside {
        background: var(--next-bg-menuBar);
        box-shadow: 2px 0 6px rgb(0 21 41 / 1%);
        height: inherit;
        position: relative;
        z-index: 1;
        display: flex;
        flex-direction: column;
        overflow-x: hidden !important;
        .el-scrollbar__view {
            overflow: hidden;
        }
    }
    .layout-header {
        padding: 0 !important;
    }
    .layout-main {
        padding: 0 !important;
        overflow: hidden;
        width: 100%;
        background-color: var(--next-bg-main-color);
    }
    .el-scrollbar {
        width: 100%;
    }
    // 此字段多次用到,建议不删除,如需修改,请重写覆盖样式
    .layout-view-bg-white {
        background: var(--el-color-white);
        width: 100%;
        height: 100%;
        border-radius: 4px;
        border: 1px solid var(--el-border-color-light, #ebeef5);
    }
    .layout-el-aside-br-color {
        border-right: 1px solid var(--el-border-color-light, #ebeef5);
    }
    // pc端左侧导航样式
    .layout-aside-pc-220 {
        width: 220px !important;
        transition: width 0.3s ease;
    }
    .layout-aside-pc-64 {
        width: 64px !important;
        transition: width 0.3s ease;
    }
    .layout-aside-pc-1 {
        width: 1px !important;
        transition: width 0.3s ease;
    }
    // 手机端左侧导航样式
    .layout-aside-mobile {
        position: fixed;
        top: 0;
        left: -220px;
        width: 220px;
        z-index: 9999999;
    }
    .layout-aside-mobile-close {
        left: -220px;
        transition: all 0.3s cubic-bezier(0.39, 0.58, 0.57, 1);
    }
    .layout-aside-mobile-open {
        left: 0;
        transition: all 0.3s cubic-bezier(0.22, 0.61, 0.36, 1);
    }
    .layout-aside-mobile-mode {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        z-index: 9999998;
        animation: error-img 0.3s;
    }
    .layout-scrollbar {
        @extend .el-scrollbar;
        padding: 15px;
    }
    .layout-mian-height-50 {
        height: calc(100vh - 50px);
    }
    .layout-columns-warp {
        flex: 1;
        display: flex;
        overflow: hidden;
    }
    .layout-hide {
        display: none;
    }
}
/* element plus 全局样式
------------------------------- */
.layout-breadcrumb-seting {
    .el-divider {
        background-color: rgb(230, 230, 230);
    }
}
/* nprogress 进度条跟随主题颜色
------------------------------- */
#nprogress {
    .bar {
        background: var(--el-color-primary) !important;
        z-index: 9999999 !important;
    }
}
/* flex 弹性布局
------------------------------- */
.flex {
    display: flex;
}
.flex-auto {
    flex: 1;
    overflow: hidden;
}
.flex-center {
    @extend .flex;
    flex-direction: column;
    width: 100%;
    overflow: hidden;
}
.flex-margin {
    margin: auto;
}
.flex-warp {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    margin: 0 -5px;
    .flex-warp-item {
        padding: 5px;
        .flex-warp-item-box {
            width: 100%;
            height: 100%;
        }
    }
}
/* cursor 鼠标形状
------------------------------- */
// 默认
.cursor-default {
    cursor: default !important;
}
// 帮助
.cursor-help {
    cursor: help !important;
}
// 手指
.cursor-pointer {
    cursor: pointer !important;
}
// 移动
.cursor-move {
    cursor: move !important;
}
/* 宽高 100%
------------------------------- */
.w100 {
    width: 100% !important;
}
.h100 {
    height: 100% !important;
}
.vh100 {
    height: 100vh !important;
}
.max100vh {
    max-height: 100vh !important;
}
.min100vh {
    min-height: 100vh !important;
}
/* 颜色值
------------------------------- */
.color-primary {
    color: var(--el-color-primary);
}
.color-success {
    color: var(--el-color-success);
}
.color-warning {
    color: var(--el-color-warning);
}
.color-danger {
    color: var(--el-color-danger);
}
.color-info {
    color: var(--el-color-info);
}
/* 字体大小全局样式
------------------------------- */
@for $i from 10 through 32 {
    .font#{$i} {
        font-size: #{$i}px !important;
    }
}
/* 外边距、内边距全局样式
------------------------------- */
@for $i from 1 through 35 {
    .mt#{$i} {
        margin-top: #{$i}px !important;
    }
    .mr#{$i} {
        margin-right: #{$i}px !important;
    }
    .mb#{$i} {
        margin-bottom: #{$i}px !important;
    }
    .ml#{$i} {
        margin-left: #{$i}px !important;
    }
    .pt#{$i} {
        padding-top: #{$i}px !important;
    }
    .pr#{$i} {
        padding-right: #{$i}px !important;
    }
    .pb#{$i} {
        padding-bottom: #{$i}px !important;
    }
    .pl#{$i} {
        padding-left: #{$i}px !important;
    }
}
src/theme/bigScreen.css
对比新文件
@@ -0,0 +1,22 @@
html{font-size:12px; font-size:62.5%; /* 10÷16=62.5% */}
@media screen and (max-width: 1920px) {
    html { font-size: 100%;}
}
@media screen and (max-width: 1336px) {
    html { font-size: 80%;}
}
@media screen and (max-width: 1200px) {
    html { font-size: 62.5%;}
}
@media screen and (max-width: 1000px) {
    html { font-size: 10px;}
}
@media screen and (max-width: 800px) {
    html { font-size: 8px;}
}
@media screen and (max-width: 700px) {
    html { font-size: 7px;}
}
@media screen and (max-width: 600px) {
    html { font-size: 6px;}
}
src/theme/common/transition.scss
对比新文件
@@ -0,0 +1,94 @@
/* 页面切换动画
------------------------------- */
.slide-right-enter-active,
.slide-right-leave-active,
.slide-left-enter-active,
.slide-left-leave-active {
    will-change: transform;
    transition: all 0.3s ease;
}
// slide-right
.slide-right-enter-from {
    opacity: 0;
    transform: translateX(-20px);
}
.slide-right-leave-to {
    opacity: 0;
    transform: translateX(20px);
}
// slide-left
.slide-left-enter-from {
    @extend .slide-right-leave-to;
}
.slide-left-leave-to {
    @extend .slide-right-enter-from;
}
// opacitys
.opacitys-enter-active,
.opacitys-leave-active {
    will-change: transform;
    transition: all 0.3s ease;
}
.opacitys-enter-from,
.opacitys-leave-to {
    opacity: 0;
}
/* Breadcrumb 面包屑过渡动画
------------------------------- */
.breadcrumb-enter-active,
.breadcrumb-leave-active {
    transition: all 0.5s ease;
}
.breadcrumb-enter-from,
.breadcrumb-leave-active {
    opacity: 0;
    transform: translateX(20px);
}
.breadcrumb-leave-active {
    position: absolute;
    z-index: -1;
}
/* logo 过渡动画
------------------------------- */
@keyframes logoAnimation {
    0% {
        transform: scale(0);
    }
    80% {
        transform: scale(1.2);
    }
    100% {
        transform: scale(1);
    }
}
/* 404、401 过渡动画
------------------------------- */
@keyframes error-num {
    0% {
        transform: translateY(60px);
        opacity: 0;
    }
    100% {
        transform: translateY(0);
        opacity: 1;
    }
}
@keyframes error-img {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}
@keyframes error-img-two {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}
src/theme/dark.scss
对比新文件
@@ -0,0 +1,236 @@
/* 深色模式样式
------------------------------- */
[data-theme='dark'] {
    // 变量(自定义时,只需修改这里的值)
    --next-bg-main: #1f1f1f;
    --next-color-white: #ffffff;
    --next-color-disabled: #191919;
    --next-color-bar: #dadada;
    --next-color-primary: #303030;
    --next-border-color: #424242;
    --next-border-black: #333333;
    --next-border-columns: #2a2a2a;
    --next-color-seting: #505050;
    --next-text-color-regular: #9b9da1;
    --next-text-color-placeholder: #7a7a7a;
    --next-color-hover: #3c3c3c;
    --next-color-hover-rgba: rgba(0, 0, 0, 0.3);
    // root
    --next-bg-main-color: var(--next-bg-main) !important;
    --next-bg-topBar: var(--next-color-disabled) !important;
    --next-bg-topBarColor: var(--next-color-bar) !important;
    --next-bg-menuBar: var(--next-color-disabled) !important;
    --next-bg-menuBarColor: var(--next-color-bar) !important;
    --next-bg-columnsMenuBar: var(--next-color-disabled) !important;
    --next-bg-columnsMenuBarColor: var(--next-color-bar) !important;
    --next-border-color-light: var(--next-border-black) !important;
    --next-color-primary-lighter: var(--next-color-primary) !important;
    --next-color-success-lighter: var(--next-color-primary) !important;
    --next-color-warning-lighter: var(--next-color-primary) !important;
    --next-color-danger-lighter: var(--next-color-primary) !important;
    --next-bg-color: var(--next-color-primary) !important;
    --next-color-dark-hover: var(--next-color-hover) !important;
    --next-color-menu-hover: var(--next-color-hover-rgba) !important;
    --next-color-user-hover: var(--next-color-hover-rgba) !important;
    --next-color-seting-main: var(--next-color-seting) !important;
    --next-color-seting-aside: var(--next-color-hover) !important;
    --next-color-seting-header: var(--next-color-primary) !important;
    // element plus
    --el-color-white: var(--next-color-disabled) !important;
    --el-text-color-primary: var(--next-color-bar) !important;
    --el-border-color: var(--next-border-black) !important;
    --el-border-color-light: var(--next-border-black) !important;
    --el-border-color-lighter: var(--next-border-black) !important;
    --el-border-color-extra-light: var(--el-color-primary-light-8) !important;
    --el-text-color-regular: var(--next-text-color-regular) !important;
    --el-bg-color: var(--next-color-disabled) !important;
    --el-color-primary-light-9: var(--next-color-hover) !important;
    --el-text-color-disabled: var(--next-text-color-placeholder) !important;
    --el-text-color-disabled-base: var(--el-color-primary) !important;
    --el-text-color-placeholder: var(--next-text-color-placeholder) !important;
    --el-disabled-bg-color: var(--next-color-disabled) !important;
    --el-fill-base: var(--next-color-white) !important;
    --el-fill-colo: var(--next-color-hover-rgba) !important;
    --el-fill-color: var(--next-color-hover-rgba) !important;
    --el-fill-color-blank: var(--next-color-disabled) !important;
    --el-fill-color-light: var(--next-color-hover-rgba) !important;
    --el-bg-color-overlay: var(--el-color-primary-light-9) !important;
    --el-mask-color: rgb(42 42 42 / 80%);
    // button
    .el-button {
        &:hover {
            border-color: var(--next-border-color) !important;
        }
    }
    .el-button--primary,
    .el-button--info,
    .el-button--danger,
    .el-button--success,
    .el-button--warning {
        --el-button-text-color: var(--next-color-white) !important;
        --el-button-hover-text-color: var(--next-color-white) !important;
        --el-button-disabled-text-color: var(--next-color-white) !important;
        &:hover {
            border-color: var(--el-button-hover-border-color, var(--el-button-hover-bg-color)) !important;
        }
    }
    // drawer
    .el-divider__text {
        background-color: var(--el-color-white) !important;
    }
    .el-drawer {
        border-left: 1px solid var(--next-border-color-light) !important;
    }
    // tabs
    .el-tabs--border-card {
        background-color: var(--el-color-white) !important;
    }
    .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
        background: var(--next-color-primary-lighter);
    }
    // alert / notice-bar
    .home-card-item {
        border: 1px solid var(--next-border-color-light) !important;
    }
    .el-alert,
    .notice-bar {
        border: 1px solid var(--next-border-color) !important;
        background-color: var(--next-color-disabled) !important;
    }
    // homeMenu
    .layout-aside {
        border-right: 1px solid var(--next-border-color-light) !important;
    }
    // colorPicker
    .el-color-picker__mask {
        background: unset !important;
    }
    .el-color-picker__trigger {
        border: 1px solid var(--next-border-color-light) !important;
    }
    // popper / dropdown
    .el-popper {
        border: 1px solid var(--next-border-color) !important;
        color: var(--el-text-color-primary) !important;
        .el-popper__arrow:before {
            background: var(--el-color-white) !important;
            border: 1px solid var(--next-border-color);
        }
        a {
            color: var(--el-text-color-primary) !important;
        }
    }
    .el-popper,
    .el-dropdown-menu {
        background: var(--el-color-white) !important;
    }
    .el-dropdown-menu__item:hover:not(.is-disabled) {
        background: var(--el-bg-color) !important;
    }
    .el-dropdown-menu__item.is-disabled {
        font-weight: 700 !important;
    }
    // input
    .el-input-group__append,
    .el-input-group__prepend {
        border: var(--el-input-border) !important;
        border-right: none !important;
        background: var(--next-color-disabled) !important;
        border-left: 0 !important;
    }
    .el-input-number__decrease,
    .el-input-number__increase {
        background: var(--next-color-disabled) !important;
    }
    // tag
    .el-select .el-select__tags .el-tag {
        background-color: var(--next-bg-color) !important;
    }
    // pagination
    .el-pagination.is-background .el-pager li:not(.disabled).active {
        color: var(--next-color-white) !important;
    }
    .el-pagination.is-background .btn-next,
    .el-pagination.is-background .btn-prev,
    .el-pagination.is-background .el-pager li {
        background-color: var(--next-bg-color);
    }
    // radio
    .el-radio-button:not(.is-active) .el-radio-button__inner {
        border: 1px solid var(--next-border-color-light) !important;
        border-left: 0 !important;
    }
    .el-radio-button.is-active .el-radio-button__inner {
        color: var(--next-color-white) !important;
    }
    // countup
    .countup-card-item-flex {
        color: var(--el-text-color-primary) !important;
    }
    // editor
    .editor-container {
        .w-e-toolbar {
            background: var(--el-color-white) !important;
            border: 1px solid var(--next-border-color-light) !important;
            .w-e-menu:hover {
                background: var(--next-color-user-hover) !important;
                i {
                    color: var(--el-text-color-primary) !important;
                }
            }
        }
        .w-e-text-container {
            border: 1px solid var(--next-border-color-light) !important;
            border-top: none !important;
            .w-e-text {
                background: var(--el-color-white) !important;
            }
        }
    }
    // date-picker
    .el-picker-panel {
        background: var(--el-color-white) !important;
    }
    // dialog
    .el-dialog {
        border: 1px solid var(--el-border-color-lighter);
        .el-dialog__header {
            color: var(--el-text-color-primary) !important;
        }
    }
    // columns
    .layout-columns-aside ul .layout-columns-active {
        color: var(--next-color-white) !important;
    }
    .layout-columns-aside {
        border-right: 1px solid var(--next-border-columns);
    }
    // tagsView
    .tags-style-one {
        .is-active {
            color: var(--el-text-color-primary) !important;
        }
        .layout-navbars-tagsview-ul-li:hover {
            border-color: var(--el-border-color-lighter) !important;
        }
    }
}
src/theme/element.scss
对比新文件
@@ -0,0 +1,282 @@
@import 'mixins/index.scss';
/* Button 按钮
------------------------------- */
// 第三方字体图标大小
.el-button i.el-icon,
.el-button i.iconfont,
.el-button i.fa,
.el-button--default i.iconfont,
.el-button--default i.fa {
    font-size: 14px !important;
    //margin-right: 5px;
}
.el-button--small i.iconfont,
.el-button--small i.fa {
    font-size: 12px !important;
    margin-right: 5px;
}
/* Input 输入框、InputNumber 计数器
------------------------------- */
.el-input {
    height: 100%;
}
// 菜单搜索
.el-autocomplete-suggestion__wrap {
    max-height: 280px !important;
}
/* Form 表单
------------------------------- */
.el-form {
    .el-form-item:last-of-type {
        margin-bottom: 0 !important;
    }
}
/* Alert 警告
------------------------------- */
.el-alert {
    border: 1px solid;
}
.el-alert__title {
    word-break: break-all;
}
/* Message 消息提示
------------------------------- */
.el-message {
    min-width: unset !important;
    padding: 15px !important;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.02);
}
/* NavMenu 导航菜单
------------------------------- */
// 鼠标 hover 时颜色
.el-menu-hover-bg-color {
    background-color: var(--next-color-menu-hover) !important;
}
// 默认样式修改
.el-menu {
    border-right: none !important;
    width: 220px;
}
.el-menu-item {
    height: 56px !important;
    line-height: 56px !important;
}
.el-menu-item,
.el-sub-menu__title {
    color: var(--next-bg-menuBarColor);
}
// 修复点击左侧菜单折叠再展开时,宽度不跟随问题
.el-menu--collapse {
    width: 64px !important;
}
// 外部链接时
.el-menu-item a,
.el-menu-item a:hover,
.el-menu-item i,
.el-sub-menu__title i {
    color: inherit;
    text-decoration: none;
}
// 第三方图标字体间距/大小设置
.el-menu-item .iconfont,
.el-sub-menu .iconfont,
.el-menu-item .fa,
.el-sub-menu .fa {
    @include generalIcon;
}
// 水平菜单、横向菜单高亮 背景色,鼠标 hover 时,有子级菜单的背景色
.el-menu-item.is-active,
.el-sub-menu.is-active .el-sub-menu__title,
.el-sub-menu:not(.is-opened):hover .el-sub-menu__title {
    @extend .el-menu-hover-bg-color;
}
.el-sub-menu.is-active.is-opened .el-sub-menu__title {
    background-color: unset !important;
}
// 子级菜单背景颜色
// .el-homeMenu--inline {
//     background: var(--next-bg-menuBar-light-1);
// }
// 水平菜单、横向菜单折叠 a 标签
.el-popper.is-dark a {
    color: var(--el-color-white) !important;
    text-decoration: none;
}
// 水平菜单、横向菜单折叠背景色
.el-popper.is-pure.is-light {
    // 水平菜单
    .el-menu--vertical {
        background: var(--next-bg-menuBar);
        .el-sub-menu.is-active .el-sub-menu__title {
            color: var(--el-menu-active-color);
        }
        .el-popper.is-pure.is-light {
            .el-menu--vertical {
                .el-sub-menu .el-sub-menu__title {
                    background-color: unset !important;
                    color: var(--next-bg-menuBarColor);
                }
                .el-sub-menu.is-active .el-sub-menu__title {
                    color: var(--el-menu-active-color);
                }
            }
        }
    }
    // 横向菜单
    .el-menu--horizontal {
        background: var(--next-bg-topBar);
        .el-menu-item,
        .el-sub-menu {
            height: 50px !important;
            line-height: 50px !important;
            color: var(--next-bg-topBarColor);
            .el-sub-menu__title {
                height: 50px !important;
                line-height: 50px !important;
                color: var(--next-bg-topBarColor);
            }
            .el-popper.is-pure.is-light {
                .el-menu--horizontal {
                    .el-sub-menu .el-sub-menu__title {
                        background-color: unset !important;
                        color: var(--next-bg-topBarColor);
                    }
                    .el-sub-menu.is-active .el-sub-menu__title {
                        color: var(--el-menu-active-color);
                    }
                }
            }
        }
        .el-menu-item.is-active,
        .el-sub-menu.is-active .el-sub-menu__title {
            color: var(--el-menu-active-color);
        }
    }
}
// 横向菜单(经典、横向)布局
.el-menu.el-menu--horizontal {
    border-bottom: none !important;
    width: 100% !important;
    .el-menu-item,
    .el-sub-menu__title {
        height: 50px !important;
        color: var(--next-bg-topBarColor);
    }
    .el-menu-item:not(.is-active):hover,
    .el-sub-menu:not(.is-active):hover .el-sub-menu__title {
        color: var(--next-bg-topBarColor);
    }
}
/* Tabs 标签页
------------------------------- */
.el-tabs__nav-wrap::after {
    height: 1px !important;
}
/* Dropdown 下拉菜单
------------------------------- */
.el-dropdown-menu {
    list-style: none !important; /*修复 Dropdown 下拉菜单样式问题 2022.03.04*/
}
.el-dropdown-menu .el-dropdown-menu__item {
    white-space: nowrap;
    &:not(.is-disabled):hover {
        background-color: var(--el-dropdown-menuItem-hover-fill);
        color: var(--el-dropdown-menuItem-hover-color);
    }
}
/* Steps 步骤条
------------------------------- */
.el-step__icon-inner {
    font-size: 30px !important;
    font-weight: 400 !important;
}
.el-step__title {
    font-size: 14px;
}
/* Dialog 对话框
------------------------------- */
.el-overlay {
    overflow: hidden;
    .el-overlay-dialog {
        display: flex;
        align-items: center;
        justify-content: center;
        position: unset !important;
        width: 100%;
        height: 100%;
        .el-dialog {
            margin: 0 auto !important;
            position: absolute;
            .el-dialog__body {
                padding: 20px !important;
            }
        }
    }
}
.el-dialog__body {
    max-height: calc(90vh - 111px) !important;
    overflow-y: auto;
    overflow-x: hidden;
}
/* Card 卡片
------------------------------- */
.el-card__header {
    padding: 15px 20px;
}
/* Table 表格 element plus 2.2.0 版本
------------------------------- */
.el-table {
    .el-button.is-text {
        padding: 0;
    }
}
/* scrollbar
------------------------------- */
.el-scrollbar__bar {
    z-index: 4;
}
.el-scrollbar__wrap {
    max-height: 100%; /*防止页面切换时,滚动条高度不变的问题(滚动条高度非滚动条滚动高度)*/
}
.el-select-dropdown .el-scrollbar__wrap {
    overflow-x: scroll !important;
}
.el-select-dropdown__wrap {
    max-height: 274px !important; /*修复Select 选择器高度问题*/
}
.el-cascader-menu__wrap.el-scrollbar__wrap {
    height: 204px !important; /*修复Cascader 级联选择器高度问题*/
}
/* Drawer 抽屉
------------------------------- */
.el-drawer {
    --el-drawer-padding-primary: unset !important;
    .el-drawer__header {
        padding: 0 15px !important;
        height: 50px;
        display: flex;
        align-items: center;
        margin-bottom: 0 !important;
        border-bottom: 1px solid var(--el-border-color);
        color: var(--el-text-color-primary);
    }
    .el-drawer__body {
        width: 100%;
        height: 100%;
        overflow: auto;
    }
}
src/theme/iconSelector.scss
对比新文件
@@ -0,0 +1,70 @@
/* Popover 弹出框(图标选择器)
------------------------------- */
.icon-selector-popper {
    padding: 0 !important;
    .icon-selector-warp {
        height: 260px;
        overflow: hidden;
        .icon-selector-warp-title {
            height: 40px;
            line-height: 40px;
            padding: 0 15px;
            .icon-selector-warp-title-tab {
                span {
                    cursor: pointer;
                    &:hover {
                        color: var(--el-color-primary);
                        text-decoration: underline;
                    }
                }
                .span-active {
                    color: var(--el-color-primary);
                    text-decoration: underline;
                }
            }
        }
        .icon-selector-warp-row {
            height: 230px;
            overflow: hidden;
            border-top: 1px solid var(--el-border-color);
            .el-row {
                padding: 15px;
            }
            .el-scrollbar__bar.is-horizontal {
                display: none;
            }
            .icon-selector-warp-item {
                display: flex;
                border: 1px solid var(--el-border-color);
                padding: 5px;
                border-radius: 5px;
                margin-bottom: 10px;
                .icon-selector-warp-item-value {
                    i {
                        font-size: 20px;
                        color: var(--el-text-color-regular);
                    }
                }
                &:hover {
                    cursor: pointer;
                    background-color: var(--el-color-primary-light-9);
                    border: 1px solid var(--el-color-primary-light-5);
                    .icon-selector-warp-item-value {
                        i {
                            color: var(--el-color-primary);
                        }
                    }
                }
            }
            .icon-selector-active {
                background-color: var(--el-color-primary-light-9);
                border: 1px solid var(--el-color-primary-light-5);
                .icon-selector-warp-item-value {
                    i {
                        color: var(--el-color-primary);
                    }
                }
            }
        }
    }
}
src/theme/index.scss
对比新文件
@@ -0,0 +1,8 @@
@import './app.scss';
@import 'common/transition.scss';
@import './other.scss';
@import './element.scss';
@import './iconSelector.scss';
@import './media/media.scss';
@import './waves.scss';
@import './dark.scss';
src/theme/loading.scss
对比新文件
@@ -0,0 +1,51 @@
.loading-next {
    width: 100%;
    height: 100%;
}
.loading-next .loading-next-box {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
.loading-next .loading-next-box-warp {
    width: 80px;
    height: 80px;
}
.loading-next .loading-next-box-warp .loading-next-box-item {
    width: 33.333333%;
    height: 33.333333%;
    background: var(--el-color-primary);
    float: left;
    animation: loading-next-animation 1.2s infinite ease;
    border-radius: 1px;
}
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(7) {
    animation-delay: 0s;
}
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(4),
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(8) {
    animation-delay: 0.1s;
}
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(1),
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(5),
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(9) {
    animation-delay: 0.2s;
}
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(2),
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(6) {
    animation-delay: 0.3s;
}
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(3) {
    animation-delay: 0.4s;
}
@keyframes loading-next-animation {
    0%,
    70%,
    100% {
        transform: scale3D(1, 1, 1);
    }
    35% {
        transform: scale3D(0, 0, 1);
    }
}
src/theme/media/chart.scss
对比新文件
@@ -0,0 +1,94 @@
@import './index.scss';
/* 页面宽度小于768px
------------------------------- */
@media screen and (max-width: $sm) {
    .big-data-down-left {
        width: 100% !important;
        flex-direction: unset !important;
        flex-wrap: wrap;
        .flex-warp-item {
            min-height: 196.24px;
            padding: 0 7.5px 15px 15px !important;
            .flex-warp-item-box {
                border: none !important;
                border-bottom: 1px solid #ebeef5 !important;
            }
        }
    }
    .big-data-down-center {
        width: 100% !important;
        .big-data-down-center-one,
        .big-data-down-center-two {
            min-height: 196.24px;
            padding-left: 15px !important;
            .big-data-down-center-one-content {
                border: none !important;
                border-bottom: 1px solid #ebeef5 !important;
            }
            .flex-warp-item-box {
                @extend .big-data-down-center-one-content;
            }
        }
    }
    .big-data-down-right {
        .flex-warp-item {
            .flex-warp-item-box {
                border: none !important;
                border-bottom: 1px solid #ebeef5 !important;
            }
            &:nth-of-type(2) {
                padding-left: 15px !important;
            }
            &:last-of-type {
                .flex-warp-item-box {
                    border: none !important;
                }
            }
        }
    }
}
/* 页面宽度大于768px小于1200px
------------------------------- */
@media screen and (min-width: $sm) and (max-width: $lg) {
    .chart-warp-bottom {
        .big-data-down-left {
            width: 50% !important;
        }
        .big-data-down-center {
            width: 50% !important;
        }
        .big-data-down-right {
            .flex-warp-item {
                width: 50% !important;
                &:nth-of-type(2) {
                    padding-left: 7.5px !important;
                }
            }
        }
    }
}
/* 页面宽度小于1200px
------------------------------- */
@media screen and (max-width: $lg) {
    .chart-warp-top {
        .up-left {
            display: none;
        }
    }
    .chart-warp-bottom {
        overflow-y: auto !important;
        flex-wrap: wrap;
        .big-data-down-right {
            width: 100% !important;
            flex-direction: unset !important;
            flex-wrap: wrap;
            .flex-warp-item {
                min-height: 196.24px;
                padding: 0 7.5px 15px 15px !important;
            }
        }
    }
}
src/theme/media/cityLinkage.scss
对比新文件
@@ -0,0 +1,10 @@
@import './index.scss';
/* 页面宽度小于576px
------------------------------- */
@media screen and (max-width: $xs) {
    .el-cascader__dropdown.el-popper {
        overflow: auto;
        max-width: 100%;
    }
}
src/theme/media/date.scss
对比新文件
@@ -0,0 +1,25 @@
@import './index.scss';
/* 页面宽度小于768px
------------------------------- */
@media screen and (max-width: $sm) {
    // 时间选择器适配
    .el-date-range-picker {
        width: 100vw;
        .el-picker-panel__body {
            min-width: 100%;
            .el-date-range-picker__content {
                .el-date-range-picker__header div {
                    margin-left: 22px;
                    margin-right: 0px;
                }
                & + .el-date-range-picker__content {
                    .el-date-range-picker__header div {
                        margin-left: 0px;
                        margin-right: 22px;
                    }
                }
            }
        }
    }
}
src/theme/media/dialog.scss
对比新文件
@@ -0,0 +1,12 @@
@import './index.scss';
/* 页面宽度小于800px
------------------------------- */
@media screen and (max-width: 800px) {
    .el-dialog {
        width: 90% !important;
    }
    .el-dialog.is-fullscreen {
        width: 100% !important;
    }
}
src/theme/media/error.scss
对比新文件
@@ -0,0 +1,45 @@
@import './index.scss';
/* 页面宽度小于768px
------------------------------- */
@media screen and (max-width: $sm) {
    .error {
        .error-flex {
            flex-direction: column-reverse !important;
            height: auto !important;
            width: 100% !important;
        }
        .right,
        .left {
            flex: unset !important;
            display: flex !important;
        }
        .left-item {
            margin: auto !important;
        }
        .right img {
            max-width: 450px !important;
            @extend .left-item;
        }
    }
}
/* 页面宽度大于768px小于992px
------------------------------- */
@media screen and (min-width: $sm) and (max-width: $md) {
    .error {
        .error-flex {
            padding-left: 30px !important;
        }
    }
}
/* 页面宽度小于1200px
------------------------------- */
@media screen and (max-width: $lg) {
    .error {
        .error-flex {
            padding: 0 30px;
        }
    }
}
src/theme/media/form.scss
对比新文件
@@ -0,0 +1,16 @@
@import './index.scss';
/* 页面宽度小于576px
------------------------------- */
@media screen and (max-width: $xs) {
    .el-form-item__label {
        width: 100% !important;
        text-align: left !important;
    }
    .el-form-item__content {
        margin-left: 0 !important;
    }
    .el-form-item {
        display: unset !important;
    }
}
src/theme/media/home.scss
对比新文件
@@ -0,0 +1,23 @@
@import './index.scss';
/* 页面宽度小于768px
------------------------------- */
@media screen and (max-width: $sm) {
    .home-media,
    .home-media-sm {
        margin-top: 15px;
    }
}
/* 页面宽度小于1200px
------------------------------- */
@media screen and (max-width: $lg) {
    .home-media-lg {
        margin-top: 15px;
    }
    .home-monitor {
        .flex-warp-item {
            width: 33.33% !important;
        }
    }
}
src/theme/media/index.scss
对比新文件
@@ -0,0 +1,15 @@
/* 栅格布局(媒体查询变量)
* https://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Media_queries
* $us ≥376px  响应式栅格
* $xs ≥576px  响应式栅格
* $sm ≥768px  响应式栅格
* $md ≥992px  响应式栅格
* $lg ≥1200px 响应式栅格
* $xl ≥1920px 响应式栅格
------------------------------- */
$us: 376px;
$xs: 576px;
$sm: 768px;
$md: 992px;
$lg: 1200px;
$xl: 1920px;
src/theme/media/layout.scss
对比新文件
@@ -0,0 +1,55 @@
@import './index.scss';
/* 页面宽度小于576px
------------------------------- */
@media screen and (max-width: $xs) {
    // MessageBox 弹框
    .el-message-box {
        width: 80% !important;
    }
}
/* 页面宽度小于768px
------------------------------- */
@media screen and (max-width: $sm) {
    // Breadcrumb 面包屑
    .layout-navbars-breadcrumb-hide {
        display: none;
    }
    // 外链视图
    .layout-view-link {
        a {
            max-width: 80%;
            text-align: center;
        }
    }
    // 菜单搜索
    .layout-search-dialog {
        .el-autocomplete {
            width: 80% !important;
        }
    }
}
/* 页面宽度小于1000px
------------------------------- */
@media screen and (max-width: 1000px) {
    // 布局配置
    .layout-drawer-content-flex {
        position: relative;
        &::after {
            content: '手机版不支持切换布局';
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            z-index: 1;
            text-align: center;
            height: 140px;
            line-height: 140px;
            background: rgba(255, 255, 255, 0.9);
            color: #666666;
        }
    }
}
src/theme/media/login.scss
对比新文件
@@ -0,0 +1,63 @@
@import './index.scss';
/* 页面宽度小于992px
------------------------------- */
@media screen and (max-width: $lg) {
    .login-container {
        .login-icon-group {
            &::before {
                content: '';
                height: 70% !important;
                transition: all 0.3s ease;
            }
            &::after {
                content: '';
                width: 100px !important;
                height: 200px !important;
                transition: all 0.3s ease;
            }
        }
    }
}
/* 页面宽度小于992px
------------------------------- */
@media screen and (max-width: $md) {
    .login-content {
        right: unset !important;
        left: 50% !important;
        transform: translate(-50%, -50%) translate3d(0, 0, 0) !important;
    }
}
/* 页面宽度小于576px
------------------------------- */
@media screen and (max-width: $xs) {
    .login-container {
        .login-icon-group {
            display: none !important;
        }
        .login-content {
            width: 100% !important;
            height: 100% !important;
            padding: 20px 0 !important;
            border-radius: 0 !important;
            box-shadow: unset !important;
            border: none !important;
        }
        .el-form-item {
            display: flex !important;
        }
    }
}
/* 页面宽度小于375px
------------------------------- */
@media screen and (max-width: $us) {
    .login-container {
        .login-content-title {
            font-size: 18px !important;
            transition: all 0.3s ease;
        }
    }
}
src/theme/media/media.scss
对比新文件
@@ -0,0 +1,13 @@
@import './login.scss';
@import './error.scss';
@import './layout.scss';
@import './personal.scss';
@import './tagsView.scss';
@import './home.scss';
@import './chart.scss';
@import './form.scss';
@import './scrollbar.scss';
@import './pagination.scss';
@import './dialog.scss';
@import './cityLinkage.scss';
@import './date.scss';
src/theme/media/pagination.scss
对比新文件
@@ -0,0 +1,15 @@
@import './index.scss';
/* 页面宽度小于576px
------------------------------- */
@media screen and (max-width: $xs) {
    .el-pager,
    .el-pagination__jump {
        display: none !important;
    }
}
// 默认居中对齐
.el-pagination {
    text-align: center !important;
}
src/theme/media/personal.scss
对比新文件
@@ -0,0 +1,16 @@
@import './index.scss';
/* 页面宽度小于768px
------------------------------- */
@media screen and (max-width: $sm) {
    .personal-info {
        padding-left: 0 !important;
        margin-top: 15px;
    }
    .personal-recommend-col {
        margin-bottom: 15px;
        &:last-of-type {
            margin-bottom: 0;
        }
    }
}
src/theme/media/scrollbar.scss
对比新文件
@@ -0,0 +1,56 @@
@import './index.scss';
/* 页面宽度小于768px
------------------------------- */
@media screen and (max-width: $sm) {
    // 滚动条的宽度
    ::-webkit-scrollbar {
        width: 3px !important;
        height: 3px !important;
    }
    ::-webkit-scrollbar-track-piece {
        background-color: var(--next-bg-main-color);
    }
    // 滚动条的设置
    ::-webkit-scrollbar-thumb {
        background-color: rgba(144, 147, 153, 0.3);
        background-clip: padding-box;
        min-height: 28px;
        border-radius: 5px;
        transition: 0.3s background-color;
    }
    ::-webkit-scrollbar-thumb:hover {
        background-color: rgba(144, 147, 153, 0.5);
    }
    // element plus scrollbar
    .el-scrollbar__bar.is-vertical {
        width: 2px !important;
    }
    .el-scrollbar__bar.is-horizontal {
        height: 2px !important;
    }
}
/* 页面宽度大于768px
------------------------------- */
@media screen and (min-width: 769px) {
    // 滚动条的宽度
    ::-webkit-scrollbar {
        width: 7px;
        height: 7px;
    }
    ::-webkit-scrollbar-track-piece {
        background-color: var(--next-bg-main-color);
    }
    // 滚动条的设置
    ::-webkit-scrollbar-thumb {
        background-color: rgba(144, 147, 153, 0.3);
        background-clip: padding-box;
        min-height: 28px;
        border-radius: 5px;
        transition: 0.3s background-color;
    }
    ::-webkit-scrollbar-thumb:hover {
        background-color: rgba(144, 147, 153, 0.5);
    }
}
src/theme/media/tagsView.scss
对比新文件
@@ -0,0 +1,11 @@
@import './index.scss';
/* 页面宽度小于768px
------------------------------- */
@media screen and (max-width: $sm) {
    .tags-view-form {
        .tags-view-form-col {
            margin-bottom: 20px;
        }
    }
}
src/theme/mixins/index.scss
对比新文件
@@ -0,0 +1,56 @@
/* 第三方图标字体间距/大小设置
------------------------------- */
@mixin generalIcon {
    font-size: 14px !important;
    display: inline-block;
    vertical-align: middle;
    margin-right: 5px;
    width: 24px;
    text-align: center;
    justify-content: center;
}
/* 文本不换行
------------------------------- */
@mixin text-no-wrap() {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}
/* 多行文本溢出
  ------------------------------- */
@mixin text-ellipsis($line: 2) {
    overflow: hidden;
    word-break: break-all;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: $line;
    -webkit-box-orient: vertical;
}
/* 滚动条(页面未使用) div 中使用:
  ------------------------------- */
// .test {
//   @include scrollBar;
// }
@mixin scrollBar {
    // 滚动条凹槽的颜色,还可以设置边框属性
    &::-webkit-scrollbar-track-piece {
        background-color: #f8f8f8;
    }
    // 滚动条的宽度
    &::-webkit-scrollbar {
        width: 9px;
        height: 9px;
    }
    // 滚动条的设置
    &::-webkit-scrollbar-thumb {
        background-color: #dddddd;
        background-clip: padding-box;
        min-height: 28px;
    }
    &::-webkit-scrollbar-thumb:hover {
        background-color: #bbb;
    }
}
src/theme/other.scss
对比新文件
@@ -0,0 +1,36 @@
/* wangeditor富文本编辑器
------------------------------- */
.editor-container {
    z-index: 9999;
    .w-e-toolbar {
        border: 1px solid var(--el-border-color-light, #ebeef5) !important;
        border-bottom: 1px solid var(--el-border-color-light, #ebeef5) !important;
        border-top-left-radius: 3px;
        border-top-right-radius: 3px;
        z-index: 2 !important;
    }
    .w-e-text-container {
        border: 1px solid var(--el-border-color-light, #ebeef5) !important;
        border-top: none !important;
        border-bottom-left-radius: 3px;
        border-bottom-right-radius: 3px;
        z-index: 1 !important;
    }
}
[data-theme='dark'] {
    // textarea - css vars
    --w-e-textarea-bg-color: var(--el-color-white) !important;
    --w-e-textarea-color: var(--el-text-color-primary) !important;
    // toolbar - css vars
    --w-e-toolbar-color: var(--el-text-color-primary) !important;
    --w-e-toolbar-bg-color: var(--el-color-white) !important;
    --w-e-toolbar-active-color: var(--el-text-color-primary) !important;
    --w-e-toolbar-active-bg-color: var(--next-color-menu-hover) !important;
    --w-e-toolbar-border-color: var(--el-border-color-light, #ebeef5) !important;
    // modal - css vars
    --w-e-modal-button-bg-color: var(--el-color-primary) !important;
    --w-e-modal-button-border-color: var(--el-color-primary) !important;
}
src/theme/waves.scss
对比新文件
@@ -0,0 +1,101 @@
/* Waves v0.6.0
* http://fian.my.id/Waves
*
* Copyright 2014 Alfiana E. Sibuea and other contributors
* Released under the MIT license
* https://github.com/fians/Waves/blob/master/LICENSE
*/
.waves-effect {
    position: relative;
    cursor: pointer;
    display: inline-block;
    overflow: hidden;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    vertical-align: middle;
    z-index: 1;
    will-change: opacity, transform;
    transition: all 0.3s ease-out;
}
.waves-effect .waves-ripple {
    position: absolute;
    border-radius: 50%;
    width: 20px;
    height: 20px;
    margin-top: -10px;
    margin-left: -10px;
    opacity: 0;
    background: rgba(0, 0, 0, 0.2);
    transition: all 0.7s ease-out;
    transition-property: opacity, -webkit-transform;
    transition-property: transform, opacity;
    transition-property: transform, opacity, -webkit-transform;
    -webkit-transform: scale(0);
    transform: scale(0);
    pointer-events: none;
}
.waves-effect.waves-light .waves-ripple {
    background-color: rgba(255, 255, 255, 0.45);
}
.waves-effect.waves-red .waves-ripple {
    background-color: rgba(244, 67, 54, 0.7);
}
.waves-effect.waves-yellow .waves-ripple {
    background-color: rgba(255, 235, 59, 0.7);
}
.waves-effect.waves-orange .waves-ripple {
    background-color: rgba(255, 152, 0, 0.7);
}
.waves-effect.waves-purple .waves-ripple {
    background-color: rgba(156, 39, 176, 0.7);
}
.waves-effect.waves-green .waves-ripple {
    background-color: rgba(76, 175, 80, 0.7);
}
.waves-effect.waves-teal .waves-ripple {
    background-color: rgba(0, 150, 136, 0.7);
}
.waves-effect input[type='button'],
.waves-effect input[type='reset'],
.waves-effect input[type='submit'] {
    border: 0;
    font-style: normal;
    font-size: inherit;
    text-transform: inherit;
    background: none;
}
.waves-notransition {
    transition: none !important;
}
.waves-circle {
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
    -webkit-mask-image: -webkit-radial-gradient(circle, #fff 100%, #000 100%);
}
.waves-input-wrapper {
    border-radius: 0.2em;
    vertical-align: bottom;
}
.waves-input-wrapper .waves-button-input {
    position: relative;
    top: 0;
    left: 0;
    z-index: 1;
}
.waves-circle {
    text-align: center;
    width: 2.5em;
    height: 2.5em;
    line-height: 2.5em;
    border-radius: 50%;
    -webkit-mask-image: none;
}
.waves-block {
    display: block;
}
a.waves-effect .waves-ripple {
    z-index: -1;
}
src/utils/arrayOperation.ts
对比新文件
@@ -0,0 +1,66 @@
/**
 * 判断两数组字符串是否相同(用于按钮权限验证),数组字符串中存在相同时会自动去重(按钮权限标识不会重复)
 * @param news 新数据
 * @param old 源数据
 * @returns 两数组相同返回 `true`,反之则反
 */
export function judementSameArr(newArr: unknown[] | string[], oldArr: string[]): boolean {
    const news = removeDuplicate(newArr);
    const olds = removeDuplicate(oldArr);
    let count = 0;
    const leng = olds.length;
    for (let i in olds) {
        for (let j in news) {
            if (olds[i] === news[j]) count++;
        }
    }
    return count === leng ? true : false;
}
/**
 * 判断两个对象是否相同
 * @param a 要比较的对象一
 * @param b 要比较的对象二
 * @returns 相同返回 true,反之则反
 */
export function isObjectValueEqual(a: { [key: string]: any }, b: { [key: string]: any }) {
    if (!a || !b) return false;
    let aProps = Object.getOwnPropertyNames(a);
    let bProps = Object.getOwnPropertyNames(b);
    if (aProps.length != bProps.length) return false;
    for (let i = 0; i < aProps.length; i++) {
        let propName = aProps[i];
        let propA = a[propName];
        let propB = b[propName];
        if (!b.hasOwnProperty(propName)) return false;
        if (propA instanceof Object) {
            if (!isObjectValueEqual(propA, propB)) return false;
        } else if (propA !== propB) {
            return false;
        }
    }
    return true;
}
/**
 * 数组、数组对象去重
 * @param arr 数组内容
 * @param attr 需要去重的键值(数组对象)
 * @returns
 */
export function removeDuplicate(arr: any, attr?: string) {
    if (!arr && !arr.length) {
        return arr;
    } else {
        if (attr) {
            const obj: any = {};
            const newArr = arr.reduce((cur: any, item: any) => {
                obj[item[attr]] ? '' : (obj[item[attr]] = true && item[attr] && cur.push(item));
                return cur;
            }, []);
            return newArr;
        } else {
            return Array.from(new Set([...arr]));
        }
    }
}
src/utils/authDirective.ts
对比新文件
@@ -0,0 +1,40 @@
import type { App } from 'vue';
import { useUserInfo } from '/@/stores/userInfo';
import { judementSameArr } from '/@/utils/arrayOperation';
/**
 * 用户权限指令
 * @directive 单个权限验证(v-auth="xxx")
 * @directive 多个权限验证,满足一个则显示(v-auths="[xxx,xxx]")
 * @directive 多个权限验证,全部满足则显示(v-auth-all="[xxx,xxx]")
 */
export function authDirective(app: App) {
    // 单个权限验证(v-auth="xxx")
    app.directive('auth', {
        mounted(el, binding) {
            const stores = useUserInfo();
            if (!stores.userInfos.authBtnList.some((v: string) => v === binding.value)) el.parentNode.removeChild(el);
        },
    });
    // 多个权限验证,满足一个则显示(v-auths="[xxx,xxx]")
    app.directive('auths', {
        mounted(el, binding) {
            let flag = false;
            const stores = useUserInfo();
            stores.userInfos.authBtnList.map((val: string) => {
                binding.value.map((v: string) => {
                    if (val === v) flag = true;
                });
            });
            if (!flag) el.parentNode.removeChild(el);
        },
    });
    // 多个权限验证,全部满足则显示(v-auth-all="[xxx,xxx]")
    app.directive('auth-all', {
        mounted(el, binding) {
            const stores = useUserInfo();
            const flag = judementSameArr(binding.value, stores.userInfos.authBtnList);
            if (!flag) el.parentNode.removeChild(el);
        },
    });
}
src/utils/authFunction.ts
对比新文件
@@ -0,0 +1,38 @@
import { useUserInfo } from '/@/stores/userInfo';
import { judementSameArr } from '/@/utils/arrayOperation';
/**
 * 单个权限验证
 * @param value 权限值
 * @returns 有权限,返回 `true`,反之则反
 */
export function auth(value: string): boolean {
    const stores = useUserInfo();
    return stores.userInfos.authBtnList.some((v: string) => v === value);
}
/**
 * 多个权限验证,满足一个则为 true
 * @param value 权限值
 * @returns 有权限,返回 `true`,反之则反
 */
export function auths(value: Array<string>): boolean {
    let flag = false;
    const stores = useUserInfo();
    stores.userInfos.authBtnList.map((val: string) => {
        value.map((v: string) => {
            if (val === v) flag = true;
        });
    });
    return flag;
}
/**
 * 多个权限验证,全部满足则为 true
 * @param value 权限值
 * @returns 有权限,返回 `true`,反之则反
 */
export function authAll(value: Array<string>): boolean {
    const stores = useUserInfo();
    return judementSameArr(value, stores.userInfos.authBtnList);
}
src/utils/commonFunction.ts
对比新文件
@@ -0,0 +1,65 @@
// 通用函数
import useClipboard from 'vue-clipboard3';
import { ElMessage } from 'element-plus';
import { formatDate } from '/@/utils/formatTime';
import { useI18n } from 'vue-i18n';
export default function () {
    const { t } = useI18n();
    const { toClipboard } = useClipboard();
    //百分比格式化
    const percentFormat = (row: any, column: number, cellValue: any) => {
        return cellValue ? `${cellValue}%` : '-';
    };
    //列表日期时间格式化
    const dateFormatYMD = (row: any, column: number, cellValue: any) => {
        if (!cellValue) return '-';
        return formatDate(new Date(cellValue), 'YYYY-mm-dd');
    };
    //列表日期时间格式化
    const dateFormatYMDHMS = (row: any, column: number, cellValue: any) => {
        if (!cellValue) return '-';
        return formatDate(new Date(cellValue), 'YYYY-mm-dd HH:MM:SS');
    };
    //列表日期时间格式化
    const dateFormatHMS = (row: any, column: number, cellValue: any) => {
        if (!cellValue) return '-';
        let time = 0;
        if (typeof row === 'number') time = row;
        if (typeof cellValue === 'number') time = cellValue;
        return formatDate(new Date(time * 1000), 'HH:MM:SS');
    };
    // 小数格式化
    const scaleFormat = (value: any = 0, scale: number = 4) => {
        return Number.parseFloat(value).toFixed(scale);
    };
    // 小数格式化
    const scale2Format = (value: any = 0) => {
        return Number.parseFloat(value).toFixed(2);
    };
    // 点击复制文本
    const copyText = (text: string) => {
        return new Promise((resolve, reject) => {
            try {
                //复制
                toClipboard(text);
                //下面可以设置复制成功的提示框等操作
                ElMessage.success(t('message.layout.copyTextSuccess'));
                resolve(text);
            } catch (e) {
                //复制失败
                ElMessage.error(t('message.layout.copyTextError'));
                reject(e);
            }
        });
    };
    return {
        percentFormat,
        dateFormatYMD,
        dateFormatYMDHMS,
        dateFormatHMS,
        scaleFormat,
        scale2Format,
        copyText,
    };
}
src/utils/customDirective.ts
对比新文件
@@ -0,0 +1,178 @@
import type { App } from 'vue';
/**
 * 按钮波浪指令
 * @directive 默认方式:v-waves,如 `<div v-waves></div>`
 * @directive 参数方式:v-waves=" |light|red|orange|purple|green|teal",如 `<div v-waves="'light'"></div>`
 */
export function wavesDirective(app: App) {
    app.directive('waves', {
        mounted(el, binding) {
            el.classList.add('waves-effect');
            binding.value && el.classList.add(`waves-${binding.value}`);
            function setConvertStyle(obj: { [key: string]: unknown }) {
                let style: string = '';
                for (let i in obj) {
                    if (obj.hasOwnProperty(i)) style += `${i}:${obj[i]};`;
                }
                return style;
            }
            function onCurrentClick(e: { [key: string]: unknown }) {
                let elDiv = document.createElement('div');
                elDiv.classList.add('waves-ripple');
                el.appendChild(elDiv);
                let styles = {
                    left: `${e.layerX}px`,
                    top: `${e.layerY}px`,
                    opacity: 1,
                    transform: `scale(${(el.clientWidth / 100) * 10})`,
                    'transition-duration': `750ms`,
                    'transition-timing-function': `cubic-bezier(0.250, 0.460, 0.450, 0.940)`,
                };
                elDiv.setAttribute('style', setConvertStyle(styles));
                setTimeout(() => {
                    elDiv.setAttribute(
                        'style',
                        setConvertStyle({
                            opacity: 0,
                            transform: styles.transform,
                            left: styles.left,
                            top: styles.top,
                        })
                    );
                    setTimeout(() => {
                        elDiv && el.removeChild(elDiv);
                    }, 750);
                }, 450);
            }
            el.addEventListener('mousedown', onCurrentClick, false);
        },
        unmounted(el) {
            el.addEventListener('mousedown', () => {});
        },
    });
}
/**
 * 自定义拖动指令
 * @description  使用方式:v-drag="[dragDom,dragHeader]",如 `<div v-drag="['.drag-container .el-dialog', '.drag-container .el-dialog__header']"></div>`
 * @description dragDom 要拖动的元素,dragHeader 要拖动的 Header 位置
 * @link 注意:https://github.com/element-plus/element-plus/issues/522
 * @lick 参考:https://blog.csdn.net/weixin_46391323/article/details/105228020?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-10&spm=1001.2101.3001.4242
 */
export function dragDirective(app: App) {
    app.directive('drag', {
        mounted(el, binding) {
            if (!binding.value) return false;
            const dragDom = document.querySelector(binding.value[0]) as HTMLElement;
            const dragHeader = document.querySelector(binding.value[1]) as HTMLElement;
            dragHeader.onmouseover = () => (dragHeader.style.cursor = `move`);
            function down(e: any, type: string) {
                // 鼠标按下,计算当前元素距离可视区的距离
                const disX = type === 'pc' ? e.clientX - dragHeader.offsetLeft : e.touches[0].clientX - dragHeader.offsetLeft;
                const disY = type === 'pc' ? e.clientY - dragHeader.offsetTop : e.touches[0].clientY - dragHeader.offsetTop;
                // body当前宽度
                const screenWidth = document.body.clientWidth;
                // 可见区域高度(应为body高度,可某些环境下无法获取)
                const screenHeight = document.documentElement.clientHeight;
                // 对话框宽度
                const dragDomWidth = dragDom.offsetWidth;
                // 对话框高度
                const dragDomheight = dragDom.offsetHeight;
                const minDragDomLeft = dragDom.offsetLeft;
                const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
                const minDragDomTop = dragDom.offsetTop;
                const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
                // 获取到的值带px 正则匹配替换
                let styL: any = getComputedStyle(dragDom).left;
                let styT: any = getComputedStyle(dragDom).top;
                // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
                if (styL.includes('%')) {
                    styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100);
                    styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100);
                } else {
                    styL = +styL.replace(/\px/g, '');
                    styT = +styT.replace(/\px/g, '');
                }
                return {
                    disX,
                    disY,
                    minDragDomLeft,
                    maxDragDomLeft,
                    minDragDomTop,
                    maxDragDomTop,
                    styL,
                    styT,
                };
            }
            function move(e: any, type: string, obj: any) {
                let { disX, disY, minDragDomLeft, maxDragDomLeft, minDragDomTop, maxDragDomTop, styL, styT } = obj;
                // 通过事件委托,计算移动的距离
                let left = type === 'pc' ? e.clientX - disX : e.touches[0].clientX - disX;
                let top = type === 'pc' ? e.clientY - disY : e.touches[0].clientY - disY;
                // 边界处理
                if (-left > minDragDomLeft) {
                    left = -minDragDomLeft;
                } else if (left > maxDragDomLeft) {
                    left = maxDragDomLeft;
                }
                if (-top > minDragDomTop) {
                    top = -minDragDomTop;
                } else if (top > maxDragDomTop) {
                    top = maxDragDomTop;
                }
                // 移动当前元素
                dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
            }
            /**
             * pc端
             * onmousedown 鼠标按下触发事件
             * onmousemove 鼠标按下时持续触发事件
             * onmouseup 鼠标抬起触发事件
             */
            dragHeader.onmousedown = (e) => {
                const obj = down(e, 'pc');
                document.onmousemove = (e) => {
                    move(e, 'pc', obj);
                };
                document.onmouseup = () => {
                    document.onmousemove = null;
                    document.onmouseup = null;
                };
            };
            /**
             * 移动端
             * ontouchstart 当按下手指时,触发ontouchstart
             * ontouchmove 当移动手指时,触发ontouchmove
             * ontouchend 当移走手指时,触发ontouchend
             */
            dragHeader.ontouchstart = (e) => {
                const obj = down(e, 'app');
                document.ontouchmove = (e) => {
                    move(e, 'app', obj);
                };
                document.ontouchend = () => {
                    document.ontouchmove = null;
                    document.ontouchend = null;
                };
            };
        },
    });
}
src/utils/directive.ts
对比新文件
@@ -0,0 +1,21 @@
import type { App } from 'vue';
import { authDirective } from '/@/utils/authDirective';
import { wavesDirective, dragDirective } from '/@/utils/customDirective';
import { preventClick } from '/@/utils/throttle';
/**
 * 导出指令方法:v-xxx
 * @methods authDirective 用户权限指令,用法:v-auth
 * @methods wavesDirective 按钮波浪指令,用法:v-waves
 * @methods dragDirective 自定义拖动指令,用法:v-drag
 */
export function directive(app: App) {
    // 用户权限指令
    authDirective(app);
    // 按钮波浪指令
    wavesDirective(app);
    // 自定义拖动指令
    dragDirective(app);
    preventClick(app);
}
src/utils/formatTime.ts
对比新文件
@@ -0,0 +1,137 @@
/**
 * 时间日期转换
 * @param date 当前时间,new Date() 格式
 * @param format 需要转换的时间格式字符串
 * @description format 字符串随意,如 `YYYY-mm、YYYY-mm-dd`
 * @description format 季度:"YYYY-mm-dd HH:MM:SS QQQQ"
 * @description format 星期:"YYYY-mm-dd HH:MM:SS WWW"
 * @description format 几周:"YYYY-mm-dd HH:MM:SS ZZZ"
 * @description format 季度 + 星期 + 几周:"YYYY-mm-dd HH:MM:SS WWW QQQQ ZZZ"
 * @returns 返回拼接后的时间字符串
 */
export function formatDate(date: Date, format: string): string {
    let we = date.getDay(); // 星期
    let z = getWeek(date); // 周
    let qut = Math.floor((date.getMonth() + 3) / 3).toString(); // 季度
    const opt: { [key: string]: string } = {
        'Y+': date.getFullYear().toString(), // 年
        'm+': (date.getMonth() + 1).toString(), // 月(月份从0开始,要+1)
        'd+': date.getDate().toString(), // 日
        'H+': date.getHours().toString(), // 时
        'M+': date.getMinutes().toString(), // 分
        'S+': date.getSeconds().toString(), // 秒
        'q+': qut, // 季度
    };
    // 中文数字 (星期)
    const week: { [key: string]: string } = {
        '0': '日',
        '1': '一',
        '2': '二',
        '3': '三',
        '4': '四',
        '5': '五',
        '6': '六',
    };
    // 中文数字(季度)
    const quarter: { [key: string]: string } = {
        '1': '一',
        '2': '二',
        '3': '三',
        '4': '四',
    };
    if (/(W+)/.test(format))
        format = format.replace(RegExp.$1, RegExp.$1.length > 1 ? (RegExp.$1.length > 2 ? '星期' + week[we] : '周' + week[we]) : week[we]);
    if (/(Q+)/.test(format)) format = format.replace(RegExp.$1, RegExp.$1.length == 4 ? '第' + quarter[qut] + '季度' : quarter[qut]);
    if (/(Z+)/.test(format)) format = format.replace(RegExp.$1, RegExp.$1.length == 3 ? '第' + z + '周' : z + '');
    for (let k in opt) {
        let r = new RegExp('(' + k + ')').exec(format);
        // 若输入的长度不为1,则前面补零
        if (r) format = format.replace(r[1], RegExp.$1.length == 1 ? opt[k] : opt[k].padStart(RegExp.$1.length, '0'));
    }
    return format;
}
/**
 * 获取当前日期是第几周
 * @param dateTime 当前传入的日期值
 * @returns 返回第几周数字值
 */
export function getWeek(dateTime: Date): number {
    let temptTime = new Date(dateTime.getTime());
    // 周几
    let weekday = temptTime.getDay() || 7;
    // 周1+5天=周六
    temptTime.setDate(temptTime.getDate() - weekday + 1 + 5);
    let firstDay = new Date(temptTime.getFullYear(), 0, 1);
    let dayOfWeek = firstDay.getDay();
    let spendDay = 1;
    if (dayOfWeek != 0) spendDay = 7 - dayOfWeek + 1;
    firstDay = new Date(temptTime.getFullYear(), 0, 1 + spendDay);
    let d = Math.ceil((temptTime.valueOf() - firstDay.valueOf()) / 86400000);
    let result = Math.ceil(d / 7);
    return result;
}
/**
 * 将时间转换为 `几秒前`、`几分钟前`、`几小时前`、`几天前`
 * @param param 当前时间,new Date() 格式或者字符串时间格式
 * @param format 需要转换的时间格式字符串
 * @description param 10秒:  10 * 1000
 * @description param 1分:   60 * 1000
 * @description param 1小时: 60 * 60 * 1000
 * @description param 24小时:60 * 60 * 24 * 1000
 * @description param 3天:   60 * 60* 24 * 1000 * 3
 * @returns 返回拼接后的时间字符串
 */
export function formatPast(param: string | Date, format: string = 'YYYY-mm-dd'): string {
    // 传入格式处理、存储转换值
    let t: any, s: number;
    // 获取js 时间戳
    let time: number = new Date().getTime();
    // 是否是对象
    typeof param === 'string' || 'object' ? (t = new Date(param).getTime()) : (t = param);
    // 当前时间戳 - 传入时间戳
    time = Number.parseInt(`${time - t}`);
    if (time < 10000) {
        // 10秒内
        return '刚刚';
    } else if (time < 60000 && time >= 10000) {
        // 超过10秒少于1分钟内
        s = Math.floor(time / 1000);
        return `${s}秒前`;
    } else if (time < 3600000 && time >= 60000) {
        // 超过1分钟少于1小时
        s = Math.floor(time / 60000);
        return `${s}分钟前`;
    } else if (time < 86400000 && time >= 3600000) {
        // 超过1小时少于24小时
        s = Math.floor(time / 3600000);
        return `${s}小时前`;
    } else if (time < 259200000 && time >= 86400000) {
        // 超过1天少于3天内
        s = Math.floor(time / 86400000);
        return `${s}天前`;
    } else {
        // 超过3天
        let date = typeof param === 'string' || 'object' ? new Date(param) : param;
        return formatDate(date, format);
    }
}
/**
 * 时间问候语
 * @param param 当前时间,new Date() 格式
 * @description param 调用 `formatAxis(new Date())` 输出 `上午好`
 * @returns 返回拼接后的时间字符串
 */
export function formatAxis(param: Date): string {
    let hour: number = new Date(param).getHours();
    if (hour < 6) return '凌晨好';
    else if (hour < 9) return '早上好';
    else if (hour < 12) return '上午好';
    else if (hour < 14) return '中午好';
    else if (hour < 17) return '下午好';
    else if (hour < 19) return '傍晚好';
    else if (hour < 22) return '晚上好';
    else return '夜里好';
}
src/utils/getStyleSheets.ts
对比新文件
@@ -0,0 +1,93 @@
import { nextTick } from 'vue';
import * as svg from '@element-plus/icons-vue';
// 获取阿里字体图标
const getAlicdnIconfont = () => {
    return new Promise((resolve, reject) => {
        nextTick(() => {
            const styles: any = document.styleSheets;
            let sheetsList = [];
            let sheetsIconList = [];
            for (let i = 0; i < styles.length; i++) {
                if (styles[i].href && styles[i].href.indexOf('at.alicdn.com') > -1) {
                    sheetsList.push(styles[i]);
                }
            }
            for (let i = 0; i < sheetsList.length; i++) {
                for (let j = 0; j < sheetsList[i].cssRules.length; j++) {
                    if (sheetsList[i].cssRules[j].selectorText && sheetsList[i].cssRules[j].selectorText.indexOf('.icon-') > -1) {
                        sheetsIconList.push(`${sheetsList[i].cssRules[j].selectorText.substring(1, sheetsList[i].cssRules[j].selectorText.length).replace(/\:\:before/gi, '')}`);
                    }
                }
            }
            if (sheetsIconList.length > 0) resolve(sheetsIconList);
            else reject('未获取到值,请刷新重试');
        });
    });
};
// 初始化获取 css 样式,获取 element plus 自带 svg 图标,增加了 ele- 前缀,使用时:ele-Aim
const getElementPlusIconfont = () => {
    return new Promise((resolve, reject) => {
        nextTick(() => {
            const icons = svg as any;
            const sheetsIconList = [];
            for (const i in icons) {
                sheetsIconList.push(`ele-${icons[i].name}`);
            }
            if (sheetsIconList.length > 0) resolve(sheetsIconList);
            else reject('未获取到值,请刷新重试');
        });
    });
};
// 初始化获取 css 样式,这里使用 fontawesome 的图标
const getAwesomeIconfont = () => {
    return new Promise((resolve, reject) => {
        nextTick(() => {
            const styles: any = document.styleSheets;
            let sheetsList = [];
            let sheetsIconList = [];
            for (let i = 0; i < styles.length; i++) {
                if (styles[i].href && styles[i].href.indexOf('netdna.bootstrapcdn.com') > -1) {
                    sheetsList.push(styles[i]);
                }
            }
            for (let i = 0; i < sheetsList.length; i++) {
                for (let j = 0; j < sheetsList[i].cssRules.length; j++) {
                    if (sheetsList[i].cssRules[j].selectorText && sheetsList[i].cssRules[j].selectorText.indexOf('.fa-') === 0 && sheetsList[i].cssRules[j].selectorText.indexOf(',') === -1) {
                        if (/::before/.test(sheetsList[i].cssRules[j].selectorText)) {
                            sheetsIconList.push(`${sheetsList[i].cssRules[j].selectorText.substring(1, sheetsList[i].cssRules[j].selectorText.length).replace(/\:\:before/gi, '')}`);
                        }
                    }
                }
            }
            if (sheetsIconList.length > 0) resolve(sheetsIconList.reverse());
            else reject('未获取到值,请刷新重试');
        });
    });
};
/**
 * 获取字体图标 `document.styleSheets`
 * @method ali 获取阿里字体图标 `<i class="iconfont 图标类名"></i>`
 * @method ele 获取 element plus 自带图标 `<i class="图标类名"></i>`
 * @method ali 获取 fontawesome 的图标 `<i class="fa 图标类名"></i>`
 */
const initIconfont = {
    // iconfont
    ali: () => {
        return getAlicdnIconfont();
    },
    // element plus
    ele: () => {
        return getElementPlusIconfont();
    },
    // fontawesome
    awe: () => {
        return getAwesomeIconfont();
    }
};
// 导出方法
export default initIconfont;
在上述文件截断后对比
src/utils/loading.ts src/utils/other.ts src/utils/request.ts src/utils/setIconfont.ts src/utils/storage.ts src/utils/theme.ts src/utils/throttle.ts src/utils/toolsValidate.ts src/utils/wartermark.ts src/views/accidentManagementSystem/accidentCases/component/DailogCases.vue src/views/accidentManagementSystem/accidentCases/component/wangEditor/index.vue src/views/accidentManagementSystem/accidentCases/index.vue src/views/accidentManagementSystem/accidentCasesCop/component/wangEditor/index.vue src/views/accidentManagementSystem/accidentCasesCop/index.vue src/views/accidentManagementSystem/accidentExpress/component/numberOfCasualties.vue src/views/accidentManagementSystem/accidentExpress/component/openAdd.vue src/views/accidentManagementSystem/accidentExpress/index.vue src/views/accidentManagementSystem/accidentReport/component/openAdd.vue src/views/accidentManagementSystem/accidentReport/index.vue src/views/accidentManagementSystem/accidentStatistics/index.vue src/views/accidentManagementSystem/workInjuryDeclaration/component/accidentName.vue src/views/accidentManagementSystem/workInjuryDeclaration/component/openAdd.vue src/views/accidentManagementSystem/workInjuryDeclaration/component/openEdit.vue src/views/accidentManagementSystem/workInjuryDeclaration/index.vue src/views/contingencyManagement/abolishDialog/abolishDialog.vue src/views/contingencyManagement/abolishDialog/component/formInformationTop.vue src/views/contingencyManagement/abolishDialog/component/formInformationTops.vue src/views/contingencyManagement/abolishDialog/component/lowerPlate.vue src/views/contingencyManagement/contingency/component/addEmergencyPersonnel.vue src/views/contingencyManagement/contingency/component/openAdd.vue src/views/contingencyManagement/contingency/component/upData.vue src/views/contingencyManagement/contingency/index.vue src/views/contingencyManagement/emergencyDrill/drillImplementationEvaluation/component/approvalProgress.vue src/views/contingencyManagement/emergencyDrill/drillImplementationEvaluation/component/flowChart.vue src/views/contingencyManagement/emergencyDrill/drillImplementationEvaluation/component/rectificationDialog.vue src/views/contingencyManagement/emergencyDrill/drillImplementationEvaluation/index.vue src/views/contingencyManagement/emergencyDrill/implementationOfEmergencyDrill/component/openAdd.vue src/views/contingencyManagement/emergencyDrill/implementationOfEmergencyDrill/component/regionsDialog.vue src/views/contingencyManagement/emergencyDrill/implementationOfEmergencyDrill/component/userSelect.vue src/views/contingencyManagement/emergencyDrill/implementationOfEmergencyDrill/index.vue src/views/contingencyManagement/emergencyDrill/releaseOfDrillPlan/component/flowChart.vue src/views/contingencyManagement/emergencyDrill/releaseOfDrillPlan/component/openAdd.vue src/views/contingencyManagement/emergencyDrill/releaseOfDrillPlan/component/regionsDialog.vue src/views/contingencyManagement/emergencyDrill/releaseOfDrillPlan/index.vue src/views/contingencyManagement/emergencyDrillStatistics/index.vue src/views/contingencyManagement/emergencyPlanStartRecord/component/openSee.vue src/views/contingencyManagement/emergencyPlanStartRecord/component/selectEmergencyPlan.vue src/views/contingencyManagement/emergencyPlanStartRecord/index.vue src/views/contingencyManagement/emergencyResources/emergencyMaterialsInspection/component/openAdd.vue src/views/contingencyManagement/emergencyResources/emergencyMaterialsInspection/index.vue src/views/contingencyManagement/emergencyResources/emergencySupplies/component/inspect.vue src/views/contingencyManagement/emergencyResources/emergencySupplies/component/maintain.vue src/views/contingencyManagement/emergencyResources/emergencySupplies/component/openAdd.vue src/views/contingencyManagement/emergencyResources/emergencySupplies/component/openEdit.vue src/views/contingencyManagement/emergencyResources/emergencySupplies/component/personInCharge.vue src/views/contingencyManagement/emergencyResources/emergencySupplies/component/regionsCheckbox.vue src/views/contingencyManagement/emergencyResources/emergencySupplies/index.vue src/views/contingencyManagement/emergencyResources/maintenanceOfEmergencyMaterials/component/openAdd.vue src/views/contingencyManagement/emergencyResources/maintenanceOfEmergencyMaterials/index.vue src/views/contingencyManagement/panManagement/component/abolishLibrary.vue src/views/contingencyManagement/panManagement/component/approval.vue src/views/contingencyManagement/panManagement/component/approvalProcess.vue src/views/contingencyManagement/panManagement/component/initiateApproval.vue src/views/contingencyManagement/panManagement/component/openAdd.vue src/views/contingencyManagement/panManagement/component/startUp.vue src/views/contingencyManagement/panManagement/component/upData.vue src/views/contingencyManagement/panManagement/index.vue src/views/contingencyManagement/processForm/component/formInformationTop.vue src/views/contingencyManagement/processForm/component/formInformationTops.vue src/views/contingencyManagement/processForm/component/lowerPlate.vue src/views/contingencyManagement/processForm/processForm.vue src/views/contingencyManagement/releaseOfDrillStart/component/formInformationTop.vue src/views/contingencyManagement/releaseOfDrillStart/component/formInformationTops.vue src/views/contingencyManagement/releaseOfDrillStart/component/lowerPlate.vue src/views/contingencyManagement/releaseOfDrillStart/releaseOfDrillStart.vue src/views/doublePrevent/dpIndex/index.vue src/views/doublePrevent/riskCheckManage/checkTaskManage/checkTask/components/recordDialog.vue src/views/doublePrevent/riskCheckManage/checkTaskManage/checkTask/index.vue src/views/doublePrevent/riskCheckManage/checkTaskManage/checkWork/components/workDialog.vue src/views/doublePrevent/riskCheckManage/checkTaskManage/checkWork/index.vue src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenCheck/components/checkDialog.vue src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenCheck/index.vue src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenRectify/components/rectifyDialog.vue src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenRectify/index.vue src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenReport/components/reportDialog.vue src/views/doublePrevent/riskCheckManage/hiddenManagement/hiddenReport/index.vue src/views/doublePrevent/riskCheckManage/riskCheckUnit/components/checkUnitDialog.vue src/views/doublePrevent/riskCheckManage/riskCheckUnit/components/selectMeasureControlDialog.vue src/views/doublePrevent/riskCheckManage/riskCheckUnit/index.vue src/views/doublePrevent/riskLevel/action/components/riskControlMeasureDialog.vue src/views/doublePrevent/riskLevel/action/index.vue src/views/doublePrevent/riskLevel/device/components/productionDeviceDialog.vue src/views/doublePrevent/riskLevel/device/index.vue src/views/doublePrevent/riskLevel/event/components/safetyRiskEventDialog.vue src/views/doublePrevent/riskLevel/event/index.vue src/views/doublePrevent/riskLevel/map/components/rectifyDialog.vue src/views/doublePrevent/riskLevel/map/index.vue src/views/doublePrevent/riskLevel/riskCheckUnit/components/checkUnitDialog.vue src/views/doublePrevent/riskLevel/riskCheckUnit/components/selectMeasureControlDialog.vue src/views/doublePrevent/riskLevel/riskCheckUnit/index.vue src/views/doublePrevent/riskLevel/unit/components/safetyRiskAnalyseUnitDialog.vue src/views/doublePrevent/riskLevel/unit/index.vue src/views/error/401.vue src/views/error/404.vue src/views/facilityManagement/EquipmentStatistics/index.vue src/views/facilityManagement/InstrumentationInformation/index.vue src/views/facilityManagement/ProductionEquipment/index.vue src/views/facilityManagement/claimReturnRecords/components/invalidDealDialog.vue src/views/facilityManagement/claimReturnRecords/components/returnAndWatch.vue src/views/facilityManagement/claimReturnRecords/index.ts src/views/facilityManagement/claimReturnRecords/index.vue src/views/facilityManagement/deviceType/component/Dailog.vue src/views/facilityManagement/deviceType/index.vue src/views/facilityManagement/goodsDetailManage/components/checkOut.vue src/views/facilityManagement/goodsDetailManage/components/goodsDetailAdd.vue src/views/facilityManagement/goodsDetailManage/components/goodsDetailEdit.vue src/views/facilityManagement/goodsDetailManage/index.ts src/views/facilityManagement/goodsDetailManage/index.vue src/views/facilityManagement/goodsTypeManage/index.vue src/views/facilityManagement/keyEquipment/index.vue src/views/facilityManagement/safetyEquipment/index.vue src/views/facilityManagement/safetyGoodsAndEquipment/components/addGoodsDialog.vue src/views/facilityManagement/safetyGoodsAndEquipment/components/batchInStorage.vue src/views/facilityManagement/safetyGoodsAndEquipment/components/batchOutStorage.vue src/views/facilityManagement/safetyGoodsAndEquipment/components/safetyGoodsAndEquipmentDialog.vue src/views/facilityManagement/safetyGoodsAndEquipment/index.ts src/views/facilityManagement/safetyGoodsAndEquipment/index.vue src/views/facilityManagement/securities/index.vue src/views/goalManagement/Goalsummary/index.vue src/views/goalManagement/IncentiveRecording/component/DailogAdd.vue src/views/goalManagement/IncentiveRecording/component/DailogSearch.vue src/views/goalManagement/IncentiveRecording/index.vue src/views/goalManagement/Incentivestandard/component/DailogAdd.vue src/views/goalManagement/Incentivestandard/index.vue src/views/goalManagement/TargetBook/component/DailogAdd.vue src/views/goalManagement/TargetBook/component/DailogSearch.vue src/views/goalManagement/TargetBook/index.vue src/views/goalManagement/index.vue src/views/goalManagement/performanceAppraisal/component/DailogAq.vue src/views/goalManagement/performanceAppraisal/component/DailogKh.vue src/views/goalManagement/performanceAppraisal/component/DailogKhS.vue src/views/goalManagement/performanceAppraisal/component/DailogSearch.vue src/views/goalManagement/performanceAppraisal/index.vue src/views/goalManagement/processForms/component/formInformationTop.vue src/views/goalManagement/processForms/component/formInformationTops.vue src/views/goalManagement/processForms/component/lowerPlate.vue src/views/goalManagement/processForms/processForms.vue src/views/goalManagement/safetyAssessment/component/Dailog.vue src/views/goalManagement/safetyAssessment/component/DailogAdd.vue src/views/goalManagement/safetyAssessment/index.vue src/views/goalManagement/targetClassification/index.vue src/views/goalManagement/targetDecompositionHalfYear/index.vue src/views/goalManagement/targetDecompositionMonth/index.vue src/views/goalManagement/targetDecompositionQuarter/index.vue src/views/goalManagement/targetDecompositionYear/component/Dailog.vue src/views/goalManagement/targetDecompositionYear/component/DailogAdd.vue src/views/goalManagement/targetDecompositionYear/index.vue src/views/goalManagement/targetEscalation/component/Dailog.vue src/views/goalManagement/targetEscalation/component/TypeDailog.vue src/views/goalManagement/targetEscalation/index.vue src/views/goalManagement/targetImprovements/component/Dailogprove.vue src/views/goalManagement/targetImprovements/index.vue src/views/goalManagement/targetSettings/component/dailogAdd.vue src/views/goalManagement/targetSettings/component/search.vue src/views/goalManagement/targetSettings/index.vue src/views/goalManagement/targetStatistics/index.vue src/views/intellectInspect/inspectBasic/discriminate/components/RFIDDialog.vue src/views/intellectInspect/inspectBasic/discriminate/index.vue src/views/intellectInspect/inspectBasic/facility/components/facilityAreaDialog.vue src/views/intellectInspect/inspectBasic/facility/index.vue src/views/intellectInspect/inspectBasic/index.vue src/views/intellectInspect/inspectBasic/inspectPoint/components/inspectPointDialog.vue src/views/intellectInspect/inspectBasic/inspectPoint/index.vue src/views/intellectInspect/inspectBasic/inspectTarget/components/inspectTargetDialog.vue src/views/intellectInspect/inspectBasic/inspectTarget/index.vue src/views/intellectInspect/inspectIndex/components/inspectRecordDialog.vue src/views/intellectInspect/inspectIndex/components/sum.vue src/views/intellectInspect/inspectIndex/index.vue src/views/intellectInspect/inspectRecordManage/inspectRecord/components/inspectRecordDialog.vue src/views/intellectInspect/inspectRecordManage/inspectRecord/components/sum.vue src/views/intellectInspect/inspectRecordManage/inspectRecord/index.vue src/views/intellectInspect/inspectTaskManage/inspectTask/components/inspectTaskDialog.vue src/views/intellectInspect/inspectTaskManage/inspectTask/index.vue src/views/intellectInspect/intelligentLine/index.vue src/views/layoutPage/index.vue src/views/loginPage/component/accountLogin.vue src/views/loginPage/loginPage.vue src/views/newHome/index.vue src/views/riskWarningSys/warningBigScreen/components/SPI.vue src/views/riskWarningSys/warningBigScreen/components/accident.vue src/views/riskWarningSys/warningBigScreen/components/danger.vue src/views/riskWarningSys/warningBigScreen/components/educate.vue src/views/riskWarningSys/warningBigScreen/components/message.vue src/views/riskWarningSys/warningBigScreen/components/monitor.vue src/views/riskWarningSys/warningBigScreen/components/profession.vue src/views/riskWarningSys/warningBigScreen/components/risk.vue src/views/riskWarningSys/warningBigScreen/components/stock.vue src/views/riskWarningSys/warningBigScreen/components/training.vue src/views/riskWarningSys/warningBigScreen/index.vue src/views/riskWarningSys/warningBigScreen/indexs/index.vue src/views/riskWarningSys/warningBigScreen/indexs/msgDetail.vue src/views/safeKnowledge/bmgz/index.vue src/views/safeKnowledge/df/index.vue src/views/safeKnowledge/index.vue src/views/safeKnowledge/inner/index.vue src/views/safeKnowledge/internationalRules/index.vue src/views/safeKnowledge/law/index.vue src/views/safeKnowledge/sfjs/index.vue src/views/safeKnowledge/xzfg/index.vue src/views/specialWorkSystem/alarm/zyyjjl/index.vue src/views/specialWorkSystem/flow/basicApprove/components/approveBasicDialog.vue src/views/specialWorkSystem/flow/basicApprove/index.vue src/views/specialWorkSystem/flow/ruleofApp/components/approveItemDialog.vue src/views/specialWorkSystem/flow/ruleofApp/components/approveLevelDialog.vue src/views/specialWorkSystem/flow/ruleofApp/components/approveRuleDialog.vue src/views/specialWorkSystem/flow/ruleofApp/index.vue src/views/specialWorkSystem/foundationSet/goods/index.vue src/views/specialWorkSystem/foundationSet/safetyAction/components/safetyActionDialog.vue src/views/specialWorkSystem/foundationSet/safetyAction/index.vue src/views/specialWorkSystem/plan/appoint/index.vue src/views/specialWorkSystem/plan/reservation/index.vue src/views/specialWorkSystem/plan/sumReserve/index.vue src/views/specialWorkSystem/process/components/dialogPermitNo.vue src/views/specialWorkSystem/process/qtjcfx/index.vue src/views/specialWorkSystem/process/zyjcgl/index.vue src/views/specialWorkSystem/workTicket/wdsp/components/brokenLog.vue src/views/specialWorkSystem/workTicket/wdsp/components/fireLog.vue src/views/specialWorkSystem/workTicket/wdsp/components/groundLog.vue src/views/specialWorkSystem/workTicket/wdsp/components/heightLog.vue src/views/specialWorkSystem/workTicket/wdsp/components/hoistLog.vue src/views/specialWorkSystem/workTicket/wdsp/components/plateLog.vue src/views/specialWorkSystem/workTicket/wdsp/components/powerLog.vue src/views/specialWorkSystem/workTicket/wdsp/components/spaceLog.vue src/views/specialWorkSystem/workTicket/wdsp/index.vue src/views/specialWorkSystem/workTicket/wdsq/components/brokenLog.vue src/views/specialWorkSystem/workTicket/wdsq/components/fireLog.vue src/views/specialWorkSystem/workTicket/wdsq/components/groundLog.vue src/views/specialWorkSystem/workTicket/wdsq/components/heightLog.vue src/views/specialWorkSystem/workTicket/wdsq/components/hoistLog.vue src/views/specialWorkSystem/workTicket/wdsq/components/plateLog.vue src/views/specialWorkSystem/workTicket/wdsq/components/powerLog.vue src/views/specialWorkSystem/workTicket/wdsq/components/spaceLog.vue src/views/specialWorkSystem/workTicket/wdsq/index.vue src/views/specialWorkSystem/workTicket/wdsqjl/index.vue src/views/specialWorkSystem/workTicket/zysq/components/broken.vue src/views/specialWorkSystem/workTicket/zysq/components/fire.vue src/views/specialWorkSystem/workTicket/zysq/components/ground.vue src/views/specialWorkSystem/workTicket/zysq/components/height.vue src/views/specialWorkSystem/workTicket/zysq/components/hoist.vue src/views/specialWorkSystem/workTicket/zysq/components/materialDialog.vue src/views/specialWorkSystem/workTicket/zysq/components/plate.vue src/views/specialWorkSystem/workTicket/zysq/components/power.vue src/views/specialWorkSystem/workTicket/zysq/components/space.vue src/views/specialWorkSystem/workTicket/zysq/index.vue src/views/system/appVersion/index.vue src/views/system/department/component/deptDialog.vue src/views/system/department/index.vue src/views/system/dic/component/addDic.vue src/views/system/dic/component/editDic.vue src/views/system/dic/index.vue src/views/system/menu/component/menuDialog.vue src/views/system/menu/index.vue src/views/system/personShiftManage/personTimeManage/durationManage/index.vue src/views/system/personShiftManage/personTimeManage/holidayTime/index.vue src/views/system/personShiftManage/personTimeManage/holidayTimeGroup/index.vue src/views/system/personShiftManage/personTimeManage/timeStrategy/index.vue src/views/system/personShiftManage/personTimeManage/workingHoursSet/index.vue src/views/system/personShiftManage/scheduleManage/schedule/index.vue src/views/system/personShiftManage/scheduleManage/strategy/index.vue src/views/system/role/component/roleDialog.vue src/views/system/role/index.vue src/views/system/user/component/userDialog.vue src/views/system/user/index.vue static/loginPage.js/login.js static/loginPage.js/loginApp.js tsconfig.json vite.config.ts yarn.lock