From 9f9a88f303c75f6e026defa8685b89c5bffce140 Mon Sep 17 00:00:00 2001 From: Zy <1448159279@qq.com> Date: Mon, 20 Apr 2026 16:38:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E9=98=B6=E6=AE=B5=E6=80=A7?= =?UTF-8?q?=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/system/InspectionItem/index.ts | 63 ++++ src/api/system/InspectionItem/type.ts | 180 ++++++++++ src/api/system/InspectionPoint/type.ts | 6 +- src/api/system/InspectionRoute/index.ts | 63 ++++ src/api/system/InspectionRoute/type.ts | 168 +++++++++ .../SdbElectricityMeterReading/index.ts | 63 ++++ .../system/SdbElectricityMeterReading/type.ts | 140 ++++++++ src/api/system/SdbWaterMeterReading/index.ts | 63 ++++ src/api/system/SdbWaterMeterReading/type.ts | 125 +++++++ src/api/system/community/index.ts | 11 +- src/api/system/house/index.ts | 4 +- src/api/workflow/index.ts | 22 ++ src/layout/components/Navbar.vue | 4 + src/permission.ts | 122 +++++-- src/store/modules/house.ts | 2 +- src/types/global.d.ts | 7 +- src/utils/request.ts | 35 +- src/views/community/AddCommunity.vue | 6 +- src/views/community/index.vue | 42 ++- src/views/login.vue | 2 - src/views/system/Decoration/index.vue | 2 +- .../Questionnaire/QuestionnaireView.vue | 27 +- .../system/Sdb/ElectricityRecord/index.vue | 310 ++++++++++++++++ .../system/Sdb/SdbElectricityDevice/index.vue | 3 - src/views/system/Sdb/SdbTopupRecord/index.vue | 32 -- src/views/system/Sdb/SdbWaterDevice/index.vue | 3 - src/views/system/Sdb/WaterRecord/index.vue | 260 ++++++++++++++ src/views/system/Visitor/index.vue | 8 +- src/views/system/Visitor/visitorMain.vue | 63 ++-- .../system/house/components/building.vue | 10 +- .../house/components/components/houseItem.vue | 3 +- .../house/components/components/table.vue | 14 +- src/views/system/house/components/unit.vue | 18 +- src/views/system/inspection/Item/index2.vue | 262 ++++++++++++++ .../inspection/Point/addInspectionPoint.vue | 331 ++++++++++++++++- src/views/system/inspection/Point/index.vue | 31 +- .../inspection/Route/addInspectionRoute.vue | 334 ++++++++++++++++++ src/views/system/inspection/Route/index2.vue | 270 ++++++++++++++ src/views/workbench/index2.vue | 72 +++- 39 files changed, 2987 insertions(+), 194 deletions(-) create mode 100644 src/api/system/InspectionItem/index.ts create mode 100644 src/api/system/InspectionItem/type.ts create mode 100644 src/api/system/InspectionRoute/index.ts create mode 100644 src/api/system/InspectionRoute/type.ts create mode 100644 src/api/system/SdbElectricityMeterReading/index.ts create mode 100644 src/api/system/SdbElectricityMeterReading/type.ts create mode 100644 src/api/system/SdbWaterMeterReading/index.ts create mode 100644 src/api/system/SdbWaterMeterReading/type.ts create mode 100644 src/api/workflow/index.ts create mode 100644 src/views/system/Sdb/ElectricityRecord/index.vue create mode 100644 src/views/system/Sdb/WaterRecord/index.vue create mode 100644 src/views/system/inspection/Item/index2.vue create mode 100644 src/views/system/inspection/Route/addInspectionRoute.vue create mode 100644 src/views/system/inspection/Route/index2.vue diff --git a/src/api/system/InspectionItem/index.ts b/src/api/system/InspectionItem/index.ts new file mode 100644 index 0000000..89e3ef0 --- /dev/null +++ b/src/api/system/InspectionItem/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { ItemVO, ItemForm, ItemQuery } from './type'; + +/** + * 查询巡检项目列表 + * @param query + * @returns {*} + */ + +export const listItem = (query?: ItemQuery): AxiosPromise => { + return request({ + url: '/inspection/item/list', + method: 'get', + params: query + }); +}; + +/** + * 查询巡检项目详细 + * @param id + */ +export const getItem = (id: string | number): AxiosPromise => { + return request({ + url: '/inspection/item/' + id, + method: 'get' + }); +}; + +/** + * 新增巡检项目 + * @param data + */ +export const addItem = (data: ItemForm) => { + return request({ + url: '/inspection/item', + method: 'post', + data: data + }); +}; + +/** + * 修改巡检项目 + * @param data + */ +export const updateItem = (data: ItemForm) => { + return request({ + url: '/inspection/item', + method: 'put', + data: data + }); +}; + +/** + * 删除巡检项目 + * @param id + */ +export const delItem = (id: string | number | Array) => { + return request({ + url: '/inspection/item/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/InspectionItem/type.ts b/src/api/system/InspectionItem/type.ts new file mode 100644 index 0000000..fb9de8a --- /dev/null +++ b/src/api/system/InspectionItem/type.ts @@ -0,0 +1,180 @@ +export interface ItemVO { + /** + * 主键ID + */ + id: string | number; + + /** + * 项目名称 + */ + itemName: string; + + /** + * 项目编号 + */ + itemCode: string; + + /** + * 巡检标准 + */ + inspectionStandard: string; + + /** + * 项目类别 + */ + category: string; + + /** + * 项目描述 + */ + description: string; + + /** + * 默认值 + */ + defaultValue: string; + + /** + * 输入类型:text/select/radio/checkbox + */ + inputType: string; + + /** + * 选项,多个用逗号分隔 + */ + options: string; + + /** + * 是否必填:0-否,1-是 + */ + isRequired: number; + + /** + * 状态:0-开启,1-关闭 + */ + status: number; + + /** + * 备注 + */ + remark: string; +} + +export interface ItemForm extends BaseEntity { + /** + * 主键ID + */ + id?: string | number; + + /** + * 项目名称 + */ + itemName?: string; + + /** + * 项目编号 + */ + itemCode?: string; + + /** + * 巡检标准 + */ + inspectionStandard?: string; + + /** + * 项目类别 + */ + category?: string; + + /** + * 项目描述 + */ + description?: string; + + /** + * 默认值 + */ + defaultValue?: string; + + /** + * 输入类型:text/select/radio/checkbox + */ + inputType?: string; + + /** + * 选项,多个用逗号分隔 + */ + options?: string; + + /** + * 是否必填:0-否,1-是 + */ + isRequired?: number; + + /** + * 状态:0-开启,1-关闭 + */ + status?: number; + + /** + * 备注 + */ + remark?: string; +} + +export interface ItemQuery extends PageQuery { + /** + * 项目名称 + */ + itemName?: string; + + /** + * 项目编号 + */ + itemCode?: string; + + /** + * 巡检标准 + */ + inspectionStandard?: string; + + /** + * 项目类别 + */ + category?: string; + + /** + * 项目描述 + */ + description?: string; + + /** + * 默认值 + */ + defaultValue?: string; + + /** + * 输入类型:text/select/radio/checkbox + */ + inputType?: string; + + /** + * 选项,多个用逗号分隔 + */ + options?: string; + + /** + * 是否必填:0-否,1-是 + */ + isRequired?: number; + + /** + * 状态:0-开启,1-关闭 + */ + status?: number; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/system/InspectionPoint/type.ts b/src/api/system/InspectionPoint/type.ts index e8fc6ae..4ea9ed4 100644 --- a/src/api/system/InspectionPoint/type.ts +++ b/src/api/system/InspectionPoint/type.ts @@ -12,7 +12,7 @@ export interface PointVO { /** * 巡检项目id */ - itemId: string | number; + itemId: string; /** * 所属路线ID @@ -64,7 +64,7 @@ export interface PointForm extends BaseEntity { /** * 巡检项目id */ - itemId?: string | number; + itemId?: string; /** * 所属路线ID @@ -111,7 +111,7 @@ export interface PointQuery extends PageQuery { /** * 巡检项目id */ - itemId?: string | number; + itemId?: string; /** * 所属路线ID diff --git a/src/api/system/InspectionRoute/index.ts b/src/api/system/InspectionRoute/index.ts new file mode 100644 index 0000000..b0792bd --- /dev/null +++ b/src/api/system/InspectionRoute/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { RouteVO, RouteForm, RouteQuery } from './type'; + +/** + * 查询巡检路线列表 + * @param query + * @returns {*} + */ + +export const listRoute = (query?: RouteQuery): AxiosPromise => { + return request({ + url: '/inspection/route/list', + method: 'get', + params: query + }); +}; + +/** + * 查询巡检路线详细 + * @param id + */ +export const getRoute = (id: string | number): AxiosPromise => { + return request({ + url: '/inspection/route/' + id, + method: 'get' + }); +}; + +/** + * 新增巡检路线 + * @param data + */ +export const addRoute = (data: RouteForm) => { + return request({ + url: '/inspection/route', + method: 'post', + data: data + }); +}; + +/** + * 修改巡检路线 + * @param data + */ +export const updateRoute = (data: RouteForm) => { + return request({ + url: '/inspection/route', + method: 'put', + data: data + }); +}; + +/** + * 删除巡检路线 + * @param id + */ +export const delRoute = (id: string | number | Array) => { + return request({ + url: '/inspection/route/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/InspectionRoute/type.ts b/src/api/system/InspectionRoute/type.ts new file mode 100644 index 0000000..500d912 --- /dev/null +++ b/src/api/system/InspectionRoute/type.ts @@ -0,0 +1,168 @@ +export interface RouteVO { + /** + * 主键ID + */ + id: string | number; + + /** + * 巡检路线名称 + */ + routeName: string; + + /** + * 路线描述 + */ + description: string; + + /** + * 巡检点 + */ + totalPoints: string; + + /** + * 预计巡检时长(分钟) + */ + estimatedTime: number; + + /** + * 备注 + */ + remark: string; + + /** + * 巡检路线状态 0开启 1关闭 + + */ + routeStatus: number; + + /** + * 起点经度 + */ + startLng: string; + + /** + * 起点纬度 + */ + startLat: string; + + /** + * 终点经度 + */ + endLng: string; + + /** + * 终点纬度 + */ + endLat: string; +} + +export interface RouteForm extends BaseEntity { + /** + * 主键ID + */ + id?: string | number; + + /** + * 巡检路线名称 + */ + routeName?: string; + + /** + * 路线描述 + */ + description?: string; + + /** + * 巡检点 + */ + totalPoints?: string; + + /** + * 预计巡检时长(分钟) + */ + estimatedTime?: number; + + /** + * 备注 + */ + remark?: string; + + /** + * 巡检路线状态 0开启 1关闭 + + */ + routeStatus?: number; + + /** + * 起点经度 + */ + startLng?: string; + + /** + * 起点纬度 + */ + startLat?: string; + + /** + * 终点经度 + */ + endLng?: string; + + /** + * 终点纬度 + */ + endLat?: string; +} + +export interface RouteQuery extends PageQuery { + /** + * 巡检路线名称 + */ + routeName?: string; + + /** + * 路线描述 + */ + description?: string; + + /** + * 巡检点 + */ + totalPoints?: string; + + /** + * 预计巡检时长(分钟) + */ + estimatedTime?: number; + + /** + * 巡检路线状态 0开启 1关闭 + + */ + routeStatus?: number; + + /** + * 起点经度 + */ + startLng?: string; + + /** + * 起点纬度 + */ + startLat?: string; + + /** + * 终点经度 + */ + endLng?: string; + + /** + * 终点纬度 + */ + endLat?: string; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/system/SdbElectricityMeterReading/index.ts b/src/api/system/SdbElectricityMeterReading/index.ts new file mode 100644 index 0000000..9055ee9 --- /dev/null +++ b/src/api/system/SdbElectricityMeterReading/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { ElectricityRecordVO, ElectricityRecordForm, ElectricityRecordQuery } from './type'; + +/** + * 查询电抄记录列表 + * @param query + * @returns {*} + */ + +export const listElectricityRecord = (query?: ElectricityRecordQuery): AxiosPromise => { + return request({ + url: '/electricityRecord/list', + method: 'get', + params: query + }); +}; + +/** + * 查询电抄记录详细 + * @param id + */ +export const getElectricityRecord = (id: string | number): AxiosPromise => { + return request({ + url: '/electricityRecord/' + id, + method: 'get' + }); +}; + +/** + * 新增电抄记录 + * @param data + */ +export const addElectricityRecord = (data: ElectricityRecordForm) => { + return request({ + url: '/electricityRecord', + method: 'post', + data: data + }); +}; + +/** + * 修改电抄记录 + * @param data + */ +export const updateElectricityRecord = (data: ElectricityRecordForm) => { + return request({ + url: '/electricityRecord', + method: 'put', + data: data + }); +}; + +/** + * 删除电抄记录 + * @param id + */ +export const delElectricityRecord = (id: string | number | Array) => { + return request({ + url: '/electricityRecord/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/SdbElectricityMeterReading/type.ts b/src/api/system/SdbElectricityMeterReading/type.ts new file mode 100644 index 0000000..01d0974 --- /dev/null +++ b/src/api/system/SdbElectricityMeterReading/type.ts @@ -0,0 +1,140 @@ +export interface ElectricityRecordVO { + /** + * 抄表记录ID + */ + id: string | number; + + /** + * 用户ID + */ + deviceCode: string; + + /** + * 总用电量 + */ + totalEnergy: number; + + /** + * 抄表时间 + */ + readTime: string; + + /** + * 当前余额 + */ + balance: number; + + /** + * 状态(0为欠费拉闸,1为合闸,2为主动拉闸) + */ + status: number; + + /** + * + */ + event: string; + + /** + * + */ + rangeTime: string; + + /** + * + */ + rangeFee: string; +} + +export interface ElectricityRecordForm extends BaseEntity { + /** + * 抄表记录ID + */ + id?: string | number; + + /** + * 用户ID + */ + deviceCode?: string; + + /** + * 总用电量 + */ + totalEnergy?: number; + + /** + * 抄表时间 + */ + readTime?: string; + + /** + * 当前余额 + */ + balance?: number; + + /** + * 状态(0为欠费拉闸,1为合闸,2为主动拉闸) + */ + status?: number; + + /** + * + */ + event?: string; + + /** + * + */ + rangeTime?: string; + + /** + * + */ + rangeFee?: string; +} + +export interface ElectricityRecordQuery extends PageQuery { + /** + * 用户ID + */ + deviceCode?: string; + + /** + * 总用电量 + */ + totalEnergy?: number; + + /** + * 抄表时间 + */ + readTime?: string; + + /** + * 当前余额 + */ + balance?: number; + + /** + * 状态(0为欠费拉闸,1为合闸,2为主动拉闸) + */ + status?: number; + + /** + * + */ + event?: string; + + /** + * + */ + rangeTime?: string; + + /** + * + */ + rangeFee?: string; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/system/SdbWaterMeterReading/index.ts b/src/api/system/SdbWaterMeterReading/index.ts new file mode 100644 index 0000000..8fd35f7 --- /dev/null +++ b/src/api/system/SdbWaterMeterReading/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { WaterRecordVO, WaterRecordForm, WaterRecordQuery } from './type'; + +/** + * 查询水抄记录列表 + * @param query + * @returns {*} + */ + +export const listWaterRecord = (query?: WaterRecordQuery): AxiosPromise => { + return request({ + url: '/waterRecord/list', + method: 'get', + params: query + }); +}; + +/** + * 查询水抄记录详细 + * @param id + */ +export const getWaterRecord = (id: string | number): AxiosPromise => { + return request({ + url: '/waterRecord/' + id, + method: 'get' + }); +}; + +/** + * 新增水抄记录 + * @param data + */ +export const addWaterRecord = (data: WaterRecordForm) => { + return request({ + url: '/waterRecord', + method: 'post', + data: data + }); +}; + +/** + * 修改水抄记录 + * @param data + */ +export const updateWaterRecord = (data: WaterRecordForm) => { + return request({ + url: '/waterRecord', + method: 'put', + data: data + }); +}; + +/** + * 删除水抄记录 + * @param id + */ +export const delWaterRecord = (id: string | number | Array) => { + return request({ + url: '/waterRecord/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/SdbWaterMeterReading/type.ts b/src/api/system/SdbWaterMeterReading/type.ts new file mode 100644 index 0000000..a36cd49 --- /dev/null +++ b/src/api/system/SdbWaterMeterReading/type.ts @@ -0,0 +1,125 @@ +export interface WaterRecordVO { + /** + * 抄表记录ID + */ + id: string | number; + + /** + * 用户ID + */ + deviceCode: string; + + /** + * 总用电量 + */ + totalEnergy: number; + + /** + * 抄表时间 + */ + readTime: string; + + /** + * 当前余额 + */ + balance: number; + + /** + * 状态(0为欠费拉闸,1为合闸,2为主动拉闸) + */ + status: number; + + /** + * 1.电表 2.水表 + */ + type: number; + + /** + * 水表外接电源状态(0.未连接 1.接通) + */ + eleStatus: number; +} + +export interface WaterRecordForm extends BaseEntity { + /** + * 抄表记录ID + */ + id?: string | number; + + /** + * 用户ID + */ + deviceCode?: string; + + /** + * 总用电量 + */ + totalEnergy?: number; + + /** + * 抄表时间 + */ + readTime?: string; + + /** + * 当前余额 + */ + balance?: number; + + /** + * 状态(0为欠费拉闸,1为合闸,2为主动拉闸) + */ + status?: number; + + /** + * 1.电表 2.水表 + */ + type?: number; + + /** + * 水表外接电源状态(0.未连接 1.接通) + */ + eleStatus?: number; +} + +export interface WaterRecordQuery extends PageQuery { + /** + * 用户ID + */ + deviceCode?: string; + + /** + * 总用电量 + */ + totalEnergy?: number; + + /** + * 抄表时间 + */ + readTime?: string; + + /** + * 当前余额 + */ + balance?: number; + + /** + * 状态(0为欠费拉闸,1为合闸,2为主动拉闸) + */ + status?: number; + + /** + * 1.电表 2.水表 + */ + type?: number; + + /** + * 水表外接电源状态(0.未连接 1.接通) + */ + eleStatus?: number; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/system/community/index.ts b/src/api/system/community/index.ts index fc80f78..5fd72c5 100644 --- a/src/api/system/community/index.ts +++ b/src/api/system/community/index.ts @@ -23,8 +23,17 @@ export function deleteVillageByIdAPI(id: number): AxiosPromise { method: 'delete' }); } + +type uploadResponseType = { + 'success': { + 'url': string; + 'fileName': string; + 'ossId': string; + }[]; + 'error': string[]; +}; /** 上传小区图片 */ -export function uploadVillageImageAPI(formdata: FormData): AxiosPromise<{ fileName: string; url: string; ossId: string }[]> { +export function uploadVillageImageAPI(formdata: FormData): AxiosPromise { return request({ url: `/village/uploadImages`, method: 'post', diff --git a/src/api/system/house/index.ts b/src/api/system/house/index.ts index bbc56e1..3e64645 100644 --- a/src/api/system/house/index.ts +++ b/src/api/system/house/index.ts @@ -73,9 +73,9 @@ export function addHouseAPI(data: addHouseType) { }); } // 删除房屋 -export function deleteHouseApi(houseIds: string) { +export function deleteHouseApi(houseIds: string | string[]) { return request({ - url: `/house/${houseIds}`, + url: `/house/` + houseIds, method: 'delete' }); } diff --git a/src/api/workflow/index.ts b/src/api/workflow/index.ts new file mode 100644 index 0000000..4f3c6e0 --- /dev/null +++ b/src/api/workflow/index.ts @@ -0,0 +1,22 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; + +/** + * 查询小区概况 + * @param query + * @returns {*} + */ +export const workSpaceTotalListApi = ( + villageId: number +): Promise<{ + totalResident: number; + totalHouse: number; + totalParking: number; + totalComplaint: number; +}> => { + return request({ + url: '/workSpace/totalList', + method: 'get', + params: villageId + }); +}; diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue index b4a71c2..00a064c 100644 --- a/src/layout/components/Navbar.vue +++ b/src/layout/components/Navbar.vue @@ -151,6 +151,8 @@ watch( border-bottom: 1px solid #dfedff; color: #fff; + color: #c0c4cc; + box-shadow: none; display: flex; align-items: center; @@ -216,6 +218,8 @@ watch( height: 100%; font-size: 18px; color: #fff; + color: #c0c4cc; + vertical-align: text-bottom; &.hover-effect { diff --git a/src/permission.ts b/src/permission.ts index 114d78b..aaa01bf 100644 --- a/src/permission.ts +++ b/src/permission.ts @@ -11,75 +11,123 @@ import { usePermissionStore } from '@/store/modules/permission'; import { ElMessage } from 'element-plus/es'; NProgress.configure({ showSpinner: false }); + +// 白名单:不需要登录就能访问的页面 const whiteList = ['/login', '/register', '/social-callback', '/register*', '/register/*']; -// ✅ 关键:防止重复添加动态路由 +// 全局标记:动态路由是否已经添加过(只加载一次!) let isDynamicRoutesAdded = false; +// 判断是否在白名单 const isWhiteList = (path: string) => { return whiteList.some((pattern) => isPathMatch(pattern, path)); }; router.beforeEach(async (to, from) => { NProgress.start(); - if (getToken()) { + + // ============================================== + // 🚥 调试日志:每次跳转都打印(方便看你跳去了哪) + // ============================================== + console.log('=========================================================='); + console.log('🔀 路由跳转:', from.path, ' → ', to.path); + console.log('🔐 是否有Token:', !!getToken()); + console.log('🚦 动态路由是否已加载:', isDynamicRoutesAdded); + + const hasToken = getToken(); + const userStore = useUserStore(); + const permissionStore = usePermissionStore(); + + if (hasToken) { + // 设置标题 to.meta.title && useSettingsStore().setTitle(to.meta.title as string); + // 已登录 且 去登录页 → 跳首页 if (to.path === '/login') { + console.log('✅ 已登录,访问登录页,直接跳首页'); NProgress.done(); return '/'; - } else if (isWhiteList(to.path)) { + } + + // 白名单页面直接放行 + if (isWhiteList(to.path)) { + console.log('✅ 白名单页面,直接放行'); return; - } else { - // ✅ 关键:判断是否已添加过动态路由 - if (useUserStore().roles.length === 0 || !isDynamicRoutesAdded) { - isRelogin.show = true; - const [err, res] = await tos(useUserStore().getInfo()); - if (err) { - await useUserStore().logout(); - ElMessage.error(err); - isDynamicRoutesAdded = false; // 重置标志 - return '/'; - } else { - isRelogin.show = false; - const accessRoutes = await usePermissionStore().generateRoutes(); + } - accessRoutes.forEach((route) => { - if (!isHttp(route.path) && !router.hasRoute(route.name)) { - router.addRoute(route); - } - }); + // ============================================== + // ✅ 【关键】只在【没有角色 + 没有加载过路由】时执行一次 + // ============================================== + console.log('👤 当前用户角色:', userStore.roles); + console.log('🧪 判断条件:roles.length === 0 && !isDynamicRoutesAdded'); + console.log('🧪 结果:', userStore.roles.length === 0 && !isDynamicRoutesAdded); - isDynamicRoutesAdded = true; // ✅ 标记已添加 + if (userStore.roles.length === 0 && !isDynamicRoutesAdded) { + console.log('=========================================================='); + console.log('🚀 【首次初始化】获取用户信息 + 生成动态路由(只执行一次)'); + console.log('=========================================================='); - if (res.user.userId === 1 && from.path === '/login') { - // ✅ 关键:返回完整路由对象 + replace - return { path: '/community/communitylist', replace: true }; - } else { - // ✅ 终极修复:返回完整路由对象,强制 replace,防止白屏 - return { - path: to.path, - query: to.query, - hash: to.hash, - replace: true - }; - } + isRelogin.show = true; + + // 获取用户信息 + const [err, res] = await tos(userStore.getInfo()); + if (err) { + console.error('❌ 获取用户信息失败:', err); + await userStore.logout(); + ElMessage.error(err); + isDynamicRoutesAdded = false; + return '/'; + } + + console.log('✅ 用户信息获取成功:', res); + isRelogin.show = false; + + // 生成动态路由 + const accessRoutes = await permissionStore.generateRoutes(); + console.log('✅ 动态路由生成成功,数量:', accessRoutes.length); + + // 添加路由(避免重复添加) + accessRoutes.forEach((route) => { + if (!isHttp(route.path) && !router.hasRoute(route.name)) { + router.addRoute(route); } + }); + + // ✅ 标记:路由已添加 + isDynamicRoutesAdded = true; + console.log('✅ 动态路由添加完成,标记 isDynamicRoutesAdded = true'); + + // 管理员登录强制跳转 + if (res.user.userId === 1 && from.path === '/login') { + console.log('👑 管理员登录,跳转到社区列表'); + return { path: '/community/communitylist', replace: true }; } else { - return; + // 重新进入当前路由(让新添加的路由生效) + console.log('🔄 重新跳转目标页面:', to.path); + return { ...to, replace: true }; } } + + // ============================================== + // ✅ 已经初始化完成 → 直接放行! + // ============================================== + console.log('✅ 已完成初始化,直接放行'); + return; } else { - isDynamicRoutesAdded = false; // ✅ 退出时重置标志 + // 未登录 + isDynamicRoutesAdded = false; + console.log('🔒 未登录,跳转到登录页'); + if (isWhiteList(to.path)) { return; } else { NProgress.done(); - return '/login'; + return `/login?redirect=${to.fullPath}`; } } }); router.afterEach(() => { NProgress.done(); + console.log('✅ 跳转完成\n\n'); }); diff --git a/src/store/modules/house.ts b/src/store/modules/house.ts index a2619b6..460f4b7 100644 --- a/src/store/modules/house.ts +++ b/src/store/modules/house.ts @@ -65,7 +65,7 @@ export const useHouseStore = defineStore( }; // 更新小区信息 - const updateVilageinfo = (data) => { + const updateVilageinfo = (data: communitylist_rows_type) => { currentVilageInfo.value = data; }; diff --git a/src/types/global.d.ts b/src/types/global.d.ts index a39382c..b0e5caa 100644 --- a/src/types/global.d.ts +++ b/src/types/global.d.ts @@ -15,7 +15,12 @@ declare global { visible: boolean; children?: Array; } - + /** 地图 */ + interface Window { + _AMapSecurityConfig?: { + securityJsCode: string; + }; + } /** * 弹窗属性 */ diff --git a/src/utils/request.ts b/src/utils/request.ts index aefbc96..a00f560 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -35,15 +35,29 @@ const service = axios.create({ } }); -// 不需要小区id 或者 加上小区id报错的接口地址 -const whiteVillageId = []; +// 不需要小区 ID 的接口白名单(支持 * 通配符) +const whiteVillageId = [ + '/village', + '/village/*' + // 以后直接在这里加新地址,支持 /xxx/*、/xxx/xxx 写法 +]; -function handleWhiteVillageid(url) { - const spliturl = url.split('?')[0]; - if (whiteVillageId.includes(spliturl)) { - return false; - } - return true; +/** + * 判断当前接口是否需要携带小区 ID + * @param {string} url - 请求地址 + * @returns {boolean} true=需要小区ID / false=不需要 + */ +export function needVillageId(url: string): boolean { + // 去掉 ? 后面的参数 + const path = url.split('?')[0]; + + // 遍历白名单,正则匹配 + return !whiteVillageId.some((pattern) => { + // 把 * 转成正则的 .* 通配 + const regPattern = pattern.replace(/\*/g, '[^\\/]*'); + const regex = new RegExp(`^${regPattern}$`); + return regex.test(path); + }); } // 请求拦截器 service.interceptors.request.use( @@ -60,11 +74,12 @@ service.interceptors.request.use( if (getToken() && !isToken) { config.headers['Authorization'] = 'Bearer ' + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改 } + console.log(needVillageId(config.url), config.url); // get请求映射params参数 const villageid = localStorage.getItem('villageid'); if (config.method === 'get' && config.params) { let url = ''; - if (villageid != 'null' && !Number.isNaN(Number(villageid)) && handleWhiteVillageid(config.url)) { + if (villageid != 'null' && !Number.isNaN(Number(villageid)) && needVillageId(config.url)) { url = config.url + '?' + @@ -82,7 +97,7 @@ service.interceptors.request.use( if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { let obj = null; - if (villageid != 'null' && !Number.isNaN(Number(villageid)) && handleWhiteVillageid(config.url)) { + if (villageid != 'null' && !Number.isNaN(Number(villageid)) && needVillageId(config.url)) { obj = { ...config.data, villageId: Number(villageid) diff --git a/src/views/community/AddCommunity.vue b/src/views/community/AddCommunity.vue index 2b64c4c..16d741c 100644 --- a/src/views/community/AddCommunity.vue +++ b/src/views/community/AddCommunity.vue @@ -301,7 +301,7 @@ const submitForm = () => { newFiles.forEach((file) => formdata.append('files', file)); uploadVillageImageAPI(formdata).then((res) => { - const uploadedUrls = res.data.map((x) => x.url).filter(Boolean); + const uploadedUrls = res.data.success.map((x) => x.url).filter(Boolean); // 4) 最终图片 = 已有图片 + 新上传图片(避免覆盖) form.value.villageImageUrl = [...existingUrls, ...uploadedUrls].join(','); submitFormInfo(); @@ -358,13 +358,13 @@ const cancelForm = () => { + diff --git a/src/views/system/inspection/Point/index.vue b/src/views/system/inspection/Point/index.vue index 4d22c8a..65ef518 100644 --- a/src/views/system/inspection/Point/index.vue +++ b/src/views/system/inspection/Point/index.vue @@ -1,10 +1,10 @@