Commit 3b8ca420c763fe0e386a8dbc023f4f8eb8742252

Authored by Vben
1 parent 37669d06

feat: add dept management page

mock/demo/system.ts
1 import { MockMethod } from 'vite-plugin-mock'; 1 import { MockMethod } from 'vite-plugin-mock';
2 -import { resultPageSuccess } from '../_util'; 2 +import { resultPageSuccess, resultSuccess } from '../_util';
3 3
4 -const list = (() => { 4 +const accountList = (() => {
5 const result: any[] = []; 5 const result: any[] = [];
6 for (let index = 0; index < 20; index++) { 6 for (let index = 0; index < 20; index++) {
7 result.push({ 7 result.push({
@@ -10,8 +10,40 @@ const list = (() =&gt; { @@ -10,8 +10,40 @@ const list = (() =&gt; {
10 email: '@email', 10 email: '@email',
11 nickname: '@cname()', 11 nickname: '@cname()',
12 role: '@first', 12 role: '@first',
13 - updateTime: '@datetime',  
14 - remark: '@cword(0,20)', 13 + createTime: '@datetime',
  14 + remark: '@cword(10,20)',
  15 + 'status|1': ['0', '1'],
  16 + });
  17 + }
  18 + return result;
  19 +})();
  20 +
  21 +const deptList = (() => {
  22 + const result: any[] = [];
  23 + for (let index = 0; index < 3; index++) {
  24 + result.push({
  25 + id: `${index}`,
  26 + deptName: ['华东分部', '华南分部', '西北分部'][index],
  27 + orderNo: index + 1,
  28 + createTime: '@datetime',
  29 + remark: '@cword(10,20)',
  30 + 'status|1': ['0', '0', '1'],
  31 + children: (() => {
  32 + const children: any[] = [];
  33 + for (let j = 0; j < 4; j++) {
  34 + children.push({
  35 + id: `${index}-${j}`,
  36 + deptName: ['研发部', '市场部', '商务部', '财务部'][j],
  37 + orderNo: j + 1,
  38 + createTime: '@datetime',
  39 + remark: '@cword(10,20)',
  40 + 'status|1': ['0', '1'],
  41 + parentDept: `${index}`,
  42 + children: undefined,
  43 + });
  44 + }
  45 + return children;
  46 + })(),
15 }); 47 });
16 } 48 }
17 return result; 49 return result;
@@ -24,7 +56,15 @@ export default [ @@ -24,7 +56,15 @@ export default [
24 method: 'get', 56 method: 'get',
25 response: ({ query }) => { 57 response: ({ query }) => {
26 const { page = 1, pageSize = 20 } = query; 58 const { page = 1, pageSize = 20 } = query;
27 - return resultPageSuccess(page, pageSize, list); 59 + return resultPageSuccess(page, pageSize, accountList);
  60 + },
  61 + },
  62 + {
  63 + url: '/api/system/getDeptList',
  64 + timeout: 100,
  65 + method: 'get',
  66 + response: () => {
  67 + return resultSuccess(deptList);
28 }, 68 },
29 }, 69 },
30 ] as MockMethod[]; 70 ] as MockMethod[];
package.json
@@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
26 }, 26 },
27 "dependencies": { 27 "dependencies": {
28 "@iconify/iconify": "^2.0.0-rc.6", 28 "@iconify/iconify": "^2.0.0-rc.6",
29 - "@vueuse/core": "^4.3.0", 29 + "@vueuse/core": "^4.3.1",
30 "@zxcvbn-ts/core": "^0.2.0", 30 "@zxcvbn-ts/core": "^0.2.0",
31 "ant-design-vue": "2.0.1", 31 "ant-design-vue": "2.0.1",
32 "apexcharts": "^3.25.0", 32 "apexcharts": "^3.25.0",
@@ -80,10 +80,10 @@ @@ -80,10 +80,10 @@
80 "eslint-config-prettier": "^8.1.0", 80 "eslint-config-prettier": "^8.1.0",
81 "eslint-plugin-prettier": "^3.3.1", 81 "eslint-plugin-prettier": "^3.3.1",
82 "eslint-plugin-vue": "^7.6.0", 82 "eslint-plugin-vue": "^7.6.0",
83 - "esno": "^0.4.4", 83 + "esno": "^0.4.5",
84 "fs-extra": "^9.1.0", 84 "fs-extra": "^9.1.0",
85 "http-server": "^0.12.3", 85 "http-server": "^0.12.3",
86 - "husky": "^5.1.1", 86 + "husky": "^5.1.2",
87 "is-ci": "^3.0.0", 87 "is-ci": "^3.0.0",
88 "less": "^4.1.1", 88 "less": "^4.1.1",
89 "lint-staged": "^10.5.4", 89 "lint-staged": "^10.5.4",
@@ -103,7 +103,7 @@ @@ -103,7 +103,7 @@
103 "vite-plugin-imagemin": "^0.2.8", 103 "vite-plugin-imagemin": "^0.2.8",
104 "vite-plugin-mock": "^2.1.5", 104 "vite-plugin-mock": "^2.1.5",
105 "vite-plugin-purge-icons": "^0.7.0", 105 "vite-plugin-purge-icons": "^0.7.0",
106 - "vite-plugin-pwa": "^0.5.5", 106 + "vite-plugin-pwa": "^0.5.6",
107 "vite-plugin-style-import": "^0.7.5", 107 "vite-plugin-style-import": "^0.7.5",
108 "vite-plugin-theme": "^0.4.8", 108 "vite-plugin-theme": "^0.4.8",
109 "vite-plugin-windicss": "0.6.2", 109 "vite-plugin-windicss": "0.6.2",
src/api/demo/model/systemModel.ts
1 import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel'; 1 import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel';
2 2
3 -export type Params = BasicPageParams & { 3 +export type AccountParams = BasicPageParams & {
4 account?: string; 4 account?: string;
5 nickname?: string; 5 nickname?: string;
6 }; 6 };
7 7
8 -export interface DemoListItem { 8 +export type DeptParams = {
  9 + deptName?: string;
  10 + status?: string;
  11 +};
  12 +
  13 +export interface AccountListItem {
9 id: string; 14 id: string;
10 account: string; 15 account: string;
11 email: string; 16 email: string;
12 nickname: string; 17 nickname: string;
13 role: number; 18 role: number;
14 - updateTime: string; 19 + createTime: string;
15 remark: string; 20 remark: string;
  21 + status: number;
  22 +}
  23 +
  24 +export interface DeptListItem {
  25 + id: string;
  26 + orderNo: string;
  27 + createTime: string;
  28 + remark: string;
  29 + status: number;
16 } 30 }
17 31
18 /** 32 /**
19 * @description: Request list return value 33 * @description: Request list return value
20 */ 34 */
21 -export type DemoListGetResultModel = BasicFetchResult<DemoListItem>; 35 +export type AccountListGetResultModel = BasicFetchResult<AccountListItem>;
  36 +
  37 +export type DeptListGetResultModel = BasicFetchResult<DeptListItem>;
src/api/demo/system.ts
1 -import { Params, DemoListGetResultModel } from './model/systemModel'; 1 +import {
  2 + AccountParams,
  3 + DeptListItem,
  4 + DeptListGetResultModel,
  5 + AccountListGetResultModel,
  6 +} from './model/systemModel';
2 import { defHttp } from '/@/utils/http/axios'; 7 import { defHttp } from '/@/utils/http/axios';
3 8
4 enum Api { 9 enum Api {
5 // The address does not exist 10 // The address does not exist
6 AccountList = '/system/getAccountList', 11 AccountList = '/system/getAccountList',
  12 + DeptList = '/system/getDeptList',
7 } 13 }
8 14
9 -export const getAccountList = (params: Params) =>  
10 - defHttp.get<DemoListGetResultModel>({ url: Api.AccountList, params }); 15 +export const getAccountList = (params: AccountParams) =>
  16 + defHttp.get<AccountListGetResultModel>({ url: Api.AccountList, params });
  17 +
  18 +export const getDeptList = (params?: DeptListItem) =>
  19 + defHttp.get<DeptListGetResultModel>({ url: Api.DeptList, params });
src/components/Basic/src/BasicArrow.vue
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 --> 4 -->
5 <template> 5 <template>
6 <span :class="getClass"> 6 <span :class="getClass">
7 - <RightOutlined /> 7 + <Icon icon="ion:chevron-forward" :style="$attrs.iconStyle" />
8 </span> 8 </span>
9 </template> 9 </template>
10 <script lang="ts"> 10 <script lang="ts">
@@ -15,9 +15,11 @@ @@ -15,9 +15,11 @@
15 15
16 import { propTypes } from '/@/utils/propTypes'; 16 import { propTypes } from '/@/utils/propTypes';
17 17
  18 + import { Icon } from '/@/components/Icon';
  19 +
18 export default defineComponent({ 20 export default defineComponent({
19 name: 'BasicArrow', 21 name: 'BasicArrow',
20 - components: { RightOutlined }, 22 + components: { RightOutlined, Icon },
21 props: { 23 props: {
22 // Expand contract, expand by default 24 // Expand contract, expand by default
23 expand: propTypes.bool, 25 expand: propTypes.bool,
src/components/Form/src/componentMap.ts
@@ -21,6 +21,7 @@ import { @@ -21,6 +21,7 @@ import {
21 import RadioButtonGroup from './components/RadioButtonGroup.vue'; 21 import RadioButtonGroup from './components/RadioButtonGroup.vue';
22 import ApiSelect from './components/ApiSelect.vue'; 22 import ApiSelect from './components/ApiSelect.vue';
23 import { BasicUpload } from '/@/components/Upload'; 23 import { BasicUpload } from '/@/components/Upload';
  24 +import { StrengthMeter } from '/@/components/StrengthMeter';
24 25
25 const componentMap = new Map<ComponentType, Component>(); 26 const componentMap = new Map<ComponentType, Component>();
26 27
@@ -51,6 +52,7 @@ componentMap.set(&#39;MonthPicker&#39;, DatePicker.MonthPicker); @@ -51,6 +52,7 @@ componentMap.set(&#39;MonthPicker&#39;, DatePicker.MonthPicker);
51 componentMap.set('RangePicker', DatePicker.RangePicker); 52 componentMap.set('RangePicker', DatePicker.RangePicker);
52 componentMap.set('WeekPicker', DatePicker.WeekPicker); 53 componentMap.set('WeekPicker', DatePicker.WeekPicker);
53 componentMap.set('TimePicker', TimePicker); 54 componentMap.set('TimePicker', TimePicker);
  55 +componentMap.set('StrengthMeter', StrengthMeter);
54 56
55 componentMap.set('Upload', BasicUpload); 57 componentMap.set('Upload', BasicUpload);
56 58
src/components/Form/src/types/index.ts
@@ -91,7 +91,6 @@ export type ComponentType = @@ -91,7 +91,6 @@ export type ComponentType =
91 | 'Select' 91 | 'Select'
92 | 'ApiSelect' 92 | 'ApiSelect'
93 | 'SelectOptGroup' 93 | 'SelectOptGroup'
94 - | 'SelectOption'  
95 | 'TreeSelect' 94 | 'TreeSelect'
96 | 'Transfer' 95 | 'Transfer'
97 | 'RadioButtonGroup' 96 | 'RadioButtonGroup'
src/components/Table/src/BasicTable.vue
@@ -65,6 +65,7 @@ @@ -65,6 +65,7 @@
65 import { useDesign } from '/@/hooks/web/useDesign'; 65 import { useDesign } from '/@/hooks/web/useDesign';
66 66
67 import { basicProps } from './props'; 67 import { basicProps } from './props';
  68 + import expandIcon from './components/ExpandIcon';
68 import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; 69 import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
69 70
70 import './style/index.less'; 71 import './style/index.less';
@@ -193,6 +194,7 @@ @@ -193,6 +194,7 @@
193 size: 'middle', 194 size: 'middle',
194 ...attrs, 195 ...attrs,
195 customRow, 196 customRow,
  197 + expandIcon: expandIcon(),
196 ...unref(getProps), 198 ...unref(getProps),
197 ...unref(getHeaderProps), 199 ...unref(getHeaderProps),
198 scroll: unref(getScrollRef), 200 scroll: unref(getScrollRef),
src/components/Table/src/components/ExpandIcon.tsx 0 → 100644
  1 +import { BasicArrow } from '/@/components/Basic';
  2 +
  3 +export default () => {
  4 + return (props: Recordable) => {
  5 + if (!props.expandable) {
  6 + return null;
  7 + }
  8 + return (
  9 + <BasicArrow
  10 + class="mr-1"
  11 + iconStyle="margin-top: -2px;"
  12 + onClick={(e: Event) => {
  13 + props.onExpand(props.record, e);
  14 + }}
  15 + expand={props.expanded}
  16 + />
  17 + );
  18 + };
  19 +};
src/components/Table/src/style/index.less
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 padding: 16px; 8 padding: 16px;
9 9
10 .ant-form { 10 .ant-form {
11 - padding: 20px 20px 4px 12px; 11 + padding: 16px 16px 6px 12px;
12 margin-bottom: 18px; 12 margin-bottom: 18px;
13 background: #fff; 13 background: #fff;
14 border-radius: 4px; 14 border-radius: 4px;
src/locales/lang/en/routes/demo/system.ts
@@ -2,4 +2,8 @@ export default { @@ -2,4 +2,8 @@ export default {
2 moduleName: 'System management', 2 moduleName: 'System management',
3 3
4 account: 'Account management', 4 account: 'Account management',
  5 +
  6 + password: 'Change password',
  7 +
  8 + dept: 'Department management',
5 }; 9 };
src/locales/lang/zh_CN/routes/demo/system.ts
@@ -2,4 +2,8 @@ export default { @@ -2,4 +2,8 @@ export default {
2 moduleName: '系统管理', 2 moduleName: '系统管理',
3 3
4 account: '账号管理', 4 account: '账号管理',
  5 +
  6 + password: '修改密码',
  7 +
  8 + dept: '部门管理',
5 }; 9 };
src/router/menus/modules/demo/system.ts
@@ -11,6 +11,16 @@ const menu: MenuModule = { @@ -11,6 +11,16 @@ const menu: MenuModule = {
11 path: 'account', 11 path: 'account',
12 name: t('routes.demo.system.account'), 12 name: t('routes.demo.system.account'),
13 }, 13 },
  14 +
  15 + {
  16 + path: 'dept',
  17 + name: t('routes.demo.system.dept'),
  18 + },
  19 +
  20 + {
  21 + path: 'changePassword',
  22 + name: t('routes.demo.system.password'),
  23 + },
14 ], 24 ],
15 }, 25 },
16 }; 26 };
src/router/routes/modules/demo/system.ts
@@ -15,12 +15,31 @@ const system: AppRouteModule = { @@ -15,12 +15,31 @@ const system: AppRouteModule = {
15 children: [ 15 children: [
16 { 16 {
17 path: 'account', 17 path: 'account',
18 - name: 'Account', 18 + name: 'AccountManagement',
19 meta: { 19 meta: {
20 title: t('routes.demo.system.account'), 20 title: t('routes.demo.system.account'),
  21 + ignoreKeepAlive: true,
21 }, 22 },
22 component: () => import('/@/views/demo/system/account/index.vue'), 23 component: () => import('/@/views/demo/system/account/index.vue'),
23 }, 24 },
  25 + {
  26 + path: 'dept',
  27 + name: 'DeptManagement',
  28 + meta: {
  29 + title: t('routes.demo.system.dept'),
  30 + ignoreKeepAlive: true,
  31 + },
  32 + component: () => import('/@/views/demo/system/dept/index.vue'),
  33 + },
  34 + {
  35 + path: 'changePassword',
  36 + name: 'ChangePassword',
  37 + meta: {
  38 + title: t('routes.demo.system.password'),
  39 + ignoreKeepAlive: true,
  40 + },
  41 + component: () => import('/@/views/demo/system/password/index.vue'),
  42 + },
24 ], 43 ],
25 }; 44 };
26 45
src/utils/http/axios/Axios.ts
@@ -83,9 +83,15 @@ export class VAxios { @@ -83,9 +83,15 @@ export class VAxios {
83 this.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => { 83 this.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {
84 // If cancel repeat request is turned on, then cancel repeat request is prohibited 84 // If cancel repeat request is turned on, then cancel repeat request is prohibited
85 const { 85 const {
86 - headers: { ignoreCancelToken = false }, 86 + headers: { ignoreCancelToken },
87 } = config; 87 } = config;
88 - !ignoreCancelToken && axiosCanceler.addPending(config); 88 +
  89 + const ignoreCancel =
  90 + ignoreCancelToken !== undefined
  91 + ? ignoreCancelToken
  92 + : this.options.requestOptions?.ignoreCancelToken;
  93 +
  94 + !ignoreCancel && axiosCanceler.addPending(config);
89 if (requestInterceptors && isFunction(requestInterceptors)) { 95 if (requestInterceptors && isFunction(requestInterceptors)) {
90 config = requestInterceptors(config); 96 config = requestInterceptors(config);
91 } 97 }
src/utils/http/axios/index.ts
@@ -202,6 +202,8 @@ function createAxios(opt?: Partial&lt;CreateAxiosOptions&gt;) { @@ -202,6 +202,8 @@ function createAxios(opt?: Partial&lt;CreateAxiosOptions&gt;) {
202 apiUrl: globSetting.apiUrl, 202 apiUrl: globSetting.apiUrl,
203 // 是否加入时间戳 203 // 是否加入时间戳
204 joinTime: true, 204 joinTime: true,
  205 + // 忽略重复请求
  206 + ignoreCancelToken: true,
205 }, 207 },
206 }, 208 },
207 opt || {} 209 opt || {}
src/utils/http/axios/types.ts
@@ -17,6 +17,7 @@ export interface RequestOptions { @@ -17,6 +17,7 @@ export interface RequestOptions {
17 errorMessageMode?: ErrorMessageMode; 17 errorMessageMode?: ErrorMessageMode;
18 // Whether to add a timestamp 18 // Whether to add a timestamp
19 joinTime?: boolean; 19 joinTime?: boolean;
  20 + ignoreCancelToken?: boolean;
20 } 21 }
21 22
22 export interface CreateAxiosOptions extends AxiosRequestConfig { 23 export interface CreateAxiosOptions extends AxiosRequestConfig {
src/views/demo/system/account/AccountModal.vue
@@ -24,6 +24,7 @@ @@ -24,6 +24,7 @@
24 }); 24 });
25 25
26 const [registerModal, { setModalProps }] = useModalInner((data) => { 26 const [registerModal, { setModalProps }] = useModalInner((data) => {
  27 + setModalProps({ confirmLoading: false });
27 isUpdate.value = !!data?.isUpdate; 28 isUpdate.value = !!data?.isUpdate;
28 29
29 if (unref(isUpdate)) { 30 if (unref(isUpdate)) {
@@ -42,7 +43,7 @@ @@ -42,7 +43,7 @@
42 // TODO custom api 43 // TODO custom api
43 console.log(values); 44 console.log(values);
44 } finally { 45 } finally {
45 - setModalProps({ confirmLoading: true }); 46 + setModalProps({ confirmLoading: false });
46 } 47 }
47 } 48 }
48 49
src/views/demo/system/account/account.data.ts
@@ -3,11 +3,6 @@ import { FormSchema } from &#39;/@/components/Table&#39;; @@ -3,11 +3,6 @@ import { FormSchema } from &#39;/@/components/Table&#39;;
3 3
4 export const columns: BasicColumn[] = [ 4 export const columns: BasicColumn[] = [
5 { 5 {
6 - title: 'ID',  
7 - dataIndex: 'id',  
8 - width: 80,  
9 - },  
10 - {  
11 title: '用户名', 6 title: '用户名',
12 dataIndex: 'account', 7 dataIndex: 'account',
13 width: 120, 8 width: 120,
@@ -23,8 +18,8 @@ export const columns: BasicColumn[] = [ @@ -23,8 +18,8 @@ export const columns: BasicColumn[] = [
23 width: 200, 18 width: 200,
24 }, 19 },
25 { 20 {
26 - title: '更新时间',  
27 - dataIndex: 'updateTime', 21 + title: '创建时间',
  22 + dataIndex: 'createTime',
28 width: 180, 23 width: 180,
29 }, 24 },
30 { 25 {
@@ -35,7 +30,6 @@ export const columns: BasicColumn[] = [ @@ -35,7 +30,6 @@ export const columns: BasicColumn[] = [
35 { 30 {
36 title: '备注', 31 title: '备注',
37 dataIndex: 'remark', 32 dataIndex: 'remark',
38 - width: 200,  
39 }, 33 },
40 ]; 34 ];
41 35
src/views/demo/system/account/index.vue
@@ -8,11 +8,11 @@ @@ -8,11 +8,11 @@
8 <TableAction 8 <TableAction
9 :actions="[ 9 :actions="[
10 { 10 {
11 - label: '编辑', 11 + icon: 'clarity:note-edit-line',
12 onClick: handleEdit.bind(null, record), 12 onClick: handleEdit.bind(null, record),
13 }, 13 },
14 { 14 {
15 - label: '删除', 15 + icon: 'ant-design:delete-outlined',
16 color: 'error', 16 color: 'error',
17 popConfirm: { 17 popConfirm: {
18 title: '是否确认删除', 18 title: '是否确认删除',
@@ -55,8 +55,9 @@ @@ -55,8 +55,9 @@
55 }, 55 },
56 useSearchForm: true, 56 useSearchForm: true,
57 showTableSetting: true, 57 showTableSetting: true,
  58 + bordered: true,
58 actionColumn: { 59 actionColumn: {
59 - width: 160, 60 + width: 80,
60 title: '操作', 61 title: '操作',
61 dataIndex: 'action', 62 dataIndex: 'action',
62 slots: { customRender: 'action' }, 63 slots: { customRender: 'action' },
src/views/demo/system/dept/DeptModal.vue 0 → 100644
  1 +<template>
  2 + <BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
  3 + <BasicForm @register="registerForm" />
  4 + </BasicModal>
  5 +</template>
  6 +<script lang="ts">
  7 + import { defineComponent, ref, computed, unref } from 'vue';
  8 + import { BasicModal, useModalInner } from '/@/components/Modal';
  9 + import { BasicForm, useForm } from '/@/components/Form/index';
  10 + import { formSchema } from './dept.data';
  11 +
  12 + import { getDeptList } from '/@/api/demo/system';
  13 + export default defineComponent({
  14 + name: 'DeptModal',
  15 + components: { BasicModal, BasicForm },
  16 + emits: ['success', 'register'],
  17 + setup(_, { emit }) {
  18 + const isUpdate = ref(true);
  19 +
  20 + const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
  21 + labelWidth: 100,
  22 + schemas: formSchema,
  23 + showActionButtonGroup: false,
  24 + actionColOptions: {
  25 + span: 23,
  26 + },
  27 + });
  28 +
  29 + const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
  30 + resetFields();
  31 + setModalProps({ confirmLoading: false });
  32 + isUpdate.value = !!data?.isUpdate;
  33 +
  34 + if (unref(isUpdate)) {
  35 + setFieldsValue({
  36 + ...data.record,
  37 + });
  38 + }
  39 + const treeData = await getDeptList();
  40 + updateSchema({
  41 + field: 'parentDept',
  42 + componentProps: { treeData },
  43 + });
  44 + });
  45 +
  46 + const getTitle = computed(() => (!unref(isUpdate) ? '新增部门' : '编辑部门'));
  47 +
  48 + async function handleSubmit() {
  49 + try {
  50 + const values = await validate();
  51 + setModalProps({ confirmLoading: true });
  52 + // TODO custom api
  53 + console.log(values);
  54 + closeModal();
  55 + emit('success');
  56 + } finally {
  57 + setModalProps({ confirmLoading: false });
  58 + }
  59 + }
  60 +
  61 + return { registerModal, registerForm, getTitle, handleSubmit };
  62 + },
  63 + });
  64 +</script>
src/views/demo/system/dept/dept.data.ts 0 → 100644
  1 +import { BasicColumn } from '/@/components/Table';
  2 +import { FormSchema } from '/@/components/Table';
  3 +import { h } from 'vue';
  4 +import { Tag } from 'ant-design-vue';
  5 +
  6 +export const columns: BasicColumn[] = [
  7 + {
  8 + title: '部门名称',
  9 + dataIndex: 'deptName',
  10 + width: 300,
  11 + },
  12 + {
  13 + title: '排序',
  14 + dataIndex: 'orderNo',
  15 + width: 80,
  16 + },
  17 + {
  18 + title: '状态',
  19 + dataIndex: 'status',
  20 + width: 120,
  21 + customRender: ({ record }) => {
  22 + const status = record.status;
  23 + const enable = ~~status === 0;
  24 + const color = enable ? 'green' : 'red';
  25 + const text = enable ? '正常' : '停用';
  26 + return h(Tag, { color: color }, () => text);
  27 + },
  28 + },
  29 + {
  30 + title: '创建时间',
  31 + dataIndex: 'createTime',
  32 + width: 180,
  33 + },
  34 + {
  35 + title: '备注',
  36 + dataIndex: 'remark',
  37 + },
  38 +];
  39 +
  40 +export const searchFormSchema: FormSchema[] = [
  41 + {
  42 + field: 'deptName',
  43 + label: '部门名称',
  44 + component: 'Input',
  45 + colProps: { span: 8 },
  46 + },
  47 + {
  48 + field: 'status',
  49 + label: '状态',
  50 + component: 'Select',
  51 + componentProps: {
  52 + options: [
  53 + { label: '启用', value: '0' },
  54 + { label: '停用', value: '1' },
  55 + ],
  56 + },
  57 + colProps: { span: 8 },
  58 + },
  59 +];
  60 +
  61 +export const formSchema: FormSchema[] = [
  62 + {
  63 + field: 'deptName',
  64 + label: '部门名称',
  65 + component: 'Input',
  66 + required: true,
  67 + },
  68 + {
  69 + field: 'parentDept',
  70 + label: '上级部门',
  71 + component: 'TreeSelect',
  72 + componentProps: {
  73 + replaceFields: {
  74 + title: 'deptName',
  75 + key: 'id',
  76 + value: 'id',
  77 + },
  78 + getPopupContainer: () => document.body,
  79 + },
  80 + required: true,
  81 + },
  82 + {
  83 + field: 'orderNo',
  84 + label: '排序',
  85 + component: 'InputNumber',
  86 + required: true,
  87 + },
  88 + {
  89 + field: 'status',
  90 + label: '状态',
  91 + component: 'RadioButtonGroup',
  92 + componentProps: {
  93 + options: [
  94 + { label: '正常', value: '0' },
  95 + { label: '禁用', value: '1' },
  96 + ],
  97 + },
  98 + required: true,
  99 + },
  100 + {
  101 + label: '备注',
  102 + field: 'remark',
  103 + component: 'InputTextArea',
  104 + },
  105 +];
src/views/demo/system/dept/index.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <BasicTable @register="registerTable">
  4 + <template #toolbar>
  5 + <a-button type="primary" @click="handleCreate"> 新增部门 </a-button>
  6 + </template>
  7 + <template #action="{ record }">
  8 + <TableAction
  9 + :actions="[
  10 + {
  11 + icon: 'clarity:note-edit-line',
  12 + onClick: handleEdit.bind(null, record),
  13 + },
  14 + {
  15 + icon: 'ant-design:delete-outlined',
  16 + color: 'error',
  17 + popConfirm: {
  18 + title: '是否确认删除',
  19 + confirm: handleDelete.bind(null, record),
  20 + },
  21 + },
  22 + ]"
  23 + />
  24 + </template>
  25 + </BasicTable>
  26 + <DeptModal @register="registerModal" @success="handleSuccess" />
  27 + </div>
  28 +</template>
  29 +<script lang="ts">
  30 + import { defineComponent } from 'vue';
  31 +
  32 + import { BasicTable, useTable, TableAction } from '/@/components/Table';
  33 + import { getDeptList } from '/@/api/demo/system';
  34 +
  35 + import { useModal } from '/@/components/Modal';
  36 + import DeptModal from './DeptModal.vue';
  37 +
  38 + import { columns, searchFormSchema } from './dept.data';
  39 +
  40 + export default defineComponent({
  41 + name: 'DeptManagement',
  42 + components: { BasicTable, DeptModal, TableAction },
  43 + setup() {
  44 + const [registerModal, { openModal }] = useModal();
  45 + const [registerTable, { reload }] = useTable({
  46 + title: '部门列表',
  47 + api: getDeptList,
  48 + columns,
  49 + formConfig: {
  50 + labelWidth: 120,
  51 + schemas: searchFormSchema,
  52 + },
  53 + pagination: false,
  54 + striped: false,
  55 + useSearchForm: true,
  56 + showTableSetting: true,
  57 + bordered: true,
  58 + showIndexColumn: false,
  59 + indentSize: 20,
  60 + actionColumn: {
  61 + width: 80,
  62 + title: '操作',
  63 + dataIndex: 'action',
  64 + slots: { customRender: 'action' },
  65 + fixed: undefined,
  66 + },
  67 + });
  68 +
  69 + function handleCreate() {
  70 + openModal(true, {
  71 + isUpdate: false,
  72 + });
  73 + }
  74 +
  75 + function handleEdit(record: Recordable) {
  76 + openModal(true, {
  77 + record,
  78 + isUpdate: true,
  79 + });
  80 + }
  81 +
  82 + function handleDelete(record: Recordable) {
  83 + console.log(record);
  84 + }
  85 +
  86 + function handleSuccess() {
  87 + reload();
  88 + }
  89 +
  90 + return {
  91 + registerTable,
  92 + registerModal,
  93 + handleCreate,
  94 + handleEdit,
  95 + handleDelete,
  96 + handleSuccess,
  97 + };
  98 + },
  99 + });
  100 +</script>
src/views/demo/system/password/index.vue 0 → 100644
  1 +<template>
  2 + <div class="p-4 flex flex-col justify-center items-center">
  3 + <BasicForm @register="register" />
  4 +
  5 + <div class="flex justify-center">
  6 + <a-button @click="resetFields"> 重置 </a-button>
  7 + <a-button class="ml-4" type="primary" @click="handleSubmit"> 确认 </a-button>
  8 + </div>
  9 + </div>
  10 +</template>
  11 +<script lang="ts">
  12 + import { defineComponent } from 'vue';
  13 +
  14 + import { BasicForm, useForm } from '/@/components/Form';
  15 +
  16 + import { formSchema } from './pwd.data';
  17 + export default defineComponent({
  18 + name: 'ChangePassword',
  19 + components: { BasicForm },
  20 + setup() {
  21 + const [register, { validate, resetFields }] = useForm({
  22 + size: 'large',
  23 + labelWidth: 100,
  24 + showActionButtonGroup: false,
  25 + schemas: formSchema,
  26 + });
  27 +
  28 + async function handleSubmit() {
  29 + try {
  30 + const values = await validate();
  31 + const { passwordOld, passwordNew } = values;
  32 +
  33 + // TODO custom api
  34 + console.log(passwordOld, passwordNew);
  35 + // const { router } = useRouter();
  36 + // router.push(pageEnum.BASE_LOGIN);
  37 + } catch (error) {}
  38 + }
  39 +
  40 + return { register, resetFields, handleSubmit };
  41 + },
  42 + });
  43 +</script>
src/views/demo/system/password/pwd.data.ts 0 → 100644
  1 +import { FormSchema } from '/@/components/Form';
  2 +
  3 +export const formSchema: FormSchema[] = [
  4 + {
  5 + field: 'passwordOld',
  6 + label: '当前密码',
  7 + component: 'InputPassword',
  8 + required: true,
  9 + },
  10 + {
  11 + field: 'passwordNew',
  12 + label: '新密码',
  13 + component: 'StrengthMeter',
  14 + componentProps: {
  15 + placeholder: '新密码',
  16 + },
  17 + rules: [
  18 + {
  19 + required: true,
  20 + message: '请输入新密码',
  21 + },
  22 + ],
  23 + },
  24 + {
  25 + field: 'confirmPassword',
  26 + label: '确认密码',
  27 + component: 'InputPassword',
  28 +
  29 + dynamicRules: ({ values }) => {
  30 + return [
  31 + {
  32 + required: true,
  33 + validator: (_, value) => {
  34 + if (!value) {
  35 + return Promise.reject('不能为空');
  36 + }
  37 + if (value !== values.passwordNew) {
  38 + return Promise.reject('两次输入的密码不一致!');
  39 + }
  40 + return Promise.resolve();
  41 + },
  42 + },
  43 + ];
  44 + },
  45 + },
  46 +];
yarn.lock
@@ -1702,18 +1702,18 @@ @@ -1702,18 +1702,18 @@
1702 resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.5.tgz#c131d88bd6713cc4d93b3bb1372edb1983225ff0" 1702 resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.5.tgz#c131d88bd6713cc4d93b3bb1372edb1983225ff0"
1703 integrity sha512-gYsNoGkWejBxNO6SNRjOh/xKeZ0H0V+TFzaPzODfBjkAIb0aQgBuixC1brandC/CDJy1wYPwSoYrXpvul7m6yw== 1703 integrity sha512-gYsNoGkWejBxNO6SNRjOh/xKeZ0H0V+TFzaPzODfBjkAIb0aQgBuixC1brandC/CDJy1wYPwSoYrXpvul7m6yw==
1704 1704
1705 -"@vueuse/core@^4.3.0":  
1706 - version "4.3.0"  
1707 - resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.3.0.tgz#409d1c8fc0b7fffcf5b5388dfc487762bb936b0c"  
1708 - integrity sha512-PQ3r6wZDCN3pY+UBB5NLQdRfwiasd8MmWppuzpvNE2Sr8T48gmWXDWw3GG4EHMXnuz5EBfQG+U+1TjSaGaK6/w== 1705 +"@vueuse/core@^4.3.1":
  1706 + version "4.3.1"
  1707 + resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.3.1.tgz#f6fdb2afef6acbe59abb9832d0a7cfa01e65ce36"
  1708 + integrity sha512-/UkL83zSkE1qb1aqidSjUxADB9ggRnchXe5CliqAb5Ak7Rt9IfdUC4zfvvAtwlIgNvT1Fo9YCtgRma4H2TVLEQ==
1709 dependencies: 1709 dependencies:
1710 - "@vueuse/shared" "4.3.0" 1710 + "@vueuse/shared" "4.3.1"
1711 vue-demi latest 1711 vue-demi latest
1712 1712
1713 -"@vueuse/shared@4.3.0":  
1714 - version "4.3.0"  
1715 - resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.3.0.tgz#82e05dc2941642814ac6fcbb5f9076c38c052968"  
1716 - integrity sha512-udc1ADIYwizTK/iSfjZQj6+QDFM099oHuX0Sj/yv0NgE9eSODcesV4zO7PtvmJanzw43hCdvtdGBz8miyRkHCQ== 1713 +"@vueuse/shared@4.3.1":
  1714 + version "4.3.1"
  1715 + resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.3.1.tgz#6f0f6c82f096ca329d9541d6f37f29a2d19dd107"
  1716 + integrity sha512-K2F+z16BqcOtEp/pJEK7cPvOMsgBChGGfx0UAatXt8Awk+b4Vi6L6//KclAV1N7w+e9u2kJlC1Ld8GqdY5ZxRg==
1717 dependencies: 1717 dependencies:
1718 vue-demi latest 1718 vue-demi latest
1719 1719
@@ -3600,11 +3600,6 @@ esbuild-register@^2.0.0: @@ -3600,11 +3600,6 @@ esbuild-register@^2.0.0:
3600 source-map-support "^0.5.19" 3600 source-map-support "^0.5.19"
3601 strip-json-comments "^3.1.1" 3601 strip-json-comments "^3.1.1"
3602 3602
3603 -esbuild@^0.8.48:  
3604 - version "0.8.48"  
3605 - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.8.48.tgz#a57e4dde84ec56da1c6ecaefee97e9da6c5b00b5"  
3606 - integrity sha512-lrH8lA8wWQ6Lpe1z6C7ZZaFSmRsUlcQAqe16nf7ITySQ7MV4+vI7qAqQlT/u+c3+9AL3VXmT4MXTxV2e63pO4A==  
3607 -  
3608 esbuild@^0.8.50: 3603 esbuild@^0.8.50:
3609 version "0.8.50" 3604 version "0.8.50"
3610 resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.8.50.tgz#ebf24fde0cdad1a369789dd6fd7a820b0a01e46c" 3605 resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.8.50.tgz#ebf24fde0cdad1a369789dd6fd7a820b0a01e46c"
@@ -3615,6 +3610,11 @@ esbuild@^0.8.52: @@ -3615,6 +3610,11 @@ esbuild@^0.8.52:
3615 resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.8.52.tgz#6dabf11c517af449a96d66da20dfc204ee7b5294" 3610 resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.8.52.tgz#6dabf11c517af449a96d66da20dfc204ee7b5294"
3616 integrity sha512-b5KzFweLLXoXQwdC/e2+Z80c8uo2M5MgP7yQEEebkFw6In4T9CvYcNoM2ElvJt8ByO04zAZUV0fZkXmXoi2s9A== 3611 integrity sha512-b5KzFweLLXoXQwdC/e2+Z80c8uo2M5MgP7yQEEebkFw6In4T9CvYcNoM2ElvJt8ByO04zAZUV0fZkXmXoi2s9A==
3617 3612
  3613 +esbuild@^0.8.53:
  3614 + version "0.8.53"
  3615 + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.8.53.tgz#b408bb0ca1b29dab13d8bbf7d59f59afe6776e86"
  3616 + integrity sha512-GIaYGdMukH58hu+lf07XWAeESBYFAsz8fXnrylHDCbBXKOSNtFmoYA8PhSeSF+3/qzeJ0VjzV9AkLURo5yfu3g==
  3617 +
3618 escalade@^3.1.1: 3618 escalade@^3.1.1:
3619 version "3.1.1" 3619 version "3.1.1"
3620 resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 3620 resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@@ -3720,12 +3720,12 @@ eslint@^7.21.0: @@ -3720,12 +3720,12 @@ eslint@^7.21.0:
3720 text-table "^0.2.0" 3720 text-table "^0.2.0"
3721 v8-compile-cache "^2.0.3" 3721 v8-compile-cache "^2.0.3"
3722 3722
3723 -esno@^0.4.4:  
3724 - version "0.4.4"  
3725 - resolved "https://registry.npmjs.org/esno/-/esno-0.4.4.tgz#88b20add264401321a6545de00c9437edd81ca24"  
3726 - integrity sha512-YthG7d+wodPWKkJTdQPMrKZCbJgtyWsel6UBekjZw8AahUTtkqvtLXcMnRXeZ5YIcjviLXw3Cmq7hVlvB7dFyw== 3723 +esno@^0.4.5:
  3724 + version "0.4.5"
  3725 + resolved "https://registry.npmjs.org/esno/-/esno-0.4.5.tgz#befd93a0b9021b8879aef359d2938d38be960c5a"
  3726 + integrity sha512-QzQZPVlpII0RJCDecsi28gjJFa6DXb/kAn3IHE+XHTw382wAA89jF40DcP/t+Yn/usrHyDlmseBppvr5Jxy7qw==
3727 dependencies: 3727 dependencies:
3728 - esbuild "^0.8.48" 3728 + esbuild "^0.8.53"
3729 esbuild-register "^2.0.0" 3729 esbuild-register "^2.0.0"
3730 3730
3731 espree@^6.2.1: 3731 espree@^6.2.1:
@@ -4811,10 +4811,10 @@ human-signals@^1.1.1: @@ -4811,10 +4811,10 @@ human-signals@^1.1.1:
4811 resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" 4811 resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
4812 integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== 4812 integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
4813 4813
4814 -husky@^5.1.1:  
4815 - version "5.1.1"  
4816 - resolved "https://registry.npmjs.org/husky/-/husky-5.1.1.tgz#8678953fd8deb86f387cbf1ad50bb2f7f96e83f2"  
4817 - integrity sha512-80LZ736V0Nr4/st0c2COYaMbEQhHNmAbLMN8J/kLk7/mo0QdUkUGNDjv/7jVkhug377Wh8wfbWyaVXEJ/h2B/Q== 4814 +husky@^5.1.2:
  4815 + version "5.1.2"
  4816 + resolved "https://registry.npmjs.org/husky/-/husky-5.1.2.tgz#dc6a1f68640455d8d98c28875e073087f86c5081"
  4817 + integrity sha512-lilaRYeDXcAOj8DuRnN9IxUyEMVbYg9rK7yVNkPB5V4hCvxIUxpMeiv9K2h77CE0HzjCnk1Br0oWe1IghXngDQ==
4818 4818
4819 iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: 4819 iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
4820 version "0.4.24" 4820 version "0.4.24"
@@ -7020,11 +7020,16 @@ prettier@^2.2.1: @@ -7020,11 +7020,16 @@ prettier@^2.2.1:
7020 resolved "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" 7020 resolved "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5"
7021 integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== 7021 integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==
7022 7022
7023 -pretty-bytes@^5.3.0, pretty-bytes@^5.5.0: 7023 +pretty-bytes@^5.3.0:
7024 version "5.5.0" 7024 version "5.5.0"
7025 resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.5.0.tgz#0cecda50a74a941589498011cf23275aa82b339e" 7025 resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.5.0.tgz#0cecda50a74a941589498011cf23275aa82b339e"
7026 integrity sha512-p+T744ZyjjiaFlMUZZv6YPC5JrkNj8maRmPaQCWFJFplUAzpIUTRaTcS+7wmZtUoFXHtESJb23ISliaWyz3SHA== 7026 integrity sha512-p+T744ZyjjiaFlMUZZv6YPC5JrkNj8maRmPaQCWFJFplUAzpIUTRaTcS+7wmZtUoFXHtESJb23ISliaWyz3SHA==
7027 7027
  7028 +pretty-bytes@^5.6.0:
  7029 + version "5.6.0"
  7030 + resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
  7031 + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==
  7032 +
7028 pretty-quick@^3.1.0: 7033 pretty-quick@^3.1.0:
7029 version "3.1.0" 7034 version "3.1.0"
7030 resolved "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.0.tgz#cb172e9086deb57455dea7c7e8f136cd0a4aef6c" 7035 resolved "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.0.tgz#cb172e9086deb57455dea7c7e8f136cd0a4aef6c"
@@ -8941,15 +8946,15 @@ vite-plugin-purge-icons@^0.7.0: @@ -8941,15 +8946,15 @@ vite-plugin-purge-icons@^0.7.0:
8941 "@purge-icons/generated" "^0.7.0" 8946 "@purge-icons/generated" "^0.7.0"
8942 rollup-plugin-purge-icons "^0.7.0" 8947 rollup-plugin-purge-icons "^0.7.0"
8943 8948
8944 -vite-plugin-pwa@^0.5.5:  
8945 - version "0.5.5"  
8946 - resolved "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.5.5.tgz#f6bcaf6f6f1af0882fff7a9334aec685b798cceb"  
8947 - integrity sha512-gwPg+pDm87iMOLORz/fOZiNNWNXhHFrMPW34XpX3F9JLl6ytcNZ6cJMYJ1FRKQPtVADqkbZjk3g3AOi1oI6HKQ== 8949 +vite-plugin-pwa@^0.5.6:
  8950 + version "0.5.6"
  8951 + resolved "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.5.6.tgz#483267e83ff3a6f5a0adc97a7e06f841a353cf30"
  8952 + integrity sha512-CQjfKdSm0YMRRdMkfdI1RqJyrCjOFUl61+puGfMNAUMM5tex9rjF9gHxqDV5pN/2jFMQoTKkLLQ7HOYM0VbF2w==
8948 dependencies: 8953 dependencies:
8949 debug "^4.3.2" 8954 debug "^4.3.2"
8950 fast-glob "^3.2.5" 8955 fast-glob "^3.2.5"
8951 - pretty-bytes "^5.5.0"  
8952 - workbox-build "^6.1.0" 8956 + pretty-bytes "^5.6.0"
  8957 + workbox-build "^6.1.1"
8953 8958
8954 vite-plugin-style-import@^0.7.5: 8959 vite-plugin-style-import@^0.7.5:
8955 version "0.7.5" 8960 version "0.7.5"
@@ -9123,24 +9128,24 @@ wordwrap@^1.0.0: @@ -9123,24 +9128,24 @@ wordwrap@^1.0.0:
9123 resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" 9128 resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
9124 integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= 9129 integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
9125 9130
9126 -workbox-background-sync@^6.1.0:  
9127 - version "6.1.0"  
9128 - resolved "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.1.0.tgz#817de1ac1546fb6035759f151b0b4c5f0d3d9506"  
9129 - integrity sha512-A7YWWmAqzLkWYqqxzxoX4mciVjdSHpfX+JMADXoJ9SoLb6l/QReNJE+CNPew+gGPH6JLKNjZeecDmUpXFhzFPA== 9131 +workbox-background-sync@^6.1.1:
  9132 + version "6.1.1"
  9133 + resolved "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.1.1.tgz#db51214299b4be7a8aa274d8037f22d917241101"
  9134 + integrity sha512-w1b3j7snz4pQ8xp0i5Nci40qlglqdk70pbORBtMfl9uikI1qGjYfKq6oYeResCXYxb5mUYS245HsUclb6RFVJA==
9130 dependencies: 9135 dependencies:
9131 - workbox-core "^6.1.0" 9136 + workbox-core "^6.1.1"
9132 9137
9133 -workbox-broadcast-update@^6.1.0:  
9134 - version "6.1.0"  
9135 - resolved "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.1.0.tgz#63c1dc2d519aa6a7b9ce1db2f8da3e1db45b3422"  
9136 - integrity sha512-70G821I1Lb4Ex+rcjfKCbuFJ4WL4RSQsqvcByt/bLpPTTLoE6+VvLX3+1QtSK8P2+NmOsKkAqx9qiQkUdGbaYw== 9138 +workbox-broadcast-update@^6.1.1:
  9139 + version "6.1.1"
  9140 + resolved "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.1.1.tgz#5815749c9ad22ba4ef5184064a62fbdae3b04bf0"
  9141 + integrity sha512-8fBNOQt8ojWWtz3FbkDnKo8CpN6l8UjD2HpQr8tue7HJVfk0X1gfnzZLIDg7HCXhqF7ld3iQbGQqGPf1ihTY6A==
9137 dependencies: 9142 dependencies:
9138 - workbox-core "^6.1.0" 9143 + workbox-core "^6.1.1"
9139 9144
9140 -workbox-build@^6.1.0:  
9141 - version "6.1.0"  
9142 - resolved "https://registry.npmjs.org/workbox-build/-/workbox-build-6.1.0.tgz#e0ba4a0004da1079e934c7452c72c92ef7b52cba"  
9143 - integrity sha512-xJPqTEf+Pg9KAoTrNeVWpMjqi4cJIRn14i02bZjjbHsLNN38qrqc8xwAW48TwoPCYLjp104ST164/3RDgrc7yw== 9145 +workbox-build@^6.1.1:
  9146 + version "6.1.1"
  9147 + resolved "https://registry.npmjs.org/workbox-build/-/workbox-build-6.1.1.tgz#8333626fad45734d842293e6c2c1b725f4e15752"
  9148 + integrity sha512-mAI3dS4VnXri6BFg02arK1403SqHy2sOlzC4NVAk6Rl2+Ddxs+PmJO4cMTyHw0KEhQFcwk6V8cJeGiXJXYzinA==
9144 dependencies: 9149 dependencies:
9145 "@babel/core" "^7.11.1" 9150 "@babel/core" "^7.11.1"
9146 "@babel/preset-env" "^7.11.0" 9151 "@babel/preset-env" "^7.11.0"
@@ -9164,119 +9169,119 @@ workbox-build@^6.1.0: @@ -9164,119 +9169,119 @@ workbox-build@^6.1.0:
9164 strip-comments "^2.0.1" 9169 strip-comments "^2.0.1"
9165 tempy "^0.6.0" 9170 tempy "^0.6.0"
9166 upath "^1.2.0" 9171 upath "^1.2.0"
9167 - workbox-background-sync "^6.1.0"  
9168 - workbox-broadcast-update "^6.1.0"  
9169 - workbox-cacheable-response "^6.1.0"  
9170 - workbox-core "^6.1.0"  
9171 - workbox-expiration "^6.1.0"  
9172 - workbox-google-analytics "^6.1.0"  
9173 - workbox-navigation-preload "^6.1.0"  
9174 - workbox-precaching "^6.1.0"  
9175 - workbox-range-requests "^6.1.0"  
9176 - workbox-recipes "^6.1.0"  
9177 - workbox-routing "^6.1.0"  
9178 - workbox-strategies "^6.1.0"  
9179 - workbox-streams "^6.1.0"  
9180 - workbox-sw "^6.1.0"  
9181 - workbox-window "^6.1.0"  
9182 -  
9183 -workbox-cacheable-response@^6.1.0:  
9184 - version "6.1.0"  
9185 - resolved "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.1.0.tgz#a99fdfe1507848486579df7b204c30e4cd0a74f2"  
9186 - integrity sha512-oDAi0vXHGaE5p9NOo4N180UTcEKm6t2JMgmlrq0PkEW2PZEu9YR/atSnCwzMW7xpDqpKWaQr/LGP4+eixS8gcA==  
9187 - dependencies:  
9188 - workbox-core "^6.1.0"  
9189 -  
9190 -workbox-core@^6.1.0:  
9191 - version "6.1.0"  
9192 - resolved "https://registry.npmjs.org/workbox-core/-/workbox-core-6.1.0.tgz#2671b64f76550e83a4c2202676b67ce372e10881"  
9193 - integrity sha512-s3KqTJfBreO4xCZpR2LB5p/EknAx8eg0QumKiIgxM4hRO0RtwS2pJvTieNEM23X3RqxRhqweriLD8To19KUvjg==  
9194 -  
9195 -workbox-expiration@^6.1.0:  
9196 - version "6.1.0"  
9197 - resolved "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.1.0.tgz#cf6bb384e49d0c92b79233c46671d9c6d82478a2"  
9198 - integrity sha512-jp2xGk+LC4AhCoOxO/bC06GQkq/oVp0ZIf1zXLQh6OD2fWZPkXNjLLSuDnjXoGGPibYrq7gEE/xjAdYGjNWl1A==  
9199 - dependencies:  
9200 - workbox-core "^6.1.0"  
9201 -  
9202 -workbox-google-analytics@^6.1.0:  
9203 - version "6.1.0"  
9204 - resolved "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.1.0.tgz#cd34100536250abc54070bcc23603213eb8e47e4"  
9205 - integrity sha512-BuUAJ747bMPC6IOKaQBXfotGybOfeHDRIC8ElF65ouB4O9kUJ3zh4EFxXmmJLgzTnji6265gXqNWcfuGiidk6A==  
9206 - dependencies:  
9207 - workbox-background-sync "^6.1.0"  
9208 - workbox-core "^6.1.0"  
9209 - workbox-routing "^6.1.0"  
9210 - workbox-strategies "^6.1.0"  
9211 -  
9212 -workbox-navigation-preload@^6.1.0:  
9213 - version "6.1.0"  
9214 - resolved "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.1.0.tgz#e36d19f0d49ab5277e6c4e13b92f40da8955d62f"  
9215 - integrity sha512-N0c5Kmzu7lPKvirukbeZ3lN8KEAZU9xA4b1wmpV0VXUfRXVEk2ayXXqwHwMGFVi6FNCHiDLOcC8a2zW5kFLAeg==  
9216 - dependencies:  
9217 - workbox-core "^6.1.0"  
9218 -  
9219 -workbox-precaching@^6.1.0:  
9220 - version "6.1.0"  
9221 - resolved "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.1.0.tgz#9ee3d28f27cd78daa62f5bd6a0d33f5682ac97a7"  
9222 - integrity sha512-zjye8MVzieBVJ3sS0hFcbKLp7pTHMfJM17YqxCxB0KykXWnxLOpYnStQ9M+bjWJsKJOQvbkPqvq5u9+mtA923g==  
9223 - dependencies:  
9224 - workbox-core "^6.1.0"  
9225 - workbox-routing "^6.1.0"  
9226 - workbox-strategies "^6.1.0"  
9227 -  
9228 -workbox-range-requests@^6.1.0:  
9229 - version "6.1.0"  
9230 - resolved "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.1.0.tgz#5fbe9edfbcdb97153ed5260575a54e53b0f85a2d"  
9231 - integrity sha512-BO025BdAvc6vTBXJfkfibcikMFLmLRECt0FrVrTiiQafdO3jWH9qX9zTdrjYf6GkiIjvejvvmSYegwU1mL6N3Q==  
9232 - dependencies:  
9233 - workbox-core "^6.1.0"  
9234 -  
9235 -workbox-recipes@^6.1.0:  
9236 - version "6.1.0"  
9237 - resolved "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.1.0.tgz#b925f2727ace05ce8762a1b6da6c0d749fd687ee"  
9238 - integrity sha512-r8YLtMtQnvfkK1htnfrrX1CxKHglZJiVlqnct9rYIU17n2LCalHdI0zQrPqzYdLLHZxTX25UpBsdib0cAATy0A==  
9239 - dependencies:  
9240 - workbox-cacheable-response "^6.1.0"  
9241 - workbox-core "^6.1.0"  
9242 - workbox-expiration "^6.1.0"  
9243 - workbox-precaching "^6.1.0"  
9244 - workbox-routing "^6.1.0"  
9245 - workbox-strategies "^6.1.0"  
9246 -  
9247 -workbox-routing@^6.1.0:  
9248 - version "6.1.0"  
9249 - resolved "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.1.0.tgz#f885cb7801e2c9c5678f197656cf27a2b649c1d5"  
9250 - integrity sha512-FXQ5cwb6Mk90fC0rfQLX0pN+r/N4eBafwkh/QanJUq0e6jMPdDFLrlsikZL/0LcXEx+yAkWLytoiS+d2HOEBOw==  
9251 - dependencies:  
9252 - workbox-core "^6.1.0"  
9253 -  
9254 -workbox-strategies@^6.1.0:  
9255 - version "6.1.0"  
9256 - resolved "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.1.0.tgz#9ddcee44408d2fb403f22a7989803b5c58560590"  
9257 - integrity sha512-HvUknzJdZWeV3x7Eq33a7TGAv9/r1TEiQK6kQ1QNzN+IKiqhIjnhKFHmMxb5hK1Gw9/aDSJTLNPDaLPfIJRQFQ==  
9258 - dependencies:  
9259 - workbox-core "^6.1.0"  
9260 -  
9261 -workbox-streams@^6.1.0:  
9262 - version "6.1.0"  
9263 - resolved "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.1.0.tgz#2dbc78ddc863b47aa4fe399d9385d3ed8567e881"  
9264 - integrity sha512-V80OIfoIXaDkjWIGFSae5sBJuaG2r4bXk6HKpntBYaVQ72LD1CgkXRmZKmLJQ9ltHCx9Vmq/7+q1OF5mTKb8Qw==  
9265 - dependencies:  
9266 - workbox-core "^6.1.0"  
9267 - workbox-routing "^6.1.0"  
9268 -  
9269 -workbox-sw@^6.1.0:  
9270 - version "6.1.0"  
9271 - resolved "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.1.0.tgz#dfaca1029264af71f13a90fdfb16cf8d64ed0537"  
9272 - integrity sha512-e2jnIWSmNrpO9Psy4D6euDdRUW8FTXAdMxOj5O02gxa01fri1kfTSM9irDnTGKUiSGc+hlycsvzGdr8bnvzDiA==  
9273 -  
9274 -workbox-window@^6.1.0:  
9275 - version "6.1.0"  
9276 - resolved "https://registry.npmjs.org/workbox-window/-/workbox-window-6.1.0.tgz#5856127f183bcccfd93655b0e3cba5f2432b9156"  
9277 - integrity sha512-sjnE+nTSnrBvYx5KmpESvsTC82P3yy8h5l4Ae4Q8uLqdH29UQ3bMd8puGVVhX1JZFCmV40cvrbZ1fUj+3/TQ9g==  
9278 - dependencies:  
9279 - workbox-core "^6.1.0" 9172 + workbox-background-sync "^6.1.1"
  9173 + workbox-broadcast-update "^6.1.1"
  9174 + workbox-cacheable-response "^6.1.1"
  9175 + workbox-core "^6.1.1"
  9176 + workbox-expiration "^6.1.1"
  9177 + workbox-google-analytics "^6.1.1"
  9178 + workbox-navigation-preload "^6.1.1"
  9179 + workbox-precaching "^6.1.1"
  9180 + workbox-range-requests "^6.1.1"
  9181 + workbox-recipes "^6.1.1"
  9182 + workbox-routing "^6.1.1"
  9183 + workbox-strategies "^6.1.1"
  9184 + workbox-streams "^6.1.1"
  9185 + workbox-sw "^6.1.1"
  9186 + workbox-window "^6.1.1"
  9187 +
  9188 +workbox-cacheable-response@^6.1.1:
  9189 + version "6.1.1"
  9190 + resolved "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.1.1.tgz#1dc71393cbce83559ad05a8ccb6c6fafa4cccc70"
  9191 + integrity sha512-jasNxelRrqCbzIAIMjHk7Ej9BOViBTQlvRJzv3Y0nYuWvxK0CDPQJSraGmTbu3LGiTBbrWEmxe1hVqvLyFKR9A==
  9192 + dependencies:
  9193 + workbox-core "^6.1.1"
  9194 +
  9195 +workbox-core@^6.1.1:
  9196 + version "6.1.1"
  9197 + resolved "https://registry.npmjs.org/workbox-core/-/workbox-core-6.1.1.tgz#c8a9b424031b0cf7dacf9d7b8e023d126c9d0167"
  9198 + integrity sha512-xsc/72AQxFtt2BHmwU8QtnVV+W5ln4nnYGuz9Q5sPWYGqW4cH0P+FpZDoGM59bmNEyNf+W9bEmidW//e5GsbwQ==
  9199 +
  9200 +workbox-expiration@^6.1.1:
  9201 + version "6.1.1"
  9202 + resolved "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.1.1.tgz#4468c3cdfe76b5888f4ae7e3aad63797a7bc24b1"
  9203 + integrity sha512-WbEv8NG1ZUiWI+jv3v7Jqed/PyCMoTpLcf3Nw7tKq0nGy6DFQtmSizO37uJ73oc8vttck97UBPQRiwyP1bZnAg==
  9204 + dependencies:
  9205 + workbox-core "^6.1.1"
  9206 +
  9207 +workbox-google-analytics@^6.1.1:
  9208 + version "6.1.1"
  9209 + resolved "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.1.1.tgz#c31876954779d65e1334c2dc3232e46d6a5f925a"
  9210 + integrity sha512-79PyeE4TyabGXqlDcRG2LKejs8yZ8OoU0/El0BwP8RGrZgp5GMDGuJkat4xggpRTVaOk8rb0aoSbVAYBWpa0pg==
  9211 + dependencies:
  9212 + workbox-background-sync "^6.1.1"
  9213 + workbox-core "^6.1.1"
  9214 + workbox-routing "^6.1.1"
  9215 + workbox-strategies "^6.1.1"
  9216 +
  9217 +workbox-navigation-preload@^6.1.1:
  9218 + version "6.1.1"
  9219 + resolved "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.1.1.tgz#3c7d39d5f102f4a76f24b48f97701b16ae56bd40"
  9220 + integrity sha512-vX5qJDk1Z663nuSSSHkcBFQQJwEe4UHynd5uoX3oC0IlecPclAbyT3QetVh0wYdXv6G6XD/LBd3iNZmlSbTosw==
  9221 + dependencies:
  9222 + workbox-core "^6.1.1"
  9223 +
  9224 +workbox-precaching@^6.1.1:
  9225 + version "6.1.1"
  9226 + resolved "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.1.1.tgz#f387ccdf60aab30228a4c7ed20a1cd8dee6aaaa4"
  9227 + integrity sha512-x8OKwtjd5ewe/x3VlKcXri1P3Tm0uV+uChdMYg/QryrCR9K8x9xwhAw8PZPkwrY0bLLsJMUoX9/lBu8DmjVqTA==
  9228 + dependencies:
  9229 + workbox-core "^6.1.1"
  9230 + workbox-routing "^6.1.1"
  9231 + workbox-strategies "^6.1.1"
  9232 +
  9233 +workbox-range-requests@^6.1.1:
  9234 + version "6.1.1"
  9235 + resolved "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.1.1.tgz#4e6d30e91cfc3855ff16cfa3df458e0487da2b4d"
  9236 + integrity sha512-ikZ0ZwbFAVMzJ08rM/spn9zC2tohGllFVii9R1q0+xMKvoGDsyzoQnoKrXgyUvcjRPn6ByFncAJ5lUKKG4TGkA==
  9237 + dependencies:
  9238 + workbox-core "^6.1.1"
  9239 +
  9240 +workbox-recipes@^6.1.1:
  9241 + version "6.1.1"
  9242 + resolved "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.1.1.tgz#0cd1bd3b2ba223db563428ec5d17e960081f70d4"
  9243 + integrity sha512-GuzJXBQM+YaFxQwFvcRarAScUoRDoaWXKxxkLWHnCJf0H//MQ8zR9Ay1mv21N6iRoSH11S0u/4yxSeembG/fLA==
  9244 + dependencies:
  9245 + workbox-cacheable-response "^6.1.1"
  9246 + workbox-core "^6.1.1"
  9247 + workbox-expiration "^6.1.1"
  9248 + workbox-precaching "^6.1.1"
  9249 + workbox-routing "^6.1.1"
  9250 + workbox-strategies "^6.1.1"
  9251 +
  9252 +workbox-routing@^6.1.1:
  9253 + version "6.1.1"
  9254 + resolved "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.1.1.tgz#833ef6439905757241f9e4d56d8e282c20199c02"
  9255 + integrity sha512-Az3Gt3cHNK+W0gTfSb4eKGfwEap9Slak16Krr5SiLhE1gXUY2C2O123HucVCedXgIoqTLOXMtNj71Cm6SwYDEg==
  9256 + dependencies:
  9257 + workbox-core "^6.1.1"
  9258 +
  9259 +workbox-strategies@^6.1.1:
  9260 + version "6.1.1"
  9261 + resolved "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.1.1.tgz#6e0adda84bcda17d3d0c48baec2eab9b988b9ca6"
  9262 + integrity sha512-7qYA9Eiq6hnP2dyenlD7ZtWI1ArBMT8yhTvHVlaOl9kYY7W+Iv3lAfRCjj/nucOKeVXATx4iVJEuFPn5J+8lzw==
  9263 + dependencies:
  9264 + workbox-core "^6.1.1"
  9265 +
  9266 +workbox-streams@^6.1.1:
  9267 + version "6.1.1"
  9268 + resolved "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.1.1.tgz#0f204f070861eb1afccddeca4a5a8ba069596bd1"
  9269 + integrity sha512-EMhY+Y2O7+XVy8MFRmiDwKezAXLzbgjQOJDbxWaGKtwNPbwOF6gGZjCvmnNAU1K+MAvvUNsAFR6AAUKMSfOyaw==
  9270 + dependencies:
  9271 + workbox-core "^6.1.1"
  9272 + workbox-routing "^6.1.1"
  9273 +
  9274 +workbox-sw@^6.1.1:
  9275 + version "6.1.1"
  9276 + resolved "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.1.1.tgz#203ce4611309df1bf9c142d1e3b3a214b1b62944"
  9277 + integrity sha512-t6LLSx/rOS8d6w4+fsJOHDqGrjO89iBF0F8nBQgBleEPjvs9Be5j4B11y34Fw7s0CggeA3Kciutr4CqnQtPQUg==
  9278 +
  9279 +workbox-window@^6.1.1:
  9280 + version "6.1.1"
  9281 + resolved "https://registry.npmjs.org/workbox-window/-/workbox-window-6.1.1.tgz#c1d60f6a56b49235e36edc73c593fa470ffffc72"
  9282 + integrity sha512-ZT1enHgi6gYfm+HgRWq8nkqLFEtjOjkq3yGV/qhMmKvI39/sIdO4g2LcjqhnUjbhweedX+9KOOu3U4xasQpGcQ==
  9283 + dependencies:
  9284 + workbox-core "^6.1.1"
9280 9285
9281 wrap-ansi@^5.1.0: 9286 wrap-ansi@^5.1.0:
9282 version "5.1.0" 9287 version "5.1.0"