create-young-proj 0.0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +13 -2
  3. package/dist/index.mjs +18 -18
  4. package/index.mjs +3 -3
  5. package/package.json +10 -12
  6. package/template-admin-server/.editorconfig +11 -0
  7. package/template-admin-server/.nvmrc +1 -0
  8. package/template-admin-server/.vscode/extensions.json +6 -0
  9. package/template-admin-server/.vscode/settings.json +4 -0
  10. package/template-admin-server/README.md +73 -0
  11. package/template-admin-server/_gitignore +15 -0
  12. package/template-admin-server/boot.mjs +11 -0
  13. package/template-admin-server/package.json +60 -0
  14. package/template-admin-server/rome.json +22 -0
  15. package/template-admin-server/src/config/config.default.ts +56 -0
  16. package/template-admin-server/src/configuration.ts +47 -0
  17. package/template-admin-server/src/controller/admin.controller.ts +397 -0
  18. package/template-admin-server/src/controller/api.controller.ts +98 -0
  19. package/template-admin-server/src/controller/base.controller.ts +70 -0
  20. package/template-admin-server/src/controller/dto/api.ts +47 -0
  21. package/template-admin-server/src/controller/dto/index.ts +36 -0
  22. package/template-admin-server/src/controller/dto/menu.ts +41 -0
  23. package/template-admin-server/src/controller/dto/role.ts +41 -0
  24. package/template-admin-server/src/controller/dto/user.ts +52 -0
  25. package/template-admin-server/src/controller/menu.controller.ts +138 -0
  26. package/template-admin-server/src/controller/role.controller.ts +116 -0
  27. package/template-admin-server/src/controller/user.controller.ts +108 -0
  28. package/template-admin-server/src/entities/Api.ts +29 -0
  29. package/template-admin-server/src/entities/BaseCreate.ts +30 -0
  30. package/template-admin-server/src/entities/Menu.ts +39 -0
  31. package/template-admin-server/src/entities/Role.ts +36 -0
  32. package/template-admin-server/src/entities/User.ts +35 -0
  33. package/template-admin-server/src/entities/index.ts +10 -0
  34. package/template-admin-server/src/filter/default.filter.ts +22 -0
  35. package/template-admin-server/src/filter/notfound.filter.ts +23 -0
  36. package/template-admin-server/src/middleware/helper.middleware.ts +28 -0
  37. package/template-admin-server/src/middleware/index.ts +9 -0
  38. package/template-admin-server/src/middleware/jwt.middleware.ts +32 -0
  39. package/template-admin-server/src/middleware/report.middleware.ts +26 -0
  40. package/template-admin-server/src/service/api.service.ts +174 -0
  41. package/template-admin-server/src/service/basic.ts +118 -0
  42. package/template-admin-server/src/service/index.ts +10 -0
  43. package/template-admin-server/src/service/menu.service.ts +139 -0
  44. package/template-admin-server/src/service/role.service.ts +286 -0
  45. package/template-admin-server/src/service/user.service.ts +124 -0
  46. package/template-admin-server/src/strategy/jwt.strategy.ts +26 -0
  47. package/template-admin-server/src/types/index.ts +42 -0
  48. package/template-admin-server/src/types/types.d.ts +31 -0
  49. package/template-admin-server/tsconfig.json +24 -0
  50. package/template-vue-admin/.vscode/extensions.json +10 -0
  51. package/template-vue-admin/.vscode/list-add.code-snippets +108 -0
  52. package/template-vue-admin/.vscode/list-export.code-snippets +72 -0
  53. package/template-vue-admin/.vscode/list.code-snippets +61 -0
  54. package/template-vue-admin/.vscode/settings.json +7 -0
  55. package/template-vue-admin/Dockerfile +42 -0
  56. package/template-vue-admin/README.md +75 -0
  57. package/template-vue-admin/_env +8 -0
  58. package/template-vue-admin/_gitignore +30 -0
  59. package/template-vue-admin/boot.mjs +16 -0
  60. package/template-vue-admin/build/custom-plugin.ts +30 -0
  61. package/template-vue-admin/build/index.ts +7 -0
  62. package/template-vue-admin/build/plugins.ts +59 -0
  63. package/template-vue-admin/config/.devrc +2 -0
  64. package/template-vue-admin/config/.onlinerc +2 -0
  65. package/template-vue-admin/config/.testrc +2 -0
  66. package/template-vue-admin/index.html +21 -0
  67. package/template-vue-admin/nitro.config.ts +19 -0
  68. package/template-vue-admin/package.json +50 -0
  69. package/template-vue-admin/plugins/env.ts +26 -0
  70. package/template-vue-admin/public/vite.svg +1 -0
  71. package/template-vue-admin/rome.json +26 -0
  72. package/template-vue-admin/routes/api/[...all].ts +49 -0
  73. package/template-vue-admin/routes/get/env.ts +18 -0
  74. package/template-vue-admin/src/App.vue +14 -0
  75. package/template-vue-admin/src/apis/delete.ts +36 -0
  76. package/template-vue-admin/src/apis/get.ts +84 -0
  77. package/template-vue-admin/src/apis/index.ts +10 -0
  78. package/template-vue-admin/src/apis/patch.ts +79 -0
  79. package/template-vue-admin/src/apis/post.ts +77 -0
  80. package/template-vue-admin/src/assets/img/login_background.jpg +0 -0
  81. package/template-vue-admin/src/auto-components.d.ts +36 -0
  82. package/template-vue-admin/src/auto-imports.d.ts +282 -0
  83. package/template-vue-admin/src/layouts/blank.vue +9 -0
  84. package/template-vue-admin/src/layouts/default/components/Link.vue +23 -0
  85. package/template-vue-admin/src/layouts/default/components/Logo.vue +20 -0
  86. package/template-vue-admin/src/layouts/default/components/Menu.vue +54 -0
  87. package/template-vue-admin/src/layouts/default/components/NavSearch.vue +52 -0
  88. package/template-vue-admin/src/layouts/default/components/ScrollPane.vue +79 -0
  89. package/template-vue-admin/src/layouts/default/components/TagsView.vue +137 -0
  90. package/template-vue-admin/src/layouts/default/components/TopMenu.vue +21 -0
  91. package/template-vue-admin/src/layouts/default/components/UserCenter.vue +50 -0
  92. package/template-vue-admin/src/layouts/default/index.vue +95 -0
  93. package/template-vue-admin/src/main.ts +44 -0
  94. package/template-vue-admin/src/modules/1-router.ts +66 -0
  95. package/template-vue-admin/src/modules/2-pinia.ts +10 -0
  96. package/template-vue-admin/src/modules/3-net.ts +75 -0
  97. package/template-vue-admin/src/modules/4-auth.ts +126 -0
  98. package/template-vue-admin/src/shims.d.ts +12 -0
  99. package/template-vue-admin/src/stores/index.ts +9 -0
  100. package/template-vue-admin/src/stores/local/index.ts +23 -0
  101. package/template-vue-admin/src/stores/session/index.ts +63 -0
  102. package/template-vue-admin/src/stores/tags.ts +109 -0
  103. package/template-vue-admin/src/typings/global.d.ts +70 -0
  104. package/template-vue-admin/src/typings/index.ts +50 -0
  105. package/template-vue-admin/src/views/403.vue +32 -0
  106. package/template-vue-admin/src/views/[...all_404].vue +556 -0
  107. package/template-vue-admin/src/views/base/login.vue +193 -0
  108. package/template-vue-admin/src/views/dashboard/[name].vue +23 -0
  109. package/template-vue-admin/src/views/index.vue +19 -0
  110. package/template-vue-admin/src/views/system/api.vue +161 -0
  111. package/template-vue-admin/src/views/system/hooks/useRole.ts +286 -0
  112. package/template-vue-admin/src/views/system/menuList.vue +195 -0
  113. package/template-vue-admin/src/views/system/role.vue +132 -0
  114. package/template-vue-admin/src/views/system/user.vue +193 -0
  115. package/template-vue-admin/src/vite-env.d.ts +52 -0
  116. package/template-vue-admin/tsconfig.json +21 -0
  117. package/template-vue-admin/tsconfig.node.json +9 -0
  118. package/template-vue-admin/unocss.config.ts +47 -0
  119. package/template-vue-admin/vite.config.ts +32 -0
  120. package/template-vue-thin/package.json +14 -13
  121. package/template-vue-thin/vite.config.ts +1 -6
@@ -0,0 +1,195 @@
1
+ <!--
2
+ * @Author: zhangyang
3
+ * @Date: 2022-05-30 16:28:37
4
+ * @LastEditTime: 2023-01-06 11:35:16
5
+ * @Description: 菜单管理
6
+ -->
7
+ <route lang="yaml">
8
+ meta:
9
+ title: 菜单管理
10
+ authPath: /system/menuList
11
+ </route>
12
+
13
+ <script lang="ts" setup>
14
+ import { deepClone, isArray } from '@bluesyoung/utils';
15
+ import { useFormMode, YoungDialog } from '@bluesyoung/ui-vue3-element-plus';
16
+ import { apis } from '@/modules/3-net';
17
+
18
+ const FORM_TEMP: NavArrItem = {
19
+ breadcrumb: 0,
20
+ component: '',
21
+ createdAt: '',
22
+ creator: '',
23
+ icon: '',
24
+ id: 0,
25
+ name: '',
26
+ not_dev: 0,
27
+ parentId: 0,
28
+ path: '',
29
+ permission: '',
30
+ redirect: '',
31
+ sort: 0,
32
+ status: 1,
33
+ title: '',
34
+ updatedAt: '',
35
+ visible: 1
36
+ };
37
+ // key 的类型必须为 string 才会生效!!!
38
+ const expandKeys = ref<Set<string>>(new Set());
39
+
40
+ let tempArr: string[] = [];
41
+ const getFatherAndSon = (arr: NavArrItem[], num?: number): string[] => {
42
+ if (num === 1) {
43
+ tempArr = [];
44
+ }
45
+ for (const item of arr) {
46
+ tempArr.push(item.id + '');
47
+ if (item.children && isArray(item.children) && item.children.length > 0) {
48
+ getFatherAndSon(deepClone(item.children));
49
+ }
50
+ }
51
+ return tempArr;
52
+ };
53
+ const expandChange = (...args: any) => {
54
+ const [row, isOpen] = args as [NavArrItem, boolean];
55
+ const autoid = row.id;
56
+ if (isOpen) {
57
+ expandKeys.value.add(autoid + '');
58
+ } else {
59
+ const allSub = getFatherAndSon([row], 1);
60
+ allSub.forEach((v) => expandKeys.value.delete(v));
61
+ }
62
+ };
63
+ const tableData = ref<NavArrItem[]>([]);
64
+
65
+ const topMenuOption = ref<Partial<NavArrItem>[]>([]);
66
+
67
+ /**
68
+ * 获取节点列表
69
+ */
70
+ const getList = async () => {
71
+ const list = Object.values(await apis.get.getMenuList());
72
+
73
+ tableData.value = list;
74
+
75
+ topMenuOption.value = [
76
+ { title: '顶级目录', children: list, id: 0 }
77
+ ];
78
+ };
79
+
80
+ const {
81
+ isAdd,
82
+ isEdit,
83
+ form,
84
+ edit,
85
+ del,
86
+ sure,
87
+ clear,
88
+ formRef,
89
+ validForm
90
+ } = useFormMode<NavArrItem>(FORM_TEMP, {
91
+ addCbk: async () => {
92
+ const res = await validForm() as boolean;
93
+ if (res) {
94
+ const v = deepClone(form.value);
95
+ await apis.post.addMenuItem(v);
96
+ ElMessage.success('菜单添加成功!');
97
+ }
98
+ return res;
99
+ },
100
+ modCbk: async () => {
101
+ const res = await validForm() as boolean;
102
+ if (res) {
103
+ const v = deepClone(form.value);
104
+ await apis.patch.changeMenuItem(v);
105
+ ElMessage.success('菜单修改成功!');
106
+ }
107
+ return res;
108
+ },
109
+ delCbk: async (nav: NavArrItem) => {
110
+ apis.delete.deleteMenu(nav.id.toString());
111
+ expandKeys.value.delete(nav.id.toString());
112
+ ElMessage.success('节点删除成功!');
113
+ // 框架有 bug,视图更新不及时
114
+ location.reload();
115
+ },
116
+ cgEffect: async () => {
117
+ await getList();
118
+ }
119
+ });
120
+
121
+ /**
122
+ * 添加节点
123
+ */
124
+ const add = () => {
125
+ form.value.parentId = 0;
126
+ isAdd.value = true;
127
+ };
128
+
129
+ const changeVisiable = async (id: number, visible: number) => {
130
+ await apis.patch.changeMenuItem({ id, visible });
131
+ ElMessage.success('修改成功!');
132
+ getList();
133
+ };
134
+
135
+ getList()
136
+ </script>
137
+
138
+ <template>
139
+ <div class="index">
140
+ <div class="caozuoFat">
141
+ <ElButton type="primary" plain @click="add">新建菜单</ElButton>
142
+ </div>
143
+ <!-- 节点列表 -->
144
+ <ElTable :data="tableData" style="width: 100%; margin-bottom: 20px;" :tree-props="{ children: 'children' }"
145
+ row-key="id" :expand-row-keys="[...expandKeys]" @expand-change="expandChange">
146
+ <ElTableColumn prop="name" label="英文名称" width="320px" />
147
+ <ElTableColumn prop="title" label="标题" />
148
+ <ElTableColumn prop="sort" label="同级排序" />
149
+ <ElTableColumn prop="component" label="页面路径" />
150
+ <ElTableColumn prop="visible" label="隐藏/显示">
151
+ <template #default="scope">
152
+ <ElSwitch v-model="scope.row.visible" :active-value="1" :inactive-value="0" active-color="#409EFF"
153
+ inactive-color="#909399" @change="(e) => changeVisiable(scope.row.id, e as number)" />
154
+ </template>
155
+ </ElTableColumn>
156
+ <ElTableColumn prop="creator" label="创建人" />
157
+ <ElTableColumn label="操作" width="300" fixed="right">
158
+ <template #default="scope">
159
+ <ElButton @click="edit(scope.row)">编辑</ElButton>
160
+ <ElButton type="danger" @click="del(scope.row)">删除</ElButton>
161
+ </template>
162
+ </ElTableColumn>
163
+ </ElTable>
164
+ <!-- 添加 / 编辑 -->
165
+ <YoungDialog width="370px" :is-add="isAdd" :is-edit="isEdit" @sure="sure" @clear="clear">
166
+ <template #body>
167
+ <ElForm ref="formRef" :model="form" label-width="80px">
168
+ <ElFormItem label="上级目录">
169
+ <ElCascader :model-value="form.parentId" :props="{
170
+ label: 'title',
171
+ value: 'id',
172
+ checkStrictly: true,
173
+ multiple: false
174
+ }" :options="topMenuOption" :show-all-levels="false"
175
+ @update:model-value="(e: any) => form.parentId = e[e.length - 1]" />
176
+ </ElFormItem>
177
+ <ElFormItem label="英文名称" prop="name" :rules="{ required: true, message: '请输入英文名', trigger: 'blur' }">
178
+ <ElInput v-model="form.name" placeholder="请输入英文名" />
179
+ </ElFormItem>
180
+ <ElFormItem label="标题" prop="title" :rules="{ required: true, message: '请输入页面标题', trigger: 'blur' }">
181
+ <ElInput v-model="form.title" placeholder="请输入页面标题" />
182
+ </ElFormItem>
183
+ <ElFormItem label="排序">
184
+ <ElInput v-model.number="form.sort" />
185
+ </ElFormItem>
186
+ <ElFormItem label="路径" prop="component" :rules="form.parentId === 0 ? {} :
187
+ { message: '请输入合法的路径, eg: /path/page', trigger: 'blur', validator: (_: any, v: string) => v.trim() === '' || /\/(.*)\/(.*)/.test(v) }
188
+ ">
189
+ <ElInput v-model="form.component" />
190
+ </ElFormItem>
191
+ </ElForm>
192
+ </template>
193
+ </YoungDialog>
194
+ </div>
195
+ </template>
@@ -0,0 +1,132 @@
1
+ <!--
2
+ * @Author: zhangyang
3
+ * @Date: 2022-03-01 20:04:26
4
+ * @LastEditTime: 2023-01-09 10:32:11
5
+ * @Description: 角色列表
6
+ -->
7
+ <route lang="yaml">
8
+ meta:
9
+ title: 角色列表
10
+ authPath: /system/role
11
+ </route>
12
+
13
+ <script lang="ts" setup>
14
+ import { YoungTable, YoungDialog, YoungPagination } from '@bluesyoung/ui-vue3-element-plus';
15
+ import { useRoleApi, useRoleBase, useRoleMenu } from './hooks/useRole';
16
+
17
+ const {
18
+ query,
19
+ getList,
20
+ tableHead,
21
+ tableData,
22
+ baseFormRef,
23
+ changeStatus,
24
+ base
25
+ } = useRoleBase();
26
+
27
+ const { showPriority, menu } = useRoleMenu();
28
+
29
+ const { showApi, api } = useRoleApi();
30
+
31
+ getList();
32
+ </script>
33
+
34
+ <template>
35
+ <div class="flex">
36
+ <div class="m-2">
37
+ <ElInput v-model="query.name" placeholder="请输入角色名称(中文)" />
38
+ </div>
39
+ <div class="m-2">
40
+ <ElInput v-model="query.keyword" placeholder="请输入角色关键字(英文)" />
41
+ </div>
42
+ <div class="m-2 w-50">
43
+ <ElSelect v-model="query.status" placeholder="请选择状态" clearable>
44
+ <ElOption :value="1" label="1-启用" />
45
+ <ElOption :value="0" label="0-禁用" />
46
+ </ElSelect>
47
+ </div>
48
+ <div class="m-2">
49
+ <ElButton type="primary" @click="getList">搜索</ElButton>
50
+ </div>
51
+ <div class="m-2">
52
+ <ElButton type="success" @click="base.isAdd = true">添加角色</ElButton>
53
+ </div>
54
+ </div>
55
+ <div class="m-2">
56
+ <YoungTable :table-data="tableData" :table-head="tableHead" :table-height="680">
57
+ <template #switch>
58
+ <ElTableColumn label="禁用/启用">
59
+ <template #default="scope">
60
+ <ElSwitch v-model="scope.row.status" :active-value="1" :inactive-value="0" active-color="#409EFF"
61
+ inactive-color="#909399" @change="(e) => changeStatus(scope.row.id, e as number)" />
62
+ </template>
63
+ </ElTableColumn>
64
+ </template>
65
+ <template #operate>
66
+ <ElTableColumn label="操作" width="300px" fixed="right">
67
+ <template #default="scope">
68
+ <ElButton type="primary" link @click="base.edit(scope.row)">信息编辑</ElButton>
69
+ <ElButton type="primary" link @click="menu.edit(scope.row)">菜单编辑</ElButton>
70
+ <ElButton type="primary" link @click="api.edit(scope.row)">接口编辑</ElButton>
71
+ <ElButton type="danger" link @click="base.del(scope.row)">删除</ElButton>
72
+ </template>
73
+ </ElTableColumn>
74
+ </template>
75
+ </YoungTable>
76
+ <YoungPagination v-model:page="query.pageNum" v-model:limit="query.pageSize" :total="query.total"
77
+ @page-change="getList" />
78
+ </div>
79
+ <!-- 基础信息编辑 -->
80
+ <YoungDialog :is-add="base.isAdd" :is-edit="base.isEdit" width="520px" @sure="base.sure" @clear="base.clear">
81
+ <template #body>
82
+ <ElForm ref="baseFormRef" :model="base.form" label-width="120px">
83
+ <ElFormItem label="角色名称(中文)" prop="name" :rules="[{ required: true, message: '请填写角色名称', trigger: 'blur' }]">
84
+ <ElInput v-model="base.form.name" class="!w-300px" />
85
+ </ElFormItem>
86
+ <ElFormItem label="关键字(英文)" prop="keyword" :rules="[{ required: true, message: '请填写关键字', trigger: 'blur' }]">
87
+ <ElInput v-model="base.form.keyword" class="!w-300px" />
88
+ </ElFormItem>
89
+ <ElFormItem label="角色描述">
90
+ <ElInput v-model="base.form.desc" class="!w-300px" />
91
+ </ElFormItem>
92
+ </ElForm>
93
+ </template>
94
+ </YoungDialog>
95
+ <!-- 菜单编辑 -->
96
+ <YoungDialog real-title="菜单编辑" :is-edit="showPriority" top="5vh" width="1200px" @sure="menu.sure" @clear="menu.clear">
97
+ <template #body>
98
+ <ElTable :data="menu.tableData" row-key="id" :default-expand-all="false" class="max-h-600px !overflow-y-auto">
99
+ <ElTableColumn prop="name" label="节点名称" width="320px">
100
+ <template #default="scope">
101
+ <ElCheckbox v-model="menu.checkMap[scope.row.id]" @change="menu.selectChange(scope.row)">{{
102
+ scope.row.title
103
+ }}</ElCheckbox>
104
+ </template>
105
+ </ElTableColumn>
106
+ <ElTableColumn v-for="(item, index) in menu.tableHead" v-bind="item" :key="index + 'fsdjhfaer'" />
107
+ <ElTableColumn prop="name" label="隐藏/显示">
108
+ <template #default="scope">
109
+ <ElSwitch v-model="scope.row.visible" :active-value="1" :inactive-value="0" active-color="#409EFF"
110
+ inactive-color="#909399" disabled />
111
+ </template>
112
+ </ElTableColumn>
113
+ </ElTable>
114
+ </template>
115
+ </YoungDialog>
116
+ <!-- 接口编辑 -->
117
+ <YoungDialog real-title="接口编辑" :is-edit="showApi" top="5vh" width="1200px" @sure="api.sure" @clear="api.clear">
118
+ <template #body>
119
+ <ElTable :data="api.tableData" row-key="id" :default-expand-all="false" class="max-h-600px !overflow-y-auto">
120
+ <ElTableColumn prop="name" width="100px">
121
+ <template #header>
122
+ <ElCheckbox v-model="api.isAll" @change="api.changeAll">全选</ElCheckbox>
123
+ </template>
124
+ <template #default="scope">
125
+ <ElCheckbox v-model="api.checkMap[scope.row.id]">{{ scope.row.title }}</ElCheckbox>
126
+ </template>
127
+ </ElTableColumn>
128
+ <ElTableColumn v-for="(item, index) in api.tableHead" v-bind="item" :key="index + 'fsdjhfaer'" />
129
+ </ElTable>
130
+ </template>
131
+ </YoungDialog>
132
+ </template>
@@ -0,0 +1,193 @@
1
+ <!--
2
+ * @Author: zhangyang
3
+ * @Date: 2022-10-27 11:28:27
4
+ * @LastEditTime: 2023-01-09 10:32:20
5
+ * @Description:
6
+ -->
7
+ <route lang="yaml">
8
+ meta:
9
+ title: 用户管理
10
+ authPath: /system/user
11
+ </route>
12
+
13
+ <script lang="ts" setup>
14
+ import { useFormMode, YoungDialog, YoungPagination, YoungTable, YoungSelect } from '@bluesyoung/ui-vue3-element-plus';
15
+ import type { TableHeadItem, TableDataItem, SelectOptionItem } from '@bluesyoung/ui-vue3-element-plus';
16
+ import { deepClone } from '@bluesyoung/utils';
17
+ import { RoleItem, UserItem } from '@/typings';
18
+ import { apis } from '@/modules/3-net';
19
+
20
+ interface Form extends UserItem { };
21
+ const FORM_TEMP: Form = {
22
+ id: 0,
23
+ username: '',
24
+ nickname: '',
25
+ mobile: '',
26
+ roleId: 1,
27
+ status: 1,
28
+ initPassword: ''
29
+ };
30
+ const {
31
+ isAdd,
32
+ isEdit,
33
+ edit,
34
+ del,
35
+ sure,
36
+ clear,
37
+ form,
38
+ formRef,
39
+ validForm
40
+ } = useFormMode<Form>(FORM_TEMP, {
41
+ addCbk: async () => {
42
+ const res = await validForm() as boolean;
43
+ if (res) {
44
+ const v = deepClone(form.value);
45
+ await apis.post.addUserItem(v);
46
+ ElMessage.success('新增成功!');
47
+ }
48
+ return res;
49
+ },
50
+ modCbk: async () => {
51
+ const res = await validForm() as boolean;
52
+ if (res) {
53
+ const v = deepClone(form.value);
54
+ await apis.patch.changeUserItem(v);
55
+ ElMessage.success('修改成功!');
56
+ }
57
+ return res;
58
+ },
59
+ delCbk: async (row) => {
60
+ await apis.delete.deleteUser(row.id.toString());
61
+ ElMessage.success('删除成功!');
62
+ query.pageNum = 1;
63
+ },
64
+ cgEffect: () => getList()
65
+ });
66
+ const tableHead: TableHeadItem<Form>[] = [
67
+ { prop: 'id', label: '用户ID' },
68
+ { prop: 'username', label: '用户名' },
69
+ { prop: 'mobile', label: '手机号' },
70
+ { prop: 'role_name', label: '角色名称' },
71
+ { prop: 'creator', label: '创建信息' },
72
+ ];
73
+ interface Query extends BaseQuery {
74
+ username: string;
75
+ mobile: string;
76
+ status: 0 | 1;
77
+ };
78
+ const query = reactive<Query>({
79
+ pageNum: 1,
80
+ pageSize: 50,
81
+ total: 0,
82
+ username: '',
83
+ mobile: '',
84
+ status: 1
85
+ });
86
+
87
+ const tableData = ref<TableDataItem<Form>[]>([]);
88
+ const roleList = ref<SelectOptionItem<number>[]>([]);
89
+ const getList = async () => {
90
+ const { list: role_list } = await apis.get.getRoleList({ noPagination: true });
91
+ roleList.value = (role_list || []).map((item: RoleItem) => {
92
+ return {
93
+ label: item.name,
94
+ value: item.id
95
+ };
96
+ });
97
+
98
+ const { list, pageNum, pageSize, total } = await apis.get.getUserList(query);
99
+ tableData.value = deepClone(list || []);
100
+ query.pageNum = +pageNum || 1;
101
+ query.pageSize = +pageSize || 50;
102
+ query.total = +total || 0;
103
+ };
104
+ /**
105
+ * @param id userId
106
+ * @param status 0 | 1
107
+ */
108
+ const changeStatus = async (id: number, status: number) => {
109
+ await apis.patch.changeUserItem({ id, status });
110
+ ElMessage.success('修改成功!');
111
+ getList();
112
+ };
113
+
114
+ const changePwd = (e: UserItem) => {
115
+ ElMessageBox.prompt('请输入新密码').then(async ({ value }) => {
116
+ value = value.trim()
117
+ if (value) {
118
+ await apis.patch.changeUserItem({ id: e.id, newPassword: value });
119
+ ElMessage.success('修改成功!');
120
+ }
121
+ }).catch(() => null);
122
+ };
123
+
124
+ getList();
125
+ </script>
126
+
127
+ <template>
128
+ <div class="flex">
129
+ <div class="m-2">
130
+ <ElInput v-model="query.username" placeholder="请输入用户名" />
131
+ </div>
132
+ <div class="m-2">
133
+ <ElInput v-model="query.mobile" placeholder="请输入手机号" :maxlength="11" />
134
+ </div>
135
+ <div class="m-2 w-50">
136
+ <ElSelect v-model="query.status" placeholder="请选择状态" clearable>
137
+ <ElOption :value="1" label="1-启用" />
138
+ <ElOption :value="0" label="0-禁用" />
139
+ </ElSelect>
140
+ </div>
141
+ <div class="m-2">
142
+ <ElButton type="primary" @click="getList">搜索</ElButton>
143
+ </div>
144
+ <div class="m-2">
145
+ <ElButton type="success" @click="isAdd = true">添加用户</ElButton>
146
+ </div>
147
+ </div>
148
+ <div class="m-2">
149
+ <YoungTable :table-data="tableData" :table-head="tableHead" :table-height="680">
150
+ <template #switch>
151
+ <ElTableColumn label="禁用/启用">
152
+ <template #default="scope">
153
+ <ElSwitch v-model="scope.row.status" :active-value="1" :inactive-value="0" active-color="#409EFF"
154
+ inactive-color="#909399" @change="(e) => changeStatus(scope.row.id, e as number)" />
155
+ </template>
156
+ </ElTableColumn>
157
+ </template>
158
+ <template #operate>
159
+ <ElTableColumn label="操作" width="300px" fixed="right">
160
+ <template #default="scope">
161
+ <ElButton type="primary" link @click="edit(scope.row)">编辑</ElButton>
162
+ <ElButton type="warning" link @click="changePwd(scope.row)">修改密码</ElButton>
163
+ <ElButton type="danger" link @click="del(scope.row)">删除</ElButton>
164
+ </template>
165
+ </ElTableColumn>
166
+ </template>
167
+ </YoungTable>
168
+ <YoungPagination v-show="query.total > 0" v-model:page="query.pageNum" v-model:limit="query.pageSize"
169
+ :total="query.total" @page-change="getList" />
170
+ </div>
171
+ <YoungDialog :is-add="isAdd" :is-edit="isEdit" width="520px" @sure="sure" @clear="clear">
172
+ <template #body>
173
+ <ElForm ref="formRef" :model="form" label-width="100px">
174
+ <ElFormItem label="用户名" prop="username" :rules="{ required: true, message: '请输用户名', trigger: 'blur' }">
175
+ <ElInput v-model="form.username" class="!w-300px" />
176
+ </ElFormItem>
177
+ <ElFormItem label="昵称" prop="nickname" :rules="{ required: true, message: '请输昵称(用于右上角展示)', trigger: 'blur' }">
178
+ <ElInput v-model="form.nickname" class="!w-300px" />
179
+ </ElFormItem>
180
+ <ElFormItem label="手机号" prop="mobile" :rules="{ required: true, message: '请输手机号', trigger: 'blur' }">
181
+ <ElInput v-model="form.mobile" :maxlength="11" class="!w-300px" />
182
+ </ElFormItem>
183
+ <ElFormItem label="角色">
184
+ <YoungSelect v-model="form.roleId" placeholder="请选择角色" :options="roleList" />
185
+ </ElFormItem>
186
+ <ElFormItem v-if="isAdd" label="初始密码" prop="initPassword"
187
+ :rules="{ required: true, message: '请输初始密码', trigger: 'blur' }">
188
+ <ElInput v-model="form.initPassword" class="!w-300px" />
189
+ </ElFormItem>
190
+ </ElForm>
191
+ </template>
192
+ </YoungDialog>
193
+ </template>
@@ -0,0 +1,52 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2022-12-03 15:57:40
4
+ * @LastEditTime: 2023-01-05 09:16:16
5
+ * @Description:
6
+ */
7
+ /// <reference types="vite/client" />
8
+ /// <reference types="vite-plugin-pages/client" />
9
+ /// <reference types="vite-plugin-vue-layouts/client" />
10
+
11
+ declare module '*.vue' {
12
+ import type { DefineComponent } from 'vue'
13
+ const component: DefineComponent<{}, {}, any>
14
+ export default component
15
+ }
16
+
17
+ /**
18
+ * import.meta.env 类型提示
19
+ */
20
+ declare interface ImportMetaEnv {
21
+ /**
22
+ * 标题
23
+ */
24
+ VITE_TITLE?: string;
25
+
26
+ /**
27
+ * 基础接口请求地址
28
+ */
29
+ VITE_BASE_HTTP: string;
30
+
31
+
32
+ /**
33
+ * 是否启用 Casdoor
34
+ */
35
+ // VITE_ENABLE_CASDOOR?: string;
36
+ /**
37
+ * Casdoor 相关
38
+ */
39
+ // VITE_CAS_SERVER?: string;
40
+ // VITE_CAS_ID?: string;
41
+ // VITE_CAS_ORG?: string;
42
+ // VITE_CAS_APP?: string;
43
+
44
+ /**
45
+ * 是否静态部署
46
+ */
47
+ VITE_USE_DEFAULT_DEPLOY_METHOD?: boolean;
48
+ }
49
+
50
+ declare interface Window {
51
+ __YOUNG_VITE_ENV__: ImportMetaEnv;
52
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "Node",
7
+ "strict": true,
8
+ "jsx": "preserve",
9
+ "resolveJsonModule": true,
10
+ "isolatedModules": true,
11
+ "esModuleInterop": true,
12
+ "lib": ["ESNext", "DOM"],
13
+ "skipLibCheck": true,
14
+ "noEmit": true,
15
+ "paths": {
16
+ "@/*": ["./src/*"]
17
+ }
18
+ },
19
+ "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", ".nitro/**/*"],
20
+ "references": [{ "path": "./tsconfig.node.json" }]
21
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "module": "ESNext",
5
+ "moduleResolution": "Node",
6
+ "allowSyntheticDefaultImports": true
7
+ },
8
+ "include": ["vite.config.ts", "build/**/*.ts"]
9
+ }
@@ -0,0 +1,47 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2022-03-01 19:11:11
4
+ * @LastEditTime: 2022-05-21 18:32:05
5
+ * @Description:
6
+ */
7
+ import {
8
+ defineConfig,
9
+ presetAttributify,
10
+ presetIcons,
11
+ presetTypography,
12
+ presetUno,
13
+ presetWebFonts,
14
+ transformerDirectives,
15
+ transformerVariantGroup,
16
+ } from 'unocss';
17
+
18
+ export default defineConfig({
19
+ shortcuts: [
20
+ [
21
+ 'btn',
22
+ 'px-4 py-1 rounded inline-block bg-teal-700 text-white cursor-pointer hover:bg-teal-800 disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50',
23
+ ],
24
+ [
25
+ 'icon-btn',
26
+ 'inline-block cursor-pointer select-none opacity-75 transition duration-200 ease-in-out hover:opacity-100 hover:text-teal-600',
27
+ ],
28
+ ],
29
+ presets: [
30
+ presetUno(),
31
+ presetAttributify(),
32
+ presetIcons({
33
+ scale: 1.2,
34
+ warn: true,
35
+ }),
36
+ presetTypography(),
37
+ presetWebFonts({
38
+ fonts: {
39
+ sans: 'DM Sans',
40
+ serif: 'DM Serif Display',
41
+ mono: 'DM Mono',
42
+ },
43
+ }),
44
+ ],
45
+ transformers: [transformerDirectives(), transformerVariantGroup()],
46
+ safelist: 'prose prose-sm m-auto text-left'.split(' '),
47
+ });
@@ -0,0 +1,32 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2022-12-03 15:57:40
4
+ * @LastEditTime: 2023-01-10 15:12:20
5
+ * @Description:
6
+ */
7
+ import { fileURLToPath, URL } from 'node:url';
8
+ import { defineConfig, loadEnv } from 'vite';
9
+ import type { ConfigEnv, UserConfigExport } from 'vite';
10
+ import { usePlugins, localServer } from './build';
11
+
12
+ // https://vitejs.dev/config/
13
+ export default ({ command, mode }: ConfigEnv): UserConfigExport => {
14
+ const root = process.cwd();
15
+ const viteEnv = loadEnv(mode, root);
16
+ console.log('🚀 ~ file: vite.config.ts ~ line 36 ~ viteEnv', viteEnv);
17
+ return defineConfig({
18
+ base: './',
19
+ plugins: usePlugins(),
20
+ resolve: {
21
+ alias: {
22
+ '@': fileURLToPath(new URL('./src', import.meta.url)),
23
+ },
24
+ },
25
+ server: {
26
+ host: true,
27
+ proxy: {
28
+ '/api': localServer,
29
+ },
30
+ },
31
+ });
32
+ };