create-jnrs-template-vue 1.1.3 → 1.1.4

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 (32) hide show
  1. package/README.md +5 -5
  2. package/bin/create.mjs +1 -1
  3. package/jnrs-template-vue/README.md +2 -2
  4. package/jnrs-template-vue/components.d.ts +2 -0
  5. package/jnrs-template-vue/package.json +7 -8
  6. package/jnrs-template-vue/public/system/menu.json +8 -4
  7. package/jnrs-template-vue/src/assets/fonts/.keep +0 -0
  8. package/jnrs-template-vue/src/assets/fonts/AlibabaPuHuiTi-Regular.woff2 +0 -0
  9. package/jnrs-template-vue/src/assets/fonts/AlimamaShuHeiTi-Bold.woff2 +0 -0
  10. package/jnrs-template-vue/src/assets/images/common/jnrs-white.svg +1 -0
  11. package/jnrs-template-vue/src/assets/styles/fonts.scss +24 -0
  12. package/jnrs-template-vue/src/assets/styles/init.scss +33 -0
  13. package/jnrs-template-vue/src/assets/styles/main.scss +27 -0
  14. package/jnrs-template-vue/src/assets/styles/root.scss +29 -0
  15. package/jnrs-template-vue/src/layout/BlankLayout.vue +2 -1
  16. package/jnrs-template-vue/src/layout/RouterTabs.vue +11 -7
  17. package/jnrs-template-vue/src/layout/SideMenu.vue +82 -23
  18. package/jnrs-template-vue/src/layout/SideMenuItem.vue +4 -4
  19. package/jnrs-template-vue/src/layout/TopHeader.vue +62 -86
  20. package/jnrs-template-vue/src/layout/index.vue +12 -8
  21. package/jnrs-template-vue/src/main.ts +2 -2
  22. package/jnrs-template-vue/src/router/routes.ts +16 -16
  23. package/jnrs-template-vue/src/views/login/index.vue +228 -38
  24. package/jnrs-template-vue/tsconfig.json +6 -1
  25. package/jnrs-template-vue/vite.config.ts +2 -3
  26. package/jnrs-template-vue/viteMockServe/index.ts +5 -0
  27. package/package.json +1 -1
  28. package/jnrs-template-vue/src/assets/styles/base.css +0 -28
  29. package/jnrs-template-vue/src/assets/styles/main.css +0 -1
  30. package/jnrs-template-vue/src/utils/storage.ts +0 -7
  31. package/jnrs-template-vue/src/utils/validate.ts +0 -321
  32. package/jnrs-template-vue/src/utils/validator.ts +0 -153
@@ -1,28 +0,0 @@
1
- *,
2
- *::before,
3
- *::after {
4
- box-sizing: border-box;
5
- margin: 0;
6
- font-weight: normal;
7
- }
8
-
9
- body {
10
- width: 100vw;
11
- color: #14161a;
12
- height: 100vh;
13
- background: #f2f2f2;
14
- transition:
15
- color 1.5s,
16
- background-color 0.5s;
17
- line-height: 1.6;
18
- }
19
-
20
- #app {
21
- min-width: 1280px;
22
- height: 100%;
23
- font-weight: normal;
24
- }
25
-
26
- a {
27
- text-decoration: none;
28
- }
@@ -1 +0,0 @@
1
- @import './base.css';
@@ -1,7 +0,0 @@
1
- /**
2
- * @Author : TanRui
3
- * @WeChat : Tan578853789
4
- * @File : storage.ts
5
- * @Date : 2025/09/30
6
- * @Desc. : 本地存储
7
- */
@@ -1,321 +0,0 @@
1
- /**
2
- * @Author : TanRui
3
- * @WeChat : Tan578853789
4
- * @File : validate.ts
5
- * @Date : 2025/10/14
6
- * @Desc. : 校验规则
7
- */
8
-
9
- // ========== 基础类型校验 ==========
10
-
11
- /**
12
- * 是否为邮箱
13
- */
14
- export function isEmail(s: string): boolean {
15
- return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(s)
16
- }
17
-
18
- /**
19
- * 是否为中国大陆手机号
20
- */
21
- export function isMobile(s: string): boolean {
22
- return /^1[3-9]\d{9}$/.test(s)
23
- }
24
-
25
- /**
26
- * 是否为电话号码(固话或手机)
27
- */
28
- export function isPhone(s: string): boolean {
29
- const mobile = /^1[3-9]\d{9}$/
30
- const landline = /^(0[1-9]\d{1,2}-?)?\d{7,8}$/
31
- return mobile.test(s) || landline.test(s)
32
- }
33
-
34
- /**
35
- * 是否为 URL(必须带协议)
36
- */
37
- export function isURL(s: string): boolean {
38
- try {
39
- new URL(s)
40
- return true
41
- } catch {
42
- return false
43
- }
44
- }
45
-
46
- // ========== 字符串内容校验 ==========
47
-
48
- export function isLowerCase(str: string): boolean {
49
- return /^[a-z]+$/.test(str)
50
- }
51
-
52
- export function isUpperCase(str: string): boolean {
53
- return /^[A-Z]+$/.test(str)
54
- }
55
-
56
- export function isAlphabets(str: string): boolean {
57
- return /^[A-Za-z]+$/.test(str)
58
- }
59
-
60
- export function isName(name: string): boolean {
61
- return /^[\u4e00-\u9fa5]{2,4}$/.test(name)
62
- }
63
-
64
- /**
65
- * 是否为纯数字字符串(可选:是否允许小数)
66
- * @param num - 输入字符串
67
- * @param type - 1: 只允许整数;2: 允许小数(默认)
68
- */
69
- export function isNum(num: string, type: 1 | 2 = 2): boolean {
70
- if (type === 1) {
71
- return /^\d+$/.test(num) // 仅整数
72
- } else {
73
- return /^\d+(\.\d+)?$/.test(num) // 允许小数
74
- }
75
- }
76
-
77
- export function isFloat(num: string): boolean {
78
- return /^-?\d+(\.\d+)?$/.test(num)
79
- }
80
-
81
- export function isNull(val: unknown): boolean {
82
- if (Array.isArray(val)) return val.length === 0
83
- if (val && typeof val === 'object') return Object.keys(val).length === 0
84
- return val == null || val === '' || val === 'null' || val === 'undefined'
85
- }
86
-
87
- // ========== 身份证校验 ==========
88
-
89
- export function isCardId(code: string): boolean {
90
- if (!code || code.length !== 18) return false
91
-
92
- const city = {
93
- '11': '北京',
94
- '12': '天津',
95
- '13': '河北',
96
- '14': '山西',
97
- '15': '内蒙古',
98
- '21': '辽宁',
99
- '22': '吉林',
100
- '23': '黑龙江',
101
- '31': '上海',
102
- '32': '江苏',
103
- '33': '浙江',
104
- '34': '安徽',
105
- '35': '福建',
106
- '36': '江西',
107
- '37': '山东',
108
- '41': '河南',
109
- '42': '湖北',
110
- '43': '湖南',
111
- '44': '广东',
112
- '45': '广西',
113
- '46': '海南',
114
- '50': '重庆',
115
- '51': '四川',
116
- '52': '贵州',
117
- '53': '云南',
118
- '54': '西藏',
119
- '61': '陕西',
120
- '62': '甘肃',
121
- '63': '青海',
122
- '64': '宁夏',
123
- '65': '新疆',
124
- '71': '台湾',
125
- '81': '香港',
126
- '82': '澳门',
127
- '91': '国外'
128
- }
129
-
130
- const province = code.slice(0, 2)
131
- if (!(province in city)) return false
132
-
133
- // 校验格式
134
- if (!/^\d{17}[\dXx]$/.test(code)) return false
135
-
136
- // 校验位计算
137
- const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
138
- const parity = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
139
- let sum = 0
140
- for (let i = 0; i < 17; i++) {
141
- sum += parseInt(code[i]!, 10) * factor[i]!
142
- }
143
- const check = parity[sum % 11]
144
- return check === code[17]!.toUpperCase()
145
- }
146
-
147
- // ========== 数值比较校验 ==========
148
-
149
- const toInt = (v: string): number => parseInt(v, 10)
150
- const toFloat = (v: string): number => parseFloat(v)
151
-
152
- export function isIntEqZero(value: string): boolean {
153
- return toInt(value) === 0
154
- }
155
- export function isIntGtZero(value: string): boolean {
156
- return toInt(value) > 0
157
- }
158
- export function isIntGteZero(value: string): boolean {
159
- return toInt(value) >= 0
160
- }
161
- export function isIntNEqZero(value: string): boolean {
162
- return toInt(value) !== 0
163
- }
164
- export function isIntLtZero(value: string): boolean {
165
- return toInt(value) < 0
166
- }
167
- export function isIntLteZero(value: string): boolean {
168
- return toInt(value) <= 0
169
- }
170
-
171
- export function isFloatEqZero(value: string): boolean {
172
- return toFloat(value) === 0
173
- }
174
- export function isFloatGtZero(value: string): boolean {
175
- return toFloat(value) > 0
176
- }
177
- export function isFloatGteZero(value: string): boolean {
178
- return toFloat(value) >= 0
179
- }
180
- export function isFloatNEqZero(value: string): boolean {
181
- return toFloat(value) !== 0
182
- }
183
- export function isFloatLtZero(value: string): boolean {
184
- return toFloat(value) < 0
185
- }
186
- export function isFloatLteZero(value: string): boolean {
187
- return toFloat(value) <= 0
188
- }
189
-
190
- export function isInteger(value: string): boolean {
191
- return /^-?\d+$/.test(value)
192
- }
193
-
194
- export function isNumber(value: string): boolean {
195
- return /^-?\d+(\.\d+)?$/.test(value)
196
- }
197
-
198
- export function isNumberGtZero(value: string): boolean {
199
- const num = toFloat(value)
200
- return !isNaN(num) && num >= 0
201
- }
202
-
203
- export function isDigits(value: string): boolean {
204
- return /^\d+$/.test(value)
205
- }
206
-
207
- // ========== 特定格式校验 ==========
208
-
209
- export function isEnglish(value: string): boolean {
210
- return /^[A-Za-z]+$/.test(value)
211
- }
212
-
213
- export function isTel(value: string): boolean {
214
- return isPhone(value)
215
- }
216
-
217
- export function isQq(value: string): boolean {
218
- return /^[1-9]\d{4,12}$/.test(value)
219
- }
220
-
221
- export function isZipCode(value: string): boolean {
222
- return /^[1-9]\d{5}$/.test(value) // 中国邮政编码第一位不能为0
223
- }
224
-
225
- export function isPwd(value: string): boolean {
226
- return /^[a-zA-Z]\w{5,11}$/.test(value) // 字母开头,6-12位
227
- }
228
-
229
- export function isWeakPwd(value: string): boolean {
230
- return /^[a-zA-Z\d!@#$%^&*()_+\-=]+$/.test(value)
231
- }
232
-
233
- export function isStrongPwd(value: string): boolean {
234
- return /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=]).{12,}$/.test(value)
235
- }
236
-
237
- export function ip(value: string): boolean {
238
- const ipv4 = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
239
- if (!ipv4.test(value)) return false
240
- return value.split('.').every((part) => {
241
- const num = parseInt(part, 10)
242
- return num >= 0 && num <= 255 && String(num) === part // 防止 01、001
243
- })
244
- }
245
-
246
- export function stringCheck(value: string): boolean {
247
- return /^[a-zA-Z0-9\u4e00-\u9fa5\-_]+$/.test(value)
248
- }
249
-
250
- export function isChinese(value: string): boolean {
251
- return /^[\u4e00-\u9fa5]+$/.test(value)
252
- }
253
-
254
- export function isChineseChar(value: string): boolean {
255
- return /^[\u4e00-\u9fa5\u3400-\u4dbf\u{20000}-\u{2a6df}\u{2a700}-\u{2b73f}\u{2b740}-\u{2b81f}\u{2b820}-\u{2ceaf}]+$/u.test(
256
- value
257
- )
258
- }
259
-
260
- export function isRightfulString(value: string): boolean {
261
- return /^[A-Za-z0-9_-]+$/.test(value)
262
- }
263
-
264
- // 车牌号(简化版,仅支持普通蓝牌/绿牌)
265
- export function isPlateNo(plateNo: string): boolean {
266
- // 普通车牌:京A12345,新能源:京AD12345
267
- return (
268
- /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-Z0-9]{5}$/.test(
269
- plateNo
270
- ) ||
271
- /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-Z0-9]{6}$/.test(
272
- plateNo
273
- )
274
- )
275
- }
276
-
277
- // ========== 默认导出 ==========
278
-
279
- export default {
280
- isAlphabets,
281
- isCardId,
282
- isChinese,
283
- isChineseChar,
284
- isDigits,
285
- isEmail,
286
- isEnglish,
287
- isFloat,
288
- stringCheck,
289
- isFloatGteZero,
290
- ip,
291
- isFloatEqZero,
292
- isFloatGtZero,
293
- isFloatLtZero,
294
- isFloatLteZero,
295
- isFloatNEqZero,
296
- isIntEqZero,
297
- isIntGtZero,
298
- isIntGteZero,
299
- isIntLtZero,
300
- isIntLteZero,
301
- isIntNEqZero,
302
- isInteger,
303
- isLowerCase,
304
- isMobile,
305
- isName,
306
- isNull,
307
- isNum,
308
- isNumber,
309
- isNumberGtZero,
310
- isPhone,
311
- isPlateNo,
312
- isPwd,
313
- isWeakPwd,
314
- isStrongPwd,
315
- isQq,
316
- isRightfulString,
317
- isTel,
318
- isURL,
319
- isUpperCase,
320
- isZipCode
321
- }
@@ -1,153 +0,0 @@
1
- /**
2
- * @Author : TanRui
3
- * @WeChat : Tan578853789
4
- * @File : validator.ts
5
- * @Date : 2025/10/14
6
- * @Desc. : 校验方法
7
- */
8
-
9
- import validate from './validate'
10
- import type { RuleItem } from 'async-validator'
11
-
12
- // 统一校验函数类型
13
- type ValidatorRuleFunction = (
14
- rule: RuleItem,
15
- value: string | undefined,
16
- callback: (error?: Error) => void
17
- ) => void
18
-
19
- // 通用校验工厂
20
- const createValidator = (
21
- validateFn: (value: string) => boolean,
22
- message: string
23
- ): ValidatorRuleFunction => {
24
- return (_rule, value, callback) => {
25
- if (value != null && value !== '' && !validateFn(value)) {
26
- callback(new Error(message))
27
- } else {
28
- callback()
29
- }
30
- }
31
- }
32
-
33
- // 带额外参数的校验
34
- const isNum: ValidatorRuleFunction = (_rule, value, callback) => {
35
- if (value != null && value !== '' && !validate.isNum(value, 1)) {
36
- callback(new Error('请输入整数!'))
37
- } else {
38
- callback()
39
- }
40
- }
41
-
42
- // 带额外参数的校验
43
- const isNumberGtZero: ValidatorRuleFunction = (_rule, value, callback) => {
44
- if (value != null && value !== '' && !validate.isNumberGtZero(value)) {
45
- callback(new Error('请输入不小于零的数字!'))
46
- } else {
47
- callback()
48
- }
49
- }
50
-
51
- // 通用规则
52
- export const isMobile = createValidator(validate.isMobile, '请输入正确的手机号!')
53
- export const isPhone = createValidator(validate.isPhone, '请输入正确的电话号码!')
54
- export const isEmail = createValidator(validate.isEmail, '请输入有效的邮箱!')
55
- export const isURL = createValidator(validate.isURL, '请输入有效的URL!')
56
- export const isLowerCase = createValidator(validate.isLowerCase, '请输入小写字母!')
57
- export const isUpperCase = createValidator(validate.isUpperCase, '请输入大写字母!')
58
- export const isAlphabets = createValidator(validate.isAlphabets, '请输入大小写字母!')
59
- export const isName = createValidator(validate.isName, '请输入有效的姓名!')
60
- export const isFloat = createValidator(validate.isFloat, '请输入浮点数!')
61
- export const isNull = createValidator(validate.isNull, '必须为空!')
62
- export const isCardId = createValidator(validate.isCardId, '请输入合法的身份证号!')
63
- export const isIntEqZero = createValidator(validate.isIntEqZero, '请输入0!')
64
- export const isIntGtZero = createValidator(validate.isIntGtZero, '整数必须大于0!')
65
- export const isIntGteZero = createValidator(validate.isIntGteZero, '整数必须大于或等于0!')
66
- export const isIntNEqZero = createValidator(validate.isIntNEqZero, '整数必须不等于0!')
67
- export const isIntLtZero = createValidator(validate.isIntLtZero, '整数必须小于0!')
68
- export const isIntLteZero = createValidator(validate.isIntLteZero, '整数必须小于或等于0!')
69
- export const isFloatEqZero = createValidator(validate.isFloatEqZero, '浮点数必须为0!')
70
- export const isFloatGtZero = createValidator(validate.isFloatGtZero, '浮点数必须大于0!')
71
- export const isFloatGteZero = createValidator(validate.isFloatGteZero, '浮点数必须大于或等于0!')
72
- export const isFloatNEqZero = createValidator(validate.isFloatNEqZero, '浮点数必须不等于0!')
73
- export const isFloatLtZero = createValidator(validate.isFloatLtZero, '浮点数必须小于0!')
74
- export const isFloatLteZero = createValidator(validate.isFloatLteZero, '浮点数必须小于或等于0!')
75
- export const isInteger = createValidator(validate.isInteger, '必须为整数!')
76
- export const isNumber = createValidator(validate.isNumber, '请输入数字!')
77
- export const isDigits = createValidator(validate.isDigits, '只能输入[0-9]数字!')
78
- export const isEnglish = createValidator(validate.isEnglish, '只能包含英文字符。')
79
- export const isTel = createValidator(validate.isTel, '请正确填写您的联系方式')
80
- export const isQq = createValidator(validate.isQq, '请正确填写您QQ号码')
81
- export const isZipCode = createValidator(validate.isZipCode, '请正确填写您的邮政编码')
82
- export const isPwd = createValidator(
83
- validate.isPwd,
84
- '以字母开头,长度在6-12之间,只能包含字符、数字和下划线'
85
- )
86
- export const isWeakPwd = createValidator(
87
- validate.isWeakPwd,
88
- '只能包含字母(大小写)、数字和特殊字符'
89
- )
90
- export const isStrongPwd = createValidator(
91
- validate.isStrongPwd,
92
- '最小长度 12 位,且必须包含大小写字母、数字和特殊字符'
93
- )
94
- export const ip = createValidator(validate.ip, '请填写正确的IP地址。')
95
- export const stringCheck = createValidator(
96
- validate.stringCheck,
97
- '只能包含中文、英文、数字、下划线等字符'
98
- )
99
- export const isChinese = createValidator(validate.isChinese, '匹配汉字')
100
- export const isChineseChar = createValidator(validate.isChineseChar, '匹配中文(包括汉字和字符)')
101
- export const isRightfulString = createValidator(
102
- validate.isRightfulString,
103
- '判断是否为合法字符(a-zA-Z0-9-_)'
104
- )
105
- export const isPlateNo = createValidator(validate.isPlateNo, '请输入合法车牌号')
106
-
107
- // ✅ 特殊规则(带参数或逻辑不同)
108
- export { isNum, isNumberGtZero }
109
-
110
- // 🔸 默认导出(保持与原 JS 使用方式完全兼容)
111
- export default {
112
- isAlphabets,
113
- isCardId,
114
- isChinese,
115
- isChineseChar,
116
- ip,
117
- isFloatGteZero,
118
- isNum,
119
- stringCheck,
120
- isDigits,
121
- isEmail,
122
- isEnglish,
123
- isFloat,
124
- isFloatEqZero,
125
- isFloatGtZero,
126
- isFloatLtZero,
127
- isFloatLteZero,
128
- isFloatNEqZero,
129
- isIntEqZero,
130
- isIntGtZero,
131
- isIntGteZero,
132
- isIntLtZero,
133
- isIntLteZero,
134
- isIntNEqZero,
135
- isInteger,
136
- isLowerCase,
137
- isMobile,
138
- isName,
139
- isNull,
140
- isNumber,
141
- isNumberGtZero,
142
- isPhone,
143
- isPlateNo,
144
- isPwd,
145
- isWeakPwd,
146
- isStrongPwd,
147
- isQq,
148
- isRightfulString,
149
- isTel,
150
- isURL,
151
- isUpperCase,
152
- isZipCode
153
- }