Merge remote-tracking branch 'origin/main'

This commit is contained in:
luozhun 2024-09-10 10:12:45 +08:00
commit 7834d915b7
39 changed files with 1747 additions and 828 deletions

BIN
.DS_Store vendored

Binary file not shown.

5
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -12,7 +12,10 @@ declare module 'vue' {
ACard: typeof import('ant-design-vue/es')['Card']
ACascader: typeof import('ant-design-vue/es')['Cascader']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
ACol: typeof import('ant-design-vue/es')['Col']
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
ADivider: typeof import('ant-design-vue/es')['Divider']
ADrawer: typeof import('ant-design-vue/es')['Drawer']
AForm: typeof import('ant-design-vue/es')['Form']
@ -27,9 +30,13 @@ declare module 'vue' {
AMenu: typeof import('ant-design-vue/es')['Menu']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
AModal: typeof import('ant-design-vue/es')['Modal']
APagination: typeof import('ant-design-vue/es')['Pagination']
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
APopover: typeof import('ant-design-vue/es')['Popover']
ARadio: typeof import('ant-design-vue/es')['Radio']
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
ARow: typeof import('ant-design-vue/es')['Row']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASpace: typeof import('ant-design-vue/es')['Space']
@ -39,7 +46,11 @@ declare module 'vue' {
ATabPane: typeof import('ant-design-vue/es')['TabPane']
ATabs: typeof import('ant-design-vue/es')['Tabs']
ATag: typeof import('ant-design-vue/es')['Tag']
ATextarea: typeof import('ant-design-vue/es')['Textarea']
ATimePicker: typeof import('ant-design-vue/es')['TimePicker']
ATimeRangePicker: typeof import('ant-design-vue/es')['TimeRangePicker']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
ATreeSelect: typeof import('ant-design-vue/es')['TreeSelect']
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']

101
policeManagement/global.d.ts vendored Normal file
View File

@ -0,0 +1,101 @@
declare const __APP_ENV: ImportMetaEnv;
declare global {
/**
*
*/
interface JsonResult<T> {
code: number;
message: string;
data?: T;
}
export interface SecurityUnitPagerQueryParams {
/** 名称 **/
name?: string;
/** 社会编码 **/
socialCode?: string;
/** 行政区划编码 **/
administrativeDivisionCodes?: string[];
/** 是否启用 **/
isEnable?: number;
/** 审核状态 **/
checkStatus?: number;
}
interface BaseEnum<T> {
value: T;
label: string
}
class TreeNodeVo<T, E = Record<string, any>> {
value: T;
parentValue: T;
label: string;
orderIndex?: number;
children?: TreeNodeVo<T>[]
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;
remark: string;
checkStatus: {
extData: {
color: string;
};
label: string;
value: number;
};
}
class SelectNodeVo<T, E = Record<string, any>> {
value: T;
label: string;
options?: SelectNodeVo<T>[]
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[];
}
}

View File

@ -608,114 +608,114 @@
}
},
"@rollup/rollup-android-arm-eabi": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.1.tgz",
"integrity": "sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz",
"integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==",
"dev": true,
"optional": true
},
"@rollup/rollup-android-arm64": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.1.tgz",
"integrity": "sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz",
"integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==",
"dev": true,
"optional": true
},
"@rollup/rollup-darwin-arm64": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.1.tgz",
"integrity": "sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz",
"integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==",
"dev": true,
"optional": true
},
"@rollup/rollup-darwin-x64": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.1.tgz",
"integrity": "sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz",
"integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==",
"dev": true,
"optional": true
},
"@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.1.tgz",
"integrity": "sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz",
"integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==",
"dev": true,
"optional": true
},
"@rollup/rollup-linux-arm-musleabihf": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.1.tgz",
"integrity": "sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz",
"integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==",
"dev": true,
"optional": true
},
"@rollup/rollup-linux-arm64-gnu": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.1.tgz",
"integrity": "sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz",
"integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==",
"dev": true,
"optional": true
},
"@rollup/rollup-linux-arm64-musl": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.1.tgz",
"integrity": "sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz",
"integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==",
"dev": true,
"optional": true
},
"@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.1.tgz",
"integrity": "sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz",
"integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==",
"dev": true,
"optional": true
},
"@rollup/rollup-linux-riscv64-gnu": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.1.tgz",
"integrity": "sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz",
"integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==",
"dev": true,
"optional": true
},
"@rollup/rollup-linux-s390x-gnu": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.1.tgz",
"integrity": "sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz",
"integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==",
"dev": true,
"optional": true
},
"@rollup/rollup-linux-x64-gnu": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.1.tgz",
"integrity": "sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz",
"integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==",
"dev": true,
"optional": true
},
"@rollup/rollup-linux-x64-musl": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.1.tgz",
"integrity": "sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz",
"integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==",
"dev": true,
"optional": true
},
"@rollup/rollup-win32-arm64-msvc": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.1.tgz",
"integrity": "sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz",
"integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==",
"dev": true,
"optional": true
},
"@rollup/rollup-win32-ia32-msvc": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.1.tgz",
"integrity": "sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz",
"integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==",
"dev": true,
"optional": true
},
"@rollup/rollup-win32-x64-msvc": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.1.tgz",
"integrity": "sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz",
"integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==",
"dev": true,
"optional": true
},
@ -750,9 +750,9 @@
}
},
"@types/node": {
"version": "22.5.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz",
"integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==",
"version": "22.5.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz",
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
"dev": true,
"requires": {
"undici-types": "~6.19.2"
@ -781,27 +781,27 @@
}
},
"@volar/language-core": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.1.tgz",
"integrity": "sha512-9AKhC7Qn2mQYxj7Dz3bVxeOk7gGJladhWixUYKef/o0o7Bm4an+A3XvmcTHVqZ8stE6lBVH++g050tBtJ4TZPQ==",
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.2.tgz",
"integrity": "sha512-sONt5RLvLL1SlBdhyUSthZzuKePbJ7DwFFB9zT0eyWpDl+v7GXGh/RkPxxWaR22bIhYtTzp4Ka1MWatl/53Riw==",
"dev": true,
"requires": {
"@volar/source-map": "2.4.1"
"@volar/source-map": "2.4.2"
}
},
"@volar/source-map": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.1.tgz",
"integrity": "sha512-Xq6ep3OZg9xUqN90jEgB9ztX5SsTz1yiV8wiQbcYNjWkek+Ie3dc8l7AVt3EhDm9mSIR58oWczHkzM2H6HIsmQ==",
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.2.tgz",
"integrity": "sha512-qiGfGgeZ5DEarPX3S+HcFktFCjfDrFPCXKeXNbrlB7v8cvtPRm8YVwoXOdGG1NhaL5rMlv5BZPVQyu4EdWWIvA==",
"dev": true
},
"@volar/typescript": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.1.tgz",
"integrity": "sha512-UoRzC0PXcwajFQTu8XxKSYNsWNBtVja6Y9gC8eLv7kYm+UEKJCcZ8g7dialsOYA0HKs3Vpg57MeCsawFLC6m9Q==",
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.2.tgz",
"integrity": "sha512-m2uZduhaHO1SZuagi30OsjI/X1gwkaEAC+9wT/nCNAtJ5FqXEkKvUncHmffG7ESDZPlFFUBK4vJ0D9Hfr+f2EA==",
"dev": true,
"requires": {
"@volar/language-core": "2.4.1",
"@volar/language-core": "2.4.2",
"path-browserify": "^1.0.1",
"vscode-uri": "^3.0.8"
}
@ -867,49 +867,49 @@
}
},
"@vue/compiler-core": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.38.tgz",
"integrity": "sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.3.tgz",
"integrity": "sha512-adAfy9boPkP233NTyvLbGEqVuIfK/R0ZsBsIOW4BZNfb4BRpRW41Do1u+ozJpsb+mdoy80O20IzAsHaihRb5qA==",
"requires": {
"@babel/parser": "^7.24.7",
"@vue/shared": "3.4.38",
"@babel/parser": "^7.25.3",
"@vue/shared": "3.5.3",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.0"
}
},
"@vue/compiler-dom": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.38.tgz",
"integrity": "sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.3.tgz",
"integrity": "sha512-wnzFArg9zpvk/811CDOZOadJRugf1Bgl/TQ3RfV4nKfSPok4hi0w10ziYUQR6LnnBAUlEXYLUfZ71Oj9ds/+QA==",
"requires": {
"@vue/compiler-core": "3.4.38",
"@vue/shared": "3.4.38"
"@vue/compiler-core": "3.5.3",
"@vue/shared": "3.5.3"
}
},
"@vue/compiler-sfc": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.38.tgz",
"integrity": "sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.3.tgz",
"integrity": "sha512-P3uATLny2tfyvMB04OQFe7Sczteno7SLFxwrOA/dw01pBWQHB5HL15a8PosoNX2aG/EAMGqnXTu+1LnmzFhpTQ==",
"requires": {
"@babel/parser": "^7.24.7",
"@vue/compiler-core": "3.4.38",
"@vue/compiler-dom": "3.4.38",
"@vue/compiler-ssr": "3.4.38",
"@vue/shared": "3.4.38",
"@babel/parser": "^7.25.3",
"@vue/compiler-core": "3.5.3",
"@vue/compiler-dom": "3.5.3",
"@vue/compiler-ssr": "3.5.3",
"@vue/shared": "3.5.3",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.10",
"postcss": "^8.4.40",
"magic-string": "^0.30.11",
"postcss": "^8.4.44",
"source-map-js": "^1.2.0"
}
},
"@vue/compiler-ssr": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.38.tgz",
"integrity": "sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.3.tgz",
"integrity": "sha512-F/5f+r2WzL/2YAPl7UlKcJWHrvoZN8XwEBLnT7S4BXwncH25iDOabhO2M2DWioyTguJAGavDOawejkFXj8EM1w==",
"requires": {
"@vue/compiler-dom": "3.4.38",
"@vue/shared": "3.4.38"
"@vue/compiler-dom": "3.5.3",
"@vue/shared": "3.5.3"
}
},
"@vue/compiler-vue2": {
@ -928,9 +928,9 @@
"integrity": "sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw=="
},
"@vue/language-core": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.1.2.tgz",
"integrity": "sha512-tt2J7C+l0J/T5PaLhJ0jvCCi0JNwu3e8azWTYxW3jmAW5B/dac0g5UxmI7l59CQgCGFotqUqI3tXjfZgoWNtog==",
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.1.6.tgz",
"integrity": "sha512-MW569cSky9R/ooKMh6xa2g1D0AtRKbL56k83dzus/bx//RDJk24RHWkMzbAlXjMdDNyxAaagKPRquBIxkxlCkg==",
"dev": true,
"requires": {
"@volar/language-core": "~2.4.1",
@ -944,46 +944,46 @@
}
},
"@vue/reactivity": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.38.tgz",
"integrity": "sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.3.tgz",
"integrity": "sha512-2w61UnRWTP7+rj1H/j6FH706gRBHdFVpIqEkSDAyIpafBXYH8xt4gttstbbCWdU3OlcSWO8/3mbKl/93/HSMpw==",
"requires": {
"@vue/shared": "3.4.38"
"@vue/shared": "3.5.3"
}
},
"@vue/runtime-core": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.38.tgz",
"integrity": "sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.3.tgz",
"integrity": "sha512-5b2AQw5OZlmCzSsSBWYoZOsy75N4UdMWenTfDdI5bAzXnuVR7iR8Q4AOzQm2OGoA41xjk53VQKrqQhOz2ktWaw==",
"requires": {
"@vue/reactivity": "3.4.38",
"@vue/shared": "3.4.38"
"@vue/reactivity": "3.5.3",
"@vue/shared": "3.5.3"
}
},
"@vue/runtime-dom": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.38.tgz",
"integrity": "sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.3.tgz",
"integrity": "sha512-wPR1DEGc3XnQ7yHbmkTt3GoY0cEnVGQnARRdAkDzZ8MbUKEs26gogCQo6AOvvgahfjIcnvWJzkZArQ1fmWjcSg==",
"requires": {
"@vue/reactivity": "3.4.38",
"@vue/runtime-core": "3.4.38",
"@vue/shared": "3.4.38",
"@vue/reactivity": "3.5.3",
"@vue/runtime-core": "3.5.3",
"@vue/shared": "3.5.3",
"csstype": "^3.1.3"
}
},
"@vue/server-renderer": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.38.tgz",
"integrity": "sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.3.tgz",
"integrity": "sha512-28volmaZVG2PGO3V3+gBPKoSHvLlE8FGfG/GKXKkjjfxLuj/50B/0OQGakM/g6ehQeqCrZYM4eHC4Ks48eig1Q==",
"requires": {
"@vue/compiler-ssr": "3.4.38",
"@vue/shared": "3.4.38"
"@vue/compiler-ssr": "3.5.3",
"@vue/shared": "3.5.3"
}
},
"@vue/shared": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.38.tgz",
"integrity": "sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw=="
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.3.tgz",
"integrity": "sha512-Jp2v8nylKBT+PlOUjun2Wp/f++TfJVFjshLzNtJDdmFJabJa7noGMncqXRM1vXGX+Yo2V7WykQFNxusSim8SCA=="
},
"acorn": {
"version": "8.12.1",
@ -1086,9 +1086,9 @@
}
},
"axios": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz",
"integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==",
"version": "1.7.7",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
"requires": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
@ -1148,9 +1148,9 @@
"dev": true
},
"caniuse-lite": {
"version": "1.0.30001653",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz",
"integrity": "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==",
"version": "1.0.30001658",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001658.tgz",
"integrity": "sha512-N2YVqWbJELVdrnsW5p+apoQyYt51aBMSsBZki1XZEfeBCexcM/sf4xiAHcXQBkuOwJBXtWF7aW1sYX6tKebPHw==",
"dev": true
},
"chalk": {
@ -1270,12 +1270,12 @@
"dev": true
},
"debug": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"requires": {
"ms": "2.1.2"
"ms": "^2.1.3"
}
},
"delayed-stream": {
@ -1312,9 +1312,9 @@
"dev": true
},
"electron-to-chromium": {
"version": "1.5.13",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz",
"integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==",
"version": "1.5.16",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.16.tgz",
"integrity": "sha512-2gQpi2WYobXmz2q23FrOBYTLcI1O/P4heW3eqX+ldmPVDQELRqhiebV380EhlGG12NtnX1qbK/FHpN0ba+7bLA==",
"dev": true
},
"emoji-regex": {
@ -1407,9 +1407,9 @@
}
},
"follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="
"version": "1.15.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="
},
"foreground-child": {
"version": "3.3.0",
@ -1719,9 +1719,9 @@
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
"muggle-string": {
@ -1829,9 +1829,9 @@
"dev": true
},
"picocolors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw=="
},
"picomatch": {
"version": "2.3.1",
@ -1876,9 +1876,9 @@
}
},
"postcss": {
"version": "8.4.41",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
"integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
"version": "8.4.45",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz",
"integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==",
"requires": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.1",
@ -2004,27 +2004,27 @@
"dev": true
},
"rollup": {
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.1.tgz",
"integrity": "sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==",
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz",
"integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==",
"dev": true,
"requires": {
"@rollup/rollup-android-arm-eabi": "4.21.1",
"@rollup/rollup-android-arm64": "4.21.1",
"@rollup/rollup-darwin-arm64": "4.21.1",
"@rollup/rollup-darwin-x64": "4.21.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.21.1",
"@rollup/rollup-linux-arm-musleabihf": "4.21.1",
"@rollup/rollup-linux-arm64-gnu": "4.21.1",
"@rollup/rollup-linux-arm64-musl": "4.21.1",
"@rollup/rollup-linux-powerpc64le-gnu": "4.21.1",
"@rollup/rollup-linux-riscv64-gnu": "4.21.1",
"@rollup/rollup-linux-s390x-gnu": "4.21.1",
"@rollup/rollup-linux-x64-gnu": "4.21.1",
"@rollup/rollup-linux-x64-musl": "4.21.1",
"@rollup/rollup-win32-arm64-msvc": "4.21.1",
"@rollup/rollup-win32-ia32-msvc": "4.21.1",
"@rollup/rollup-win32-x64-msvc": "4.21.1",
"@rollup/rollup-android-arm-eabi": "4.21.2",
"@rollup/rollup-android-arm64": "4.21.2",
"@rollup/rollup-darwin-arm64": "4.21.2",
"@rollup/rollup-darwin-x64": "4.21.2",
"@rollup/rollup-linux-arm-gnueabihf": "4.21.2",
"@rollup/rollup-linux-arm-musleabihf": "4.21.2",
"@rollup/rollup-linux-arm64-gnu": "4.21.2",
"@rollup/rollup-linux-arm64-musl": "4.21.2",
"@rollup/rollup-linux-powerpc64le-gnu": "4.21.2",
"@rollup/rollup-linux-riscv64-gnu": "4.21.2",
"@rollup/rollup-linux-s390x-gnu": "4.21.2",
"@rollup/rollup-linux-x64-gnu": "4.21.2",
"@rollup/rollup-linux-x64-musl": "4.21.2",
"@rollup/rollup-win32-arm64-msvc": "4.21.2",
"@rollup/rollup-win32-ia32-msvc": "4.21.2",
"@rollup/rollup-win32-x64-msvc": "4.21.2",
"@types/estree": "1.0.5",
"fsevents": "~2.3.2"
}
@ -2039,9 +2039,9 @@
}
},
"sass": {
"version": "1.77.8",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz",
"integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==",
"version": "1.78.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.78.0.tgz",
"integrity": "sha512-AaIqGSrjo5lA2Yg7RvFZrlXDBCp3nV4XP73GrLGvdRWWwk+8H3l0SDvq/5bA4eF+0RFPLuWUk3E+P1U/YqnpsQ==",
"requires": {
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",
@ -2307,14 +2307,12 @@
"dev": true
},
"unplugin": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.12.2.tgz",
"integrity": "sha512-bEqQxeC7rxtxPZ3M5V4Djcc4lQqKPgGe3mAWZvxcSmX5jhGxll19NliaRzQSQPrk4xJZSGniK3puLWpRuZN7VQ==",
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.13.1.tgz",
"integrity": "sha512-6Kq1iSSwg7KyjcThRUks9LuqDAKvtnioxbL9iEtB9ctTyBA5OmrB8gZd/d225VJu1w3UpUsKV7eGrvf59J7+VA==",
"dev": true,
"requires": {
"acorn": "^8.12.1",
"chokidar": "^3.6.0",
"webpack-sources": "^3.2.3",
"webpack-virtual-modules": "^0.6.2"
}
},
@ -2358,14 +2356,14 @@
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"vite": {
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz",
"integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==",
"version": "5.4.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz",
"integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==",
"dev": true,
"requires": {
"esbuild": "^0.21.3",
"fsevents": "~2.3.3",
"postcss": "^8.4.41",
"postcss": "^8.4.43",
"rollup": "^4.20.0"
}
},
@ -2376,15 +2374,15 @@
"dev": true
},
"vue": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.38.tgz",
"integrity": "sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.3.tgz",
"integrity": "sha512-xvRbd0HpuLovYbOHXRHlSBsSvmUJbo0pzbkKTApWnQGf3/cu5Z39mQeA5cZdLRVIoNf3zI6MSoOgHUT5i2jO+Q==",
"requires": {
"@vue/compiler-dom": "3.4.38",
"@vue/compiler-sfc": "3.4.38",
"@vue/runtime-dom": "3.4.38",
"@vue/server-renderer": "3.4.38",
"@vue/shared": "3.4.38"
"@vue/compiler-dom": "3.5.3",
"@vue/compiler-sfc": "3.5.3",
"@vue/runtime-dom": "3.5.3",
"@vue/server-renderer": "3.5.3",
"@vue/shared": "3.5.3"
}
},
"vue-component-type-helpers": {
@ -2406,13 +2404,13 @@
}
},
"vue-tsc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.1.2.tgz",
"integrity": "sha512-PH1BDxWT3eaPhl73elyZj6DV0nR3K4IFoUM1sGzMXXQneovVUwHQytdSyAHiED5MtEINGSHpL/Hs9ch+c/tDTw==",
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.1.6.tgz",
"integrity": "sha512-f98dyZp5FOukcYmbFpuSCJ4Z0vHSOSmxGttZJCsFeX0M4w/Rsq0s4uKXjcSRsZqsRgQa6z7SfuO+y0HVICE57Q==",
"dev": true,
"requires": {
"@volar/typescript": "~2.4.1",
"@vue/language-core": "2.1.2",
"@vue/language-core": "2.1.6",
"semver": "^7.5.4"
},
"dependencies": {
@ -2449,12 +2447,6 @@
"loose-envify": "^1.0.0"
}
},
"webpack-sources": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
"dev": true
},
"webpack-virtual-modules": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
@ -2565,9 +2557,9 @@
"dev": true
},
"yaml": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz",
"integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==",
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz",
"integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==",
"dev": true
}
}

View File

@ -147,7 +147,7 @@ const props = withDefaults(defineProps<FormProMaxProps<T>>(), {
scrollToFirstError: undefined,
validateOnRuleChange: undefined,
})
console.log(props)
const formProMaxRef = ref<FormInstance>(null!)
const getResponsive = (item: FormProMaxItemProps): Grid => {

View File

@ -1,20 +1,17 @@
<template>
<i v-if="type==='class'" :class="[`iconfont ${fontClass}`]" :style="{fontSize:`${size}px`}"/>
<svg v-else-if="type === 'svg'" :style="{width:`${size}px`,height:`${size}px`}">
<use :href="`#${fontClass}`"/>
<i v-if="type === 'class'" :class="[`iconfont ${fontClass}`]" :style="{ fontSize: `${size}px` }" />
<svg v-else-if="type === 'svg'" :style="{ width: `${size}px`, height: `${size}px` }">
<use :href="`#${fontClass}`" />
</svg>
</template>
<script setup lang="ts">
import {IconFontProps} from "@/types/components/iconfont/IconFont";
import { IconFontProps } from '@/types/components/iconfont/IconFont'
withDefaults(defineProps<IconFontProps>(), {
size: 25,
type: "svg"
});
type: 'svg',
})
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>

View File

@ -1,15 +1,16 @@
<template>
<div class="table-pro-content">
<div class="card padding" v-if="props.searchFormOptions">
<FormProMax ref="searchFormRef" :form-item-options="props.searchFormOptions" v-model:value="searchParams" v-bind="props.searchFormProps">
<FormProMax ref="searchFormRef" :form-item-options="props.searchFormOptions" v-model:value="searchParams"
v-bind="props.searchFormProps">
<template v-slot:formOperation>
<a-space class="margin-right flex-end">
<a-button type="primary" @click="search">
<search-outlined />
<search-outlined/>
搜索
</a-button>
<a-button danger @click="resetFormAndTable">
<rollback-outlined />
<rollback-outlined/>
重置
</a-button>
</a-space>
@ -26,7 +27,7 @@
<a-tooltip>
<template #title>刷新数据</template>
<a-button shape="circle" @click="requestGetTableData">
<ReloadOutlined />
<ReloadOutlined/>
</a-button>
</a-tooltip>
</template>
@ -34,34 +35,34 @@
<a-tooltip>
<template #title>打印数据</template>
<a-button shape="circle">
<PrinterOutlined />
<PrinterOutlined/>
</a-button>
</a-tooltip>
</template>
</a-space>
</div>
<a-table
class="margin-top"
v-bind="props"
:columns="tableColumns"
:row-selection="props.isSelection ? (props.selectionProps ? props.selectionProps : defaultSelectProps) : null"
:data-source="dataSource"
:loading="loading"
:pagination="false"
class="margin-top"
v-bind="props"
:columns="tableColumns"
:row-selection="props.isSelection ? (props.selectionProps ? props.selectionProps : defaultSelectProps) : null"
:data-source="dataSource"
:loading="loading"
:pagination="false"
>
<template v-for="(_, key) in slots" v-slot:[key]="scope">
<slot v-if="!includes(['tableHeader', 'tableHeaderRight'], String(key))" :name="key" v-bind="scope"></slot>
</template>
</a-table>
<a-pagination
v-if="props.isPagination"
class="flex-end margin-top margin-right"
v-model:current="pageParams.current"
v-model:page-size="pageParams.size"
:total="pageParams.total"
v-bind="props.paginationProps"
@change="handleCurrentChange"
@showSizeChange="handleSizeChange"
v-if="props.isPagination"
class="flex-end margin-top margin-right"
v-model:current="pageParams.current"
v-model:page-size="pageParams.size"
:total="pageParams.total"
v-bind="props.paginationProps"
@change="handleCurrentChange"
@showSizeChange="handleSizeChange"
/>
</div>
</div>
@ -69,13 +70,19 @@
<script setup lang="ts" generic="T extends BaseTableRowRecord = {},P extends { [key: string]: any } ={}">
import FormProMax from '@/components/form/FormProMax.vue'
import { PrinterOutlined, ReloadOutlined, RollbackOutlined, SearchOutlined } from '@ant-design/icons-vue'
import { computed, onMounted, Ref, ref } from 'vue'
import { FormInstance } from 'ant-design-vue'
import useTableProMax from '@/hooks/useTableProMax'
import { includes, isEmpty } from 'lodash-es'
import { BaseTableRowRecord, TableProMaxProps, TableProMaxRowSelect, TableProMaxSlots } from '@/types/components/table'
import {PrinterOutlined, ReloadOutlined, RollbackOutlined, SearchOutlined} from '@ant-design/icons-vue'
import {computed, onMounted, Ref, ref} from 'vue'
import {FormInstance} from 'ant-design-vue'
import useTableProMax from '@/hooks/useTableProMax.ts'
import {includes, isEmpty} from 'lodash-es'
import {
BaseTableRowRecord,
TableProMaxProps,
TableProMaxRowSelect,
TableProMaxSlots
} from '@/types/components/table/index.ts'
//
const selectKeys = ref<string[]>([])
const selectRows = ref<T[]>([]) as Ref<T[]>
@ -137,6 +144,8 @@ const props = withDefaults(defineProps<TableProMaxProps<T, P>>(), {
showExpandColumn: undefined,
sticky: undefined,
})
console.log(props)
const slots = defineSlots<TableProMaxSlots<T>>()
const tableColumns = computed(() => {
@ -147,7 +156,7 @@ const tableColumns = computed(() => {
dataIndex: 'index',
width: 60,
title: '序号',
customRender: ({ index }) => index + 1,
customRender: ({index}) => index + 1,
})
}
}
@ -163,14 +172,24 @@ const searchFormRef = ref<FormInstance>() as Ref<FormInstance>
*/
const searchParams = ref<P | Record<string, any>>(props.defaultSearchParams || {}) as Ref<P>
const { loading, dataSource, pageParams, search, requestGetTableData, handleSizeChange, handleCurrentChange, resetState } = useTableProMax(
props.requestApi,
searchFormRef,
searchParams,
props.isPagination,
props.dataCallback,
props.requestError
const {
loading,
dataSource,
pageParams,
search,
requestGetTableData,
handleSizeChange,
handleCurrentChange,
resetState
} = useTableProMax(
props.requestApi,
searchFormRef,
searchParams,
props.isPagination,
props.dataCallback,
props.requestError
)
console.log('pageParams', pageParams)
onMounted(() => props.requestAuto && requestGetTableData(true))

View File

@ -1,81 +0,0 @@
declare const __APP_ENV: ImportMetaEnv;
declare module 'lodash-es' {
import { includes, isEmpty, ceil, divide } from 'lodash';
export { includes, isEmpty, ceil, divide };
}
/**
*
*/
interface JsonResult<T> {
code: number;
message: string;
data?: T;
}
class TreeNodeVo<T, E = Record<string, any>> {
value: T;
parentValue: T;
label: string;
orderIndex?: number;
children?: TreeNodeVo<T>[]
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;
remark: string;
checkStatus: {
extData: {
color: string;
};
label: string;
value: number;
};
}
class SelectNodeVo<T, E = Record<string, any>> {
value: T;
label: string;
options?: SelectNodeVo<T>[]
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[];
}

View File

@ -1,4 +1,4 @@
import { createRouter, createWebHistory, createWebHashHistory } from "vue-router";
import { createRouter, createWebHistory } from "vue-router";
import { staticRouter } from "@/router/staticRouters.ts";
import { message, Modal } from "ant-design-vue";
import { useUserStore } from "@/stores/modules/userStore.ts";

View File

@ -3,7 +3,7 @@ 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 { FormProMaxItemOptions, FormProMaxProps } from "@/types/components/form/index.ts";
import { PageParams, PageResult } from "@/types/hooks/useTableProMax.ts";

View File

@ -0,0 +1,37 @@
import { BaseTableRowRecord } from "@/types/components/table";
// interface BaseEnum<T> {
// value: T;
// label: string
// }
export interface publicUnitPagerQueryParams extends BaseTableRowRecord {
provinceName: any;
[x: string]: any;
/** 名称 **/
name?: string;
/** 社会编码 **/
socialCode?: string;
/** 行政区划编码 **/
administrativeDivisionCodes?: string[];
/** 是否启用 **/
isEnable?: BaseEnum<number>;
/** 审核状态 **/
checkStatus?: number;
/** 账号 **/
account?: string,
sex?: BaseEnum<number>,
telephone?: string,
createTime?: string,
snowFlakeId?: string,
remark?: string,
isAdmin?: BaseEnum<number | string>
}
export interface FromItem {
snowFlakeId?: string,
name: string,
sex: number,
telephone: string,
isEnable: BaseEnum<number>,
remark?: string,
}

View File

@ -0,0 +1,69 @@
const dbName = 'myDatabase' // 定义数据库名称
const storeName = 'treeStore' // 定义存储空间名称
// 打开或创建 IndexedDB 数据库的函数
export const openDB = () => {
return new Promise<IDBDatabase>((resolve, reject) => {
// 尝试打开名为 'myDatabase' 的数据库,如果不存在则创建
const request = indexedDB.open(dbName, 1)
// 如果数据库需要升级(例如第一次打开或版本号增加),会触发此事件
request.onupgradeneeded = (event) => {
const db = (event.target as IDBOpenDBRequest).result
// 创建一个新的对象存储空间(相当于数据库中的表)名为 'treeStore'
db.createObjectStore(storeName)
}
// 成功打开数据库后执行此回调
request.onsuccess = (event) => {
// 将数据库实例传递给 resolve供后续使用
resolve((event.target as IDBOpenDBRequest).result)
}
// 如果打开数据库失败,执行此回调
request.onerror = (event) => {
// 将错误信息传递给 reject
reject((event.target as IDBOpenDBRequest).error)
}
})
}
// 将树形结构数据存储到 IndexedDB 中的函数
export const storeTreeData = async (data: any) => {
const db = await openDB() // 打开数据库并获取数据库实例
const transaction = db.transaction(storeName, 'readwrite') // 创建一个读写事务
const store = transaction.objectStore(storeName) // 获取存储空间
// 使用 'treeData' 作为键,将数据存储到存储空间中
store.put(data, 'treeData')
// 事务完成后执行的回调
transaction.oncomplete = () => {
console.log('Data stored successfully') // 数据存储成功后输出信息
}
}
// 从 IndexedDB 中加载缓存数据的函数
export const loadTreeFromCache = async (): Promise<any | null> => {
const db = await openDB()
const transaction = db.transaction(storeName, 'readonly')
const store = transaction.objectStore(storeName)
return new Promise<any | null>((resolve, reject) => {
const request = store.get('treeData')
request.onsuccess = () => {
if (request.result !== undefined) {
resolve(request.result) // 返回缓存数据
} else {
resolve(null) // 如果没有缓存数据,返回 null
}
}
request.onerror = () => {
reject(request.error)
}
})
}
// export { openDB, storeTreeData, loadTreeFromCache }

View File

@ -1,8 +1,195 @@
<template>
<div>
<!-- 企事业单位 -->
企事业单位
<TableProMax ref="tableRef" :request-api="reqApi" :columns="columns" :searchFormOptions="searchFormOptions" :scroll="{ x }">
<!-- <template #tableHeader>
<a-space>
<a-button type="primary" @click="addUserManagement">新增用户</a-button>
</a-space>
</template> -->
</TableProMax>
<a-modal v-model:open="visible" :title="title" @ok="submit" @cancel="closeModal">
<!-- <FormProMax ref="formRef" v-model:value="formParams" :form-item-options="formItemOptions" /> -->
</a-modal>
</div>
</template>
<script setup lang="ts"></script>
<script setup lang="tsx">
import { openDB, storeTreeData, loadTreeFromCache } from '@/utils/DB.ts'
import api from '@/axios'
import { ref, reactive } from 'vue'
import TableProMax from '@/components/table/TableProMax.vue'
import { TableProMaxProps } from '@/types/components/table/index.ts'
import { ComponentExposed } from 'vue-component-type-helpers'
import { dictSelectNodes } from '@/config/dict.ts'
import { publicUnitPagerQueryParams, FromItem } from '@/types/views/publicUnit.ts'
// import FormProMax from '@/components/form/FormProMax.vue'
import { FormProMaxItemOptions } from '@/types/components/form//index.ts'
import { FormExpose } from 'ant-design-vue/es/form/Form'
import { message } from 'ant-design-vue'
const formRef = ref<FormExpose>(null)
type TableProps = TableProMaxProps<publicUnitPagerQueryParams>
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null!)
const reqApi: TableProps['requestApi'] = (params) => api.post('/policeUnit/policeEnterprisesUnitPager', params) //
const columns: TableProps['columns'] = [
{
dataIndex: 'name',
title: '单位名称',
},
// {
// dataIndex: 'code',
// title: '',
// },
{
dataIndex: 'provinceName',
title: '行政区划',
customRender: ({ record }) => {
return `${record?.provinceName}/${record?.cityName}/${record?.districtsName}/${record?.streetName}`
},
},
// {
// dataIndex: 'isEnable',
// title: '',
// customRender: ({ text }) => <a-tag color={text?.extData?.color}>{text?.label}</a-tag>,
// width: 150,
// },
// {
// dataIndex: 'checkStatus',
// title: '',
// customRender: ({ record }) => {
// return record.checkStatus?.extData?.color === 'success' ? <a-tag color='green'>{record?.checkStatus?.label}</a-tag> : <a-tag color='#f50'>{record?.checkStatus?.label}</a-tag>
// },
// },
{
dataIndex: 'address',
title: '详细地址',
},
{
dataIndex: 'contactPersonInfo',
title: '联系人姓名',
customRender: ({ record }) => {
return record?.contactPersonInfo?.name
},
},
{
dataIndex: 'contactPersonInfo',
title: '联系人手机号',
customRender: ({ record }) => {
return record?.contactPersonInfo?.telephone
},
},
{
dataIndex: 'createTime',
title: '创建时间',
},
{
dataIndex: 'remark',
title: '备注',
},
]
const x: number = columns.reduce((a, b) => a + (b.width as number), 0)
const visible = ref(false)
const title = ref('新增用户')
const addUserManagement = () => {
visible.value = true
title.value = ''
}
const getTree = async () => {
//
const cachedData = await loadTreeFromCache()
if (cachedData) {
console.log('未发请求')
// 使
return cachedData
} else {
console.log('发起了请求')
// API
const res = await api.get<any>('/common/administrativeDivisionTree')
await storeTreeData(res.data)
return res.data
}
}
const loadOptions = async () => {
const treeData = await getTree()
searchFormOptions.treeSelect.options = treeData
}
loadOptions()
const searchFormOptions = reactive<TableProps['searchFormOptions']>({
name: {
type: 'input',
label: '名称',
},
treeSelect: {
type: 'cascader',
label: '行政区划',
},
telephone: {
type: 'input',
label: '手机号',
},
// isEnable: {
// type: 'select',
// label: '',
// options: [
// {
// value: null,
// label: '',
// },
// ...dictSelectNodes('IsEnable'),
// ],
// },
})
const formParams = ref<{
snowFlakeId?: string
name: string
sex: number
telephone: string
isEnable: any
remark?: string
}>({
name: '',
sex: 0,
telephone: '',
isEnable: 0,
})
const submit = async () => {
// await formRef.value.validate()
}
const closeModal = () => {
visible.value = false
}
const formItemOptions = ref<FormProMaxItemOptions<FromItem>>({
name: {
type: 'input',
label: '姓名',
required: true,
},
sex: {
type: 'radioGroup',
label: '性别',
options: dictSelectNodes('Sex'),
required: true,
},
telephone: {
type: 'input',
label: '手机号',
required: true,
},
isEnable: {
type: 'radioGroup',
label: '启用状态',
options: dictSelectNodes('IsEnable'),
required: true,
},
remark: {
type: 'inputTextArea',
label: '备注',
},
})
</script>

View File

@ -77,6 +77,7 @@
</template>
<script setup lang="ts">
import { storeTreeData, loadTreeFromCache } from '@/utils/DB.ts'
import { useRouter } from 'vue-router'
const router = useRouter()
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
@ -101,74 +102,6 @@ const cascaderChange = (value: any): void => {
formState.administrativeDivisionCodes = [...value]
}
const dbName = 'myDatabase' //
const storeName = 'treeStore' //
// IndexedDB
const openDB = () => {
return new Promise<IDBDatabase>((resolve, reject) => {
// 'myDatabase'
const request = indexedDB.open(dbName, 1)
//
request.onupgradeneeded = (event) => {
const db = (event.target as IDBOpenDBRequest).result
// 'treeStore'
db.createObjectStore(storeName)
}
//
request.onsuccess = (event) => {
// resolve使
resolve((event.target as IDBOpenDBRequest).result)
}
//
request.onerror = (event) => {
// reject
reject((event.target as IDBOpenDBRequest).error)
}
})
}
// IndexedDB
const storeTreeData = async (data: any) => {
const db = await openDB() //
const transaction = db.transaction(storeName, 'readwrite') //
const store = transaction.objectStore(storeName) //
// 使 'treeData'
store.put(data, 'treeData')
//
transaction.oncomplete = () => {
console.log('Data stored successfully') //
}
}
// IndexedDB
const loadTreeFromCache = async (): Promise<any | null> => {
const db = await openDB()
const transaction = db.transaction(storeName, 'readonly')
const store = transaction.objectStore(storeName)
return new Promise<any | null>((resolve, reject) => {
const request = store.get('treeData')
request.onsuccess = () => {
if (request.result !== undefined) {
resolve(request.result) //
} else {
resolve(null) // null
}
}
request.onerror = () => {
reject(request.error)
}
})
}
// IndexedDB
const getTree = async () => {
//

View File

@ -2,371 +2,243 @@
<!-- 后台用户 -->
<!-- template 内部必须有一个根节点 div否则<Transition>将会失效所以这个<a-modal></a-modal> div -->
<div>
<div class="h-16 w-full bg-white rounded shadow-md py-5 px-10 flex items-center">
<div class="mr-5">名称</div>
<a-input class="w-40 mr-5" v-model:value="searchUser" autocomplete="off" placeholder="请输入名称搜索" />
<div class="mr-5 ml-5">是否启用</div>
<a-space>
<a-select ref="select" v-model:value="isEnableValue" style="width: 120px" @focus="focus" @change="handleChange">
<a-select-option v-for="(item, index) in enumsIsEnable" :key="index" :value="item.value">{{ item.label }}</a-select-option>
</a-select>
</a-space>
<div class="mr-5 ml-5">性别</div>
<a-space>
<a-select ref="select" v-model:value="sexValue" style="width: 120px" @focus="focus" @change="sexChange">
<a-select-option v-for="(item, index) in enumsSex" :key="index" :value="item.value">{{ item.label }}</a-select-option>
</a-select>
</a-space>
<div class="mr-5 ml-5">手机号</div>
<a-input class="w-40 mr-5" v-model:value="searchTelePhone" autocomplete="off" placeholder="请输入手机号搜索" />
<a-button @click="search" class="ml-5 flex items-center" type="primary"> <SearchOutlined style="font-size: 16px" />搜索 </a-button>
<a-button @click="resetSearch" class="ml-5 flex items-center"><SyncOutlined style="font-size: 16px" />重置</a-button>
</div>
<div class="w-full h-full bg-white mt-5 rounded">
<div class="w-full h-16 py-5 px-10 flex items-center">
<a-button class="flex items-center" type="primary" @click="addUser"><PlusOutlined style="font-size: 16px" />新增</a-button>
<!-- <a-button :disabled="!hasSelected" class="ml-5 flex items-center" type="primary" danger @click="search"><DeleteOutlined style="font-size: 16px" />删除</a-button> -->
</div>
<div class="px-10">
<!-- :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }" -->
<a-table :pagination="pagination" :columns="columns" :data-source="tableData" />
</div>
</div>
<TableProMax
ref="tableRef"
:request-api="reqApi"
:columns="columns"
:searchFormOptions="searchFormOptions"
:scroll="{x}"
>
<template #tableHeader>
<a-space>
<a-button type="primary" @click="addUserManagement">新增用户</a-button>
</a-space>
</template>
</TableProMax>
<!-- template 内部必须有一个根节点 div否则<Transition>将会失效所以这个<a-modal></a-modal> div -->
<a-modal v-model:open="visible" :title="title" @ok="submit" @cancel="closeModal">
<a-form ref="formRef" name="custom-validation" :model="formState" :rules="rules" v-bind="layout" @finish="handleFinish" @validate="handleValidate" @finishFailed="handleFinishFailed">
<!-- 用户根据单位代码去查询 审核状态 -->
<a-form-item has-feedback label="姓名" name="name">
<a-input v-model:value="formState.name" autocomplete="off" />
</a-form-item>
<a-form-item has-feedback label="性别" name="sex">
<a-radio-group v-model:value="formState.sex" name="radioGroup">
<a-radio v-for="(item, index) in enumsSex" :key="index" :value="item.value">{{ item.label }}</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item has-feedback label="手机号" name="telephone">
<a-input v-model:value="formState.telephone" autocomplete="off" />
</a-form-item>
<a-form-item has-feedback label="启用状态" name="isEnable">
<a-radio-group v-model:value="formState.isEnable" name="radioGroup">
<a-radio v-for="(item, index) in enumsIsEnable" :key="index" :value="item.value">{{ item.label }}</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
<FormProMax ref="formRef" v-model:value="formParams" :form-item-options="formItemOptions"/>
</a-modal>
</div>
</template>
<script setup lang="tsx">
/**
* @current 当前页
* @pages 总页数
* @size 每页多少条
* @total 总条数
*/
import { message } from 'ant-design-vue'
import { dictSelectNodes } from '@/config/dict.ts'
const enumsSex = ref<any[]>(dictSelectNodes('Sex'))
const enumsIsEnable = ref<any[]>(dictSelectNodes('IsEnable'))
import TableProMax from "@/components/table/TableProMax.vue";
import {TableProMaxProps} from "@/types/components/table";
import {message} from 'ant-design-vue'
import {dictSelectNodes} from '@/config/dict.ts'
// const enumsSex = ref<any[]>(dictSelectNodes('Sex'))
// const enumsIsEnable = ref<any[]>(dictSelectNodes('IsEnable'))
import api from '@/axios/index.ts'
import { SearchOutlined, SyncOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons-vue'
import { ref, computed, reactive, onMounted, watch } from 'vue'
import {ref, reactive, onMounted} from 'vue'
import FormProMax from "@/components/form/FormProMax.vue";
import {FormProMaxItemOptions} from "@/types/components/form";
import {FormExpose} from "ant-design-vue/es/form/Form";
import {publicUnitPagerQueryParams, FromItem} from "@/types/views/publicUnit.ts";
const focus = () => {
console.log('focus')
}
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null!)
const formRef = ref<FormExpose>(null)
type TableProps = TableProMaxProps<publicUnitPagerQueryParams>
const reqApi: TableProps['requestApi'] = (params) => api.post('/managementPoliceUnitUser/pager', params) //
const formParams = ref<{
snowFlakeId?: string,
name: string,
sex: number,
telephone: string,
isEnable: any,
const handlePageChange = (page: any, pageSize: any) => {
console.log('🚀 ~ handlePageChange ~ page, pageSize:', page, pageSize)
pagination.current = page
pagination.pageSize = pageSize
getUserList()
}
const pagination = reactive({
pageSize: 5, //
showSizeChanger: true, //
pageSizeOptions: ['5', '10'], //
showQuickJumper: true, //
showTotal: (total: string | number) => `${total}`, //
current: 1, //
total: null as number | string | null, //
onChange: handlePageChange, //
}>({
name: '',
sex: 0,
telephone: '',
isEnable: 0,
})
const getUserList = async function (params?: any) {
let obj = { page: { size: pagination.pageSize, current: pagination.current }, params }
const res = await api.post<any>('/managementPoliceUnitUser/pager', obj)
const { total, records } = res.data
tableData.value = records
pagination.total = Number(total)
}
onMounted(() => {
getUserList()
const formItemOptions = ref<FormProMaxItemOptions<FromItem>>({
name: {
type: 'input',
label: '姓名',
required: true,
rules: [
{required: true, message: '请输入姓名'}
],
},
sex: {
type: 'radioGroup',
label: '性别',
options: dictSelectNodes('Sex'),
required: true,
},
telephone: {
type: 'input',
label: '手机号',
required: true,
rules: [
{required: true, message: '请输入手机号'},
{
validator: (rule, value) => {
const phoneRegex = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
if (!value) {
return Promise.reject('手机号不能为空');
} else if (!phoneRegex.test(value)) {
return Promise.reject('手机号格式不正确');
} else {
return Promise.resolve();
}
},
trigger: 'blur',
},
],
},
isEnable: {
type: 'radioGroup',
label: '启用状态',
options: dictSelectNodes('IsEnable'),
required: true,
},
})
type Key = string | number
interface DataType {
key: Key
name: string
age: number
address: string
}
interface RecordItem {
account: string
createTime: string
createUserName: string | null
isAdmin: LabelValue //
isEnable: EnableStatus //
name: string
sex: LabelValue //
snowFlakeId: string // Snowflake ID
telephone: string
}
interface LabelValue {
value: number
label: string
}
interface EnableStatus {
value: number
label: string
extData: {
color: string
}
}
const columns = [
// {
// title: '',
// customRender: (text, record, index, column) => {
// console.log(index)
// },
// },
const columns: TableProps['columns'] = [
{
title: '账号',
dataIndex: 'account',
title: '账号',
width: 100,
ellipsis: true
},
{
title: '名称',
dataIndex: 'name',
title: '名称',
width: 200,
ellipsis: true
},
{
dataIndex: 'sex',
title: '性别',
customRender: ({ record }: { record: RecordItem }) => {
return <a-tag>{record.sex.label}</a-tag>
},
customRender: ({text}) => <a-tag>{text?.label}</a-tag>,
width: 150
},
{
dataIndex: 'telephone',
title: '手机号码',
width: 150,
ellipsis: true
},
{
dataIndex: 'createTime',
title: '创建时间',
width: 200,
ellipsis: true,
},
{
title: '是否启用',
dataIndex: 'isEnable',
customRender: ({ record }: { record: RecordItem }) => {
return record.isEnable.extData?.color === 'success' ? <a-tag color='green'>{record.isEnable.label}</a-tag> : <a-tag color='#f50'>{record.isEnable.label}</a-tag>
},
},
{
title: '创建时间',
dataIndex: 'createTime',
title: '是否启用',
customRender: ({text}) => <a-tag color={text?.extData?.color}>{text?.label}</a-tag>,
width: 150
},
{
dataIndex: 'opt',
title: '操作',
fixed: 'right',
customRender({ record }: { record: RecordItem }) {
return record.isAdmin.value === 1 ? (
<a-space>
<a-button
type='primary'
onClick={async () => {
console.log(record)
{
visible.value = true
title.value = '编辑用户'
formState.name = record.name
formState.telephone = record.telephone
formState.sex = record.sex.value
formState.isEnable = record.isEnable.value
formState.snowFlakeId = record.snowFlakeId
}
}}
>
编辑
</a-button>
<a-button type='primary' danger>
<a-popconfirm
title='确认删除账号吗?'
onConfirm={async () => {
{
const resp = await api.delete('/managementPoliceUnitUser/deleteById', {
managementPoliceUnitUserId: record.snowFlakeId,
})
message.success(resp.message)
getUserList()
}
}}
>
删除
</a-popconfirm>
</a-button>
</a-space>
) : (
<i></i>
fixed: "right",
customRender({record}) {
return (
record.isAdmin.value === 1 ?
<a-space>
<a-popconfirm
style="width:100%"
title="确认删除账号吗?"
onConfirm={async () => {
const resp = await api.delete('/managementPoliceUnitUser/deleteById', {
managementPoliceUnitUserId: record.snowFlakeId,
})
message.success(resp.message)
await tableRef.value?.requestGetTableData()
}}>
<a-button type="primary" danger>删除</a-button>
</a-popconfirm>
<a-button type="primary" onClick={async () => {
visible.value = true
title.value = "编辑用户"
formParams.value.snowFlakeId = record.snowFlakeId
formParams.value.name = record.name,
formParams.value.sex = record.sex.value,
formParams.value.telephone = record.telephone,
formParams.value.isEnable = record.isEnable?.value
}}>
编辑
</a-button>
</a-space>
:
<div>超级管理员不能编辑</div>
)
},
}
},
]
const saveOrUpdate = async () => {
const res = await api.post<any>('/managementPoliceUnitUser/saveOrUpdate', formState)
message.success(res.message)
visible.value = false
getUserList() //
resetForm() //
resetFormState()
if (formState.hasOwnProperty('snowFlakeId')) {
delete formState.snowFlakeId
const x: number = columns.reduce((a, b) => a + (b.width as number), 0)
const searchFormOptions: TableProps["searchFormOptions"] = {
name: {
type: 'input',
label: '名称'
}, sex: {
type: 'select',
label: '性别',
options: [
{
value: null,
label: '全部'
}, ...dictSelectNodes('Sex')
]
},
telephone: {
type: 'input',
label: '手机号'
},
isEnable: {
type: 'select',
label: '是否启用',
options: [
{
value: null,
label: '全部'
}, ...dictSelectNodes('IsEnable')
]
}
if (title.value === '新增用户') {
}
// console.log('saveOrUpdate', res)
}
const visible = ref(false)
const title = ref('')
const submit = async () => {
await formRef.value?.validate() //
console.log('表单校验完成')
saveOrUpdate()
}
const closeModal = () => {
resetForm()
resetFormState()
}
const addUser = () => {
const title = ref('新增用户')
const addUserManagement = () => {
visible.value = true
}
const submit = async () => {
await formRef.value.validate()
const snowFlakeId = ref('')
if (title.value === '新增用户') {
snowFlakeId.value = ''
} else {
snowFlakeId.value = formParams.value.snowFlakeId
}
const managementSecurityUnitUserSaveOrUpdateParams = {
snowFlakeId: snowFlakeId.value,
name: formParams.value.name,
sex: formParams.value.sex,
telephone: formParams.value.telephone,
isEnable: formParams.value.isEnable,
}
const resp = await api.post('/managementPoliceUnitUser/saveOrUpdate', managementSecurityUnitUserSaveOrUpdateParams)
message.success(resp.message)
tableRef.value?.requestGetTableData()
closeModal()
}
const closeModal = () => {
formParams.value = {
name: '',
sex: 0,
telephone: '',
isEnable: 0
}
visible.value = false
title.value = '新增用户'
}
const tableData = ref<DataType[]>([])
const layout = {
labelCol: { span: 4 },
wrapperCol: { span: 14 },
}
import type { FormInstance } from 'ant-design-vue'
import type { Rule } from 'ant-design-vue/es/form'
interface FormState {
name: string
sex: string | number
telephone: string
isEnable: string | number
snowFlakeId?: string | number
[key: string]: any //
}
const formRef = ref<FormInstance>()
const formState = reactive<FormState>({
name: '',
sex: '',
telephone: '',
isEnable: '',
})
const checkName = async (_rule: Rule, value: string) => {
if (value === '') {
return Promise.reject('请输入姓名')
} else {
return Promise.resolve()
}
}
const checkSex = async (_rule: Rule, value: string) => {
if (value === '') {
return Promise.reject('请选择姓名')
} else {
return Promise.resolve()
}
}
var reg_tel = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
const checkTelephone = async (_rule: Rule, value: string) => {
if (reg_tel.test(value.trim())) {
return Promise.resolve()
} else {
return Promise.reject('手机号格式不正确')
}
}
const checkIsEnable = async (_rule: Rule, value: string) => {
if (value === '') {
return Promise.reject('请选择启用状态')
} else {
return Promise.resolve()
}
}
const rules: Record<string, Rule[]> = {
name: [{ required: true, validator: checkName, trigger: 'change' }],
sex: [{ required: true, validator: checkSex, trigger: 'change' }],
telephone: [{ required: true, validator: checkTelephone, trigger: 'change' }],
isEnable: [{ required: true, validator: checkIsEnable, trigger: 'change' }],
}
const handleFinish = (values: FormState) => {
console.log('自定义校验成功')
console.log(values)
}
const handleFinishFailed = (errors: any) => {
console.log(errors)
}
const resetForm = () => {
formRef.value?.resetFields()
}
const resetFormState = () => {
// Object.keys(formState).forEach((key) => (formState[key] = ''))
for (const key in formState) {
if (Object.prototype.hasOwnProperty.call(formState, key)) {
formState[key] = '' // nullundefined
}
}
}
const handleValidate = (...args: any[]) => {
console.log(args)
}
//
const searchParams = reactive({
name: '',
telephone: '',
sex: null,
isEnable: null,
})
const searchUser = ref('')
const isEnableValue = ref(null)
const sexValue = ref(null)
const searchTelePhone = ref('')
const handleChange = (value: string) => {
console.log(`selected ${value}`)
}
const sexChange = (value: string) => {
console.log(`selected ${value}`)
}
const search = async () => {
searchParams.name = searchUser.value
searchParams.telephone = searchTelePhone.value
searchParams.sex = sexValue.value
searchParams.isEnable = isEnableValue.value
getUserList(searchParams)
}
const resetSearch = () => {
searchUser.value = ''
isEnableValue.value = null
sexValue.value = null
searchTelePhone.value = ''
}
</script>

View File

@ -1,4 +1,20 @@
/// <reference types="vite/client" />
// vue3导入模块报红解决方案——找不到模块“./XXX.vue”或其相应的类型声明
// 报错原因是typescript 只能理解 .ts 文件,无法理解 .vue文件
// 因此需要给.vue文件加上类型说明文件
declare module '*.vue' {
import type { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
declare module 'lodash-es' {
import { includes, isEmpty, ceil, divide } from 'lodash';
export { includes, isEmpty, ceil, divide };
}
interface ImportMetaEnv {
// 项目名称
readonly VITE_APP_NAME: string;
@ -15,13 +31,5 @@ interface ImportMetaEnv {
readonly VITE_APP_RSA_PUBLIC_KEY: string;
}
// vue3导入模块报红解决方案——找不到模块“./XXX.vue”或其相应的类型声明
// 报错原因是typescript 只能理解 .ts 文件,无法理解 .vue文件
// // 因此需要给.vue文件加上类型说明文件
declare module '*.vue' {
import type { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}

View File

@ -1,40 +1,82 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": [
"ES2020",
"DOM",
"DOM.Iterable"
"composite": true, // [ty-reference](1)
"target": "ES2020", // JavaScript
"useDefineForClassFields": true, // 使 `defineProperty`
"module": "ESNext", //
"lib": [ //
"ES2020", // ES2020
"DOM", // DOM
"DOM.Iterable" // DOM
],
"skipLibCheck": true,
"skipLibCheck": true, //
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "preserve",
"jsxImportSource": "vue",
"moduleResolution": "bundler", // bundler
"allowImportingTsExtensions": true, // TypeScript
"isolatedModules": true, //
"moduleDetection": "force", // ESM
"noEmit": false, //
"declaration": true, // .d.ts
"emitDeclarationOnly": true, // JS
"jsx": "preserve", // JSX
"jsxImportSource": "vue", // JSX Vue
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": "./",
"strict": false, //
"noUnusedLocals": true, // 使
"noUnusedParameters": true, // 使
"noFallthroughCasesInSwitch": true, // switch fallthrough
"baseUrl": "./", //
/* */
"paths": {
"@/*": [
"src/*"
"paths": { //
"@/*": [ // @/ src/
"./src/*"
]
},
"allowSyntheticDefaultImports": true
"allowSyntheticDefaultImports": true //
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue"
"include": [ //
"src/**/*.ts", // src TypeScript
"src/**/*.d.ts", // src
"src/**/*.tsx", // src JSX
"src/**/*.vue", // src Vue
"global.d.ts"
]
}
// //
// {
// "compilerOptions": {
// "target": "ES2020",
// "useDefineForClassFields": true,
// "module": "ESNext",
// "lib": [
// "ES2020",
// "DOM",
// "DOM.Iterable"
// ],
// "skipLibCheck": true,
// /* Bundler mode */
// "moduleResolution": "bundler",
// "allowImportingTsExtensions": true,
// "isolatedModules": true,
// "moduleDetection": "force",
// "noEmit": true,
// "jsx": "preserve",
// /* Linting */
// "strict": true,
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "noFallthroughCasesInSwitch": true,
// "baseUrl": "/",
// /* */
// "paths": {
// "@/*": [
// "./src/*"
// ]
// },
// },
// "include": [
// "src/**/*.ts",
// "src/**/*.tsx",
// "src/**/*.vue"
// ]
// }

View File

@ -1,16 +1,40 @@
{
// "compilerOptions": {
// "paths": {
// "@/*": ["src/*"]
// }
// },
"files": [],
"references": [
"compilerOptions": {
"baseUrl": "/", //
"paths": { //
"@/*": [ // @/ src/
"./src/*"
]
}
},
"files": [], //
"references": [ // tsconfig
{
"path": "./tsconfig.app.json"
"path": "./tsconfig.app.json" // tsconfig.app.json
},
{
"path": "./tsconfig.node.json"
"path": "./tsconfig.node.json" // tsconfig.node.json
}
],
"include": [ //
"env.d.ts", //
"src/vite-env.d.ts", // Vite
"src/**/*.ts", // src TypeScript
"src/**/*.tsx", // src JSX
"src/**/*.vue", // src Vue
"global.d.ts", // global.d.ts
"vite.config.ts" // Node
]
}
}
// //
// {
// "files": [],
// "references": [
// {
// "path": "./tsconfig.app.json"
// },
// {
// "path": "./tsconfig.node.json"
// }
// ]
// }

View File

@ -1,24 +1,47 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": [
"ES2023"
"composite": true, // [ty-reference](1)
"target": "ES2022", // JavaScript
"lib": [ //
"ES2023" // ES2023
],
"module": "ESNext",
"skipLibCheck": true,
"module": "ESNext", //
"skipLibCheck": true, //
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
"moduleResolution": "bundler", // bundler
"allowImportingTsExtensions": true, // TypeScript
"isolatedModules": true, //
"moduleDetection": "force", // ESM
"noEmit": false, //
"declaration": true, // .d.ts
"emitDeclarationOnly": true, // JS
"strict": true, //
"noUnusedLocals": true, // 使
"noUnusedParameters": true, // 使
"noFallthroughCasesInSwitch": true // switch fallthrough
},
"include": [
"vite.config.ts"
"include": [ //
"vite.config.ts" // Vite
]
}
//
// {
// "compilerOptions": {
// "target": "ES2022",
// "lib": ["ES2023"],
// "module": "ESNext",
// "skipLibCheck": true,
// /* Bundler mode */
// "moduleResolution": "bundler",
// "allowImportingTsExtensions": true,
// "isolatedModules": true,
// "moduleDetection": "force",
// "noEmit": true,
// /* Linting */
// "strict": true,
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "noFallthroughCasesInSwitch": true
// },
// "include": ["vite.config.ts"]
// }

View File

@ -5,7 +5,7 @@ import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
import * as path from "node:path";
import vueJsx from '@vitejs/plugin-vue-jsx'
const pathSrc = path.resolve(__dirname, 'src');
// const pathSrc = path.resolve(__dirname, 'src');
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
@ -26,7 +26,8 @@ export default defineConfig(({ mode }) => {
],
resolve: {
alias: {
'@': pathSrc,
"@": path.resolve(__dirname, './src')
// '@': pathSrc,
// '@': '/src'
}
},

BIN
policeSecurityServer/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -6,6 +6,7 @@ $--my-antd-important: !important;
background-color: #F5222D;
border-color: #F5222D;
&:hover, &:focus {
color: #ffffff $--my-antd-important;
background-color: #ff4d4f $--my-antd-important;

View File

@ -161,7 +161,7 @@ const props = withDefaults(defineProps<FormProMaxProps<T>>(), {
labelCol: () => {
return {
style: {
width: '100px'
width: '120px'
}
}
},

View File

@ -9,7 +9,7 @@
import {IconFontProps} from "@/types/components/iconfont/IconFont";
withDefaults(defineProps<IconFontProps>(), {
size: 25,
size: 20,
type: "svg"
});

View File

@ -154,7 +154,7 @@ const tableColumns = computed(() => {
if (!(cols?.[0].dataIndex === 'index')) {
cols?.unshift({
dataIndex: 'index',
width: 60,
width: 80,
title: '序号',
customRender: ({index}) => index + 1
})

View File

@ -6,6 +6,8 @@ type DictType =
| 'IsEnable'
| 'IsOrNot'
| 'Sex'
| 'ServiceProjectType'
| 'MiniProgramUserIdentity'
export const initEnums = () => {
api.get<Record<DictType, SelectNodeVo<any>[]>>('/common/enums').then(resp => {

View File

@ -1,7 +1,7 @@
import {SystemMenu} from "@/types/config";
export const ROUTER_WHITE_LIST: string[] = ['/login', '/test','/enterprise'];
export const CLIENT_TYPE:string = "MANAGEMENT_SECURITY";
export const ROUTER_WHITE_LIST: string[] = ['/login', '/test', '/enterprise'];
export const CLIENT_TYPE: string = "MANAGEMENT_SECURITY";
export const UNIT_TYPE = {
security: 'SECURITY_UNIT',
@ -12,27 +12,39 @@ export const SYSTEM_MENUS: SystemMenu[] = [
title: '首页',
name: 'index',
path: '/index',
icon: 'icon-shouye',
type: "menu",
component: () => import('@/views/index.vue')
}, {
title: '用户管理',
name: 'userManagement',
path: '/userManagement',
icon: 'icon-yonghuguanli_huaban',
type: 'dir',
children: [
{
title: '后台管理',
name: 'bgManagement',
path: '/bgManagement',
icon:'icon-guanlianbaoan',
type: 'menu',
component: () => import('@/views/userManagement/bgManagement/index.vue')
}, {
title: '小程序管理',
name: 'uniManagement',
path: '/uniManagement',
icon:'icon-guanlianbaoan',
type: 'menu',
component: () => import('@/views/userManagement/uniManagement/index.vue')
}
]
},
{
title: '服务项目管理',
name: 'serviceManagement',
path: '/serviceManagement',
icon:'icon-xiangmuguanli-',
type: 'menu',
component: () => import('@/views/serviceManagement/index.vue')
}
]

View File

@ -62,7 +62,10 @@ interface BaseEnum<T> {
label: string
}
interface TypeEnum<T> {
value: string;
label: string
}
interface dataStatus {
account: string;
password: string;

View File

@ -10,7 +10,7 @@ export interface BgManagementPagerQueryParams extends BaseTableRowRecord{
/** 是否启用 **/
isEnable?: BaseEnum<number>;
/** 审核状态 **/
checkStatus?: number;
checkStatus?: BaseEnum<number>;
/** 账号 **/
account?:string,
sex?:BaseEnum<number>,

View File

@ -0,0 +1,25 @@
import {BaseTableRowRecord} from "@/types/components/table";
export interface serviceProjectSaveOrUpdateParams extends BaseTableRowRecord {
snowFlakeId: string
enterprisesUnitId: string,
enterprisesUnitName: string,
projectManagerMiniProgramUserId: string,
projectManagerMiniProgramUserName: string,
name: string,
type: TypeEnum<string>,
isRecruitSecurity: BaseEnum<number>,
idNumber: string,
serviceArea: number,
buildingTotal: number,
houseTotal: number,
staffTotal: number,
securityUserTotal: number,
remark: string,
createUserName: string,
createTime: string,
enterprisesUnitAdministrativeDivisionCodes:Record<string, any>
}

View File

@ -138,6 +138,7 @@ const rules: Record<string, Rule[]> = {
const DivisionTree = async ()=>{
const resp = await api.get<TreeNodeVo<string>[]>('/common/administrativeDivisionTree')
administrativeDivisionTree.value = resp.data as TreeNodeVo<string>[]
}
// 2

View File

@ -1,12 +1,420 @@
<template>
<div>服务项目管理</div>
</template>
<script setup lang="ts">
<div>
<TableProMax
ref="tableRef"
:request-api="reqApi"
:columns="columns"
:searchFormOptions="searchFormOptions"
:scroll="{x}"
>
<template #tableHeader>
<a-space>
<a-button type="primary" @click="addServiceProjects">新增服务项目</a-button>
</a-space>
</template>
</TableProMax>
<a-modal
v-model:open="visible"
:title="serviceTitle"
@ok="submit"
@cancel="closeModal"
>
<FormProMax ref="formRef" v-model:value="formParams" :form-item-options="formItemOptions"/>
</a-modal>
</div>
</template>
<script setup lang="tsx">
import TableProMax from "@/components/table/TableProMax.vue";
import {TableProMaxProps} from "@/types/components/table";
import api from "@/axios";
import {onMounted, ref} from "vue";
import {ComponentExposed} from "vue-component-type-helpers";
import {dictSelectNodes} from "@/config/dict.ts";
import {serviceProjectSaveOrUpdateParams} from "@/types/views/serviceManagement.ts";
import {FormExpose} from "ant-design-vue/es/form/Form";
import {FormProMaxItemOptions} from "@/types/components/form";
import FormProMax from "@/components/form/FormProMax.vue";
import {message} from "ant-design-vue";
type TableProps = TableProMaxProps<serviceProjectSaveOrUpdateParams> //
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null!)
// table
const reqApi: TableProps['requestApi'] = (params) => api.post('/serviceProject/pager', params) //
const searchFormOptions: TableProps["searchFormOptions"] = {
name: {
type: 'input',
label: '服务项目名称'
},
projectManagerMiniProgramUserName:{
type: 'input',
label: '服务经理用户名称'
},
remark: {
type: 'input',
label: '备注'
},
type: {
type: 'select',
label: '服务项目类型',
options: [
{
value: null,
label: '全部'
},...dictSelectNodes('ServiceProjectType')
]
}
}
const visible = ref(false)
const serviceTitle = ref('新增服务项目')
const formRef = ref<FormExpose>(null)
const formParams = ref<{
snowFlakeId?: string,
enterprisesUnitId:string,
administrativeDivisionCodes?:null,
projectManagerMiniProgramUserId?:string,
name: string,
type:string,
isRecruitSecurity:number,
idNumber?: string,
serviceArea?:number,
buildingTotal?:number,
houseTotal?:number,
staffTotal?:number,
securityUserTotal?:number
remark?: string,
}>({
name:'',
isRecruitSecurity:0,
enterprisesUnitId:null,
type:'property'
})
const columns: TableProps['columns'] = [
{
dataIndex: 'enterprisesUnitName',
title: '企事业单位名称',
width: 150,
ellipsis: true
},
{
dataIndex: 'projectManagerMiniProgramUserName',
title: '项目经理小程序用户名称',
width: 200,
ellipsis: true
}, {
dataIndex: 'name',
title: '服务项目名称',
width: 150,
ellipsis: true
},
{
dataIndex:'type',
title: '服务类型',
customRender: ({text}) => <a-tag>{text?.label}</a-tag>,
width:100
},
{
dataIndex:'isRecruitSecurity',
title: '是否自招保安',
customRender: ({text}) => <a-tag>{text?.label}</a-tag>,
width:100
},
{
dataIndex:'idNumber',
title: '证件号',
width:200
},
{
dataIndex:'serviceArea',
title:'服务区域面积',
width:100
},
{
dataIndex:'buildingTotal',
title:'楼栋数量',
width:100
},
{
dataIndex:'houseTotal',
title:'户数',
width:100
},
{
dataIndex:'staffTotal',
title:'工作人员数量',
width:100
},
{
dataIndex:'securityUserTotal',
title:'保安人员数量',
width:100
},
{
dataIndex:'createUserName',
title:'创建人名称',
width:100
},
{
dataIndex: 'createTime',
title: '创建时间',
width: 100,
ellipsis: true,
},
{
dataIndex: 'remark',
title: '备注',
width: 200,
ellipsis: true
},{
dataIndex: 'opt',
title: '操作',
fixed: "right",
width:200,
customRender({record}){
return <a-space>
<a-popconfirm
title="确认删除账号吗?"
onConfirm={async () => {
const resp = await api.delete('/serviceProject/deleteById', {
serviceProjectId: record.snowFlakeId,
})
message.success(resp.message)
await tableRef.value?.requestGetTableData()
}}>
<a-button type="primary" danger>删除</a-button>
</a-popconfirm>
<a-button type="primary" onClick={ async ()=>{
console.log(record)
visible.value = true
serviceTitle.value = '编辑服务项目'
if(record.isRecruitSecurity === null ){
idNumberDisabled.value = false
}
if(record.type.value === 'security'){
isRecruitSecurityHidden.value = true
formParams.value.isRecruitSecurity = null
}else{
formParams.value.isRecruitSecurity = record.isRecruitSecurity.value
if(record.isRecruitSecurity.value === 1){
idNumberDisabled.value = true
}
}
formParams.value.snowFlakeId = record.snowFlakeId
formParams.value.name = record.name
formParams.value.type = record.type.value
formParams.value.remark = record.remark
formParams.value.idNumber = record.idNumber
formParams.value.serviceArea = record.serviceArea
formParams.value.buildingTotal = record.buildingTotal
formParams.value.houseTotal = record.houseTotal
formParams.value.staffTotal = record.staffTotal
formParams.value. securityUserTotal = record.securityUserTotal
formParams.value.enterprisesUnitId = record.enterprisesUnitName
enterprisesUnitId.value = record.enterprisesUnitId
formParams.value.administrativeDivisionCodes = record.enterprisesUnitAdministrativeDivisionCodes
}}>编辑</a-button>
</a-space>
}
},
]
const x: number = columns.reduce((a, b) => a + (b.width as number), 0)
const administrativeDivisionTree = ref<TreeNodeVo<string>[]>([]) //
const getAdministrativeDivisionTree = async ()=>{
const resp = await api.get<TreeNodeVo<string>[]>('/common/administrativeDivisionTree')
administrativeDivisionTree.value = resp.data as TreeNodeVo<string>[]
}
//
const enterprisesUnitIdList = ref<SelectNodeVo<string>[]>([])
const enterprisesUnitId = ref('')
const isRecruitSecurityHidden = ref<boolean>(false)
const idNumberDisabled = ref<boolean>(false)
const formItemOptions = ref<FormProMaxItemOptions<serviceProjectSaveOrUpdateParams>>({
name: {
type: 'input',
label: '名称',
required: true,
},
administrativeDivisionCodes:{
type:'cascader',
label:'行政区划',
required: true,
options: administrativeDivisionTree,
componentsProps:{
showSearch:true,
onChange: async (values)=>{
const resp = await api.post<SelectNodeVo<string>[]>('/enterprisesUnit/queryListByAdministrativeDivisionCodes',values)
enterprisesUnitIdList.value = resp.data
}
}
},
enterprisesUnitId:{
type:'select',
label:'企事业单位',
options:enterprisesUnitIdList,
componentsProps:{
allowClear:true
}
},
type: {
type: 'radioGroup',
label: '服务类型',
options: dictSelectNodes('ServiceProjectType'),
required: true,
componentsProps:{
onChange:(e)=>{
if(e.target.value === 'security'){
isRecruitSecurityHidden.value = true
formParams.value.isRecruitSecurity = null
idNumberDisabled.value = false
}else{
formParams.value.isRecruitSecurity = 0
isRecruitSecurityHidden.value = false
}
}
}
},
isRecruitSecurity: {
type: 'radioGroup',
label: '是否自招保安',
options:dictSelectNodes('IsOrNot'),
hidden:isRecruitSecurityHidden as any,
componentsProps:{
onChange:(e)=>{
idNumberDisabled.value = e.target.value !== 0;
formParams.value.idNumber = ''
}
}
},
idNumber: {
type: 'input',
label: '证件号',
componentsProps:{
disabled:idNumberDisabled as any
}
},
serviceArea:{
type:'inputNumber',
label:'服务区域面积',
},
buildingTotal:{
type:'inputNumber',
label:'楼栋数量',
componentsProps:{
formatter:(value:any)=>{
return Math.round(value)?Math.round(value):'' as any
},
min:0
}
},
houseTotal:{
type:'inputNumber',
label:'户数',
componentsProps:{
formatter:(value:any)=>{
return Math.round(value)?Math.round(value):'' as any
},
min:0
}
},
staffTotal:{
type:'inputNumber',
label:'工作人员数量',
componentsProps:{
formatter:(value:any)=>{
return Math.round(value)?Math.round(value):'' as any
},
min:0
}
},
securityUserTotal:{
type:'inputNumber',
label:'保安人员数量',
componentsProps:{
formatter:(value:any)=>{
return Math.round(value)?Math.round(value):'' as any
},
min:0
}
},
remark: {
type: 'inputTextArea',
label: '备注',
}
})
const submit = async()=>{
await formRef.value.validate()
const snowFlakeId = ref('')
const UnitId = ref('')
if (serviceTitle.value === '新增服务项目') {
snowFlakeId.value = ''
UnitId.value = formParams.value.enterprisesUnitId
} else {
snowFlakeId.value = formParams.value.snowFlakeId
UnitId.value = enterprisesUnitId.value
}
const serviceProjectSaveOrUpdateParams = {
snowFlakeId: snowFlakeId.value,
enterprisesUnitId:UnitId.value,
name: formParams.value.name,
type:formParams.value.type,
isRecruitSecurity:formParams.value.isRecruitSecurity,
idNumber: formParams.value.idNumber,
serviceArea:formParams.value.serviceArea,
buildingTotal:formParams.value.buildingTotal,
houseTotal:formParams.value.houseTotal,
staffTotal:formParams.value.staffTotal,
securityUserTotal:formParams.value.securityUserTotal,
remark: formParams.value.remark,
}
const resp = await api.post('/serviceProject/saveOrUpdate',serviceProjectSaveOrUpdateParams)
message.success(resp.message)
await tableRef.value?.requestGetTableData()
await closeModal()
}
const closeModal = async()=>{
visible.value = false
formParams.value = {
enterprisesUnitId:'',
administrativeDivisionCodes:'',
name:'',
type:'property',
isRecruitSecurity:0,
idNumber:'',
serviceArea:null,
buildingTotal:null,
houseTotal:null,
staffTotal:null,
securityUserTotal:null,
remark:''
}
// await formRef.value.resetFields()
enterprisesUnitId.value = ''
serviceTitle.value = '新增服务项目'
isRecruitSecurityHidden.value = false
idNumberDisabled.value = false
}
const addServiceProjects = () => {
visible.value = true
}
onMounted(async ()=>{
await getAdministrativeDivisionTree()
})
</script>
<style scoped lang="scss">
</style>
</style>

View File

@ -91,19 +91,18 @@ const columns: TableProps['columns'] = [
return (
record.isAdmin.value === 1?
<a-space>
<a-button type="primary" danger>
<a-popconfirm
title="确认删除账号吗?"
onConfirm={async () => {
const resp = await api.delete('/managementSecurityUnitUser/deleteById', {
managementSecurityUnitUserId: record.snowFlakeId,
})
message.success(resp.message)
await tableRef.value?.requestGetTableData()
}}>
删除
</a-popconfirm>
</a-button>
<a-popconfirm
style="width:100%"
title="确认删除账号吗?"
onConfirm={async () => {
const resp = await api.delete('/managementSecurityUnitUser/deleteById', {
managementSecurityUnitUserId: record.snowFlakeId,
})
message.success(resp.message)
await tableRef.value?.requestGetTableData()
}}>
<a-button type="primary" danger>删除</a-button>
</a-popconfirm>
<a-button type="primary" onClick={async () => {
visible.value = true
title.value = "编辑用户"
@ -118,7 +117,7 @@ const columns: TableProps['columns'] = [
</a-button>
</a-space>
:
<i></i>
<div>超级管理员不能编辑</div>
)
}
},
@ -218,27 +217,24 @@ const submit = async () => {
}
const resp = await api.post('/managementSecurityUnitUser/saveOrUpdate', managementSecurityUnitUserSaveOrUpdateParams)
message.success(resp.message)
close()
}
const close = () => {
tableRef.value?.requestGetTableData()
visible.value = false
closeModal()
}
const closeModal = () => {
formParams.value = {
name: '',
sex: 0,
telephone: '',
isEnable: 0,
remark: ''
name:'',
sex:0,
telephone:'',
isEnable:0,
remark:''
}
visible.value = false
title.value = '新增用户'
}
//Form
const addUserManagement = () => {
visible.value = true
title.value = ''
}
</script>

View File

@ -1,11 +1,235 @@
<template>
<div>小程序管理</div>
</template>
<script setup lang="ts">
<div>
<TableProMax
ref="tableRef"
:request-api="reqApi"
:columns="columns"
:searchFormOptions="searchFormOptions"
:scroll="{x}"
>
</TableProMax>
<a-modal
v-model:open="visible"
:title="title"
@ok="submit"
@cancel="closeModal"
>
<FormProMax ref="formRef" v-model:value="formParams" :form-item-options="formItemOptions"/>
</a-modal>
</div>
</template>
<script setup lang="tsx">
import TableProMax from "@/components/table/TableProMax.vue";
import {TableProMaxProps} from "@/types/components/table";
import api from "@/axios";
import {ref} from "vue";
import {ComponentExposed} from "vue-component-type-helpers";
import {dictSelectNodes} from "@/config/dict.ts";
import {BgManagementPagerQueryParams, FromItem} from "@/types/views/bgManagement.ts";
import FormProMax from "@/components/form/FormProMax.vue";
import {FormProMaxItemOptions} from "@/types/components/form";
import {FormExpose} from "ant-design-vue/es/form/Form";
import {message} from "ant-design-vue";
import {UNIT_TYPE} from "@/config";
type TableProps = TableProMaxProps<BgManagementPagerQueryParams>
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null!)
// table
const reqApi: TableProps['requestApi'] = (params) => api.post('/management/miniProgramUserPager', params) //
const columns: TableProps['columns'] = [
{
dataIndex: 'name',
title: '名称',
width: 150,
ellipsis: true
},
{
dataIndex: 'identity',
title: '身份类型',
width: 150,
customRender: ({text}) => <div>{text?.label}</div>,
},
{
dataIndex: 'sex',
title: '性别',
customRender: ({text}) => <a-tag>{text?.label}</a-tag>,
width: 100
}, {
dataIndex: 'telephone',
title: '手机号码',
width: 150,
ellipsis: true
},
{
dataIndex: 'createTime',
title: '创建时间',
width: 200,
ellipsis: true,
},
{
dataIndex: 'isEnable',
title: '是否启用',
customRender: ({text}) => <a-tag color={text?.extData?.color}>{text?.label}</a-tag>,
width: 150
}, {
dataIndex: 'opt',
title: '操作',
fixed: "right",
customRender({record}) {
if (record.checkStatus.value === 1) {
return <a-space>
<a-popconfirm
title="确认审核通过嘛?"
onConfirm={async () => {
const resp = await api.post('/management/passMiniProgramUser', {
dataId: record.snowFlakeId,
unitOptType: UNIT_TYPE.security
})
message.success(resp.message)
await tableRef.value?.requestGetTableData()
}}>
<a-button type="primary">审核通过</a-button>
</a-popconfirm>
</a-space>
}
return <a-space >
<a-button
className={record.isEnable.value === 0 ? 'btn-danger' : 'btn-success'}
onClick={async () => {
const resp = await api.post('/management/disableOrEnableMiniProgramUser', {
dataId: record.snowFlakeId,
unitOptType: UNIT_TYPE.security
})
message.success(resp.message)
await tableRef.value?.requestGetTableData()
}}
>{record.isEnable.value === 0 ? '禁用' : '启用'}
</a-button>
</a-space>
}
},
]
const x: number = columns.reduce((a, b) => a + (b.width as number), 0)
const searchFormOptions: TableProps["searchFormOptions"] = {
name: {
type: 'input',
label: '名称'
}, sex: {
type: 'select',
label: '性别',
options: [
{
value: null,
label: '全部'
}, ...dictSelectNodes('Sex')
]
},
telephone: {
type: 'input',
label: '手机号'
},
isEnable: {
type: 'select',
label: '是否启用',
options: [
{
value: null,
label: '全部'
}, ...dictSelectNodes('IsEnable')
]
}
}
const visible = ref(false)
const title = ref('新增用户')
const formRef = ref<FormExpose>(null)
const formParams = ref<{
snowFlakeId?: string,
name: string,
sex: number,
telephone: string,
isEnable: any,
remark?: string,
}>({
name: '',
sex: 0,
telephone: '',
isEnable: 0,
})
const formItemOptions = ref<FormProMaxItemOptions<FromItem>>({
name: {
type: 'input',
label: '姓名',
required: true,
},
sex: {
type: 'radioGroup',
label: '性别',
options: dictSelectNodes('Sex'),
required: true,
},
telephone: {
type: 'input',
label: '手机号',
required: true,
},
isEnable: {
type: 'radioGroup',
label: '启用状态',
options: dictSelectNodes('IsEnable'),
required: true,
},
remark: {
type: 'inputTextArea',
label: '备注',
}
})
const submit = async () => {
await formRef.value.validate()
const snowFlakeId = ref('')
if (title.value === '新增用户') {
snowFlakeId.value = ''
} else {
snowFlakeId.value = formParams.value.snowFlakeId
}
const managementSecurityUnitUserSaveOrUpdateParams = {
snowFlakeId: snowFlakeId.value,
name: formParams.value.name,
sex: formParams.value.sex,
telephone: formParams.value.telephone,
isEnable: formParams.value.isEnable,
remark: formParams.value.remark
}
const resp = await api.post('/managementSecurityUnitUser/saveOrUpdate', managementSecurityUnitUserSaveOrUpdateParams)
message.success(resp.message)
tableRef.value?.requestGetTableData()
closeModal()
}
const closeModal = () => {
formParams.value = {
name: '',
sex: 0,
telephone: '',
isEnable: 0,
remark: ''
}
visible.value = false
title.value = '新增用户'
}
//Form
// const addUserManagement = () => {
// visible.value = true
// }
</script>
<style scoped lang="scss">
</style>
</style>

View File

@ -37,4 +37,4 @@
"src/**/*.tsx",
"src/**/*.vue"
]
}
}

View File

@ -5,7 +5,8 @@ VITE_DROP_CONSOLE=false
# axios
VITE_APP_BASE_API=/api
VITE_APP_PROXY_URL=http://localhost:8765
# VITE_APP_PROXY_URL=http://localhost:8765
VITE_APP_PROXY_URL=http://172.10.10.93:8765
# rsa 公钥
VITE_APP_RSA_PUBLIC_KEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJps/EXxxSpEM1Ix4R0NWIOBciHCr7P7coDT8tNKfelgR7txcJOqHCO/MIWe7T04aHQTcpQxqx9hMca7dbqz8TZpz9jvLzE/6ZonVKxHsoFnNlHMp1/CPAJ9f6D9wYicum2KltJkmQ0g//D9W2zPCYoGOmSRFcZx/KEBa4EM53jQIDAQAB

View File

@ -3,8 +3,8 @@ import {SystemMenu} from "@/types/config";
export const CLIENT_TYPE = "MANAGEMENT_SUPER";
export const ROUTER_WHITE_LIST: string[] = ['/login', '/test'];
export const UNIT_TYPE = {
security: 'SECURITY_UNIT',
police: 'POLICE_UNIT'
security: 'SECURITY_UNIT', //安全
police: 'POLICE_UNIT' //警察
}
export const SYSTEM_MENUS: SystemMenu[] = [