Commit 79d55aa3e91242c30bfcb9e90b3acf95e3df0288

Authored by 芋道源码
Committed by Gitee
2 parents 0de7fdae c7924e04

!245 优化表单校验和查询参数,增加 vue3 简单使用说明

Merge pull request !245 from xingyu/master
Showing 30 changed files with 310 additions and 96 deletions
README.md
@@ -192,14 +192,14 @@ ps:核心功能已经实现,正在对接微信小程序中... @@ -192,14 +192,14 @@ ps:核心功能已经实现,正在对接微信小程序中...
192 | [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.8.2 | - | 192 | [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.8.2 | - |
193 | [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 4.0.0 | - | 193 | [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 4.0.0 | - |
194 194
195 -### Vue2 前端 195 +### [Vue2 前端](./yudao-ui-admin)
196 196
197 | 框架 | 说明 | 版本 | 197 | 框架 | 说明 | 版本 |
198 |------------------------------------------------------------------------------|---------------|--------| 198 |------------------------------------------------------------------------------|---------------|--------|
199 | [Vue](https://cn.vuejs.org/index.html) | JavaScript 框架 | 2.6.12 | 199 | [Vue](https://cn.vuejs.org/index.html) | JavaScript 框架 | 2.6.12 |
200 | [Vue Element Admin](https://panjiachen.github.io/vue-element-admin-site/zh/) | 后台前端解决方案 | - | 200 | [Vue Element Admin](https://panjiachen.github.io/vue-element-admin-site/zh/) | 后台前端解决方案 | - |
201 201
202 -### Vue3 前端 202 +### [Vue3 前端](./yudao-ui-admin-vue3)
203 203
204 | 框架 | 说明 | 版本 | 204 | 框架 | 说明 | 版本 |
205 |----------------------------------------------------------------------|------------------|--------| 205 |----------------------------------------------------------------------|------------------|--------|
yudao-ui-admin-vue3/README.md
@@ -22,6 +22,8 @@ @@ -22,6 +22,8 @@
22 - node >=14.18.0(建议使用 16 版本) ,pnpm >=7 22 - node >=14.18.0(建议使用 16 版本) ,pnpm >=7
23 - 开发建议使用 [谷歌浏览器-开发者版](https://www.google.cn/intl/zh-CN/chrome/dev/) 不支持 IE\QQ 等浏览器 23 - 开发建议使用 [谷歌浏览器-开发者版](https://www.google.cn/intl/zh-CN/chrome/dev/) 不支持 IE\QQ 等浏览器
24 24
  25 +### 点击查看[使用说明](./use.md)
  26 +
25 ### 前端依赖 27 ### 前端依赖
26 28
27 | 框架 | 说明 | 版本 | 29 | 框架 | 说明 | 版本 |
yudao-ui-admin-vue3/package.json
@@ -65,8 +65,8 @@ @@ -65,8 +65,8 @@
65 "@types/nprogress": "^0.2.0", 65 "@types/nprogress": "^0.2.0",
66 "@types/qrcode": "^1.4.2", 66 "@types/qrcode": "^1.4.2",
67 "@types/qs": "^6.9.7", 67 "@types/qs": "^6.9.7",
68 - "@typescript-eslint/eslint-plugin": "^5.31.0",  
69 - "@typescript-eslint/parser": "^5.31.0", 68 + "@typescript-eslint/eslint-plugin": "^5.32.0",
  69 + "@typescript-eslint/parser": "^5.32.0",
70 "@vitejs/plugin-vue": "^3.0.1", 70 "@vitejs/plugin-vue": "^3.0.1",
71 "@vitejs/plugin-vue-jsx": "^2.0.0", 71 "@vitejs/plugin-vue-jsx": "^2.0.0",
72 "autoprefixer": "^10.4.8", 72 "autoprefixer": "^10.4.8",
@@ -91,7 +91,7 @@ @@ -91,7 +91,7 @@
91 "stylelint-config-standard": "^26.0.0", 91 "stylelint-config-standard": "^26.0.0",
92 "stylelint-order": "^5.0.0", 92 "stylelint-order": "^5.0.0",
93 "typescript": "4.7.4", 93 "typescript": "4.7.4",
94 - "unplugin-vue-define-options": "^0.6.2", 94 + "unplugin-vue-define-options": "^0.7.1",
95 "vite": "3.0.4", 95 "vite": "3.0.4",
96 "vite-plugin-compression": "^0.5.1", 96 "vite-plugin-compression": "^0.5.1",
97 "vite-plugin-eslint": "^1.7.0", 97 "vite-plugin-eslint": "^1.7.0",
yudao-ui-admin-vue3/src/api/system/dept/types.ts
1 export type DeptVO = { 1 export type DeptVO = {
2 id: number 2 id: number
3 name: string 3 name: string
4 - status: number  
5 parentId: number 4 parentId: number
6 - createTime: string 5 + status: number
  6 + sort: number
  7 + leaderUserId: number
  8 + phone: string
  9 + email: string
7 } 10 }
8 11
9 export type DeptListReqVO = { 12 export type DeptListReqVO = {
yudao-ui-admin-vue3/src/config/axios/index.ts
1 import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios' 1 import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
2 -import { ElMessage, ElMessageBox, ElNotification } from 'element-plus' 2 +import { ElMessage, ElNotification } from 'element-plus'
3 import qs from 'qs' 3 import qs from 'qs'
4 import { config } from '@/config/axios/config' 4 import { config } from '@/config/axios/config'
5 -import { getAccessToken, getRefreshToken, getTenantId } from '@/utils/auth' 5 +import { getAccessToken, getTenantId, removeToken } from '@/utils/auth'
6 import errorCode from './errorCode' 6 import errorCode from './errorCode'
7 import { useI18n } from '@/hooks/web/useI18n' 7 import { useI18n } from '@/hooks/web/useI18n'
8 8
@@ -22,7 +22,7 @@ export const isRelogin = { show: false } @@ -22,7 +22,7 @@ export const isRelogin = { show: false }
22 // 请求队列 22 // 请求队列
23 // const requestList = [] 23 // const requestList = []
24 // 是否正在刷新中 24 // 是否正在刷新中
25 -let isRefreshToken = false 25 +// const isRefreshToken = false
26 26
27 export const PATH_URL = base_url[import.meta.env.VITE_API_BASEPATH] 27 export const PATH_URL = base_url[import.meta.env.VITE_API_BASEPATH]
28 28
@@ -55,18 +55,26 @@ service.interceptors.request.use( @@ -55,18 +55,26 @@ service.interceptors.request.use(
55 config.data = qs.stringify(data) 55 config.data = qs.stringify(data)
56 } 56 }
57 // get参数编码 57 // get参数编码
58 - if (config.method?.toUpperCase() === 'GET' && config.params) {  
59 - let url = config.url as string 58 + if (config.method?.toUpperCase() === 'GET' && params) {
  59 + let url = config.url + '?'
  60 + for (const propName of Object.keys(params)) {
  61 + const value = params[propName]
  62 + if (value !== void 0 && value !== null && typeof value !== 'undefined') {
  63 + if (typeof value === 'object') {
  64 + for (const val of Object.keys(value)) {
  65 + const params = propName + '[' + val + ']'
  66 + const subPart = encodeURIComponent(params) + '='
  67 + url += subPart + encodeURIComponent(value[val]) + '&'
  68 + }
  69 + } else {
  70 + url += `${propName}=${encodeURIComponent(value)}&`
  71 + }
  72 + }
  73 + }
60 // 给 get 请求加上时间戳参数,避免从缓存中拿数据 74 // 给 get 请求加上时间戳参数,避免从缓存中拿数据
61 // const now = new Date().getTime() 75 // const now = new Date().getTime()
62 // params = params.substring(0, url.length - 1) + `?_t=${now}` 76 // params = params.substring(0, url.length - 1) + `?_t=${now}`
63 - url += '?'  
64 - const keys = Object.keys(params)  
65 - for (const key of keys) {  
66 - if (params[key] !== void 0 && params[key] !== null) {  
67 - url += `${key}=${encodeURIComponent(params[key])}&`  
68 - }  
69 - } 77 + url = url.slice(0, -1)
70 config.params = {} 78 config.params = {}
71 config.url = url 79 config.url = url
72 } 80 }
@@ -90,6 +98,13 @@ service.interceptors.response.use( @@ -90,6 +98,13 @@ service.interceptors.response.use(
90 const { t } = useI18n() 98 const { t } = useI18n()
91 // 未设置状态码则默认成功状态 99 // 未设置状态码则默认成功状态
92 const code = data.code || result_code 100 const code = data.code || result_code
  101 + // 二进制数据则直接返回
  102 + if (
  103 + response.request.responseType === 'blob' ||
  104 + response.request.responseType === 'arraybuffer'
  105 + ) {
  106 + return response.data
  107 + }
93 // 获取错误信息 108 // 获取错误信息
94 const msg = data.msg || errorCode[code] || errorCode['default'] 109 const msg = data.msg || errorCode[code] || errorCode['default']
95 if (ignoreMsgs.indexOf(msg) !== -1) { 110 if (ignoreMsgs.indexOf(msg) !== -1) {
@@ -97,15 +112,16 @@ service.interceptors.response.use( @@ -97,15 +112,16 @@ service.interceptors.response.use(
97 return Promise.reject(msg) 112 return Promise.reject(msg)
98 } else if (code === 401) { 113 } else if (code === 401) {
99 // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了 114 // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
100 - if (!isRefreshToken) {  
101 - isRefreshToken = true  
102 - // 1. 如果获取不到刷新令牌,则只能执行登出操作  
103 - if (!getRefreshToken()) {  
104 - return handleAuthorized()  
105 - }  
106 - // 2. 进行刷新访问令牌  
107 - // TODO: 引入refreshToken会循环依赖报错  
108 - } 115 + return handleAuthorized()
  116 + // if (!isRefreshToken) {
  117 + // isRefreshToken = true
  118 + // // 1. 如果获取不到刷新令牌,则只能执行登出操作
  119 + // if (!getRefreshToken()) {
  120 + // return handleAuthorized()
  121 + // }
  122 + // // 2. 进行刷新访问令牌
  123 + // // TODO: 引入refreshToken会循环依赖报错
  124 + // }
109 } else if (code === 500) { 125 } else if (code === 500) {
110 ElMessage.error(t('sys.api.errMsg500')) 126 ElMessage.error(t('sys.api.errMsg500'))
111 return Promise.reject(new Error(msg)) 127 return Promise.reject(new Error(msg))
@@ -149,21 +165,12 @@ service.interceptors.response.use( @@ -149,21 +165,12 @@ service.interceptors.response.use(
149 return Promise.reject(error) 165 return Promise.reject(error)
150 } 166 }
151 ) 167 )
152 -function handleAuthorized() { 168 +const handleAuthorized = () => {
153 const { t } = useI18n() 169 const { t } = useI18n()
154 if (!isRelogin.show) { 170 if (!isRelogin.show) {
  171 + removeToken()
155 isRelogin.show = true 172 isRelogin.show = true
156 - ElMessageBox.confirm(t('sys.api.timeoutMessage'), t('common.confirmTitle'), {  
157 - confirmButtonText: t('login.relogin'),  
158 - cancelButtonText: t('common.cancel'),  
159 - type: 'warning'  
160 - })  
161 - .then(() => {  
162 - isRelogin.show = false  
163 - })  
164 - .catch(() => {  
165 - isRelogin.show = false  
166 - }) 173 + ElNotification.error(t('sys.api.timeoutMessage'))
167 } 174 }
168 return Promise.reject(t('sys.api.timeoutMessage')) 175 return Promise.reject(t('sys.api.timeoutMessage'))
169 } 176 }
yudao-ui-admin-vue3/src/utils/tree.ts
@@ -213,7 +213,7 @@ export const eachTree = (treeDatas: any[], callBack: Fn, parentNode = {}) => { @@ -213,7 +213,7 @@ export const eachTree = (treeDatas: any[], callBack: Fn, parentNode = {}) => {
213 * @param {*} parentId 父节点字段 默认 'parentId' 213 * @param {*} parentId 父节点字段 默认 'parentId'
214 * @param {*} children 孩子节点字段 默认 'children' 214 * @param {*} children 孩子节点字段 默认 'children'
215 */ 215 */
216 -export const handleTree = (data, id?: string, parentId?: string, children?: string) => { 216 +export const handleTree = (data: any[], id?: string, parentId?: string, children?: string) => {
217 const config = { 217 const config = {
218 id: id || 'id', 218 id: id || 'id',
219 parentId: parentId || 'parentId', 219 parentId: parentId || 'parentId',
@@ -222,7 +222,7 @@ export const handleTree = (data, id?: string, parentId?: string, children?: stri @@ -222,7 +222,7 @@ export const handleTree = (data, id?: string, parentId?: string, children?: stri
222 222
223 const childrenListMap = {} 223 const childrenListMap = {}
224 const nodeIds = {} 224 const nodeIds = {}
225 - const tree = [] 225 + const tree: any[] = []
226 226
227 for (const d of data) { 227 for (const d of data) {
228 const parentId = d[config.parentId] 228 const parentId = d[config.parentId]
yudao-ui-admin-vue3/src/views/infra/apiAccessLog/apiAccessLog.data.ts
@@ -50,7 +50,16 @@ const crudSchemas = reactive<CrudSchema[]>([ @@ -50,7 +50,16 @@ const crudSchemas = reactive<CrudSchema[]>([
50 }, 50 },
51 { 51 {
52 label: '请求时间', 52 label: '请求时间',
53 - field: 'beginTime' 53 + field: 'beginTime',
  54 + search: {
  55 + show: true,
  56 + component: 'DatePicker',
  57 + componentProps: {
  58 + type: 'datetimerange',
  59 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  60 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  61 + }
  62 + }
54 }, 63 },
55 { 64 {
56 label: '执行时长', 65 label: '执行时长',
yudao-ui-admin-vue3/src/views/infra/apiErrorLog/apiErrorLog.data.ts
@@ -50,7 +50,16 @@ const crudSchemas = reactive<CrudSchema[]>([ @@ -50,7 +50,16 @@ const crudSchemas = reactive<CrudSchema[]>([
50 }, 50 },
51 { 51 {
52 label: '异常发生时间', 52 label: '异常发生时间',
53 - field: 'exceptionTime' 53 + field: 'exceptionTime',
  54 + search: {
  55 + show: true,
  56 + component: 'DatePicker',
  57 + componentProps: {
  58 + type: 'datetimerange',
  59 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  60 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  61 + }
  62 + }
54 }, 63 },
55 { 64 {
56 label: '异常名', 65 label: '异常名',
yudao-ui-admin-vue3/src/views/infra/codegen/codegen.data.ts
@@ -50,6 +50,15 @@ const crudSchemas = reactive<CrudSchema[]>([ @@ -50,6 +50,15 @@ const crudSchemas = reactive<CrudSchema[]>([
50 field: 'createTime', 50 field: 'createTime',
51 form: { 51 form: {
52 show: false 52 show: false
  53 + },
  54 + search: {
  55 + show: true,
  56 + component: 'DatePicker',
  57 + componentProps: {
  58 + type: 'datetimerange',
  59 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  60 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  61 + }
53 } 62 }
54 }, 63 },
55 { 64 {
yudao-ui-admin-vue3/src/views/infra/config/config.data.ts
@@ -91,6 +91,15 @@ const crudSchemas = reactive<CrudSchema[]>([ @@ -91,6 +91,15 @@ const crudSchemas = reactive<CrudSchema[]>([
91 field: 'createTime', 91 field: 'createTime',
92 form: { 92 form: {
93 show: false 93 show: false
  94 + },
  95 + search: {
  96 + show: true,
  97 + component: 'DatePicker',
  98 + componentProps: {
  99 + type: 'datetimerange',
  100 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  101 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  102 + }
94 } 103 }
95 }, 104 },
96 { 105 {
yudao-ui-admin-vue3/src/views/infra/dataSourceConfig/dataSourceConfig.data.ts
@@ -58,6 +58,15 @@ const crudSchemas = reactive<CrudSchema[]>([ @@ -58,6 +58,15 @@ const crudSchemas = reactive<CrudSchema[]>([
58 field: 'createTime', 58 field: 'createTime',
59 form: { 59 form: {
60 show: false 60 show: false
  61 + },
  62 + search: {
  63 + show: true,
  64 + component: 'DatePicker',
  65 + componentProps: {
  66 + type: 'datetimerange',
  67 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  68 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  69 + }
61 } 70 }
62 }, 71 },
63 { 72 {
yudao-ui-admin-vue3/src/views/infra/fileConfig/fileConfig.data.ts
@@ -76,6 +76,15 @@ const crudSchemas = reactive<CrudSchema[]>([ @@ -76,6 +76,15 @@ const crudSchemas = reactive<CrudSchema[]>([
76 field: 'createTime', 76 field: 'createTime',
77 form: { 77 form: {
78 show: false 78 show: false
  79 + },
  80 + search: {
  81 + show: true,
  82 + component: 'DatePicker',
  83 + componentProps: {
  84 + type: 'datetimerange',
  85 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  86 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  87 + }
79 } 88 }
80 }, 89 },
81 { 90 {
yudao-ui-admin-vue3/src/views/infra/fileList/fileList.data.ts
@@ -36,6 +36,15 @@ const crudSchemas = reactive<CrudSchema[]>([ @@ -36,6 +36,15 @@ const crudSchemas = reactive<CrudSchema[]>([
36 field: 'createTime', 36 field: 'createTime',
37 form: { 37 form: {
38 show: false 38 show: false
  39 + },
  40 + search: {
  41 + show: true,
  42 + component: 'DatePicker',
  43 + componentProps: {
  44 + type: 'datetimerange',
  45 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  46 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  47 + }
39 } 48 }
40 }, 49 },
41 { 50 {
yudao-ui-admin-vue3/src/views/pay/app/app.data.ts
@@ -8,9 +8,10 @@ const { t } = useI18n() // 国际化 @@ -8,9 +8,10 @@ const { t } = useI18n() // 国际化
8 // 表单校验 8 // 表单校验
9 export const rules = reactive({ 9 export const rules = reactive({
10 name: [required], 10 name: [required],
11 - code: [required],  
12 - sort: [required],  
13 - status: [required] 11 + status: [required],
  12 + payNotifyUrl: [required],
  13 + refundNotifyUrl: [required],
  14 + merchantId: [required]
14 }) 15 })
15 16
16 // CrudSchema 17 // CrudSchema
@@ -53,6 +54,15 @@ const crudSchemas = reactive<CrudSchema[]>([ @@ -53,6 +54,15 @@ const crudSchemas = reactive<CrudSchema[]>([
53 field: 'createTime', 54 field: 'createTime',
54 form: { 55 form: {
55 show: false 56 show: false
  57 + },
  58 + search: {
  59 + show: true,
  60 + component: 'DatePicker',
  61 + componentProps: {
  62 + type: 'datetimerange',
  63 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  64 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  65 + }
56 } 66 }
57 }, 67 },
58 { 68 {
yudao-ui-admin-vue3/src/views/pay/merchant/merchant.data.ts
@@ -7,9 +7,9 @@ const { t } = useI18n() // 国际化 @@ -7,9 +7,9 @@ const { t } = useI18n() // 国际化
7 7
8 // 表单校验 8 // 表单校验
9 export const rules = reactive({ 9 export const rules = reactive({
  10 + no: [required],
10 name: [required], 11 name: [required],
11 - code: [required],  
12 - sort: [required], 12 + shortName: [required],
13 status: [required] 13 status: [required]
14 }) 14 })
15 15
@@ -77,6 +77,15 @@ const crudSchemas = reactive<CrudSchema[]>([ @@ -77,6 +77,15 @@ const crudSchemas = reactive<CrudSchema[]>([
77 field: 'createTime', 77 field: 'createTime',
78 form: { 78 form: {
79 show: false 79 show: false
  80 + },
  81 + search: {
  82 + show: true,
  83 + component: 'DatePicker',
  84 + componentProps: {
  85 + type: 'datetimerange',
  86 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  87 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  88 + }
80 } 89 }
81 }, 90 },
82 { 91 {
yudao-ui-admin-vue3/src/views/pay/order/order.data.ts
@@ -158,6 +158,22 @@ const crudSchemas = reactive<CrudSchema[]>([ @@ -158,6 +158,22 @@ const crudSchemas = reactive<CrudSchema[]>([
158 field: 'channelOrderNo' 158 field: 'channelOrderNo'
159 }, 159 },
160 { 160 {
  161 + label: t('common.createTime'),
  162 + field: 'createTime',
  163 + form: {
  164 + show: false
  165 + },
  166 + search: {
  167 + show: true,
  168 + component: 'DatePicker',
  169 + componentProps: {
  170 + type: 'datetimerange',
  171 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  172 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  173 + }
  174 + }
  175 + },
  176 + {
161 label: t('table.action'), 177 label: t('table.action'),
162 field: 'action', 178 field: 'action',
163 width: '270px', 179 width: '270px',
yudao-ui-admin-vue3/src/views/pay/refund/refund.data.ts
@@ -84,6 +84,15 @@ const crudSchemas = reactive<CrudSchema[]>([ @@ -84,6 +84,15 @@ const crudSchemas = reactive<CrudSchema[]>([
84 field: 'createTime', 84 field: 'createTime',
85 form: { 85 form: {
86 show: false 86 show: false
  87 + },
  88 + search: {
  89 + show: true,
  90 + component: 'DatePicker',
  91 + componentProps: {
  92 + type: 'datetimerange',
  93 + valueFormat: 'YYYY-MM-DD HH:mm:ss',
  94 + defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  95 + }
87 } 96 }
88 }, 97 },
89 { 98 {
yudao-ui-admin-vue3/src/views/system/dept/dept.data.ts
1 import { required } from '@/utils/formRules' 1 import { required } from '@/utils/formRules'
2 import { reactive } from 'vue' 2 import { reactive } from 'vue'
  3 +// 表单校验
  4 +export const rules = reactive({
  5 + name: [required],
  6 + sort: [required],
  7 + email: [required],
  8 + phone: [
  9 + {
  10 + pattern:
  11 + /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/,
  12 + trigger: 'blur',
  13 + message: '请输入正确的手机号码'
  14 + }
  15 + ]
  16 +})
3 17
4 export const modelSchema = reactive<FormSchema[]>([ 18 export const modelSchema = reactive<FormSchema[]>([
5 { 19 {
@@ -17,7 +31,7 @@ export const modelSchema = reactive&lt;FormSchema[]&gt;([ @@ -17,7 +31,7 @@ export const modelSchema = reactive&lt;FormSchema[]&gt;([
17 }, 31 },
18 { 32 {
19 label: '负责人', 33 label: '负责人',
20 - field: 'email', 34 + field: 'leaderUserId',
21 component: 'Input' 35 component: 'Input'
22 }, 36 },
23 { 37 {
@@ -33,7 +47,7 @@ export const modelSchema = reactive&lt;FormSchema[]&gt;([ @@ -33,7 +47,7 @@ export const modelSchema = reactive&lt;FormSchema[]&gt;([
33 { 47 {
34 label: '显示排序', 48 label: '显示排序',
35 field: 'sort', 49 field: 'sort',
36 - component: 'Input' 50 + component: 'InputNumber'
37 }, 51 },
38 { 52 {
39 label: '状态', 53 label: '状态',
yudao-ui-admin-vue3/src/views/system/dept/index.vue
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 import { useI18n } from '@/hooks/web/useI18n' 2 import { useI18n } from '@/hooks/web/useI18n'
3 -import { ElInput, ElCard, ElTree, ElTreeSelect } from 'element-plus' 3 +import { ElInput, ElCard, ElTree, ElTreeSelect, ElSelect, ElOption } from 'element-plus'
4 import { handleTree } from '@/utils/tree' 4 import { handleTree } from '@/utils/tree'
5 import { onMounted, ref, unref, watch } from 'vue' 5 import { onMounted, ref, unref, watch } from 'vue'
6 import * as DeptApi from '@/api/system/dept' 6 import * as DeptApi from '@/api/system/dept'
7 import { Form, FormExpose } from '@/components/Form' 7 import { Form, FormExpose } from '@/components/Form'
8 -import { modelSchema } from './dept.data' 8 +import { modelSchema, rules } from './dept.data'
9 import { DeptVO } from '@/api/system/dept/types' 9 import { DeptVO } from '@/api/system/dept/types'
10 import { useMessage } from '@/hooks/web/useMessage' 10 import { useMessage } from '@/hooks/web/useMessage'
  11 +import { getListSimpleUsersApi } from '@/api/system/user'
11 const message = useMessage() 12 const message = useMessage()
12 interface Tree { 13 interface Tree {
13 id: number 14 id: number
@@ -34,7 +35,7 @@ const filterText = ref(&#39;&#39;) @@ -34,7 +35,7 @@ const filterText = ref(&#39;&#39;)
34 const deptOptions = ref() // 树形结构 35 const deptOptions = ref() // 树形结构
35 const treeRef = ref<InstanceType<typeof ElTree>>() 36 const treeRef = ref<InstanceType<typeof ElTree>>()
36 const getTree = async () => { 37 const getTree = async () => {
37 - const res = await DeptApi.getDeptPageApi(null) 38 + const res = await DeptApi.listSimpleDeptApi()
38 deptOptions.value = handleTree(res) 39 deptOptions.value = handleTree(res)
39 } 40 }
40 const filterNode = (value: string, data: Tree) => { 41 const filterNode = (value: string, data: Tree) => {
@@ -44,6 +45,13 @@ const filterNode = (value: string, data: Tree) =&gt; { @@ -44,6 +45,13 @@ const filterNode = (value: string, data: Tree) =&gt; {
44 watch(filterText, (val) => { 45 watch(filterText, (val) => {
45 treeRef.value!.filter(val) 46 treeRef.value!.filter(val)
46 }) 47 })
  48 +// 用户列表
  49 +const userOption = ref()
  50 +const leaderUserId = ref()
  51 +const getUserList = async () => {
  52 + const res = await getListSimpleUsersApi()
  53 + userOption.value = res
  54 +}
47 // 新增 55 // 新增
48 const handleAdd = (data: { id: number }) => { 56 const handleAdd = (data: { id: number }) => {
49 // 重置表单 57 // 重置表单
@@ -54,11 +62,12 @@ const handleAdd = (data: { id: number }) =&gt; { @@ -54,11 +62,12 @@ const handleAdd = (data: { id: number }) =&gt; {
54 } 62 }
55 // 编辑 63 // 编辑
56 const handleUpdate = async (data: { id: number }) => { 64 const handleUpdate = async (data: { id: number }) => {
57 - showForm.value = true  
58 const res = await DeptApi.getDeptApi(data.id) 65 const res = await DeptApi.getDeptApi(data.id)
59 formTitle.value = '修改- ' + res?.name 66 formTitle.value = '修改- ' + res?.name
60 deptParentId.value = res.parentId 67 deptParentId.value = res.parentId
  68 + leaderUserId.value = res.leaderUserId
61 unref(formRef)?.setValues(res) 69 unref(formRef)?.setValues(res)
  70 + showForm.value = true
62 } 71 }
63 // 删除 72 // 删除
64 const handleDelete = async (data: { id: number }) => { 73 const handleDelete = async (data: { id: number }) => {
@@ -78,7 +87,7 @@ const submitForm = async () =&gt; { @@ -78,7 +87,7 @@ const submitForm = async () =&gt; {
78 try { 87 try {
79 const data = unref(formRef)?.formModel as DeptVO 88 const data = unref(formRef)?.formModel as DeptVO
80 data.parentId = deptParentId.value 89 data.parentId = deptParentId.value
81 - // TODO: 表单提交待完善 90 + data.leaderUserId = leaderUserId.value
82 if (formTitle.value.startsWith('新增')) { 91 if (formTitle.value.startsWith('新增')) {
83 await DeptApi.createDeptApi(data) 92 await DeptApi.createDeptApi(data)
84 } else if (formTitle.value.startsWith('修改')) { 93 } else if (formTitle.value.startsWith('修改')) {
@@ -92,6 +101,7 @@ const submitForm = async () =&gt; { @@ -92,6 +101,7 @@ const submitForm = async () =&gt; {
92 } 101 }
93 onMounted(async () => { 102 onMounted(async () => {
94 await getTree() 103 await getTree()
  104 + await getUserList()
95 }) 105 })
96 </script> 106 </script>
97 <template> 107 <template>
@@ -123,14 +133,29 @@ onMounted(async () =&gt; { @@ -123,14 +133,29 @@ onMounted(async () =&gt; {
123 <span class="custom-tree-node"> 133 <span class="custom-tree-node">
124 <span>{{ node.label }}</span> 134 <span>{{ node.label }}</span>
125 <span> 135 <span>
126 - <el-button link v-hasPermi="['system:dept:create']" @click="handleAdd(data)">  
127 - <Icon icon="ep:plus" class="mr-1px" /> 136 + <el-button
  137 + link
  138 + type="primary"
  139 + v-hasPermi="['system:dept:create']"
  140 + @click="handleAdd(data)"
  141 + >
  142 + <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
128 </el-button> 143 </el-button>
129 - <el-button link v-hasPermi="['system:dept:update']" @click="handleUpdate(data)">  
130 - <Icon icon="ep:edit" class="mr-1px" /> 144 + <el-button
  145 + link
  146 + type="primary"
  147 + v-hasPermi="['system:dept:update']"
  148 + @click="handleUpdate(data)"
  149 + >
  150 + <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
131 </el-button> 151 </el-button>
132 - <el-button link v-hasPermi="['system:dept:delete']" @click="handleDelete(data)">  
133 - <Icon icon="ep:delete" class="mr-1px" /> 152 + <el-button
  153 + link
  154 + type="primary"
  155 + v-hasPermi="['system:dept:delete']"
  156 + @click="handleDelete(data)"
  157 + >
  158 + <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
134 </el-button> 159 </el-button>
135 </span> 160 </span>
136 </span> 161 </span>
@@ -149,7 +174,7 @@ onMounted(async () =&gt; { @@ -149,7 +174,7 @@ onMounted(async () =&gt; {
149 </div> 174 </div>
150 <div v-if="showForm"> 175 <div v-if="showForm">
151 <!-- 操作工具栏 --> 176 <!-- 操作工具栏 -->
152 - <Form :schema="modelSchema" ref="formRef"> 177 + <Form ref="formRef" :schema="modelSchema" :rules="rules">
153 <template #parentId> 178 <template #parentId>
154 <el-tree-select 179 <el-tree-select
155 node-key="id" 180 node-key="id"
@@ -159,6 +184,16 @@ onMounted(async () =&gt; { @@ -159,6 +184,16 @@ onMounted(async () =&gt; {
159 check-strictly 184 check-strictly
160 /> 185 />
161 </template> 186 </template>
  187 + <template #leaderUserId>
  188 + <el-select v-model="leaderUserId">
  189 + <el-option
  190 + v-for="item in userOption"
  191 + :key="parseInt(item.id)"
  192 + :label="item.nickname"
  193 + :value="parseInt(item.id)"
  194 + />
  195 + </el-select>
  196 + </template>
162 </Form> 197 </Form>
163 <!-- 操作按钮 --> 198 <!-- 操作按钮 -->
164 <el-button 199 <el-button
yudao-ui-admin-vue3/src/views/system/dict/dict.data.ts
@@ -7,9 +7,9 @@ import { CrudSchema, useCrudSchemas } from &#39;@/hooks/web/useCrudSchemas&#39; @@ -7,9 +7,9 @@ import { CrudSchema, useCrudSchemas } from &#39;@/hooks/web/useCrudSchemas&#39;
7 const { t } = useI18n() 7 const { t } = useI18n()
8 // 表单校验 8 // 表单校验
9 export const dictDataRules = reactive({ 9 export const dictDataRules = reactive({
10 - dictType: [required],  
11 label: [required], 10 label: [required],
12 - value: [required] 11 + value: [required],
  12 + sort: [required]
13 }) 13 })
14 // crudSchemas 14 // crudSchemas
15 export const crudSchemas = reactive<CrudSchema[]>([ 15 export const crudSchemas = reactive<CrudSchema[]>([
@@ -29,6 +29,9 @@ export const crudSchemas = reactive&lt;CrudSchema[]&gt;([ @@ -29,6 +29,9 @@ export const crudSchemas = reactive&lt;CrudSchema[]&gt;([
29 field: 'dictType', 29 field: 'dictType',
30 table: { 30 table: {
31 show: false 31 show: false
  32 + },
  33 + form: {
  34 + show: false
32 } 35 }
33 }, 36 },
34 { 37 {
yudao-ui-admin-vue3/src/views/system/menu/index.vue
@@ -25,11 +25,12 @@ import { MenuVO } from &#39;@/api/system/menu/types&#39; @@ -25,11 +25,12 @@ import { MenuVO } from &#39;@/api/system/menu/types&#39;
25 import { SystemMenuTypeEnum, CommonStatusEnum } from '@/utils/constants' 25 import { SystemMenuTypeEnum, CommonStatusEnum } from '@/utils/constants'
26 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' 26 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
27 import { useMessage } from '@/hooks/web/useMessage' 27 import { useMessage } from '@/hooks/web/useMessage'
  28 +import { required } from '@/utils/formRules.js'
28 const message = useMessage() 29 const message = useMessage()
29 const { t } = useI18n() // 国际化 30 const { t } = useI18n() // 国际化
30 // ========== 创建菜单树结构 ========== 31 // ========== 创建菜单树结构 ==========
31 const loading = ref(true) 32 const loading = ref(true)
32 -const menuData = ref([]) // 树形结构 33 +const menuData = ref<any[]>([]) // 树形结构
33 const getList = async () => { 34 const getList = async () => {
34 const res = await MenuApi.getMenuListApi(queryParams) 35 const res = await MenuApi.getMenuListApi(queryParams)
35 menuData.value = handleTree(res) 36 menuData.value = handleTree(res)
@@ -44,7 +45,7 @@ const menuProps = { @@ -44,7 +45,7 @@ const menuProps = {
44 const menuOptions = ref() // 树形结构 45 const menuOptions = ref() // 树形结构
45 const getTree = async () => { 46 const getTree = async () => {
46 const res = await MenuApi.listSimpleMenusApi() 47 const res = await MenuApi.listSimpleMenusApi()
47 - const menu = { id: 0, name: '主类目', children: [] } 48 + const menu = { id: 0, name: '主类目', children: [] as any[] }
48 menu.children = handleTree(res) 49 menu.children = handleTree(res)
49 console.info(menu) 50 console.info(menu)
50 menuOptions.value = menu 51 menuOptions.value = menu
@@ -85,12 +86,12 @@ const menuForm = ref&lt;MenuVO&gt;({ @@ -85,12 +86,12 @@ const menuForm = ref&lt;MenuVO&gt;({
85 createTime: '' 86 createTime: ''
86 }) 87 })
87 // 表单校验 88 // 表单校验
88 -const rules = {  
89 - name: [{ required: true, message: '菜单名称不能为空', trigger: 'blur' }],  
90 - sort: [{ required: true, message: '菜单顺序不能为空', trigger: 'blur' }],  
91 - path: [{ required: true, message: '路由地址不能为空', trigger: 'blur' }],  
92 - status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]  
93 -} 89 +const rules = reactive({
  90 + name: [required],
  91 + sort: [required],
  92 + path: [required],
  93 + status: [required]
  94 +})
94 // 设置标题 95 // 设置标题
95 const setDialogTile = (type: string) => { 96 const setDialogTile = (type: string) => {
96 dialogTitle.value = t('action.' + type) 97 dialogTitle.value = t('action.' + type)
yudao-ui-admin-vue3/src/views/system/notice/notice.data.ts
@@ -8,8 +8,7 @@ const { t } = useI18n() // 国际化 @@ -8,8 +8,7 @@ const { t } = useI18n() // 国际化
8 // 表单校验 8 // 表单校验
9 export const rules = reactive({ 9 export const rules = reactive({
10 title: [required], 10 title: [required],
11 - type: [required],  
12 - status: [required] 11 + type: [required]
13 }) 12 })
14 13
15 // CrudSchema 14 // CrudSchema
yudao-ui-admin-vue3/src/views/system/post/post.data.ts
@@ -9,8 +9,7 @@ const { t } = useI18n() // 国际化 @@ -9,8 +9,7 @@ const { t } = useI18n() // 国际化
9 export const rules = reactive({ 9 export const rules = reactive({
10 name: [required], 10 name: [required],
11 code: [required], 11 code: [required],
12 - sort: [required],  
13 - status: [required] 12 + sort: [required]
14 }) 13 })
15 14
16 // CrudSchema 15 // CrudSchema
yudao-ui-admin-vue3/src/views/system/sms/smsTemplate/sms.template.data.ts
@@ -8,13 +8,12 @@ const { t } = useI18n() // 国际化 @@ -8,13 +8,12 @@ const { t } = useI18n() // 国际化
8 // 表单校验 8 // 表单校验
9 export const rules = reactive({ 9 export const rules = reactive({
10 type: [required], 10 type: [required],
  11 + status: [required],
  12 + code: [required],
11 name: [required], 13 name: [required],
12 content: [required], 14 content: [required],
13 apiTemplateId: [required], 15 apiTemplateId: [required],
14 - channelId: [required],  
15 - code: [required],  
16 - sort: [required],  
17 - status: [required] 16 + channelId: [required]
18 }) 17 })
19 18
20 // CrudSchema 19 // CrudSchema
yudao-ui-admin-vue3/src/views/system/user/index.vue
@@ -9,6 +9,7 @@ import { @@ -9,6 +9,7 @@ import {
9 ElTreeSelect, 9 ElTreeSelect,
10 ElSelect, 10 ElSelect,
11 ElOption, 11 ElOption,
  12 + ElTransfer,
12 ElForm, 13 ElForm,
13 ElFormItem, 14 ElFormItem,
14 ElUpload, 15 ElUpload,
@@ -62,7 +63,7 @@ const { getList, setSearchParams, delList, exportList } = methods @@ -62,7 +63,7 @@ const { getList, setSearchParams, delList, exportList } = methods
62 63
63 // ========== 创建部门树结构 ========== 64 // ========== 创建部门树结构 ==========
64 const filterText = ref('') 65 const filterText = ref('')
65 -const deptOptions = ref([]) // 树形结构 66 +const deptOptions = ref<any[]>([]) // 树形结构
66 const searchForm = ref<FormExpose>() 67 const searchForm = ref<FormExpose>()
67 const treeRef = ref<InstanceType<typeof ElTree>>() 68 const treeRef = ref<InstanceType<typeof ElTree>>()
68 const getTree = async () => { 69 const getTree = async () => {
@@ -268,6 +269,7 @@ const handleFileSuccess = (response: any): void =&gt; { @@ -268,6 +269,7 @@ const handleFileSuccess = (response: any): void =&gt; {
268 text += '< ' + username + ': ' + data.failureUsernames[username] + ' >' 269 text += '< ' + username + ': ' + data.failureUsernames[username] + ' >'
269 } 270 }
270 message.alert(text) 271 message.alert(text)
  272 + getList()
271 } 273 }
272 // 文件数超出提示 274 // 文件数超出提示
273 const handleExceed = (): void => { 275 const handleExceed = (): void => {
@@ -281,8 +283,8 @@ const excelUploadError = (): void =&gt; { @@ -281,8 +283,8 @@ const excelUploadError = (): void =&gt; {
281 onMounted(async () => { 283 onMounted(async () => {
282 await getTree() 284 await getTree()
283 await getPostOptions() 285 await getPostOptions()
  286 + await getList()
284 }) 287 })
285 -getList()  
286 </script> 288 </script>
287 289
288 <template> 290 <template>
@@ -482,7 +484,7 @@ getList() @@ -482,7 +484,7 @@ getList()
482 </template> 484 </template>
483 </Dialog> 485 </Dialog>
484 <!-- 分配用户角色 --> 486 <!-- 分配用户角色 -->
485 - <Dialog v-model="roleDialogVisible" title="分配角色"> 487 + <Dialog v-model="roleDialogVisible" title="分配角色" maxHeight="450px">
486 <el-form :model="userRole" label-width="80px"> 488 <el-form :model="userRole" label-width="80px">
487 <el-form-item label="用户名称"> 489 <el-form-item label="用户名称">
488 <el-input v-model="userRole.username" :disabled="true" /> 490 <el-input v-model="userRole.username" :disabled="true" />
@@ -491,14 +493,15 @@ getList() @@ -491,14 +493,15 @@ getList()
491 <el-input v-model="userRole.nickname" :disabled="true" /> 493 <el-input v-model="userRole.nickname" :disabled="true" />
492 </el-form-item> 494 </el-form-item>
493 <el-form-item label="角色"> 495 <el-form-item label="角色">
494 - <el-select v-model="userRole.roleIds" multiple>  
495 - <el-option  
496 - v-for="item in roleOptions"  
497 - :key="parseInt(item.id)"  
498 - :label="item.name"  
499 - :value="parseInt(item.id)"  
500 - />  
501 - </el-select> 496 + <el-transfer
  497 + v-model="userRole.roleIds"
  498 + :titles="['角色列表', '已选择']"
  499 + :props="{
  500 + key: 'id',
  501 + label: 'name'
  502 + }"
  503 + :data="roleOptions"
  504 + />
502 </el-form-item> 505 </el-form-item>
503 </el-form> 506 </el-form>
504 <!-- 操作按钮 --> 507 <!-- 操作按钮 -->
yudao-ui-admin-vue3/src/views/system/user/user.data.ts
@@ -7,8 +7,18 @@ import { CrudSchema, useCrudSchemas } from &#39;@/hooks/web/useCrudSchemas&#39; @@ -7,8 +7,18 @@ import { CrudSchema, useCrudSchemas } from &#39;@/hooks/web/useCrudSchemas&#39;
7 const { t } = useI18n() 7 const { t } = useI18n()
8 // 表单校验 8 // 表单校验
9 export const rules = reactive({ 9 export const rules = reactive({
  10 + username: [required],
10 nickname: [required], 11 nickname: [required],
11 - status: [required] 12 + email: [required],
  13 + status: [required],
  14 + mobile: [
  15 + {
  16 + pattern:
  17 + /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/,
  18 + trigger: 'blur',
  19 + message: '请输入正确的手机号码'
  20 + }
  21 + ]
12 }) 22 })
13 // crudSchemas 23 // crudSchemas
14 const crudSchemas = reactive<CrudSchema[]>([ 24 const crudSchemas = reactive<CrudSchema[]>([
yudao-ui-admin-vue3/use.md 0 → 100644
  1 +# 注意事项
  2 +
  3 +- 项目路径请不要使用中文命名!!!会造成解析乱码!!!请使用全英文路径!!!全英文路径!!!全英文路径!!!
  4 +- node >=16 , pnpm >=7,非node16+ pnpm 7+ 安装问题不予解决、不适配
  5 +- 开发建议使用 [谷歌浏览器-开发者版](https://www.google.cn/intl/zh-CN/chrome/dev/) 不支持 IE\QQ 等浏览器
  6 +- 本框架使用 TypeScript ,简称ts,和java的类型差不多,为了简化没过多使用 type
  7 +- 本框架使用 Vue3.2 + setup语法糖,请自行学习相关内容
  8 +- [点击查看:为什么Vue3.2,什么是setup,Vite为什么第一次加载速度慢](https://www.baidu.com)
  9 +- idea 怎么开发? 不知道。
  10 +- 启动方式详见[README.md](./README.md)
  11 +
  12 +## 简单使用
  13 +
  14 +- 目录结构与 vue2 版本基本保持一致
  15 +- 一个页面(以post为例)由4部分组成
  16 +
  17 +```bash
  18 +/src/api/system/post/ [index.ts | types.ts]
  19 +/src/views/system/post/ [index.vue | post.data.ts]
  20 +```
  21 +
  22 +- 其中api内index.ts 与 vue2 基本一致,只不过axios封装了get post put delete upload download 等方法,不用写method: 'get' 了
  23 +- api内types.ts,是接口中的类型声明,与java中vo等保持一致, java中long int => ts 中 number
  24 +- views中,index.vue 与 vue2 基本一致,本框架封装了Search Table Form Descriptions等组件,也可以按照vue2方式去写,参考menu
  25 +- post.data.ts 中主要是表单校验 rules 和表单 crudSchemas ,通过修改crudSchemas 就可以控制增删改查的字段、输入框还是下拉框等等
  26 +- 本框架集成了国际化,不需要可以自己想办法移除,后期不会提供删减版 使用方式
  27 +
  28 +```bash
  29 +import { useI18n } from '@/hooks/web/useI18n'
  30 +const { t } = useI18n()
  31 +t('common.createTime')
  32 +对应翻译文档在 src/locales
  33 +```
yudao-ui-admin-vue3/vite.config.ts
@@ -138,6 +138,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig =&gt; { @@ -138,6 +138,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig =&gt; {
138 'vue-router', 138 'vue-router',
139 'vue-types', 139 'vue-types',
140 'vue-i18n', 140 'vue-i18n',
  141 + 'element-plus/es',
141 'element-plus/es/locale/lang/zh-cn', 142 'element-plus/es/locale/lang/zh-cn',
142 'element-plus/es/locale/lang/en', 143 'element-plus/es/locale/lang/en',
143 '@iconify/iconify', 144 '@iconify/iconify',
yudao-ui-admin/src/views/system/dept/index.vue
@@ -167,7 +167,7 @@ export default { @@ -167,7 +167,7 @@ export default {
167 ], 167 ],
168 phone: [ 168 phone: [
169 { 169 {
170 - pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, 170 + pattern: /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/,
171 message: "请输入正确的手机号码", 171 message: "请输入正确的手机号码",
172 trigger: "blur" 172 trigger: "blur"
173 } 173 }
yudao-ui-admin/src/views/system/tenant/index.vue
@@ -183,8 +183,6 @@ export default { @@ -183,8 +183,6 @@ export default {
183 accountCount: [{ required: true, message: "账号额度不能为空", trigger: "blur" }], 183 accountCount: [{ required: true, message: "账号额度不能为空", trigger: "blur" }],
184 expireTime: [{ required: true, message: "过期时间不能为空", trigger: "blur" }], 184 expireTime: [{ required: true, message: "过期时间不能为空", trigger: "blur" }],
185 domain: [{ required: true, message: "绑定域名不能为空", trigger: "blur" }], 185 domain: [{ required: true, message: "绑定域名不能为空", trigger: "blur" }],
186 - username: [{ required: true, message: "用户名称不能为空", trigger: "blur" }],  
187 - password: [{ required: true, message: "用户密码不能为空", trigger: "blur" }],  
188 } 186 }
189 }; 187 };
190 }, 188 },