From 15981273b011581cc3010b220d082dd0f9a99ad4 Mon Sep 17 00:00:00 2001 From: lzq Date: Thu, 21 Aug 2025 19:16:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E7=85=A7=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/file-watcher.ts | 67 ++- plugin/iconfont-process.ts | 5 +- src/common/utils/http-util.ts | 2 +- src/common/utils/times.ts | 16 + src/dts/auto-imports.d.ts | 17 +- src/dts/components.d.ts | 2 + .../dispose-recode/DisposeRecodeDetail.vue | 13 +- src/pages/dispose-recode/dispose-recode.d.ts | 1 + src/pages/sys/menus/Menus.vue | 24 +- src/pages/sys/menus/menu-api.ts | 4 +- src/pages/sys/menus/menu-form/MenuForm.vue | 7 +- src/pages/sys/menus/menu.d.ts | 2 +- src/pages/tsp-photo/TspPhoto.vue | 391 ++++++++++++++++++ src/pages/tsp-photo/page.ts | 4 + src/pages/tsp-photo/tsp-photo-api.ts | 14 + src/pages/tsp-photo/tsp-photo.d.ts | 26 ++ src/pages/tsp/tsp.d.ts | 4 +- 17 files changed, 539 insertions(+), 60 deletions(-) create mode 100644 src/pages/tsp-photo/TspPhoto.vue create mode 100644 src/pages/tsp-photo/page.ts create mode 100644 src/pages/tsp-photo/tsp-photo-api.ts create mode 100644 src/pages/tsp-photo/tsp-photo.d.ts diff --git a/plugin/file-watcher.ts b/plugin/file-watcher.ts index dce4dc7..537d3dc 100644 --- a/plugin/file-watcher.ts +++ b/plugin/file-watcher.ts @@ -3,33 +3,72 @@ import fs from 'fs' import path from 'path' interface FileWatcherOptions { + // 目标可以是文件路径或文件夹路径 file: string; - fn: (content: string) => void; + // 回调函数,接收变化的文件路径、内容(如果有)和变化类型 + fn: (filePath: string, content?: string, eventType?: 'add' | 'change' | 'unlink') => void; + // 防抖延迟,默认300ms delay?: number; } export function fileWatcher(options: FileWatcherOptions): Plugin { const {file, fn, delay = 300} = options + const targetPath = path.resolve(file) let debounceTimer: NodeJS.Timeout | null = null + // 检查目标是否为文件夹 + const isDir = fs.existsSync(targetPath) && fs.statSync(targetPath).isDirectory() + console.log('正在监听文件:' + targetPath) return { name: 'file-watcher-plugin', - configureServer(server) { - server.watcher.add(path.resolve(file)) - server.watcher.on('change', (filePath: string) => { - if (filePath === path.resolve(file)) { - if (debounceTimer) clearTimeout(debounceTimer) - debounceTimer = setTimeout(() => { - try { - const content = fs.readFileSync(filePath, 'utf-8') - fn(content) - } catch (error) { - console.error('文件变化处理失败:', error) - } - }, delay) + configureServer(server) { + // 添加要监听的目标(文件或文件夹) + server.watcher.add(targetPath) + + // 处理文件/文件夹变化的通用函数 + const handleChange = (filePath: string, eventType: 'add' | 'change' | 'unlink') => { + if (isDir && !filePath.startsWith(targetPath)) { + return } + if (!isDir && filePath !== targetPath) { + return + } + // 防抖处理 + if (debounceTimer) { + clearTimeout(debounceTimer) + } + + debounceTimer = setTimeout(async () => { + try { + let content: string | undefined + if (!isDir) { + content = fs.readFileSync(filePath, 'utf-8') + } + fn(filePath, content, eventType) + } catch (error) { + console.error('处理文件变化时出错:', error) + } + }, delay) + } + + if (isDir) { + // 监听文件新增 + server.watcher.on('add', (filePath) => { + handleChange(filePath, 'add') + }) + + // 监听文件删除 + server.watcher.on('unlink', (filePath) => { + handleChange(filePath, 'unlink') + }) + } + + // 监听文件修改 + server.watcher.on('change', (filePath) => { + handleChange(filePath, 'change') }) + }, } } diff --git a/plugin/iconfont-process.ts b/plugin/iconfont-process.ts index 3baca55..57d4877 100644 --- a/plugin/iconfont-process.ts +++ b/plugin/iconfont-process.ts @@ -12,8 +12,9 @@ interface IconfontJson { } export default function iconfontProcess(outPath: string) { - return function (content: string) { - const json = JSON.parse(content) as IconfontJson + return function (filePath: string, content?: string, eventType?: 'add' | 'change' | 'unlink') { + console.log(filePath, content, eventType) + const json = JSON.parse(content!) as IconfontJson const names = json.glyphs.map(glyph => glyph.font_class) const dtsFile = outPath + '/iconfont.d.ts' console.log('正在生成文件:', dtsFile) diff --git a/src/common/utils/http-util.ts b/src/common/utils/http-util.ts index 926c366..a1f9d16 100644 --- a/src/common/utils/http-util.ts +++ b/src/common/utils/http-util.ts @@ -48,7 +48,7 @@ const paramsSerializer = (params: any) => { Toast.error(r?.message ?? '操作失败') } */ const errHandler = throttle(500, (r?: R) => { - Toast.error(r?.message ?? '操作失败') + Toast.error(r?.message ?? '服务器错误') }) /** * axios 实例 diff --git a/src/common/utils/times.ts b/src/common/utils/times.ts index c34b115..7fcb740 100644 --- a/src/common/utils/times.ts +++ b/src/common/utils/times.ts @@ -136,10 +136,26 @@ export function pretty(date: DateTime | Date | number | string) { return '现在' } +export function endOfMonth(date?: DateTime) { + if (date == null) { + return date = now() + } + return date.endOf('month') +} + +export function beginOfMonth(date?: DateTime) { + if (date == null) { + return date = now() + } + return date.startOf('month') +} + export default { now, parse, format, pretty, FMT, + endOfMonth, + beginOfMonth, } diff --git a/src/dts/auto-imports.d.ts b/src/dts/auto-imports.d.ts index 6b47d8e..a606bd4 100644 --- a/src/dts/auto-imports.d.ts +++ b/src/dts/auto-imports.d.ts @@ -82,21 +82,6 @@ declare global { // for type re-export declare global { // @ts-ignore - export type { - Component, - ComponentPublicInstance, - ComputedRef, - DirectiveBinding, - ExtractDefaultPropTypes, - ExtractPropTypes, - ExtractPublicPropTypes, - InjectionKey, - PropType, - Ref, - MaybeRef, - MaybeRefOrGetter, - VNode, - WritableComputedRef - } from 'vue' + export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' import('vue') } diff --git a/src/dts/components.d.ts b/src/dts/components.d.ts index 20fc2e8..c765d28 100644 --- a/src/dts/components.d.ts +++ b/src/dts/components.d.ts @@ -25,6 +25,7 @@ declare module 'vue' { IxFormItem: typeof import('@idux/components/form')['IxFormItem'] IxFormWrapper: typeof import('@idux/components/form')['IxFormWrapper'] IxIcon: typeof import('@idux/components/icon')['IxIcon'] + IxImage: typeof import('@idux/components/image')['IxImage'] IxInput: typeof import('@idux/components/input')['IxInput'] IxInputNumber: typeof import('@idux/components/input-number')['IxInputNumber'] IxLayoutSiderTrigger: typeof import('@idux/components/layout')['IxLayoutSiderTrigger'] @@ -44,6 +45,7 @@ declare module 'vue' { IxTable: typeof import('@idux/components/table')['IxTable'] IxTabs: typeof import('@idux/components/tabs')['IxTabs'] IxTag: typeof import('@idux/components/tag')['IxTag'] + IxTagGroup: typeof import('@idux/components/tag')['IxTagGroup'] IxTooltip: typeof import('@idux/components/tooltip')['IxTooltip'] IxTreeSelect: typeof import('@idux/components/tree-select')['IxTreeSelect'] IxUpload: typeof import('@idux/components/upload')['IxUpload'] diff --git a/src/pages/dispose-recode/DisposeRecodeDetail.vue b/src/pages/dispose-recode/DisposeRecodeDetail.vue index 459619f..fc69777 100644 --- a/src/pages/dispose-recode/DisposeRecodeDetail.vue +++ b/src/pages/dispose-recode/DisposeRecodeDetail.vue @@ -63,11 +63,18 @@ defineExpose({

出出场车头照出场前

出场车身照出场后

+
装车照片
+
+ +
+
+

装车照片

+
- + 确定 + + diff --git a/src/pages/dispose-recode/dispose-recode.d.ts b/src/pages/dispose-recode/dispose-recode.d.ts index bfa1ef0..cba011e 100644 --- a/src/pages/dispose-recode/dispose-recode.d.ts +++ b/src/pages/dispose-recode/dispose-recode.d.ts @@ -18,6 +18,7 @@ declare global { inBodyPhoto: string outFrontPhoto: string outBodyPhoto: string + tspPhotos?: string[] } interface SearchParam { diff --git a/src/pages/sys/menus/Menus.vue b/src/pages/sys/menus/Menus.vue index 9ee4c53..bac5c5c 100644 --- a/src/pages/sys/menus/Menus.vue +++ b/src/pages/sys/menus/Menus.vue @@ -27,12 +27,12 @@ - +

是否删除已选数据?

@@ -59,6 +59,7 @@ import MenuApi from '@/pages/sys/menus/menu-api.ts' import { TreeSelectNode } from '@idux/components/tree-select/src/types' import Toast from '@/components/toast' import { useMenuDetailStore } from '@/pages/sys/menus/menu-detail/menu-detail-store.ts' +import Iconfont from '@/components/iconfont/Iconfont.vue' const searchForm = useFormGroup({ title: [ '' ], @@ -67,11 +68,6 @@ const searchForm = useFormGroup({ const visibleDialog = ref(false) const tableSpin = ref(false) const selectedRowKeys = ref([]) -const pagination = reactive({ - current: 1, - size: 100, - total: 0, -}) const datasource = ref() const columns: TableColumn[] = [ @@ -96,6 +92,9 @@ const columns: TableColumn[] = [ { title: '图标', dataKey: 'icon', + customCell({value}: { value: string; record: MenuTypes.SysMenu; rowIndex: number }) { + return h(Iconfont, {name: value as IconfontTypes.name}) + } }, { title: '路径', @@ -180,12 +179,9 @@ function searchHandler() { function pageList() { tableSpin.value = true - MenuApi.pageList(searchForm.getValue(), {...pagination}) + MenuApi.list(searchForm.getValue()) .then(res => { - pagination.current = res.data.current - pagination.size = res.data.size - pagination.total = res.data.total - datasource.value = colls.toTree(res.data.records.map(it => { + datasource.value = colls.toTree(res.data.map(it => { return { key: it.id, ...it @@ -197,10 +193,6 @@ function pageList() { }) } -function pagingChangeHandler() { - pageList() -} - function del(...recode: { id: string }[]) { const toastId = Toast.loading('正在提交') MenuApi.del(recode.map(it => it.id)) diff --git a/src/pages/sys/menus/menu-api.ts b/src/pages/sys/menus/menu-api.ts index 4d1862c..b7d5286 100644 --- a/src/pages/sys/menus/menu-api.ts +++ b/src/pages/sys/menus/menu-api.ts @@ -13,8 +13,8 @@ export default { paging(data: MenuTypes.SearchForm & G.PageParam) { return get>('/sys_menu/page_list', data) }, - list(pid: string | null = null) { - return get('/sys_menu/list', {pid: pid}) + list(data?: MenuTypes.SearchForm | null) { + return get('/sys_menu/list', data) }, detail(id: string) { return get('/sys_menu/detail', {id}) diff --git a/src/pages/sys/menus/menu-form/MenuForm.vue b/src/pages/sys/menus/menu-form/MenuForm.vue index 0c12084..066ce2c 100644 --- a/src/pages/sys/menus/menu-form/MenuForm.vue +++ b/src/pages/sys/menus/menu-form/MenuForm.vue @@ -95,6 +95,7 @@ import { TableColumnSelectable } from '@idux/components/table' import { TablePagination } from '@idux/components/table/src/types' +import Iconfont from '@/components/iconfont/Iconfont.vue' interface IconData { name: string @@ -120,9 +121,9 @@ const columns: TableColumn[] = [ { title: '图标', dataKey: 'name', - /* customCell: ({record}: { record: IconData }) => { - return h(Iconfont, {name: record.name}) - } */ + customCell: ({record}: { record: IconData }) => { + return h(Iconfont, {name: record.name as IconfontTypes.name}) + } }, { title: '名称', diff --git a/src/pages/sys/menus/menu.d.ts b/src/pages/sys/menus/menu.d.ts index 7ebe7d8..3b7e8a0 100644 --- a/src/pages/sys/menus/menu.d.ts +++ b/src/pages/sys/menus/menu.d.ts @@ -27,7 +27,7 @@ declare global { children?: SysMenu[] } - type SearchForm = Partial> + type SearchForm = Partial> type MenuForm = Pick type AddForm = Pick type ModifyForm = Pick diff --git a/src/pages/tsp-photo/TspPhoto.vue b/src/pages/tsp-photo/TspPhoto.vue new file mode 100644 index 0000000..1ebea3e --- /dev/null +++ b/src/pages/tsp-photo/TspPhoto.vue @@ -0,0 +1,391 @@ + + + + + diff --git a/src/pages/tsp-photo/page.ts b/src/pages/tsp-photo/page.ts new file mode 100644 index 0000000..b588441 --- /dev/null +++ b/src/pages/tsp-photo/page.ts @@ -0,0 +1,4 @@ +export default { + title: '临时收纳点照片', + component: () => import('@/pages/tsp-photo/TspPhoto.vue'), +} as RouterTypes.PageConfig diff --git a/src/pages/tsp-photo/tsp-photo-api.ts b/src/pages/tsp-photo/tsp-photo-api.ts new file mode 100644 index 0000000..bfd5d0f --- /dev/null +++ b/src/pages/tsp-photo/tsp-photo-api.ts @@ -0,0 +1,14 @@ +import { get, } from '@/common/utils/http-util.ts' + +export default { + save(data?: TspPhotoTypes.TspPhotoSaveParam) { + return get('/tsp_photo/save', data) + }, + listPhoto(data?: TspPhotoTypes.TspPhotoSearchParam) { + return get('/tsp_photo/list_photo', data) + }, + obtainStatus(data?: TspPhotoTypes.TspPhotoSearchParam) { + return get('/tsp_photo/obtain_status', data) + }, + +} diff --git a/src/pages/tsp-photo/tsp-photo.d.ts b/src/pages/tsp-photo/tsp-photo.d.ts new file mode 100644 index 0000000..9e0b994 --- /dev/null +++ b/src/pages/tsp-photo/tsp-photo.d.ts @@ -0,0 +1,26 @@ +export {} +declare global { + namespace TspPhotoTypes { + interface TspPhotoSearchParam { + tspId?: string + pointName?: string + month?: Date + day?: number + uploadDate?: string + } + + interface TspPhotoSearchResult { + photos?: string[] + } + + interface ObtainStatusResult { + [key: string]: number | undefined | null + } + + interface TspPhotoSaveParam { + tspId?: string + uploadDate?: string + photos?: string[] + } + } +} diff --git a/src/pages/tsp/tsp.d.ts b/src/pages/tsp/tsp.d.ts index e68a10b..1979fd2 100644 --- a/src/pages/tsp/tsp.d.ts +++ b/src/pages/tsp/tsp.d.ts @@ -21,8 +21,8 @@ declare global { } interface SearchParam { - pointName: string - status: 'ZhengChang' | 'FenZhengChang' | '' + pointName?: string + status?: 'ZhengChang' | 'FenZhengChang' | '' } interface StatisticsResult {