diff --git a/.env.development b/.env.development index 1b230d8..7230ff9 100644 --- a/.env.development +++ b/.env.development @@ -9,9 +9,9 @@ VITE_APP_ENV='development' # 开发环境 VITE_APP_BASE_API='/dev-api' # # 开发环境 接口代理地址 -VITE_APP_PROXY_API='http://192.168.1.222:8080' +#VITE_APP_PROXY_API='http://192.168.1.222:8080' # 开发环境 接口代理地址 -#VITE_APP_PROXY_API='http://192.168.1.6:8080' +VITE_APP_PROXY_API='http://192.168.1.6:8080' # 图片基础地址 VITE_IMG_URL='http://192.168.1.222:8080' diff --git a/src/api/system/Inspection/index.ts b/src/api/system/Inspection/index.ts index 0b3de09..f0fab18 100644 --- a/src/api/system/Inspection/index.ts +++ b/src/api/system/Inspection/index.ts @@ -80,3 +80,49 @@ export const list_statapi = (query?: { taskTimeBegin: string; taskTimeEnd: strin params: query }); }; + +export type exportPageApiQuery = { + /** + * 数据类型:1-日报 / 2-周报 / 3-月报 + */ + dataType?: string; + /** + * 页码 + */ + pageNum: number; + /** + * 每页条数 + */ + pageSize: number; + /** + * 查询开始日期 + */ + queryDateBegin?: string; + /** + * 查询结束日期 + */ + queryDateEnd?: string; + /** + * 日期 + */ + statDate?: string; +}; + +type exportAllApiQuery = Omit; +/** 导出当前页 数据api */ +export const exportPageApi = (data: exportPageApiQuery): AxiosPromise => { + return request({ + url: '/inspection/data/export/page', + method: 'POST', + data + }); +}; + +/** 导出 所有 数据api */ +export const exportAllApi = (data: exportAllApiQuery): AxiosPromise => { + return request({ + url: '/inspection/data/export', + method: 'POST', + data + }); +}; diff --git a/src/api/system/InspectionPlan/type.ts b/src/api/system/InspectionPlan/type.ts index 47cbfcd..6eb4b9d 100644 --- a/src/api/system/InspectionPlan/type.ts +++ b/src/api/system/InspectionPlan/type.ts @@ -3,17 +3,12 @@ export interface PlanVO { * 主键ID */ id: string | number; - + inspectorIds: string; /** * 巡检计划名称 */ planName: string; - /** - * 巡检人员ID,多个用逗号分隔 - */ - inspectorIds: string; - /** * 执行周期,如:开始日期-结束日期 */ @@ -33,6 +28,11 @@ export interface PlanVO { * 巡检设置:0-必须拍照,1-可以跳检 */ inspectSetting: number; + inspectSettingDict: { + dictLabel: string; + dictValue: string; + listClass: string; + }; /** * 计划路线,多个用逗号分隔 @@ -53,7 +53,11 @@ export interface PlanVO { * 执行周期具体日期 */ executeDay: string; - + executeDayList: { + dictLabel: string; + dictValue: string; + listClass: string; + }[]; /** 巡检人员信息 */ inspectorList: { 'userId': string; diff --git a/src/api/system/SdbBill/index.ts b/src/api/system/SdbBill/index.ts index 4e06267..3132d7e 100644 --- a/src/api/system/SdbBill/index.ts +++ b/src/api/system/SdbBill/index.ts @@ -120,3 +120,13 @@ export const queryResidentList_Cars = (query: { pageNum: number; pageSize: numbe params: query }); }; +/** + * 生成账单 + */ +export const manualGenerateApi = (data: { billId: string; chargePeriod: string; yearMonths?: string[]; year?: string[] }) => { + return request({ + url: '/bill/manualGenerate', + method: 'POST', + data + }); +}; diff --git a/src/api/system/SdbBill/type.ts b/src/api/system/SdbBill/type.ts index 4537fc7..a5f70b3 100644 --- a/src/api/system/SdbBill/type.ts +++ b/src/api/system/SdbBill/type.ts @@ -3,6 +3,7 @@ export interface BillVO { * 账单管理表id */ id: string; + billName:string; /** * 账单编号 @@ -106,7 +107,7 @@ export interface BillForm extends BaseEntity { /** * 创建时间 */ - cerateTime?: string; + createTime?: string; } export interface BillQuery extends PageQuery { diff --git a/src/api/system/equipment/archive/type.ts b/src/api/system/equipment/archive/type.ts index 7afb7f6..edc76af 100644 --- a/src/api/system/equipment/archive/type.ts +++ b/src/api/system/equipment/archive/type.ts @@ -19,6 +19,7 @@ export interface DeviceVO { * 设备编号 */ deviceCode: string; + shelfLife:string; /** * 设备型号 diff --git a/src/api/system/resident/type.ts b/src/api/system/resident/type.ts index 99fb471..a74ecaa 100644 --- a/src/api/system/resident/type.ts +++ b/src/api/system/resident/type.ts @@ -80,7 +80,7 @@ export interface ResidentForm extends BaseEntity { * 主键 住户管理id */ userId?: string; - unitNoId: string; + unitNoId?: string; /** * 住户编号 diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss index 92439b4..6e242c0 100644 --- a/src/assets/styles/index.scss +++ b/src/assets/styles/index.scss @@ -260,30 +260,3 @@ aside { border-radius: 5px; } -.bgColor { - width: 850px; - height: 850px; - background: #fdf1ee; - filter: blur(200px); - display: block; - position: absolute; - top: 0; - right: 0; - transform: translateY(-50%) translateX(0%); - pointer-events: none; - z-index: 1; - border-radius: 50%; - - @media (max-width: 1540px) { - width: 800px; - height: 400px; - } - @media (max-width: 1280px) { - width: 600px; - height: 300px; - } - @media (max-width: 1030px) { - width: 400px; - height: 200px; - } -} diff --git a/src/components/Map/GD.vue b/src/components/Map/GD.vue index c7f3b5b..4193fdf 100644 --- a/src/components/Map/GD.vue +++ b/src/components/Map/GD.vue @@ -134,6 +134,31 @@ function clearLocation() { markers.value = []; } +let lastFitTime = 0; +let fitTimer: ReturnType | null = null; +const FIT_THROTTLE_MS = 100; // 节流间隔(ms) +// === 新增函数 === +function throttledFitView() { + const now = Date.now(); + if (now - lastFitTime >= FIT_THROTTLE_MS) { + // 距离上次调用已超过阈值,立即执行 + if (fitTimer) { + clearTimeout(fitTimer); + fitTimer = null; + } + fitMapView(Array.from(AddMarkered.values())); + lastFitTime = now; + } else if (!fitTimer) { + // 未超过阈值,延迟到阈值时再执行 + fitTimer = setTimeout(() => { + fitMapView(Array.from(AddMarkered.values())); + lastFitTime = Date.now(); + fitTimer = null; + }, FIT_THROTTLE_MS); + } + // 如果已经有定时器在等,不重复创建 +} + // ===================== 多点标记(可增删) ===================== function addMarker_more(angular: number[], pointName: string, pointId: string) { if (!isMapAvailable()) { @@ -145,7 +170,8 @@ function addMarker_more(angular: number[], pointName: string, pointId: string) { map.value.remove(AddMarkered.get(pointId)); AddMarkered.delete(pointId); // 删除后重新适配视野 - fitMapView(Array.from(AddMarkered.values())); + // fitMapView(Array.from(AddMarkered.values())); + throttledFitView(); return; } @@ -161,7 +187,8 @@ function addMarker_more(angular: number[], pointName: string, pointId: string) { }); AddMarkered.set(pointId, marker); markers.value.push(marker); - fitMapView(Array.from(AddMarkered.values())); + // fitMapView(Array.from(AddMarkered.values())); + throttledFitView(); return marker; } @@ -320,6 +347,10 @@ onUnmounted(() => { AMAP.value = null; map.value = null; mapReady.value = false; + if (fitTimer) { + clearTimeout(fitTimer); + fitTimer = null; + } }); diff --git a/src/components/Map/TDT.vue b/src/components/Map/TDT.vue index 6686ff5..0173c5c 100644 --- a/src/components/Map/TDT.vue +++ b/src/components/Map/TDT.vue @@ -92,6 +92,28 @@ function loadTDT(): Promise { document.body.appendChild(script); }); } +let lastFitTime = 0; +let fitTimer: ReturnType | null = null; +const FIT_THROTTLE_MS = 100; // 节流间隔(ms) +function throttledFitView(data: any[]) { + const now = Date.now(); + if (now - lastFitTime >= FIT_THROTTLE_MS) { + if (fitTimer) { + clearTimeout(fitTimer); + fitTimer = null; + } + const points = data.map((m: any) => m.getLngLat()); + fitMapView(points); + lastFitTime = now; + } else if (!fitTimer) { + fitTimer = setTimeout(() => { + const points = data.map((m: any) => m.getLngLat()); + fitMapView(points); + lastFitTime = Date.now(); + fitTimer = null; + }, FIT_THROTTLE_MS); + } +} /** 根据提供的 坐标点数组 设置地图视野,调整后的视野会保证包含提供的坐标点。 */ function fitMapView(overlays: any[] = []) { @@ -106,7 +128,7 @@ function isMapAvailable() { /** 点击事件 */ function bindMapClick() { if (!isMapAvailable()) return; - map.addEventListener('click', (e) => { + map.addEventListener('click', (e: { lnglat: { lng: any; lat: any } }) => { const { lng, lat } = e.lnglat; emits('clickPoint', [lng, lat]); }); @@ -125,7 +147,7 @@ function addMarker_only(LngLat: LngLat, pointName: string = '巡检点') { //向地图上添加标注 markers = [marker]; map.addOverLay(marker); - fitMapView(markers.map((item) => item.getLngLat())); + throttledFitView(markers); return marker; } /** 清空单点标记 */ @@ -151,6 +173,7 @@ function addMarker_more(LngLat: LngLat, pointName: string, pointId: string) { }); PointMap.set(pointId, marker); map.addOverLay(marker); + throttledFitView([marker]); } // !=================================================================== @@ -164,7 +187,7 @@ function initDrawTool() { handler.on('draw', lineDraw); } // 监听 绘画完成事件 -function lineDraw(data) { +function lineDraw(data: { currentPolyline: any }) { if (lines.length > 0) { lines.forEach((item) => { map.removeOverLay(item); @@ -225,6 +248,10 @@ function clearMapMarker() { } else { waitQueue.value.clear = true; } + if (fitTimer) { + clearTimeout(fitTimer); + fitTimer = null; + } } onMounted(async () => { @@ -271,6 +298,11 @@ onUnmounted(() => { // 销毁地图实例 map = null; + + if (fitTimer) { + clearTimeout(fitTimer); + fitTimer = null; + } }); diff --git a/src/components/Process/approvalRecord.vue b/src/components/Process/approvalRecord.vue index 23820f6..9e18dde 100644 --- a/src/components/Process/approvalRecord.vue +++ b/src/components/Process/approvalRecord.vue @@ -64,6 +64,7 @@ import { flowHisTaskList } from '@/api/workflow/instance'; import { propTypes } from '@/utils/propTypes'; import { listByIds } from '@/api/system/oss'; import FlowChart from '@/components/Process/flowChart.vue'; + const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { wf_task_status } = toRefs(proxy?.useDict('wf_task_status')); const props = defineProps({ @@ -101,9 +102,8 @@ const init = async (businessId: string | number) => { } }); }; -const getIds = async (ids: string | number) => { - const res = await listByIds(ids); - return res; +const getIds = async (ids: string) => { + return listByIds(ids); }; /** 下载按钮操作 */ diff --git a/src/components/StepTimeline/index.vue b/src/components/StepTimeline/index.vue new file mode 100644 index 0000000..520cde5 --- /dev/null +++ b/src/components/StepTimeline/index.vue @@ -0,0 +1,160 @@ + + + + + diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue index 8c9718e..49de0f9 100644 --- a/src/layout/components/Navbar.vue +++ b/src/layout/components/Navbar.vue @@ -161,7 +161,7 @@ watch( position: relative; background: #dfedff; background: transparent; - border-bottom: 1px solid #dfedff; + //border-bottom: 1px solid #dfedff; color: #c0c4cc; diff --git a/src/layout/index.vue b/src/layout/index.vue index 390681d..bb593d8 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -3,10 +3,11 @@
-
+ +
@@ -23,9 +24,12 @@ import { AppMain, Navbar, Settings } from './components'; import { useAppStore } from '@/store/modules/app'; import { useSettingsStore } from '@/store/modules/settings'; // import { NavTypeEnum } from '@/enums/NavTypeEnum'; +import { useBgColor } from '@/store/modules/bgColor'; import { initWebSocket } from '@/utils/websocket'; import { initSSE } from '@/utils/sse'; +const bgColorStore = useBgColor(); + // ========================================== // ✅ 第2步:缩放逻辑(从旧 script 移过来) // ========================================== @@ -120,7 +124,6 @@ const setLayout = () => { diff --git a/src/store/modules/bgColor.ts b/src/store/modules/bgColor.ts new file mode 100644 index 0000000..8d75a0a --- /dev/null +++ b/src/store/modules/bgColor.ts @@ -0,0 +1,13 @@ +import { defineStore } from 'pinia'; + +export const useBgColor = defineStore('backgroundColor', () => { + const isShow = ref(false); + const toggleBgColor = (bol: boolean = false) => { + isShow.value = bol; + console.log(isShow.value); + }; + return { + toggleBgColor, + isShow + }; +}); diff --git a/src/utils/money.ts b/src/utils/money.ts index 2193080..a3bb8cf 100644 --- a/src/utils/money.ts +++ b/src/utils/money.ts @@ -83,6 +83,14 @@ export function convertToChineseCapital(num: number | string): string { return result; } +/** + * 标准化为Big实例,空/undefined/null转0 + * @param num 数字 | 数字字符串 + */ +function toBig(num: string | number | undefined | null): Big { + if (num === null || num === undefined || num === '') return new Big(0); + return new Big(num); +} /** * 金额加法 * @param a 数值 @@ -93,56 +101,46 @@ export function moneyAdd(a: number | string = 0, b: number | string = 0): string return new Big(a).plus(b).toFixed(2); } -// 金额减法 -export function sub(a, b) { - let r1, r2; - try { - r1 = a.toString().split('.')[1].length; - } catch (e) { - r1 = 0; - } - try { - r2 = b.toString().split('.')[1].length; - } catch (e) { - r2 = 0; - } - const m = Math.pow(10, Math.max(r1, r2)); - return (a * m - b * m) / m; +/** + * 减法 a - b + */ +export function sub(a: string | number, b: string | number): number { + return Number(toBig(a).minus(toBig(b))); } -// 金额乘法 -export function mul(a, b) { - let m = 0; - const s1 = a.toString(), - s2 = b.toString(); - try { - m += s1.split('.')[1].length; - } catch (e) {} - try { - m += s2.split('.')[1].length; - } catch (e) {} - return (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) / Math.pow(10, m); +/** + * 乘法 a * b + */ +export function mul(a: string | number, b: string | number): number { + return Number(toBig(a).times(toBig(b))); } -// 金额除法 -export function div(a, b) { - let t1 = 0, - t2 = 0; - try { - t1 = a.toString().split('.')[1].length; - } catch (e) {} - try { - t2 = b.toString().split('.')[1].length; - } catch (e) {} - const x = Number(a.toString().replace('.', '')); - const y = Number(b.toString().replace('.', '')); - return (x / y) * Math.pow(10, t2 - t1); +/** + * 除法 a / b + * @throws 除数为0抛异常,业务try catch捕获 + */ +export function div(a: string | number, b: string | number): number { + const bigB = toBig(b); + if (bigB.eq(0)) throw new Error('除数不能为0'); + return Number(toBig(a).div(bigB)); } - // 保留2位小数(金额专用) export function toFixed2(val) { return Number(val).toFixed(2); } +// 判断 a 和 b 是否数值相等 +export function eq(a: string | number, b: string | number): boolean { + return toBig(a).eq(toBig(b)); +} +/** + * 金额保留指定位小数(四舍五入,默认2位) + * @param num 计算结果 + * @param digit 保留位数 + */ +export function toFixedMoney(num: string | number, digit = 2): number { + return Number(toBig(num).toFixed(digit, Big.roundHalfUp)); +} + /** * 智能金额格式化(带单位:元/万元/亿元) diff --git a/src/views/community/AddCommunity.vue b/src/views/community/AddCommunity.vue index 1df66c8..7227d3b 100644 --- a/src/views/community/AddCommunity.vue +++ b/src/views/community/AddCommunity.vue @@ -216,7 +216,7 @@ function headerToken() { Authorization: 'Bearer ' + useStore.token }; } - +const allowImgSuffix = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'heic']; /** 检测文件大小和格式 */ function handleBeforeUpload(file: UploadFile): Promise { return new Promise((resolve, reject) => { @@ -226,7 +226,7 @@ function handleBeforeUpload(file: UploadFile): Promise {