create-young-proj 0.10.1 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +6 -0
- package/dist/index.mjs +9 -9
- package/package.json +1 -1
- package/template-nuxt-admin/README.md +42 -1
- package/template-nuxt-admin/components/TopUser.vue +4 -4
- package/template-nuxt-admin/components/YoungChangePassword.vue +5 -5
- package/template-nuxt-admin/components/layout/Main.vue +2 -2
- package/template-nuxt-admin/components/layout/NavBar.vue +11 -2
- package/template-nuxt-admin/components/layout/SideBar.vue +7 -2
- package/template-nuxt-admin/components/layout/SubMenu.vue +9 -2
- package/template-nuxt-admin/components/layout/TabsBar.vue +4 -5
- package/template-nuxt-admin/composables/api.ts +20 -21
- package/template-nuxt-admin/composables/nav.ts +20 -3
- package/template-nuxt-admin/composables/tags.ts +29 -1
- package/template-nuxt-admin/composables/user.ts +21 -3
- package/template-nuxt-admin/middleware/auth.global.ts +26 -7
- package/template-nuxt-admin/nuxt.config.ts +5 -1
- package/template-nuxt-admin/package.json +1 -1
- package/template-nuxt-admin/pages/home/[id].vue +2 -2
- package/template-nuxt-admin/pages/index.vue +2 -7
- package/template-nuxt-admin/pages/login.vue +5 -3
- package/template-nuxt-admin/pages/system/menuList.vue +0 -1
- package/template-nuxt-admin/public/bg.webp +0 -0
- package/template-nuxt-admin/public/favicon.svg +2 -0
- package/template-nuxt-admin/public/logo.svg +2 -0
- package/template-nuxt-admin/server/plugins/env.ts +3 -4
- package/template-nuxt-admin/utils/tool.ts +62 -70
- package/template-nuxt-admin/public/favicon.ico +0 -0
- package/template-vue-admin/.vscode/extensions.json +0 -10
- package/template-vue-admin/.vscode/list-add.code-snippets +0 -108
- package/template-vue-admin/.vscode/list-export.code-snippets +0 -72
- package/template-vue-admin/.vscode/list.code-snippets +0 -61
- package/template-vue-admin/.vscode/settings.json +0 -7
- package/template-vue-admin/Dockerfile +0 -42
- package/template-vue-admin/README.md +0 -75
- package/template-vue-admin/_env +0 -8
- package/template-vue-admin/_gitignore +0 -30
- package/template-vue-admin/boot.mjs +0 -16
- package/template-vue-admin/build/custom-plugin.ts +0 -57
- package/template-vue-admin/build/index.ts +0 -7
- package/template-vue-admin/build/plugins.ts +0 -59
- package/template-vue-admin/config/.devrc +0 -2
- package/template-vue-admin/config/.onlinerc +0 -2
- package/template-vue-admin/config/.testrc +0 -2
- package/template-vue-admin/index.html +0 -21
- package/template-vue-admin/nitro.config.ts +0 -19
- package/template-vue-admin/package.json +0 -51
- package/template-vue-admin/plugins/init.ts +0 -31
- package/template-vue-admin/public/vite.svg +0 -1
- package/template-vue-admin/rome.json +0 -26
- package/template-vue-admin/routes/api/[...all].ts +0 -49
- package/template-vue-admin/routes/get/env.ts +0 -18
- package/template-vue-admin/src/App.vue +0 -14
- package/template-vue-admin/src/apis/delete.ts +0 -36
- package/template-vue-admin/src/apis/get.ts +0 -83
- package/template-vue-admin/src/apis/index.ts +0 -10
- package/template-vue-admin/src/apis/patch.ts +0 -78
- package/template-vue-admin/src/apis/post.ts +0 -76
- package/template-vue-admin/src/assets/img/login_background.jpg +0 -0
- package/template-vue-admin/src/auto-components.d.ts +0 -38
- package/template-vue-admin/src/auto-imports.d.ts +0 -302
- package/template-vue-admin/src/layouts/blank.vue +0 -9
- package/template-vue-admin/src/layouts/default/components/Link.vue +0 -23
- package/template-vue-admin/src/layouts/default/components/Logo.vue +0 -20
- package/template-vue-admin/src/layouts/default/components/Menu.vue +0 -54
- package/template-vue-admin/src/layouts/default/components/NavSearch.vue +0 -52
- package/template-vue-admin/src/layouts/default/components/ScrollPane.vue +0 -79
- package/template-vue-admin/src/layouts/default/components/TagsView.vue +0 -137
- package/template-vue-admin/src/layouts/default/components/TopMenu.vue +0 -21
- package/template-vue-admin/src/layouts/default/components/UserCenter.vue +0 -50
- package/template-vue-admin/src/layouts/default/index.vue +0 -95
- package/template-vue-admin/src/main.ts +0 -46
- package/template-vue-admin/src/modules/1-router.ts +0 -48
- package/template-vue-admin/src/modules/2-pinia.ts +0 -10
- package/template-vue-admin/src/modules/3-net.ts +0 -79
- package/template-vue-admin/src/modules/4-auth.ts +0 -124
- package/template-vue-admin/src/modules/5-checkupdate.ts +0 -38
- package/template-vue-admin/src/shims.d.ts +0 -12
- package/template-vue-admin/src/stores/index.ts +0 -9
- package/template-vue-admin/src/stores/local/index.ts +0 -31
- package/template-vue-admin/src/stores/session/index.ts +0 -63
- package/template-vue-admin/src/stores/tags.ts +0 -109
- package/template-vue-admin/src/typings/global.d.ts +0 -70
- package/template-vue-admin/src/typings/index.ts +0 -13
- package/template-vue-admin/src/typings/system.d.ts +0 -46
- package/template-vue-admin/src/views/403.vue +0 -33
- package/template-vue-admin/src/views/[...all_404].vue +0 -557
- package/template-vue-admin/src/views/base/login.vue +0 -194
- package/template-vue-admin/src/views/dashboard/[name].vue +0 -28
- package/template-vue-admin/src/views/index.vue +0 -25
- package/template-vue-admin/src/views/system/api.vue +0 -160
- package/template-vue-admin/src/views/system/hooks/useRole.ts +0 -286
- package/template-vue-admin/src/views/system/menuList.vue +0 -194
- package/template-vue-admin/src/views/system/role.vue +0 -131
- package/template-vue-admin/src/views/system/user.vue +0 -192
- package/template-vue-admin/src/vite-env.d.ts +0 -52
- package/template-vue-admin/tsconfig.json +0 -21
- package/template-vue-admin/tsconfig.node.json +0 -9
- package/template-vue-admin/unocss.config.ts +0 -47
- package/template-vue-admin/vite.config.ts +0 -32
@@ -1,194 +0,0 @@
|
|
1
|
-
<!--
|
2
|
-
* @Author: zhangyang
|
3
|
-
* @Date: 2022-05-30 16:28:37
|
4
|
-
* @LastEditTime: 2023-08-02 10:44:18
|
5
|
-
* @Description: 菜单管理
|
6
|
-
-->
|
7
|
-
<route lang="yaml">
|
8
|
-
meta:
|
9
|
-
title: 菜单管理
|
10
|
-
</route>
|
11
|
-
|
12
|
-
<script lang="ts" setup>
|
13
|
-
import { deepClone, isArray } from '@bluesyoung/utils';
|
14
|
-
import { useFormMode, YoungDialog } from '@bluesyoung/ui-vue3-element-plus';
|
15
|
-
import { apis } from '@/modules/3-net';
|
16
|
-
|
17
|
-
const FORM_TEMP: NavArrItem = {
|
18
|
-
breadcrumb: 0,
|
19
|
-
component: '',
|
20
|
-
createdAt: '',
|
21
|
-
creator: '',
|
22
|
-
icon: '',
|
23
|
-
id: 0,
|
24
|
-
name: '',
|
25
|
-
not_dev: 0,
|
26
|
-
parentId: 0,
|
27
|
-
path: '',
|
28
|
-
permission: '',
|
29
|
-
redirect: '',
|
30
|
-
sort: 0,
|
31
|
-
status: 1,
|
32
|
-
title: '',
|
33
|
-
updatedAt: '',
|
34
|
-
visible: 1
|
35
|
-
};
|
36
|
-
// key 的类型必须为 string 才会生效!!!
|
37
|
-
const expandKeys = ref<Set<string>>(new Set());
|
38
|
-
|
39
|
-
let tempArr: string[] = [];
|
40
|
-
const getFatherAndSon = (arr: NavArrItem[], num?: number): string[] => {
|
41
|
-
if (num === 1) {
|
42
|
-
tempArr = [];
|
43
|
-
}
|
44
|
-
for (const item of arr) {
|
45
|
-
tempArr.push(item.id + '');
|
46
|
-
if (item.children && isArray(item.children) && item.children.length > 0) {
|
47
|
-
getFatherAndSon(deepClone(item.children));
|
48
|
-
}
|
49
|
-
}
|
50
|
-
return tempArr;
|
51
|
-
};
|
52
|
-
const expandChange = (...args: any) => {
|
53
|
-
const [row, isOpen] = args as [NavArrItem, boolean];
|
54
|
-
const autoid = row.id;
|
55
|
-
if (isOpen) {
|
56
|
-
expandKeys.value.add(autoid + '');
|
57
|
-
} else {
|
58
|
-
const allSub = getFatherAndSon([row], 1);
|
59
|
-
allSub.forEach((v) => expandKeys.value.delete(v));
|
60
|
-
}
|
61
|
-
};
|
62
|
-
const tableData = ref<NavArrItem[]>([]);
|
63
|
-
|
64
|
-
const topMenuOption = ref<Partial<NavArrItem>[]>([]);
|
65
|
-
|
66
|
-
/**
|
67
|
-
* 获取节点列表
|
68
|
-
*/
|
69
|
-
const getList = async () => {
|
70
|
-
const list = Object.values(await apis.get.getMenuList());
|
71
|
-
|
72
|
-
tableData.value = list;
|
73
|
-
|
74
|
-
topMenuOption.value = [
|
75
|
-
{ title: '顶级目录', children: list, id: 0 }
|
76
|
-
];
|
77
|
-
};
|
78
|
-
|
79
|
-
const {
|
80
|
-
isAdd,
|
81
|
-
isEdit,
|
82
|
-
form,
|
83
|
-
edit,
|
84
|
-
del,
|
85
|
-
sure,
|
86
|
-
clear,
|
87
|
-
formRef,
|
88
|
-
validForm
|
89
|
-
} = useFormMode<NavArrItem>(FORM_TEMP, {
|
90
|
-
addCbk: async () => {
|
91
|
-
const res = await validForm() as boolean;
|
92
|
-
if (res) {
|
93
|
-
const v = deepClone(form.value);
|
94
|
-
await apis.post.addMenuItem(v);
|
95
|
-
ElMessage.success('菜单添加成功!');
|
96
|
-
}
|
97
|
-
return res;
|
98
|
-
},
|
99
|
-
modCbk: async () => {
|
100
|
-
const res = await validForm() as boolean;
|
101
|
-
if (res) {
|
102
|
-
const v = deepClone(form.value);
|
103
|
-
await apis.patch.changeMenuItem(v);
|
104
|
-
ElMessage.success('菜单修改成功!');
|
105
|
-
}
|
106
|
-
return res;
|
107
|
-
},
|
108
|
-
delCbk: async (nav: NavArrItem) => {
|
109
|
-
apis.delete.deleteMenu(nav.id.toString());
|
110
|
-
expandKeys.value.delete(nav.id.toString());
|
111
|
-
ElMessage.success('节点删除成功!');
|
112
|
-
// 框架有 bug,视图更新不及时
|
113
|
-
location.reload();
|
114
|
-
},
|
115
|
-
cgEffect: async () => {
|
116
|
-
await getList();
|
117
|
-
}
|
118
|
-
});
|
119
|
-
|
120
|
-
/**
|
121
|
-
* 添加节点
|
122
|
-
*/
|
123
|
-
const add = () => {
|
124
|
-
form.value.parentId = 0;
|
125
|
-
isAdd.value = true;
|
126
|
-
};
|
127
|
-
|
128
|
-
const changeVisiable = async (id: number, visible: number) => {
|
129
|
-
await apis.patch.changeMenuItem({ id, visible });
|
130
|
-
ElMessage.success('修改成功!');
|
131
|
-
getList();
|
132
|
-
};
|
133
|
-
|
134
|
-
getList()
|
135
|
-
</script>
|
136
|
-
|
137
|
-
<template>
|
138
|
-
<div class="index">
|
139
|
-
<div class="caozuoFat">
|
140
|
-
<ElButton type="primary" plain @click="add">新建菜单</ElButton>
|
141
|
-
</div>
|
142
|
-
<!-- 节点列表 -->
|
143
|
-
<ElTable :data="tableData" style="width: 100%; margin-bottom: 20px;" :tree-props="{ children: 'children' }"
|
144
|
-
row-key="id" :expand-row-keys="[...expandKeys]" @expand-change="expandChange">
|
145
|
-
<ElTableColumn prop="name" label="英文名称" width="320px" />
|
146
|
-
<ElTableColumn prop="title" label="标题" />
|
147
|
-
<ElTableColumn prop="sort" label="同级排序" />
|
148
|
-
<ElTableColumn prop="component" label="页面路径" />
|
149
|
-
<ElTableColumn prop="visible" label="隐藏/显示">
|
150
|
-
<template #default="scope">
|
151
|
-
<ElSwitch v-model="scope.row.visible" :active-value="1" :inactive-value="0" active-color="#409EFF"
|
152
|
-
inactive-color="#909399" @change="(e) => changeVisiable(scope.row.id, e as number)" />
|
153
|
-
</template>
|
154
|
-
</ElTableColumn>
|
155
|
-
<ElTableColumn prop="creator" label="创建人" />
|
156
|
-
<ElTableColumn label="操作" width="300" fixed="right">
|
157
|
-
<template #default="scope">
|
158
|
-
<ElButton @click="edit(scope.row)">编辑</ElButton>
|
159
|
-
<ElButton type="danger" @click="del(scope.row)">删除</ElButton>
|
160
|
-
</template>
|
161
|
-
</ElTableColumn>
|
162
|
-
</ElTable>
|
163
|
-
<!-- 添加 / 编辑 -->
|
164
|
-
<YoungDialog width="370px" :is-add="isAdd" :is-edit="isEdit" @sure="sure" @clear="clear">
|
165
|
-
<template #body>
|
166
|
-
<ElForm ref="formRef" :model="form" label-width="80px">
|
167
|
-
<ElFormItem label="上级目录">
|
168
|
-
<ElCascader :model-value="form.parentId" :props="{
|
169
|
-
label: 'title',
|
170
|
-
value: 'id',
|
171
|
-
checkStrictly: true,
|
172
|
-
multiple: false
|
173
|
-
}" :options="topMenuOption" :show-all-levels="false"
|
174
|
-
@update:model-value="(e: any) => form.parentId = e[e.length - 1]" />
|
175
|
-
</ElFormItem>
|
176
|
-
<ElFormItem label="英文名称" prop="name" :rules="{ required: true, message: '请输入英文名', trigger: 'blur' }">
|
177
|
-
<ElInput v-model="form.name" placeholder="请输入英文名" />
|
178
|
-
</ElFormItem>
|
179
|
-
<ElFormItem label="标题" prop="title" :rules="{ required: true, message: '请输入页面标题', trigger: 'blur' }">
|
180
|
-
<ElInput v-model="form.title" placeholder="请输入页面标题" />
|
181
|
-
</ElFormItem>
|
182
|
-
<ElFormItem label="排序">
|
183
|
-
<ElInputNumber v-model.number="form.sort" />
|
184
|
-
</ElFormItem>
|
185
|
-
<ElFormItem label="路径" prop="component" :rules="form.parentId === 0 ? {} :
|
186
|
-
{ message: '请输入合法的路径, eg: /path/page', trigger: 'blur', validator: (_: any, v: string) => v.trim() === '' || /\/(.*)\/(.*)/.test(v) }
|
187
|
-
">
|
188
|
-
<ElInput v-model="form.component" />
|
189
|
-
</ElFormItem>
|
190
|
-
</ElForm>
|
191
|
-
</template>
|
192
|
-
</YoungDialog>
|
193
|
-
</div>
|
194
|
-
</template>
|
@@ -1,131 +0,0 @@
|
|
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
|
-
</route>
|
11
|
-
|
12
|
-
<script lang="ts" setup>
|
13
|
-
import { YoungTable, YoungDialog, YoungPagination } from '@bluesyoung/ui-vue3-element-plus';
|
14
|
-
import { useRoleApi, useRoleBase, useRoleMenu } from './hooks/useRole';
|
15
|
-
|
16
|
-
const {
|
17
|
-
query,
|
18
|
-
getList,
|
19
|
-
tableHead,
|
20
|
-
tableData,
|
21
|
-
baseFormRef,
|
22
|
-
changeStatus,
|
23
|
-
base
|
24
|
-
} = useRoleBase();
|
25
|
-
|
26
|
-
const { showPriority, menu } = useRoleMenu();
|
27
|
-
|
28
|
-
const { showApi, api } = useRoleApi();
|
29
|
-
|
30
|
-
getList();
|
31
|
-
</script>
|
32
|
-
|
33
|
-
<template>
|
34
|
-
<div class="flex">
|
35
|
-
<div class="m-2">
|
36
|
-
<ElInput v-model="query.name" placeholder="请输入角色名称(中文)" />
|
37
|
-
</div>
|
38
|
-
<div class="m-2">
|
39
|
-
<ElInput v-model="query.keyword" placeholder="请输入角色关键字(英文)" />
|
40
|
-
</div>
|
41
|
-
<div class="m-2 w-50">
|
42
|
-
<ElSelect v-model="query.status" placeholder="请选择状态" clearable>
|
43
|
-
<ElOption :value="1" label="1-启用" />
|
44
|
-
<ElOption :value="0" label="0-禁用" />
|
45
|
-
</ElSelect>
|
46
|
-
</div>
|
47
|
-
<div class="m-2">
|
48
|
-
<ElButton type="primary" @click="getList">搜索</ElButton>
|
49
|
-
</div>
|
50
|
-
<div class="m-2">
|
51
|
-
<ElButton type="success" @click="base.isAdd = true">添加角色</ElButton>
|
52
|
-
</div>
|
53
|
-
</div>
|
54
|
-
<div class="m-2">
|
55
|
-
<YoungTable :table-data="tableData" :table-head="tableHead" :table-height="680">
|
56
|
-
<template #switch>
|
57
|
-
<ElTableColumn label="禁用/启用">
|
58
|
-
<template #default="scope">
|
59
|
-
<ElSwitch v-model="scope.row.status" :active-value="1" :inactive-value="0" active-color="#409EFF"
|
60
|
-
inactive-color="#909399" @change="(e) => changeStatus(scope.row.id, e as number)" />
|
61
|
-
</template>
|
62
|
-
</ElTableColumn>
|
63
|
-
</template>
|
64
|
-
<template #operate>
|
65
|
-
<ElTableColumn label="操作" width="300px" fixed="right">
|
66
|
-
<template #default="scope">
|
67
|
-
<ElButton type="primary" link @click="base.edit(scope.row)">信息编辑</ElButton>
|
68
|
-
<ElButton type="primary" link @click="menu.edit(scope.row)">菜单编辑</ElButton>
|
69
|
-
<ElButton type="primary" link @click="api.edit(scope.row)">接口编辑</ElButton>
|
70
|
-
<ElButton type="danger" link @click="base.del(scope.row)">删除</ElButton>
|
71
|
-
</template>
|
72
|
-
</ElTableColumn>
|
73
|
-
</template>
|
74
|
-
</YoungTable>
|
75
|
-
<YoungPagination v-model:page="query.pageNum" v-model:limit="query.pageSize" :total="query.total"
|
76
|
-
@page-change="getList" />
|
77
|
-
</div>
|
78
|
-
<!-- 基础信息编辑 -->
|
79
|
-
<YoungDialog :is-add="base.isAdd" :is-edit="base.isEdit" width="520px" @sure="base.sure" @clear="base.clear">
|
80
|
-
<template #body>
|
81
|
-
<ElForm ref="baseFormRef" :model="base.form" label-width="120px">
|
82
|
-
<ElFormItem label="角色名称(中文)" prop="name" :rules="[{ required: true, message: '请填写角色名称', trigger: 'blur' }]">
|
83
|
-
<ElInput v-model="base.form.name" class="!w-300px" />
|
84
|
-
</ElFormItem>
|
85
|
-
<ElFormItem label="关键字(英文)" prop="keyword" :rules="[{ required: true, message: '请填写关键字', trigger: 'blur' }]">
|
86
|
-
<ElInput v-model="base.form.keyword" class="!w-300px" />
|
87
|
-
</ElFormItem>
|
88
|
-
<ElFormItem label="角色描述">
|
89
|
-
<ElInput v-model="base.form.desc" class="!w-300px" />
|
90
|
-
</ElFormItem>
|
91
|
-
</ElForm>
|
92
|
-
</template>
|
93
|
-
</YoungDialog>
|
94
|
-
<!-- 菜单编辑 -->
|
95
|
-
<YoungDialog real-title="菜单编辑" :is-edit="showPriority" top="5vh" width="1200px" @sure="menu.sure" @clear="menu.clear">
|
96
|
-
<template #body>
|
97
|
-
<ElTable :data="menu.tableData" row-key="id" :default-expand-all="false" class="max-h-600px !overflow-y-auto">
|
98
|
-
<ElTableColumn prop="name" label="节点名称" width="320px">
|
99
|
-
<template #default="scope">
|
100
|
-
<ElCheckbox v-model="menu.checkMap[scope.row.id]" @change="menu.selectChange(scope.row)">{{
|
101
|
-
scope.row.title
|
102
|
-
}}</ElCheckbox>
|
103
|
-
</template>
|
104
|
-
</ElTableColumn>
|
105
|
-
<ElTableColumn v-for="(item, index) in menu.tableHead" v-bind="item" :key="index + 'fsdjhfaer'" />
|
106
|
-
<ElTableColumn prop="name" label="隐藏/显示">
|
107
|
-
<template #default="scope">
|
108
|
-
<ElSwitch v-model="scope.row.visible" :active-value="1" :inactive-value="0" active-color="#409EFF"
|
109
|
-
inactive-color="#909399" disabled />
|
110
|
-
</template>
|
111
|
-
</ElTableColumn>
|
112
|
-
</ElTable>
|
113
|
-
</template>
|
114
|
-
</YoungDialog>
|
115
|
-
<!-- 接口编辑 -->
|
116
|
-
<YoungDialog real-title="接口编辑" :is-edit="showApi" top="5vh" width="1200px" @sure="api.sure" @clear="api.clear">
|
117
|
-
<template #body>
|
118
|
-
<ElTable :data="api.tableData" row-key="id" :default-expand-all="false" class="max-h-600px !overflow-y-auto">
|
119
|
-
<ElTableColumn prop="name" width="100px">
|
120
|
-
<template #header>
|
121
|
-
<ElCheckbox v-model="api.isAll" @change="api.changeAll">全选</ElCheckbox>
|
122
|
-
</template>
|
123
|
-
<template #default="scope">
|
124
|
-
<ElCheckbox v-model="api.checkMap[scope.row.id]">{{ scope.row.title }}</ElCheckbox>
|
125
|
-
</template>
|
126
|
-
</ElTableColumn>
|
127
|
-
<ElTableColumn v-for="(item, index) in api.tableHead" v-bind="item" :key="index + 'fsdjhfaer'" />
|
128
|
-
</ElTable>
|
129
|
-
</template>
|
130
|
-
</YoungDialog>
|
131
|
-
</template>
|
@@ -1,192 +0,0 @@
|
|
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
|
-
</route>
|
11
|
-
|
12
|
-
<script lang="ts" setup>
|
13
|
-
import { useFormMode, YoungDialog, YoungPagination, YoungTable, YoungSelect } from '@bluesyoung/ui-vue3-element-plus';
|
14
|
-
import type { TableHeadItem, TableDataItem, SelectOptionItem } from '@bluesyoung/ui-vue3-element-plus';
|
15
|
-
import { deepClone } from '@bluesyoung/utils';
|
16
|
-
import { RoleItem, UserItem } from '@/typings';
|
17
|
-
import { apis } from '@/modules/3-net';
|
18
|
-
|
19
|
-
interface Form extends UserItem { };
|
20
|
-
const FORM_TEMP: Form = {
|
21
|
-
id: 0,
|
22
|
-
username: '',
|
23
|
-
nickname: '',
|
24
|
-
mobile: '',
|
25
|
-
roleId: 1,
|
26
|
-
status: 1,
|
27
|
-
initPassword: ''
|
28
|
-
};
|
29
|
-
const {
|
30
|
-
isAdd,
|
31
|
-
isEdit,
|
32
|
-
edit,
|
33
|
-
del,
|
34
|
-
sure,
|
35
|
-
clear,
|
36
|
-
form,
|
37
|
-
formRef,
|
38
|
-
validForm
|
39
|
-
} = useFormMode<Form>(FORM_TEMP, {
|
40
|
-
addCbk: async () => {
|
41
|
-
const res = await validForm() as boolean;
|
42
|
-
if (res) {
|
43
|
-
const v = deepClone(form.value);
|
44
|
-
await apis.post.addUserItem(v);
|
45
|
-
ElMessage.success('新增成功!');
|
46
|
-
}
|
47
|
-
return res;
|
48
|
-
},
|
49
|
-
modCbk: async () => {
|
50
|
-
const res = await validForm() as boolean;
|
51
|
-
if (res) {
|
52
|
-
const v = deepClone(form.value);
|
53
|
-
await apis.patch.changeUserItem(v);
|
54
|
-
ElMessage.success('修改成功!');
|
55
|
-
}
|
56
|
-
return res;
|
57
|
-
},
|
58
|
-
delCbk: async (row) => {
|
59
|
-
await apis.delete.deleteUser(row.id.toString());
|
60
|
-
ElMessage.success('删除成功!');
|
61
|
-
query.pageNum = 1;
|
62
|
-
},
|
63
|
-
cgEffect: () => getList()
|
64
|
-
});
|
65
|
-
const tableHead: TableHeadItem<Form>[] = [
|
66
|
-
{ prop: 'id', label: '用户ID' },
|
67
|
-
{ prop: 'username', label: '用户名' },
|
68
|
-
{ prop: 'mobile', label: '手机号' },
|
69
|
-
{ prop: 'role_name', label: '角色名称' },
|
70
|
-
{ prop: 'creator', label: '创建信息' },
|
71
|
-
];
|
72
|
-
interface Query extends BaseQuery {
|
73
|
-
username: string;
|
74
|
-
mobile: string;
|
75
|
-
status: 0 | 1;
|
76
|
-
};
|
77
|
-
const query = reactive<Query>({
|
78
|
-
pageNum: 1,
|
79
|
-
pageSize: 50,
|
80
|
-
total: 0,
|
81
|
-
username: '',
|
82
|
-
mobile: '',
|
83
|
-
status: 1
|
84
|
-
});
|
85
|
-
|
86
|
-
const tableData = ref<TableDataItem<Form>[]>([]);
|
87
|
-
const roleList = ref<SelectOptionItem<number>[]>([]);
|
88
|
-
const getList = async () => {
|
89
|
-
const { list: role_list } = await apis.get.getRoleList({ noPagination: true });
|
90
|
-
roleList.value = (role_list || []).map((item: RoleItem) => {
|
91
|
-
return {
|
92
|
-
label: item.name,
|
93
|
-
value: item.id
|
94
|
-
};
|
95
|
-
});
|
96
|
-
|
97
|
-
const { list, pageNum, pageSize, total } = await apis.get.getUserList(query);
|
98
|
-
tableData.value = deepClone(list || []);
|
99
|
-
query.pageNum = +pageNum || 1;
|
100
|
-
query.pageSize = +pageSize || 50;
|
101
|
-
query.total = +total || 0;
|
102
|
-
};
|
103
|
-
/**
|
104
|
-
* @param id userId
|
105
|
-
* @param status 0 | 1
|
106
|
-
*/
|
107
|
-
const changeStatus = async (id: number, status: number) => {
|
108
|
-
await apis.patch.changeUserItem({ id, status });
|
109
|
-
ElMessage.success('修改成功!');
|
110
|
-
getList();
|
111
|
-
};
|
112
|
-
|
113
|
-
const changePwd = (e: UserItem) => {
|
114
|
-
ElMessageBox.prompt('请输入新密码').then(async ({ value }) => {
|
115
|
-
value = value.trim()
|
116
|
-
if (value) {
|
117
|
-
await apis.patch.changeUserItem({ id: e.id, newPassword: value });
|
118
|
-
ElMessage.success('修改成功!');
|
119
|
-
}
|
120
|
-
}).catch(() => null);
|
121
|
-
};
|
122
|
-
|
123
|
-
getList();
|
124
|
-
</script>
|
125
|
-
|
126
|
-
<template>
|
127
|
-
<div class="flex">
|
128
|
-
<div class="m-2">
|
129
|
-
<ElInput v-model="query.username" placeholder="请输入用户名" />
|
130
|
-
</div>
|
131
|
-
<div class="m-2">
|
132
|
-
<ElInput v-model="query.mobile" placeholder="请输入手机号" :maxlength="11" />
|
133
|
-
</div>
|
134
|
-
<div class="m-2 w-50">
|
135
|
-
<ElSelect v-model="query.status" placeholder="请选择状态" clearable>
|
136
|
-
<ElOption :value="1" label="1-启用" />
|
137
|
-
<ElOption :value="0" label="0-禁用" />
|
138
|
-
</ElSelect>
|
139
|
-
</div>
|
140
|
-
<div class="m-2">
|
141
|
-
<ElButton type="primary" @click="getList">搜索</ElButton>
|
142
|
-
</div>
|
143
|
-
<div class="m-2">
|
144
|
-
<ElButton type="success" @click="isAdd = true">添加用户</ElButton>
|
145
|
-
</div>
|
146
|
-
</div>
|
147
|
-
<div class="m-2">
|
148
|
-
<YoungTable :table-data="tableData" :table-head="tableHead" :table-height="680">
|
149
|
-
<template #switch>
|
150
|
-
<ElTableColumn label="禁用/启用">
|
151
|
-
<template #default="scope">
|
152
|
-
<ElSwitch v-model="scope.row.status" :active-value="1" :inactive-value="0" active-color="#409EFF"
|
153
|
-
inactive-color="#909399" @change="(e) => changeStatus(scope.row.id, e as number)" />
|
154
|
-
</template>
|
155
|
-
</ElTableColumn>
|
156
|
-
</template>
|
157
|
-
<template #operate>
|
158
|
-
<ElTableColumn label="操作" width="300px" fixed="right">
|
159
|
-
<template #default="scope">
|
160
|
-
<ElButton type="primary" link @click="edit(scope.row)">编辑</ElButton>
|
161
|
-
<ElButton type="warning" link @click="changePwd(scope.row)">修改密码</ElButton>
|
162
|
-
<ElButton type="danger" link @click="del(scope.row)">删除</ElButton>
|
163
|
-
</template>
|
164
|
-
</ElTableColumn>
|
165
|
-
</template>
|
166
|
-
</YoungTable>
|
167
|
-
<YoungPagination v-show="query.total > 0" v-model:page="query.pageNum" v-model:limit="query.pageSize"
|
168
|
-
:total="query.total" @page-change="getList" />
|
169
|
-
</div>
|
170
|
-
<YoungDialog :is-add="isAdd" :is-edit="isEdit" width="520px" @sure="sure" @clear="clear">
|
171
|
-
<template #body>
|
172
|
-
<ElForm ref="formRef" :model="form" label-width="100px">
|
173
|
-
<ElFormItem label="用户名" prop="username" :rules="{ required: true, message: '请输用户名', trigger: 'blur' }">
|
174
|
-
<ElInput v-model="form.username" class="!w-300px" />
|
175
|
-
</ElFormItem>
|
176
|
-
<ElFormItem label="昵称" prop="nickname" :rules="{ required: true, message: '请输昵称(用于右上角展示)', trigger: 'blur' }">
|
177
|
-
<ElInput v-model="form.nickname" class="!w-300px" />
|
178
|
-
</ElFormItem>
|
179
|
-
<ElFormItem label="手机号" prop="mobile" :rules="{ required: true, message: '请输手机号', trigger: 'blur' }">
|
180
|
-
<ElInput v-model="form.mobile" :maxlength="11" class="!w-300px" />
|
181
|
-
</ElFormItem>
|
182
|
-
<ElFormItem label="角色">
|
183
|
-
<YoungSelect v-model="form.roleId" placeholder="请选择角色" :options="roleList" />
|
184
|
-
</ElFormItem>
|
185
|
-
<ElFormItem v-if="isAdd" label="初始密码" prop="initPassword"
|
186
|
-
:rules="{ required: true, message: '请输初始密码', trigger: 'blur' }">
|
187
|
-
<ElInput v-model="form.initPassword" class="!w-300px" />
|
188
|
-
</ElFormItem>
|
189
|
-
</ElForm>
|
190
|
-
</template>
|
191
|
-
</YoungDialog>
|
192
|
-
</template>
|
@@ -1,52 +0,0 @@
|
|
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
|
-
}
|
@@ -1,21 +0,0 @@
|
|
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
|
-
}
|
@@ -1,47 +0,0 @@
|
|
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
|
-
});
|
@@ -1,32 +0,0 @@
|
|
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
|
-
};
|