diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..cca4566 Binary files /dev/null and b/.DS_Store differ diff --git a/policeManagement/.env.development b/policeManagement/.env.development index 9c1f396..853dff4 100644 --- a/policeManagement/.env.development +++ b/policeManagement/.env.development @@ -6,7 +6,7 @@ VITE_DROP_CONSOLE=false # axios VITE_APP_BASE_API=/api # VITE_APP_PROXY_URL=http://localhost:8765 -VITE_APP_PROXY_URL=http://172.10.10.151:8765 +VITE_APP_PROXY_URL=http://172.10.10.93:8765 # rsa 公钥 diff --git a/policeManagement/components.d.ts b/policeManagement/components.d.ts index 5334f5d..6c45d91 100644 --- a/policeManagement/components.d.ts +++ b/policeManagement/components.d.ts @@ -26,16 +26,30 @@ declare module 'vue' { ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider'] AMenu: typeof import('ant-design-vue/es')['Menu'] AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] + AModal: typeof import('ant-design-vue/es')['Modal'] + APopconfirm: typeof import('ant-design-vue/es')['Popconfirm'] + ARadio: typeof import('ant-design-vue/es')['Radio'] + ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup'] + ASelect: typeof import('ant-design-vue/es')['Select'] + ASelectOption: typeof import('ant-design-vue/es')['SelectOption'] + ASpace: typeof import('ant-design-vue/es')['Space'] ASpin: typeof import('ant-design-vue/es')['Spin'] ASubMenu: typeof import('ant-design-vue/es')['SubMenu'] + ATable: typeof import('ant-design-vue/es')['Table'] ATabPane: typeof import('ant-design-vue/es')['TabPane'] ATabs: typeof import('ant-design-vue/es')['Tabs'] + ATag: typeof import('ant-design-vue/es')['Tag'] + ATooltip: typeof import('ant-design-vue/es')['Tooltip'] + FormProMax: typeof import('./src/components/form/FormProMax.vue')['default'] HelloWorld: typeof import('./src/components/HelloWorld.vue')['default'] + IconFont: typeof import('./src/components/iconfont/IconFont.vue')['default'] Layout: typeof import('./src/components/layout/layout.vue')['default'] LayoutHeader: typeof import('./src/components/layout/header/LayoutHeader.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] + SingleImageFileUpload: typeof import('./src/components/upload/SingleImageFileUpload.vue')['default'] Sliber: typeof import('./src/components/layout/sliber/sliber.vue')['default'] + TableProMax: typeof import('./src/components/table/TableProMax.vue')['default'] TelephoneLogin: typeof import('./src/components/login/TelephoneLogin.vue')['default'] } } diff --git a/policeManagement/package-lock.json b/policeManagement/package-lock.json index 391e80e..b74197e 100644 --- a/policeManagement/package-lock.json +++ b/policeManagement/package-lock.json @@ -734,6 +734,21 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "@types/lodash": { + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", + "dev": true + }, + "@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, "@types/node": { "version": "22.5.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz", @@ -743,6 +758,11 @@ "undici-types": "~6.19.2" } }, + "@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" + }, "@vitejs/plugin-vue": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.3.tgz", @@ -2332,6 +2352,11 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, "vite": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz", @@ -2362,6 +2387,11 @@ "@vue/shared": "3.4.38" } }, + "vue-component-type-helpers": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.1.6.tgz", + "integrity": "sha512-ng11B8B/ZADUMMOsRbqv0arc442q7lifSubD0v8oDXIFoMg/mXwAPUunrroIDkY+mcD0dHKccdaznSVp8EoX3w==" + }, "vue-demi": { "version": "0.14.10", "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", @@ -2402,6 +2432,15 @@ "is-plain-object": "3.0.1" } }, + "vue-uuid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vue-uuid/-/vue-uuid-3.0.0.tgz", + "integrity": "sha512-+5DP857xVmTHYd00dMC1c1gVg/nxG6+K4Lepojv9ckHt8w0fDpGc5gQCCttS9D+AkSkTJgb0cekidKjTWu5OQQ==", + "requires": { + "@types/uuid": "^8.3.4", + "uuid": "^8.3.2" + } + }, "warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", diff --git a/policeManagement/package.json b/policeManagement/package.json index 4e5611a..d0630cf 100644 --- a/policeManagement/package.json +++ b/policeManagement/package.json @@ -13,13 +13,17 @@ "ant-design-vue": "^4.2.3", "axios": "^1.7.5", "jsencrypt": "^3.3.2", + "lodash-es": "^4.17.21", "pinia": "^2.2.2", "pinia-plugin-persistedstate": "^3.2.0", + "vue-component-type-helpers": "^2.1.2", "sass": "^1.77.8", "vue": "^3.4.37", - "vue-router": "4" + "vue-router": "4", + "vue-uuid": "^3.0.0" }, "devDependencies": { + "@types/lodash-es": "^4.17.12", "@types/node": "^22.5.1", "@vitejs/plugin-vue": "^5.1.2", "@vitejs/plugin-vue-jsx": "^4.0.1", diff --git a/policeManagement/src/components/form/FormProMax.vue b/policeManagement/src/components/form/FormProMax.vue new file mode 100644 index 0000000..29522b8 --- /dev/null +++ b/policeManagement/src/components/form/FormProMax.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/policeManagement/src/components/iconfont/IconFont.vue b/policeManagement/src/components/iconfont/IconFont.vue new file mode 100644 index 0000000..fc208f1 --- /dev/null +++ b/policeManagement/src/components/iconfont/IconFont.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/policeManagement/src/components/layout/layout.vue b/policeManagement/src/components/layout/layout.vue index f139d4e..d729689 100644 --- a/policeManagement/src/components/layout/layout.vue +++ b/policeManagement/src/components/layout/layout.vue @@ -23,9 +23,9 @@ --> - + + + diff --git a/policeManagement/src/components/tsx/ModalPro.tsx b/policeManagement/src/components/tsx/ModalPro.tsx new file mode 100644 index 0000000..7b82c7d --- /dev/null +++ b/policeManagement/src/components/tsx/ModalPro.tsx @@ -0,0 +1,49 @@ +import { h, Ref, ref, VNode } from 'vue' +import { Modal } from 'ant-design-vue' +import { FormExpose } from 'ant-design-vue/es/form/Form' +import { ExclamationCircleOutlined } from '@ant-design/icons-vue' +import FormProMax from '@/components/form/FormProMax.vue' +import { FormProMaxItemOptions, FormProMaxProps } from '@/types/components/form' + +export function submitSimpleFormModal(props: { + title: string + formParams?: T & Record + formProps?: Omit, 'formItemOptions'> + formOptions: FormProMaxItemOptions + submit: (params: T) => Promise + cancel?: (params: T) => Promise + icon?: () => VNode + maskClosable?: boolean + width?: string | number +}) { + if (!props.formParams) props.formParams = {} as T + if (!props.width) props.width = 520 + + const formRef = ref(null) + const _formParams = ref({ + ...props.formParams, + }) as Ref + + Modal.confirm({ + icon: props.icon ? props.icon() : ' ', + width: props.width, + maskClosable: props.maskClosable ?? true, + title: props.title, + content: () => , + onOk: async () => { + await formRef.value?.validate() + await props.submit(_formParams.value) + }, + onCancel: async () => props.cancel && (await props.cancel(_formParams.value)), + }) +} + +export const deleteDataModal = (name: string, submit: () => Promise, cancel?: () => Promise) => { + Modal.confirm({ + title: `确认删除【${name}】吗?`, + icon: h(ExclamationCircleOutlined), + content: h('div', { style: 'color:red;' }, '此操作将删除数据,且无法找回!'), + onOk: async () => await submit(), + onCancel: async () => cancel && (await cancel()), + }) +} diff --git a/policeManagement/src/components/upload/SingleImageFileUpload.vue b/policeManagement/src/components/upload/SingleImageFileUpload.vue new file mode 100644 index 0000000..da2f465 --- /dev/null +++ b/policeManagement/src/components/upload/SingleImageFileUpload.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/policeManagement/src/config/dict.ts b/policeManagement/src/config/dict.ts new file mode 100644 index 0000000..e27fe55 --- /dev/null +++ b/policeManagement/src/config/dict.ts @@ -0,0 +1,17 @@ +import api from "@/axios"; + +type DictType = + 'CheckStatus' + | 'DeleteFlag' + | 'IsEnable' + | 'IsOrNot' + | 'Sex' + +export const initEnums = () => { + api.get[]>>('/common/enums').then(resp => { + sessionStorage.setItem('dictMap', JSON.stringify(resp.data)) + }) +} + +export const dictSelectNodes = (enumType: DictType): SelectNodeVo[] => JSON.parse(sessionStorage.getItem('dictMap') as string)?.[enumType] || [] + diff --git a/policeManagement/src/global.d.ts b/policeManagement/src/global.d.ts index 98e6ca2..5c53b42 100644 --- a/policeManagement/src/global.d.ts +++ b/policeManagement/src/global.d.ts @@ -1,4 +1,8 @@ declare const __APP_ENV: ImportMetaEnv; +declare module 'lodash-es' { + import { includes, isEmpty, ceil, divide } from 'lodash'; + export { includes, isEmpty, ceil, divide }; +} /** * 全局返回 @@ -8,6 +12,34 @@ interface JsonResult { message: string; data?: T; } +class TreeNodeVo> { + value: T; + parentValue: T; + label: string; + orderIndex?: number; + children?: TreeNodeVo[] + extData?: E; +} +declare interface Grid { + //栅格占据的列数 + span?: number; + //栅格左侧的间隔格数 + offset?: number; + //栅格向右移动格数 + push?: number; + //栅格向左移动格数 + pull?: number; + //<768px 响应式栅格数或者栅格属性对象 + xs?: number; + //≥768px 响应式栅格数或者栅格属性对象 + sm?: number; + //≥992px 响应式栅格数或者栅格属性对象 + md?: number; + //≥1200px 响应式栅格数或者栅格属性对象 + lg?: number; + //≥1920px 响应式栅格数或者栅格属性对象 + xl?: number; +} interface dataStatus { account: string; password: string; @@ -19,4 +51,31 @@ interface dataStatus { label: string; value: number; }; +} +class SelectNodeVo> { + value: T; + label: string; + options?: SelectNodeVo[] + orderIndex?: number; + disabled?: boolean; + extData?: E +} + +interface ExtData { + color?: string; +} + +interface Option { + label: string; + value: string | number; + extData?: ExtData | null; +} + +interface OptionsResponse { + IsEnable: Option[]; + IsOrNot: Option[]; + Sex: Option[]; + CheckStatus: Option[]; + ServiceProjectType: Option[]; + DeleteFlag: Option[]; } \ No newline at end of file diff --git a/policeManagement/src/hooks/useTableProMax.ts b/policeManagement/src/hooks/useTableProMax.ts new file mode 100644 index 0000000..e122e5d --- /dev/null +++ b/policeManagement/src/hooks/useTableProMax.ts @@ -0,0 +1,134 @@ +import { ref, Ref } from "vue"; +import { Page, PageParams, PageResult } from "@/types/hooks/useTableProMax.ts"; +import { FormInstance } from "ant-design-vue"; +import { BaseTableRowRecord, RequestApiType } from "@/types/components/table"; + +/** + * + * @param api 查询方法 + * @param searchFormRef 表单校验 + * @param searchParams 查询的参数 + * @param isPageTable 是否分页 + * @param dataCallBack 查询到数据后的回调 + * @param requestError 查询出错回调 + */ +export default | PageParams

>(api: RequestApiType, + searchFormRef: Ref, + searchParams: Ref

, + isPageTable: boolean = true, + dataCallBack?: (data: T[]) => T[], + requestError?: (errorMsg: any) => void) => { + + const dataSource = ref([]) as Ref; + const loading = ref(false); + const pageParams = ref({ + current: 1, + size: 10, + total: 0 + }) + + /** + * 获取表格数据 + */ + const requestGetTableData = async (isInit: boolean = false) => { + try { + //校验表单 + !isInit && await searchFormRef.value?.validate(); + //组装参数 + let totalSearchParams; + if (isPageTable) { + totalSearchParams = { + params: searchParams.value, + page: { + current: pageParams.value.current, + size: pageParams.value.size + } + } as PageParams

; + } else { + totalSearchParams = searchParams.value + } + + loading.value = true; + + const resp = await api(totalSearchParams as P); + let tableData: T[]; + + if (isPageTable) { + const { current, records, size, total } = resp.data as PageResult; + isPageTable && updatePageParams({ + current: parseInt(current), + size: parseInt(size), + total: parseInt(total) + }); + tableData = records; + } else { + tableData = resp.data as T[] + } + dataCallBack && (tableData = dataCallBack(tableData)); + dataSource.value = tableData; + } catch (error) { + requestError && requestError(error); + } finally { + loading.value = false; + } + } + + /** + * 更新分页信息 + */ + const updatePageParams = (ps: Page) => Object.assign(pageParams.value, ps) + + /** + * 重置表格状态 包括 dataSource loading pageParams + */ + const resetState = () => { + dataSource.value = []; + loading.value = false; + pageParams.value = { + current: 1, + size: 10, + total: 0 + } + } + + /** + * 表格数据查询 与 requestGetTableData 区别是会将页面重置为1 + * 如果只做刷新数据请用 requestGetTableData + */ + const search = async () => { + pageParams.value.current = 1; + await requestGetTableData(); + }; + + /** + * @description 每页条数改变 + * @param _ + * @param {Number} size 页显示数量 + */ + const handleSizeChange = async (_: number, size: number) => { + pageParams.value.current = 1; + pageParams.value.size = size; + await requestGetTableData(); + }; + + /** + * @description 当前页改变 + * @param current 当前页 + */ + const handleCurrentChange = async (current: number) => { + pageParams.value.current = current; + await requestGetTableData(); + }; + + return { + dataSource, + loading, + pageParams, + requestGetTableData, + search, + handleSizeChange, + handleCurrentChange, + resetState + }; + +} diff --git a/policeManagement/src/main.ts b/policeManagement/src/main.ts index 8f8746d..77bdb85 100644 --- a/policeManagement/src/main.ts +++ b/policeManagement/src/main.ts @@ -12,7 +12,9 @@ import router from "@/router"; import pinia from "@/stores"; const vueApp = createApp(App); +import {initEnums} from "@/config/dict.ts"; +initEnums() vueApp .use(router) .use(pinia) diff --git a/policeManagement/src/router/staticRouters.ts b/policeManagement/src/router/staticRouters.ts index 0d8e59f..b891f2d 100644 --- a/policeManagement/src/router/staticRouters.ts +++ b/policeManagement/src/router/staticRouters.ts @@ -1,5 +1,6 @@ +// name 唯一 import { RouteRecordRaw } from "vue-router"; export const Layout = () => import("@/components/layout/layout.vue"); export const staticRouter: RouteRecordRaw[] = @@ -28,6 +29,38 @@ export const staticRouter: RouteRecordRaw[] = ] }, + { + + path: '/user', + name: 'user', + meta: { + title: '用户管理', + keepalive: true + }, + component: Layout, + children: [ + { + path: 'index', + name: 'user-index', + meta: { + title: '后台用户', + keepalive: true + }, + component: () => import('@/views/user/user.vue') + }, + { + path: 'weapp', + name: 'weapp', + meta: { + + title: '小程序用户', + keepalive: true + }, + component: () => import('@/views/user/user-weapp.vue') + }, + ] + }, + { path: '/query-', diff --git a/policeManagement/src/types/components/form/index.ts b/policeManagement/src/types/components/form/index.ts new file mode 100644 index 0000000..32da75d --- /dev/null +++ b/policeManagement/src/types/components/form/index.ts @@ -0,0 +1,73 @@ +import { + FormProps, + RangePicker, + Input, + InputNumber, + Textarea, + InputPassword, + RadioGroup, + Select, + TreeSelect, + Cascader, + CheckboxGroup, + DatePicker, + FormItem, TimeRangePicker, TimePicker, +} from "ant-design-vue"; +import { Ref, UnwrapRef, VNode } from "vue"; +import { ComponentProps } from "vue-component-type-helpers"; + +type FormProMaxItemType = + | 'custom' + | 'input' + | 'inputPassword' + | 'inputNumber' + | 'inputTextArea' + | 'radioGroup' + | 'select' + | 'selectIcon' + | 'selectUser' + | 'treeSelect' + | 'cascader' + | 'checkboxGroup' + | 'datePicker' + | 'rangePicker' + | 'timeRangePicker' + | 'timePicker'; + +interface FormProMaxItemCommonProps extends ComponentProps { + label?: string, + grid?: Grid, + placeholder?: string, + remarkRender?: () => VNode | string, + customRender?: () => VNode; + options?: (SelectNodeVo | TreeNodeVo)[] | Ref<(SelectNodeVo | TreeNodeVo)[]> +} + +export interface FormProMaxItemProps extends FormProMaxItemCommonProps { + type: T + componentsProps?: C +} + +export type FormProMaxItemOptions = { + [key in keyof T | string]: + FormProMaxItemProps<'custom', ComponentProps>> + | FormProMaxItemProps<'input', ComponentProps> + | FormProMaxItemProps<'inputPassword', ComponentProps> + | FormProMaxItemProps<'inputNumber', ComponentProps> + | FormProMaxItemProps<'inputTextArea', ComponentProps> + | FormProMaxItemProps<'radioGroup', ComponentProps> + | FormProMaxItemProps<'select', ComponentProps> + | FormProMaxItemProps<'treeSelect', ComponentProps> + | FormProMaxItemProps<'cascader', ComponentProps> + | FormProMaxItemProps<'checkboxGroup', ComponentProps> + | FormProMaxItemProps<'datePicker', ComponentProps> + | FormProMaxItemProps<'rangePicker', ComponentProps> + | FormProMaxItemProps<'timeRangePicker', ComponentProps> + | FormProMaxItemProps<'timePicker', ComponentProps> +} + +export interface FormProMaxProps extends FormProps { + grid?: Grid + gutter?: number; + formItemOptions?: FormProMaxItemOptions | Ref> | UnwrapRef> +} diff --git a/policeManagement/src/types/components/iconfont/IconFont.ts b/policeManagement/src/types/components/iconfont/IconFont.ts new file mode 100644 index 0000000..9b3dd6e --- /dev/null +++ b/policeManagement/src/types/components/iconfont/IconFont.ts @@ -0,0 +1,5 @@ +export interface IconFontProps { + fontClass?: string, + size?: number, + type?: 'class' | 'svg' +} \ No newline at end of file diff --git a/policeManagement/src/types/components/table/index.ts b/policeManagement/src/types/components/table/index.ts new file mode 100644 index 0000000..cffa49f --- /dev/null +++ b/policeManagement/src/types/components/table/index.ts @@ -0,0 +1,55 @@ +import { PaginationProps, Table, TableProps } from "ant-design-vue"; +import { TableRowSelection } from "ant-design-vue/lib/table/interface"; +import { Ref, UnwrapRef } from "vue"; +import { ColumnType } from "ant-design-vue/es/table/interface"; +import { ComponentSlots } from "vue-component-type-helpers"; +import { FormProMaxItemOptions, FormProMaxProps } from "@/types/components/form"; +import { PageParams, PageResult } from "@/types/hooks/useTableProMax.ts"; + + +export type TableProMaxColumnType = Omit, 'dataIndex'> & { + dataIndex: keyof T | string | string[] | number | number[]; +} + + +export type TableProMaxProps< + T extends BaseTableRowRecord = {}, + P extends { [key: string]: any } = {} +> = Partial, "dataSource" | 'pagination' | 'loading' | 'rowKey' | 'columns'>> & { + rowKey?: keyof T, + columns?: TableProMaxColumnType[], + searchFormProps?: Omit, 'formItems'> + searchFormOptions?: FormProMaxItemOptions

| Ref> | UnwrapRef>, + defaultSearchParams?: { [key in keyof P | string]: any }; + requestAuto?: boolean, + requestApi: RequestApiType, + requestError?: (errorMsg: any) => void, + dataCallback?: (data: T[]) => T[], + isPagination?: boolean, + paginationProps?: TableProMaxPaginationProps, + isSelection?: boolean, + selectionProps?: TableProMaxRowSelect, + isPrinter?: boolean, + needIndex?: boolean +} + +export type TableProMaxSlots = ComponentSlots & { + tableHeader: (scope: { selectKeys: string[], selectRows: T[] }) => any, + tableHeaderRight: (scope: { selectKeys: string[], selectRows: T[] }) => any, +} + +export type RequestApiType = (params: P | PageParams

) => Promise>>; + +export type TableProMaxPaginationProps = Partial>; + +export type TableProMaxRowSelect = TableRowSelection; + +export interface BaseTableRowRecord { + snowFlakeId?: string; + createUserName?: string; + createTime?: Date | string; + updateUserName?: string; + updateTime?: Date | string +} diff --git a/policeManagement/src/types/config/index.ts b/policeManagement/src/types/config/index.ts new file mode 100644 index 0000000..a2dab60 --- /dev/null +++ b/policeManagement/src/types/config/index.ts @@ -0,0 +1,13 @@ +import { RouteComponent } from "vue-router"; + +export interface SystemMenu { + type: 'dir' | 'menu'; + title: string; + path: string; + name: string; + icon?: string; + + component?: RouteComponent; + children?: SystemMenu[]; +} + diff --git a/policeManagement/src/types/hooks/useTableProMax.ts b/policeManagement/src/types/hooks/useTableProMax.ts new file mode 100644 index 0000000..3989828 --- /dev/null +++ b/policeManagement/src/types/hooks/useTableProMax.ts @@ -0,0 +1,26 @@ +/** + * 分页对象 + */ +export interface Page { + current: number, + size: number, + total: number +} + +/** + * 分页参数 + */ +export interface PageParams = {}> { + params: T & { [key: string]: any }, + page: Omit +} + +/** + * 分页结果 + */ +export interface PageResult { + current: string, + records: T[], + size: string, + total: string +} \ No newline at end of file diff --git a/policeManagement/src/utils/index.ts b/policeManagement/src/utils/index.ts new file mode 100644 index 0000000..257081a --- /dev/null +++ b/policeManagement/src/utils/index.ts @@ -0,0 +1,17 @@ +import {ceil, divide} from "lodash-es"; + +/** + * 将文件大小转为字符串格式 + * @param fileSizeInBytes + */ +export const convertFileSizeToStr = (fileSizeInBytes: number): string => { + if (fileSizeInBytes < 1024) { + return fileSizeInBytes + "B"; + } else if (fileSizeInBytes < 1024 * 1024) { + return (ceil(divide(fileSizeInBytes, 1024), 2)) + "KB"; + } else if (fileSizeInBytes < 1024 * 1024 * 1024) { + return (ceil(divide(fileSizeInBytes, (1024 * 1024)), 2)) + "MB"; + } else { + return (ceil(divide(fileSizeInBytes, (1024 * 1024 * 1024)), 2)) + "GB"; + } +} diff --git a/policeManagement/src/utils/minioUtil.ts b/policeManagement/src/utils/minioUtil.ts new file mode 100644 index 0000000..34c404d --- /dev/null +++ b/policeManagement/src/utils/minioUtil.ts @@ -0,0 +1,26 @@ +import api from "@/axios"; +import dayjs from "dayjs"; +import { uuid } from "vue-uuid"; + +/** + * 生成一个简单的对象文件地址 + * @param fileName 原始文件名 + * @param parentDir 上级目录 + */ +export const generateSimpleObjectName = (fileName: string, parentDir?: String): string => { + let objectName = parentDir + dayjs().format('/YYYY/MM/DD/') + uuid.v4().replace(/-/g, ''); + if (fileName && fileName.length > 0) { + objectName += fileName.substring(fileName.lastIndexOf('.')) + } + return objectName; +} + +/** + * 获取生成预签名的 URL + */ +export const getResignedObjectUrl = async (bucketName: string, objectName: string): Promise => { + return (await api.get('/common/getResignedObjectUrl', { + bucketName, + objectName + })).data as string; +} diff --git a/policeManagement/src/views/user/user-weapp.vue b/policeManagement/src/views/user/user-weapp.vue new file mode 100644 index 0000000..eb7f79a --- /dev/null +++ b/policeManagement/src/views/user/user-weapp.vue @@ -0,0 +1,8 @@ + + + diff --git a/policeManagement/src/views/user/user.vue b/policeManagement/src/views/user/user.vue new file mode 100644 index 0000000..c34366b --- /dev/null +++ b/policeManagement/src/views/user/user.vue @@ -0,0 +1,372 @@ + + + diff --git a/securityManagement/.env.development b/securityManagement/.env.development index e876cce..5c29a1e 100644 --- a/securityManagement/.env.development +++ b/securityManagement/.env.development @@ -5,7 +5,7 @@ VITE_DROP_CONSOLE=false # axios VITE_APP_BASE_API=/api -VITE_APP_PROXY_URL=http://172.10.10.151:8765 +VITE_APP_PROXY_URL=http://172.10.10.93:8765 # rsa 公钥 VITE_APP_RSA_PUBLIC_KEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJps/EXxxSpEM1Ix4R0NWIOBciHCr7P7coDT8tNKfelgR7txcJOqHCO/MIWe7T04aHQTcpQxqx9hMca7dbqz8TZpz9jvLzE/6ZonVKxHsoFnNlHMp1/CPAJ9f6D9wYicum2KltJkmQ0g//D9W2zPCYoGOmSRFcZx/KEBa4EM53jQIDAQAB diff --git a/securityManagement/src/config/index.ts b/securityManagement/src/config/index.ts index 7934799..f5c4938 100644 --- a/securityManagement/src/config/index.ts +++ b/securityManagement/src/config/index.ts @@ -3,7 +3,10 @@ import {SystemMenu} from "@/types/config"; export const ROUTER_WHITE_LIST: string[] = ['/login', '/test','/enterprise']; export const CLIENT_TYPE:string = "MANAGEMENT_SECURITY"; - +export const UNIT_TYPE = { + security: 'SECURITY_UNIT', + police: 'POLICE_UNIT' +} export const SYSTEM_MENUS: SystemMenu[] = [ { title: '首页', diff --git a/securityManagement/src/types/config/index.ts b/securityManagement/src/types/config/index.ts index f81e2db..05d2b12 100644 --- a/securityManagement/src/types/config/index.ts +++ b/securityManagement/src/types/config/index.ts @@ -10,3 +10,4 @@ export interface SystemMenu { component?: RouteComponent; children?: SystemMenu[]; } + diff --git a/securityManagement/src/types/views/bgManagement.ts b/securityManagement/src/types/views/bgManagement.ts index 6986e6d..8f6b7fa 100644 --- a/securityManagement/src/types/views/bgManagement.ts +++ b/securityManagement/src/types/views/bgManagement.ts @@ -8,7 +8,7 @@ export interface BgManagementPagerQueryParams extends BaseTableRowRecord{ /** 行政区划编码 **/ administrativeDivisionCodes?: string[]; /** 是否启用 **/ - isEnable?: number; + isEnable?: BaseEnum; /** 审核状态 **/ checkStatus?: number; /** 账号 **/ @@ -18,5 +18,15 @@ export interface BgManagementPagerQueryParams extends BaseTableRowRecord{ createTime?:string, snowFlakeId?:string, remark?:string, + isAdmin?:BaseEnum +} + +export interface FromItem { + snowFlakeId?: string, + name: string, + sex: number, + telephone: string, + isEnable: BaseEnum, + remark?: string, } diff --git a/securityManagement/src/views/test.vue b/securityManagement/src/views/test.vue index 057eb32..39d9e87 100644 --- a/securityManagement/src/views/test.vue +++ b/securityManagement/src/views/test.vue @@ -1,264 +1,11 @@ + + \ No newline at end of file diff --git a/securityManagement/src/views/userManagement/bgManagement/index.vue b/securityManagement/src/views/userManagement/bgManagement/index.vue index d3e0a2c..1e3030d 100644 --- a/securityManagement/src/views/userManagement/bgManagement/index.vue +++ b/securityManagement/src/views/userManagement/bgManagement/index.vue @@ -1,12 +1,248 @@ - - \ No newline at end of file +