ljr-cli 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/bin/commands/demo1.js +12 -0
  2. package/bin/commands/demo2.js +60 -0
  3. package/bin/commands/init.js +130 -0
  4. package/bin/commands/sync.js +144 -0
  5. package/bin/index.js +19 -202
  6. package/bin/templates/vue2.7.16/README.md +15 -13
  7. package/bin/templates/vue2.7.16/public/index.html +5 -5
  8. package/bin/templates/vue3.5.25-2025.12.4/.vscode/settings.json +1 -0
  9. package/bin/templates/vue3.5.25-2025.12.4/README.md +28 -17
  10. package/bin/templates/vue3.5.25-2025.12.4/auto-imports.d.ts +229 -0
  11. package/bin/templates/vue3.5.25-2025.12.4/components.d.ts +49 -0
  12. package/bin/templates/vue3.5.25-2025.12.4/eslint.config.ts +1 -0
  13. package/bin/templates/vue3.5.25-2025.12.4/index.html +2 -2
  14. package/bin/templates/vue3.5.25-2025.12.4/package.json +3 -1
  15. package/bin/templates/vue3.5.25-2025.12.4/pnpm-lock.yaml +480 -11
  16. package/bin/templates/vue3.5.25-2025.12.4/src/assets/images/login_bg.jpg +0 -0
  17. package/bin/templates/vue3.5.25-2025.12.4/src/assets/images/login_bg_black.jpg +0 -0
  18. package/bin/templates/vue3.5.25-2025.12.4/src/assets/images/sc_login_icon.png +0 -0
  19. package/bin/templates/vue3.5.25-2025.12.4/src/boot/el-icon.ts +9 -0
  20. package/bin/templates/vue3.5.25-2025.12.4/src/boot/index.ts +2 -0
  21. package/bin/templates/vue3.5.25-2025.12.4/src/boot/pinia.ts +8 -3
  22. package/bin/templates/vue3.5.25-2025.12.4/src/boot/style.ts +2 -1
  23. package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/header.ts +97 -0
  24. package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/header.vue +37 -13
  25. package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/left-right.vue +3 -7
  26. package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/menu.ts +19 -0
  27. package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/menu.vue +89 -5
  28. package/bin/templates/vue3.5.25-2025.12.4/src/components/layout/up-down.vue +24 -0
  29. package/bin/templates/vue3.5.25-2025.12.4/src/components/login/change-password.vue +111 -0
  30. package/bin/templates/vue3.5.25-2025.12.4/src/components/login/user-login.vue +61 -0
  31. package/bin/templates/vue3.5.25-2025.12.4/src/css/base.css +204 -0
  32. package/bin/templates/vue3.5.25-2025.12.4/src/css/global.css +1596 -0
  33. package/bin/templates/vue3.5.25-2025.12.4/src/css/index.css +3 -0
  34. package/bin/templates/vue3.5.25-2025.12.4/src/css/theme.css +61 -0
  35. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/device/index.ts +1 -0
  36. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/dialog.vue +66 -0
  37. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/helper.ts +90 -0
  38. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/index.ts +2 -0
  39. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/template.ts +41 -0
  40. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/template.vue +29 -0
  41. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/index.ts +31 -0
  42. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/layout.ts +47 -0
  43. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/layout.vue +51 -0
  44. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/notification.ts +27 -0
  45. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/notification.vue +29 -0
  46. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/permission.ts +22 -0
  47. package/bin/templates/vue3.5.25-2025.12.4/src/dialogs/user-info/permission.vue +23 -0
  48. package/bin/templates/vue3.5.25-2025.12.4/src/directive/rememberScrollPosition.ts +1 -1
  49. package/bin/templates/vue3.5.25-2025.12.4/src/enums/device.ts +42 -0
  50. package/bin/templates/vue3.5.25-2025.12.4/src/enums/index.ts +2 -0
  51. package/bin/templates/vue3.5.25-2025.12.4/src/enums/status.ts +23 -0
  52. package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/permission/role.ts +40 -0
  53. package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/permission/role.vue +39 -0
  54. package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/permission/user.vue +10 -0
  55. package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/template/base-info.vue +5 -0
  56. package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/template/base-info2.vue +5 -0
  57. package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/template/list.ts +40 -0
  58. package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/template/list.vue +39 -0
  59. package/bin/templates/vue3.5.25-2025.12.4/src/pages/index/template/store.vue +89 -0
  60. package/bin/templates/vue3.5.25-2025.12.4/src/pages/index.vue +7 -2
  61. package/bin/templates/vue3.5.25-2025.12.4/src/pages/login.vue +34 -64
  62. package/bin/templates/vue3.5.25-2025.12.4/src/stores/account(/351/200/211/351/241/271/345/274/217api/345/206/231/346/263/225/347/244/272/344/276/213).ts +49 -0
  63. package/bin/templates/vue3.5.25-2025.12.4/src/stores/account.ts +46 -28
  64. package/bin/templates/vue3.5.25-2025.12.4/src/stores/dd.ts +85 -29
  65. package/bin/templates/vue3.5.25-2025.12.4/src/stores/layout.ts +99 -21
  66. package/bin/templates/vue3.5.25-2025.12.4/typed-router.d.ts +90 -0
  67. package/bin/templates/vue3.5.25-2025.12.4/uno.config.ts +53 -0
  68. package/bin/templates/vue3.5.25-2025.12.4/vite.config.ts +12 -1
  69. package/package.json +4 -6
  70. package/bin/demo1.js +0 -39
  71. package/bin/demo2.js +0 -87
  72. package/bin/templates/vue3.5.25-2025.12.4/src/stores//347/273/204/345/220/210/345/274/217pinia/345/206/231/346/263/225(/344/273/245account/344/270/272/344/276/213).ts +0 -28
  73. /package/bin/templates/vue3.5.25-2025.12.4/{public → src/assets}/favicon.svg +0 -0
@@ -0,0 +1,39 @@
1
+ <script setup lang="ts">
2
+ import { useRole } from "./role"
3
+
4
+ const { formData, tableData, onSubmit } = useRole()
5
+ </script>
6
+
7
+ <template>
8
+ <div class="c-layout">
9
+ <!-- 顶部搜索 -->
10
+ <el-form :inline="true" :model="formData">
11
+ <el-row :gutter="20">
12
+ <el-col :span="6">
13
+ <el-form-item label="角色">
14
+ <el-input v-model="formData.user" clearable />
15
+ </el-form-item>
16
+ </el-col>
17
+ <el-col :span="6">
18
+ <el-form-item label="备注">
19
+ <el-input v-model="formData.user" clearable />
20
+ </el-form-item>
21
+ </el-col>
22
+ <el-col :span="12" class="text-right">
23
+ <el-button type="primary" @click="onSubmit">查询</el-button>
24
+ <el-button @click="onSubmit">重置</el-button>
25
+ </el-col>
26
+ </el-row>
27
+ </el-form>
28
+ <!-- 中间表格 -->
29
+ <el-table class="c-flex-1 c-overflow-auto" :data="tableData" border height="100%">
30
+ <el-table-column prop="date" label="日期" width="180" />
31
+ <el-table-column prop="name" label="姓名" width="180" />
32
+ <el-table-column prop="address" label="地址" />
33
+ </el-table>
34
+
35
+ <div class="mt-4 flex justify-end">
36
+ <el-pagination background layout="prev, pager, next" :page-sizes="[10, 20, 50, 100]" :total="1000" />
37
+ </div>
38
+ </div>
39
+ </template>
@@ -0,0 +1,10 @@
1
+ <script setup lang="ts">
2
+ const router = useRouter()
3
+ console.log("router=====>", router)
4
+ </script>
5
+
6
+ <template>
7
+ <div>
8
+ <div class="about">用户管理</div>
9
+ </div>
10
+ </template>
@@ -0,0 +1,5 @@
1
+ <script setup lang="ts"></script>
2
+
3
+ <template>
4
+ <div class="c-layout">基础信息</div>
5
+ </template>
@@ -0,0 +1,5 @@
1
+ <script setup lang="ts"></script>
2
+
3
+ <template>
4
+ <div class="c-layout">基础信息2</div>
5
+ </template>
@@ -0,0 +1,40 @@
1
+ export function useList() {
2
+ const formData = reactive({
3
+ user: "",
4
+ region: "",
5
+ date: "",
6
+ })
7
+
8
+ const tableData = ref([
9
+ {
10
+ date: "2016-05-03",
11
+ name: "Tom",
12
+ address: "No. 189, Grove St, Los Angeles",
13
+ },
14
+ {
15
+ date: "2016-05-02",
16
+ name: "Tom",
17
+ address: "No. 189, Grove St, Los Angeles",
18
+ },
19
+ {
20
+ date: "2016-05-04",
21
+ name: "Tom",
22
+ address: "No. 189, Grove St, Los Angeles",
23
+ },
24
+ {
25
+ date: "2016-05-01",
26
+ name: "Tom",
27
+ address: "No. 189, Grove St, Los Angeles",
28
+ },
29
+ ])
30
+
31
+ const onSubmit = () => {
32
+ console.log("submit!")
33
+ }
34
+
35
+ return {
36
+ formData,
37
+ tableData,
38
+ onSubmit,
39
+ }
40
+ }
@@ -0,0 +1,39 @@
1
+ <script setup lang="ts">
2
+ import { useList } from "./list"
3
+
4
+ const { formData, tableData, onSubmit } = useList()
5
+ </script>
6
+
7
+ <template>
8
+ <div class="c-layout">
9
+ <!-- 顶部搜索 -->
10
+ <el-form :inline="true" :model="formData">
11
+ <el-row :gutter="20">
12
+ <el-col :span="6">
13
+ <el-form-item label="角色">
14
+ <el-input v-model="formData.user" clearable />
15
+ </el-form-item>
16
+ </el-col>
17
+ <el-col :span="6">
18
+ <el-form-item label="备注">
19
+ <el-input v-model="formData.user" clearable />
20
+ </el-form-item>
21
+ </el-col>
22
+ <el-col :span="12" class="text-right">
23
+ <el-button type="primary" @click="onSubmit">查询</el-button>
24
+ <el-button @click="onSubmit">重置</el-button>
25
+ </el-col>
26
+ </el-row>
27
+ </el-form>
28
+ <!-- 中间表格 -->
29
+ <el-table class="c-flex-1 c-overflow-auto" :data="tableData" border height="100%">
30
+ <el-table-column prop="date" label="日期" width="180" />
31
+ <el-table-column prop="name" label="姓名" width="180" />
32
+ <el-table-column prop="address" label="地址" />
33
+ </el-table>
34
+
35
+ <div class="mt-4 flex justify-end">
36
+ <el-pagination background layout="prev, pager, next" :page-sizes="[10, 20, 50, 100]" :total="1000" />
37
+ </div>
38
+ </div>
39
+ </template>
@@ -0,0 +1,89 @@
1
+ <script setup lang="ts">
2
+ import { useAccountStore, useDDStore } from "@/stores"
3
+ const router = useRouter()
4
+
5
+ const accountStore = useAccountStore()
6
+ const ddStore = useDDStore()
7
+ function printAccountStore() {
8
+ console.log("认证仓库=====>", accountStore)
9
+ }
10
+ </script>
11
+
12
+ <template>
13
+ <div class="c-card-layout" style="padding: 50px">
14
+ <el-card class="c-w-full">
15
+ <template v-slot:header>
16
+ <div class="clearfix">
17
+ <span>是否需要登录</span>
18
+ <el-button class="c-right" size="small" type="primary" @click="accountStore.changeNeedLogin()">
19
+ 改变是否需要登录
20
+ </el-button>
21
+ </div>
22
+ </template>
23
+ <div>
24
+ {{ accountStore.needLogin }}
25
+ </div>
26
+ </el-card>
27
+
28
+ <el-card class="c-w-full">
29
+ <template v-slot:header>
30
+ <div class="clearfix">
31
+ <span>当前登录信息</span>
32
+ <div class="c-right">
33
+ <el-button size="small" type="primary" @click="accountStore.login()"> 登录 </el-button>
34
+ <el-button size="small" type="danger" @click="accountStore.logout()"> 退出登录 </el-button>
35
+ </div>
36
+ </div>
37
+ </template>
38
+ <div>
39
+ <h3 class="c-mb-10">用户名称:{{ accountStore.userInfo?.name }}</h3>
40
+ <h3 class="c-mb-10">token:{{ accountStore.token }}</h3>
41
+ </div>
42
+ </el-card>
43
+
44
+ <el-card class="c-w-full">
45
+ <div style="text-align: right">
46
+ <el-button type="primary" size="small" @click="printAccountStore()"> 打印认证仓库 </el-button>
47
+ </div>
48
+ </el-card>
49
+
50
+ <el-card class="c-w-full">
51
+ <div style="text-align: right">
52
+ <el-button
53
+ type="primary"
54
+ size="small"
55
+ :disabled="accountStore.needLogin && !accountStore.token"
56
+ @click="router.push('/')"
57
+ >
58
+ 跳转首页
59
+ </el-button>
60
+ </div>
61
+ </el-card>
62
+
63
+ <el-card class="c-w-full">
64
+ <template v-slot:header>
65
+ <div class="clearfix">
66
+ <span>数据字典</span>
67
+ <el-button class="c-right" size="small" type="primary" @click="ddStore.clearDD()">
68
+ 清空城市和性别字典
69
+ </el-button>
70
+ </div>
71
+ </template>
72
+ <div>
73
+ <h3 class="c-mb-10">
74
+ 性别: {{ ddStore.dd.gender }}
75
+ <el-button class="c-right" size="small" type="primary" @click="ddStore.getDD('gender')">
76
+ 获取性别数据字典
77
+ </el-button>
78
+ </h3>
79
+ <h3 class="c-mb-10">
80
+ 城市: {{ ddStore.dd.city }}
81
+ <el-button class="c-right" size="small" type="primary" @click="ddStore.getDD('city')">
82
+ 获取城市数据字典
83
+ </el-button>
84
+ </h3>
85
+ <h3 class="c-mb-10">城市字典值转换名称: {{ ddStore.ddValueToName("city", "1") }}</h3>
86
+ </div>
87
+ </el-card>
88
+ </div>
89
+ </template>
@@ -1,13 +1,18 @@
1
1
  <script setup lang="ts">
2
+ import { useLayoutStore } from "@/stores"
2
3
  import leftRightLayout from "@/components/layout/left-right.vue"
4
+ import upDownLayout from "@/components/layout/up-down.vue"
5
+
6
+ const layoutStore = useLayoutStore()
3
7
  </script>
4
8
 
5
9
  <template>
6
- <left-right-layout>
10
+ <!-- 布局 -->
11
+ <component :is="layoutStore.layout === 'left-right' ? leftRightLayout : upDownLayout">
7
12
  <router-view v-slot="{ Component }">
8
13
  <transition name="el-fade-in-linear" mode="out-in">
9
14
  <component :is="Component" />
10
15
  </transition>
11
16
  </router-view>
12
- </left-right-layout>
17
+ </component>
13
18
  </template>
@@ -1,76 +1,46 @@
1
1
  <script setup lang="ts">
2
- import { useAccountStore, useDDStore } from "@/stores"
3
- const router = useRouter()
2
+ import loginBg from "@/assets/images/login_bg.jpg"
3
+ import UserLogin from "@/components/login/user-login.vue"
4
+ import ChangePassword from "@/components/login/change-password.vue"
4
5
 
5
- const accountStore = useAccountStore()
6
- const ddStore = useDDStore()
7
- function printAccountStore() {
8
- console.log("认证仓库=====>", accountStore)
6
+ const isLogin = ref(true)
7
+ const loading = ref(false)
8
+
9
+ function changeLoading(status = false) {
10
+ loading.value = status
11
+ }
12
+
13
+ function changeIsLogin(status = false) {
14
+ isLogin.value = status
9
15
  }
10
16
  </script>
11
17
 
12
18
  <template>
13
- <div class="c-card-layout" style="padding: 50px">
14
- <el-card class="c-w-full">
15
- <template v-slot:header>
16
- <div class="clearfix">
17
- <span>是否需要登录</span>
18
- <el-button class="c-right" size="small" type="primary" @click="accountStore.changeNeedLogin()">
19
- 改变是否需要登录
20
- </el-button>
21
- </div>
22
- </template>
23
- <div>
24
- {{ accountStore.needLogin }}
25
- </div>
26
- </el-card>
27
-
28
- <el-card class="c-w-full">
29
- <template v-slot:header>
30
- <div class="clearfix">
31
- <span>当前登录信息</span>
32
- <div class="c-right">
33
- <el-button size="small" type="primary" @click="accountStore.login()"> 登录 </el-button>
34
- <el-button size="small" type="danger" @click="accountStore.logout()"> 退出登录 </el-button>
35
- </div>
36
- </div>
37
- </template>
38
- <div>
39
- <h3 class="c-mb-10">用户名称:{{ accountStore.userInfo?.name }}</h3>
40
- <h3 class="c-mb-10">token:{{ accountStore.token }}</h3>
41
- </div>
42
- </el-card>
43
-
44
- <el-card class="c-w-full">
45
- <div style="text-align: right">
46
- <el-button type="primary" size="small" @click="printAccountStore()"> 打印认证仓库 </el-button>
47
- </div>
48
- </el-card>
19
+ <div class="w-full h-full relative">
20
+ <img class="w-full h-full object-cover" :src="loginBg" alt="登录背景" />
49
21
 
50
- <el-card class="c-w-full">
51
- <div style="text-align: right">
52
- <el-button
53
- type="primary"
54
- size="small"
55
- :disabled="accountStore.needLogin && !accountStore.token"
56
- @click="router.push('/')"
22
+ <!-- 操作容器 -->
23
+ <div class="absolute top-0 right-1/4 h-full flex items-center">
24
+ <div v-loading="loading" class="relative w-110 overflow-hidden border-2 border-solid border-white/80 rounded-xl">
25
+ <div
26
+ class="relative flex flex-col px-10 py-14"
27
+ style="
28
+ background:
29
+ linear-gradient(0deg, rgb(255 255 255 / 60%) 0%, rgb(255 255 255 / 60%) 100%),
30
+ radial-gradient(
31
+ 106.7% 134.87% at 3.55% 95.71%,
32
+ rgb(97 171 255 / 1%) 0%,
33
+ rgb(78 157 255 / 8%) 31.16%,
34
+ rgb(97 171 255 / 0%) 100%
35
+ );
36
+ "
57
37
  >
58
- 跳转首页
59
- </el-button>
60
- </div>
61
- </el-card>
62
-
63
- <el-card class="c-w-full">
64
- <template v-slot:header>
65
- <div class="clearfix">
66
- <span>数据字典</span>
67
- <el-button class="c-right" size="small" type="primary" @click="ddStore.getDD()"> 获取数据字典 </el-button>
38
+ <transition name="el-fade-in-linear" mode="out-in">
39
+ <UserLogin v-if="isLogin" @change-loading="changeLoading" @changeIsLogin="changeIsLogin" />
40
+ <ChangePassword v-else @change-loading="changeLoading" @changeIsLogin="changeIsLogin" />
41
+ </transition>
68
42
  </div>
69
- </template>
70
- <div>
71
- <h3 class="c-mb-10">sex: {{ ddStore.sex }}</h3>
72
- <h3 class="c-mb-10">city: {{ ddStore.citys }}</h3>
73
43
  </div>
74
- </el-card>
44
+ </div>
75
45
  </div>
76
46
  </template>
@@ -0,0 +1,49 @@
1
+ interface UserInfo {
2
+ /** 用户名 */
3
+ name: string
4
+ /** token */
5
+ token: string
6
+ }
7
+
8
+ interface State {
9
+ /** 是否需要登录 */
10
+ needLogin: boolean
11
+ /** 用户名 */
12
+ userInfo?: UserInfo
13
+ }
14
+
15
+ /**
16
+ * 认证数据
17
+ */
18
+ export const useAccountStore = defineStore("account", {
19
+ state: (): State => ({
20
+ needLogin: false,
21
+ userInfo: undefined,
22
+ }),
23
+ getters: {
24
+ /** token */
25
+ token(): string {
26
+ return this.userInfo?.token || ""
27
+ },
28
+ },
29
+ actions: {
30
+ /** 改变是否需要登录 */
31
+ changeNeedLogin() {
32
+ this.needLogin = !this.needLogin
33
+ },
34
+ /** 登录 */
35
+ login() {
36
+ this.userInfo = {
37
+ name: "李某铷",
38
+ token: "我是token-xxxx",
39
+ }
40
+ },
41
+ /** 退出登录 */
42
+ logout() {
43
+ this.userInfo = undefined
44
+ },
45
+ },
46
+ persist: {
47
+ storage: localStorage, // 存储方式(默认localStorage,可选sessionStorage)
48
+ },
49
+ })
@@ -1,6 +1,10 @@
1
1
  interface UserInfo {
2
2
  /** 用户名 */
3
3
  name: string
4
+ /** 头像 */
5
+ avatar?: string
6
+ /** 角色 */
7
+ role?: string
4
8
  /** token */
5
9
  token: string
6
10
  }
@@ -13,37 +17,51 @@ interface State {
13
17
  }
14
18
 
15
19
  /**
16
- * 认证数据
20
+ * 认证数据,组合式API写法,不管是选项式API写法还是组合式API写法,同一个项目里,最好是同一种写法,此项目统一采用组合式API写法
17
21
  */
18
- export const useAccountStore = defineStore("account", {
19
- state: (): State => ({
20
- needLogin: false,
21
- userInfo: undefined,
22
- }),
23
- getters: {
24
- /** token */
25
- token(): string {
26
- return this.userInfo?.token || ""
27
- },
28
- },
29
- actions: {
30
- /** 改变是否需要登录 */
31
- changeNeedLogin() {
32
- this.needLogin = !this.needLogin
33
- },
34
- /** 登录 */
35
- login() {
36
- this.userInfo = {
22
+ export const useAccountStore = defineStore(
23
+ "account",
24
+ () => {
25
+ const needLogin = ref<State["needLogin"]>(true)
26
+ const userInfo = ref<State["userInfo"]>(undefined)
27
+
28
+ const token = computed(() => userInfo.value?.token || "")
29
+
30
+ function changeNeedLogin() {
31
+ needLogin.value = !needLogin.value
32
+ }
33
+
34
+ function login() {
35
+ userInfo.value = {
37
36
  name: "李某铷",
38
37
  token: "我是token-xxxx",
38
+ role: "管理员",
39
39
  }
40
- },
41
- /** 退出登录 */
42
- logout() {
43
- this.userInfo = undefined
44
- },
40
+ }
41
+
42
+ /** 退出登录
43
+ * @author ljr <395181403@qq.com>
44
+ * @param { Boolean } jumpHome 是否跳转到首页
45
+ * @returns { void }
46
+ * @example
47
+ * logout() // 退出登录
48
+ */
49
+ function logout() {
50
+ userInfo.value = undefined
51
+ }
52
+
53
+ return {
54
+ needLogin,
55
+ userInfo,
56
+ token,
57
+ changeNeedLogin,
58
+ login,
59
+ logout,
60
+ }
45
61
  },
46
- persist: {
47
- storage: localStorage, // 存储方式(默认localStorage,可选sessionStorage)
62
+ {
63
+ persist: {
64
+ storage: localStorage,
65
+ },
48
66
  },
49
- })
67
+ )
@@ -1,35 +1,91 @@
1
- interface DD {
2
- /** 标签 */
1
+ /** 数据字典项 */
2
+ interface DDOption {
3
+ /** 字典名称 */
3
4
  label: string
4
- /** */
5
+ /** 字典编码 */
5
6
  value: string | number
6
7
  }
7
8
 
8
- interface State {
9
- /** 性别 */
10
- sex: DD[]
11
- /** 城市 */
12
- citys?: DD[]
13
- }
9
+ /** 数据字典已知字段 */
10
+ type DDField = "city" | "gender"
11
+ type DDFieldArr = Array<DDField>
12
+
13
+ export const useDDStore = defineStore("dd", () => {
14
+ const dd = ref<Record<DDField, DDOption[]>>({
15
+ city: [],
16
+ gender: [],
17
+ })
18
+
19
+ /** 获取数据字典
20
+ * @param { string | string[] } fields 字典的字段,支持单个字符串用逗号隔开
21
+ * @example
22
+ * getDD("city") // 获取城市的数据字典
23
+ * getDD(["city", "gender"]) // 获取城市和性别的数据字典
24
+ */
25
+ function getDD(field: DDField | DDFieldArr) {
26
+ const fieldArr = typeof field === "string" ? [field] : field
27
+
28
+ // 通过fieldArr去获取对应的数据字典,以下跳过请求,直接赋值
29
+ if (fieldArr.length) {
30
+ fieldArr.forEach((e) => {
31
+ if (e.includes("city")) {
32
+ nextTick(() => {
33
+ if (!dd.value[e]?.length) {
34
+ dd.value[e] = [
35
+ { label: "北京", value: "1" },
36
+ { label: "上海", value: "2" },
37
+ { label: "广州", value: "3" },
38
+ { label: "深圳", value: "4" },
39
+ { label: "厦门", value: "5" },
40
+ ]
41
+ }
42
+ })
43
+ }
44
+ if (e.includes("gender")) {
45
+ nextTick(() => {
46
+ if (!dd.value[e]?.length) {
47
+ dd.value[e] = [
48
+ { label: "男", value: "1" },
49
+ { label: "女", value: "0" },
50
+ ]
51
+ }
52
+ })
53
+ }
54
+ })
55
+ }
56
+ }
57
+
58
+ function clearDD(field: DDField | DDFieldArr = ["gender", "city"]) {
59
+ const fieldArr = typeof field === "string" ? [field] : field
60
+
61
+ fieldArr.forEach((e) => {
62
+ dd.value[e] = []
63
+ })
64
+ }
65
+
66
+ /** 数据字典值转换名称
67
+ * @param { DDField } field 字段
68
+ * @param { string | number } fieldValue 字段值
69
+ * @returns { String } 对应的label或空串
70
+ * @example
71
+ * ddValueToName("city", "1")
72
+ */
73
+ function ddValueToName(field: DDField, fieldValue: string | number) {
74
+ const currentDD = dd.value[field]
75
+ if (currentDD?.length) {
76
+ return currentDD.find((f) => f.value === fieldValue)?.label
77
+ }
78
+
79
+ return fieldValue ?? ""
80
+ }
81
+
82
+ /** 初始化 */
83
+ function init() {
84
+ getDD(["city", "gender"])
85
+ }
86
+
87
+ // 创建 store 时直接初始化
88
+ init()
14
89
 
15
- /**
16
- * 数据字典
17
- */
18
- export const useDDStore = defineStore("dd", {
19
- state: (): State => ({ sex: [], citys: [] }),
20
- actions: {
21
- getDD() {
22
- this.citys = [
23
- { label: "北京", value: "1" },
24
- { label: "上海", value: "2" },
25
- { label: "广州", value: "3" },
26
- { label: "深圳", value: "4" },
27
- { label: "厦门", value: "5" },
28
- ]
29
- this.sex = [
30
- { label: "男", value: "1" },
31
- { label: "女", value: "0" },
32
- ]
33
- },
34
- },
90
+ return { dd, getDD, clearDD, ddValueToName, init }
35
91
  })