mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 22:57:17 +08:00 
			
		
		
		
	Merge branch '1.0.x' into dev
# Conflicts: # continew-admin-ui/components.d.ts # continew-admin-ui/src/components/footer/index.vue
This commit is contained in:
		| @@ -11,6 +11,7 @@ | ||||
|     "report": "cross-env REPORT=true npm run build", | ||||
|     "preview": "npm run build && vite preview --host", | ||||
|     "type:check": "vue-tsc --noEmit --skipLibCheck", | ||||
|     "lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix", | ||||
|     "lint-staged": "npx lint-staged" | ||||
|   }, | ||||
|   "lint-staged": { | ||||
|   | ||||
| @@ -1,12 +1,27 @@ | ||||
| <template> | ||||
|   <a-layout-footer class="footer"> | ||||
|     {{ `Copyright © 2022-${new Date().getFullYear()}` }}  | ||||
|     <a href="https://blog.charles7c.top/about/me" target="_blank" rel="noopenner noreferrer">Charles7c</a> | ||||
|     <a | ||||
|       href="https://blog.charles7c.top/about/me" | ||||
|       target="_blank" | ||||
|       rel="noopenner noreferrer" | ||||
|       >Charles7c</a | ||||
|     > | ||||
|     <span> ⋅ </span> | ||||
|     <a href="https://github.com/Charles7c/continew-admin" target="_blank" rel="noopenner noreferrer">{{ $t('title') }}</a>  | ||||
|     v1.1.0-SNAPSHOT | ||||
|     <a | ||||
|       href="https://github.com/Charles7c/continew-admin" | ||||
|       target="_blank" | ||||
|       rel="noopenner noreferrer" | ||||
|       >{{ $t('title') }}</a | ||||
|     >  v1.1.0-SNAPSHOT | ||||
|     <span> ⋅ </span> | ||||
|     <a href="https://beian.miit.gov.cn" target="_blank" rel="noopenner noreferrer">津ICP备2022005864号-2</a> | ||||
|     <a | ||||
|       href="https://beian.miit.gov.cn" | ||||
|       target="_blank" | ||||
|       rel="noopenner noreferrer" | ||||
|       > | ||||
|       津ICP备2022005864号-2 | ||||
|     </a> | ||||
|   </a-layout-footer> | ||||
| </template> | ||||
|  | ||||
|   | ||||
| @@ -160,7 +160,10 @@ | ||||
|             :size="32" | ||||
|             :style="{ marginRight: '8px', cursor: 'pointer' }" | ||||
|           > | ||||
|             <img alt="avatar" :src="getAvatar(loginStore.avatar, loginStore.gender)" /> | ||||
|             <img | ||||
|               alt="avatar" | ||||
|               :src="getAvatar(loginStore.avatar, loginStore.gender)" | ||||
|             /> | ||||
|           </a-avatar> | ||||
|           <template #content> | ||||
|             <a-doption> | ||||
|   | ||||
| @@ -2,10 +2,14 @@ | ||||
|   <div class="header-operation-right"> | ||||
|     <a-button-group> | ||||
|       <a-tooltip :content="showQuery ? '隐藏搜索栏' : '显示搜索栏'"> | ||||
|         <a-button @click="toggleSearch"><template #icon><icon-search /></template></a-button> | ||||
|         <a-button @click="toggleSearch" | ||||
|           ><template #icon><icon-search /></template | ||||
|         ></a-button> | ||||
|       </a-tooltip> | ||||
|       <a-tooltip content="刷新"> | ||||
|         <a-button @click="handleRefresh"><template #icon><icon-refresh /></template></a-button> | ||||
|         <a-button @click="handleRefresh" | ||||
|           ><template #icon><icon-refresh /></template | ||||
|         ></a-button> | ||||
|       </a-tooltip> | ||||
|     </a-button-group> | ||||
|   </div> | ||||
| @@ -42,4 +46,4 @@ | ||||
|   }; | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="less"></style> | ||||
| <style scoped lang="less"></style> | ||||
|   | ||||
							
								
								
									
										4
									
								
								continew-admin-ui/src/hooks/axios.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								continew-admin-ui/src/hooks/axios.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| import axios, { Axios, AxiosResponse, AxiosRequestConfig } from 'axios'; | ||||
|  | ||||
| declare module "axios" { | ||||
| declare module 'axios' { | ||||
|   interface AxiosResponse<T = any> { | ||||
|     success: boolean; // 是否成功 | ||||
|     code: number; // 状态码 | ||||
| @@ -9,4 +9,4 @@ declare module "axios" { | ||||
|     data: T; // 返回数据 | ||||
|   } | ||||
|   export function create(config?: AxiosRequestConfig): AxiosInstance; | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -15,7 +15,8 @@ const LIST: AppRouteRecordRaw = { | ||||
|     { | ||||
|       path: 'search-table', // The midline path complies with SEO specifications | ||||
|       name: 'SearchTable', | ||||
|       component: () => import('@/views/arco-design/list/search-table/index.vue'), | ||||
|       component: () => | ||||
|         import('@/views/arco-design/list/search-table/index.vue'), | ||||
|       meta: { | ||||
|         locale: 'menu.list.searchTable', | ||||
|         requiresAuth: true, | ||||
|   | ||||
| @@ -15,7 +15,8 @@ const VISUALIZATION: AppRouteRecordRaw = { | ||||
|     { | ||||
|       path: 'data-analysis', | ||||
|       name: 'DataAnalysis', | ||||
|       component: () => import('@/views/arco-design/visualization/data-analysis/index.vue'), | ||||
|       component: () => | ||||
|         import('@/views/arco-design/visualization/data-analysis/index.vue'), | ||||
|       meta: { | ||||
|         locale: 'menu.visualization.dataAnalysis', | ||||
|         requiresAuth: true, | ||||
| @@ -26,7 +27,9 @@ const VISUALIZATION: AppRouteRecordRaw = { | ||||
|       path: 'multi-dimension-data-analysis', | ||||
|       name: 'MultiDimensionDataAnalysis', | ||||
|       component: () => | ||||
|         import('@/views/arco-design/visualization/multi-dimension-data-analysis/index.vue'), | ||||
|         import( | ||||
|           '@/views/arco-design/visualization/multi-dimension-data-analysis/index.vue' | ||||
|         ), | ||||
|       meta: { | ||||
|         locale: 'menu.visualization.multiDimensionDataAnalysis', | ||||
|         requiresAuth: true, | ||||
| @@ -36,7 +39,8 @@ const VISUALIZATION: AppRouteRecordRaw = { | ||||
|     { | ||||
|       path: 'monitor', | ||||
|       name: 'Monitor', | ||||
|       component: () => import('@/views/arco-design/visualization/monitor/index.vue'), | ||||
|       component: () => | ||||
|         import('@/views/arco-design/visualization/monitor/index.vue'), | ||||
|       meta: { | ||||
|         locale: 'menu.dashboard.monitor', | ||||
|         requiresAuth: true, | ||||
|   | ||||
| @@ -2,7 +2,10 @@ import Unknown from '../assets/images/avatar/unknown.png'; | ||||
| import Male from '../assets/images/avatar/male.png'; | ||||
| import Female from '../assets/images/avatar/female.png'; | ||||
|  | ||||
| export default function getAvatar(avatar: string | undefined, gender: number | undefined) { | ||||
| export default function getAvatar( | ||||
|   avatar: string | undefined, | ||||
|   gender: number | undefined | ||||
| ) { | ||||
|   if (avatar) { | ||||
|     const baseUrl = import.meta.env.VITE_API_BASE_URL; | ||||
|     return `${baseUrl}/avatar/${avatar}`; | ||||
|   | ||||
| @@ -55,12 +55,7 @@ | ||||
|             {{ $t('login.form.rememberMe') }} | ||||
|           </a-checkbox> | ||||
|         </div> | ||||
|         <a-button | ||||
|           :loading="loading" | ||||
|           type="primary" | ||||
|           long | ||||
|           html-type="submit" | ||||
|         > | ||||
|         <a-button :loading="loading" type="primary" long html-type="submit"> | ||||
|           {{ $t('login.form.login') }} | ||||
|         </a-button> | ||||
|       </a-space> | ||||
|   | ||||
| @@ -69,4 +69,4 @@ | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
| </style> | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| export default { | ||||
|   'login.form.title': 'Login to ContiNew Admin', | ||||
|   'login.form.subTitle': 'Continue to build the latest popular technology stack in the background management framework', | ||||
|   'login.form.subTitle': | ||||
|     'Continue to build the latest popular technology stack in the background management framework', | ||||
|  | ||||
|   'login.form.placeholder.username': 'Please enter username', | ||||
|   'login.form.placeholder.password': 'Please enter password', | ||||
| @@ -27,5 +28,6 @@ export default { | ||||
|   'login.banner.subSlogan2': | ||||
|     'Rich basic functions, low threshold to use, enterprise rapid development scaffolding', | ||||
|   'login.banner.slogan3': 'The code is standard and open source and free', | ||||
|   'login.banner.subSlogan3': 'The backend code is fully compliant with the Alibaba coding specification, and the frontend code is strictly ESLint checked', | ||||
|   'login.banner.subSlogan3': | ||||
|     'The backend code is fully compliant with the Alibaba coding specification, and the frontend code is strictly ESLint checked', | ||||
| }; | ||||
|   | ||||
| @@ -21,9 +21,11 @@ export default { | ||||
|   'login.form.logout.success': '退出成功', | ||||
|  | ||||
|   'login.banner.slogan1': '中后台管理框架', | ||||
|   'login.banner.subSlogan1': 'Continue New Admin,持续以最新流行技术栈构建,拥抱变化,迭代优化', | ||||
|   'login.banner.subSlogan1': | ||||
|     'Continue New Admin,持续以最新流行技术栈构建,拥抱变化,迭代优化', | ||||
|   'login.banner.slogan2': '内置了常见问题的解决方案', | ||||
|   'login.banner.subSlogan2': '基础功能丰富,使用门槛低,企业级快速开发脚手架', | ||||
|   'login.banner.slogan3': '代码规范且开源免费', | ||||
|   'login.banner.subSlogan3': '后端代码完全遵循阿里巴巴编码规范,前端代码使用严格的 ESLint 检查', | ||||
|   'login.banner.subSlogan3': | ||||
|     '后端代码完全遵循阿里巴巴编码规范,前端代码使用严格的 ESLint 检查', | ||||
| }; | ||||
|   | ||||
| @@ -61,7 +61,9 @@ | ||||
|           <a-table-column title="登录行为" data-index="description" /> | ||||
|           <a-table-column title="登录状态" align="center"> | ||||
|             <template #cell="{ record }"> | ||||
|               <a-tag v-if="record.status === 1" color="green"><span class="circle pass" />成功</a-tag> | ||||
|               <a-tag v-if="record.status === 1" color="green" | ||||
|                 ><span class="circle pass" />成功</a-tag | ||||
|               > | ||||
|               <a-tooltip v-else :content="record.errorMsg"> | ||||
|                 <a-tag color="red" style="cursor: pointer"> | ||||
|                   <span class="circle fail" />失败 | ||||
| @@ -88,7 +90,9 @@ | ||||
|   } from '@/api/monitor/log'; | ||||
|  | ||||
|   const { proxy } = getCurrentInstance() as any; | ||||
|   const { SuccessFailureStatusEnum } = proxy.useDict('SuccessFailureStatusEnum'); | ||||
|   const { SuccessFailureStatusEnum } = proxy.useDict( | ||||
|     'SuccessFailureStatusEnum' | ||||
|   ); | ||||
|  | ||||
|   const loginLogList = ref<LoginLogRecord[]>([]); | ||||
|   const total = ref(0); | ||||
|   | ||||
| @@ -72,7 +72,9 @@ | ||||
|           <a-table-column title="所属模块" data-index="module" /> | ||||
|           <a-table-column title="操作状态" align="center"> | ||||
|             <template #cell="{ record }"> | ||||
|               <a-tag v-if="record.status === 1" color="green"><span class="circle pass" />成功</a-tag> | ||||
|               <a-tag v-if="record.status === 1" color="green" | ||||
|                 ><span class="circle pass" />成功</a-tag | ||||
|               > | ||||
|               <a-tooltip v-else :content="record.errorMsg"> | ||||
|                 <a-tag color="red" style="cursor: pointer"> | ||||
|                   <span class="circle fail" />失败 | ||||
| @@ -98,7 +100,9 @@ | ||||
|   } from '@/api/monitor/log'; | ||||
|  | ||||
|   const { proxy } = getCurrentInstance() as any; | ||||
|   const { SuccessFailureStatusEnum } = proxy.useDict('SuccessFailureStatusEnum'); | ||||
|   const { SuccessFailureStatusEnum } = proxy.useDict( | ||||
|     'SuccessFailureStatusEnum' | ||||
|   ); | ||||
|  | ||||
|   const operationLogList = ref<OperationLogRecord[]>([]); | ||||
|   const total = ref(0); | ||||
|   | ||||
| @@ -50,15 +50,27 @@ | ||||
|           </a-table-column> | ||||
|           <a-table-column title="状态码" align="center"> | ||||
|             <template #cell="{ record }"> | ||||
|               <a-tag v-if="record.statusCode >= 400" color="red">{{ record.statusCode }}</a-tag> | ||||
|               <a-tag v-else-if="record.statusCode === 200" color="green">{{ record.statusCode }}</a-tag> | ||||
|               <a-tag v-if="record.statusCode >= 400" color="red">{{ | ||||
|                 record.statusCode | ||||
|               }}</a-tag> | ||||
|               <a-tag v-else-if="record.statusCode === 200" color="green">{{ | ||||
|                 record.statusCode | ||||
|               }}</a-tag> | ||||
|               <a-tag v-else color="orange">{{ record.statusCode }}</a-tag> | ||||
|             </template> | ||||
|           </a-table-column> | ||||
|           <a-table-column title="请求方式" align="center" data-index="requestMethod" /> | ||||
|           <a-table-column | ||||
|             title="请求方式" | ||||
|             align="center" | ||||
|             data-index="requestMethod" | ||||
|           /> | ||||
|           <a-table-column title="请求 URI"> | ||||
|             <template #cell="{ record }"> | ||||
|               <span :title="decodeURIComponent(record.requestUrl)">{{ record.requestUrl.match(/(\w+):\/\/([^/:]+)(:\d*)?([^#|\?|\n]*)(\?.*)?/)[4] }}</span> | ||||
|               <span :title="decodeURIComponent(record.requestUrl)">{{ | ||||
|                 record.requestUrl.match( | ||||
|                   /(\w+):\/\/([^/:]+)(:\d*)?([^#|\?|\n]*)(\?.*)?/ | ||||
|                 )[4] | ||||
|               }}</span> | ||||
|             </template> | ||||
|           </a-table-column> | ||||
|           <a-table-column title="客户端 IP" data-index="clientIp" /> | ||||
| @@ -66,18 +78,33 @@ | ||||
|           <a-table-column title="浏览器" data-index="browser" /> | ||||
|           <a-table-column title="请求耗时"> | ||||
|             <template #cell="{ record }"> | ||||
|               <a-tag v-if="record.elapsedTime > 500" color="red">{{ record.elapsedTime }} ms</a-tag> | ||||
|               <a-tag v-else-if="record.elapsedTime > 200" color="orange">{{ record.elapsedTime }} ms</a-tag> | ||||
|               <a-tag v-if="record.elapsedTime > 500" color="red" | ||||
|                 >{{ record.elapsedTime }} ms</a-tag | ||||
|               > | ||||
|               <a-tag v-else-if="record.elapsedTime > 200" color="orange" | ||||
|                 >{{ record.elapsedTime }} ms</a-tag | ||||
|               > | ||||
|               <a-tag v-else color="green">{{ record.elapsedTime }} ms</a-tag> | ||||
|             </template> | ||||
|           </a-table-column> | ||||
|           <a-table-column title="创建时间" data-index="createTime" /> | ||||
|           <a-table-column title="操作" align="center"> | ||||
|             <template #cell="{ record }"> | ||||
|               <a-button type="text" size="small" title="查看详情" @click="toDetail(record.id)"> | ||||
|               <a-button | ||||
|                 type="text" | ||||
|                 size="small" | ||||
|                 title="查看详情" | ||||
|                 @click="toDetail(record.id)" | ||||
|               > | ||||
|                 <template #icon><icon-eye /></template>详情 | ||||
|               </a-button> | ||||
|               <a-button v-if="record.exceptionDetail" type="text" size="small" title="查看异常详情" @click="toExceptionDetail(record)"> | ||||
|               <a-button | ||||
|                 v-if="record.exceptionDetail" | ||||
|                 type="text" | ||||
|                 size="small" | ||||
|                 title="查看异常详情" | ||||
|                 @click="toExceptionDetail(record)" | ||||
|               > | ||||
|                 <template #icon><icon-bug /></template>异常 | ||||
|               </a-button> | ||||
|             </template> | ||||
| @@ -126,7 +153,9 @@ | ||||
|                 <a-tag v-else-if="systemLog.elapsedTime > 200" color="orange"> | ||||
|                   {{ systemLog.elapsedTime }} ms | ||||
|                 </a-tag> | ||||
|                 <a-tag v-else color="green">{{ systemLog.elapsedTime }} ms</a-tag> | ||||
|                 <a-tag v-else color="green" | ||||
|                   >{{ systemLog.elapsedTime }} ms</a-tag | ||||
|                 > | ||||
|               </span> | ||||
|             </a-descriptions-item> | ||||
|             <a-descriptions-item label="创建时间"> | ||||
| @@ -136,14 +165,23 @@ | ||||
|               <span v-else>{{ systemLog.createTime }}</span> | ||||
|             </a-descriptions-item> | ||||
|           </a-descriptions> | ||||
|           <a-descriptions title="协议信息" :column="2" bordered style="margin-top: 25px"> | ||||
|           <a-descriptions | ||||
|             title="协议信息" | ||||
|             :column="2" | ||||
|             bordered | ||||
|             style="margin-top: 25px" | ||||
|           > | ||||
|             <a-descriptions-item label="状态码"> | ||||
|               <a-skeleton v-if="loading" :animation="true"> | ||||
|                 <a-skeleton-line :rows="1" /> | ||||
|               </a-skeleton> | ||||
|               <span v-else> | ||||
|                 <a-tag v-if="systemLog.statusCode >= 400" color="red">{{ systemLog.statusCode }}</a-tag> | ||||
|                 <a-tag v-else-if="systemLog.statusCode === 200" color="green">{{ systemLog.statusCode }}</a-tag> | ||||
|                 <a-tag v-if="systemLog.statusCode >= 400" color="red">{{ | ||||
|                   systemLog.statusCode | ||||
|                 }}</a-tag> | ||||
|                 <a-tag v-else-if="systemLog.statusCode === 200" color="green">{{ | ||||
|                   systemLog.statusCode | ||||
|                 }}</a-tag> | ||||
|                 <a-tag v-else color="orange">{{ systemLog.statusCode }}</a-tag> | ||||
|               </span> | ||||
|             </a-descriptions-item> | ||||
| @@ -168,7 +206,8 @@ | ||||
|                   v-if="systemLog.responseBody" | ||||
|                   :path="'res'" | ||||
|                   :data="JSON.parse(systemLog.responseBody)" | ||||
|                   :show-length="true" /> | ||||
|                   :show-length="true" | ||||
|                 /> | ||||
|                 <span v-else>无</span> | ||||
|               </a-space> | ||||
|             </a-descriptions-item> | ||||
| @@ -181,7 +220,8 @@ | ||||
|                   v-if="systemLog.responseHeaders" | ||||
|                   :path="'res'" | ||||
|                   :data="JSON.parse(systemLog.responseHeaders)" | ||||
|                   :show-length="true" /> | ||||
|                   :show-length="true" | ||||
|                 /> | ||||
|                 <span v-else>无</span> | ||||
|               </a-space> | ||||
|             </a-descriptions-item> | ||||
| @@ -194,7 +234,8 @@ | ||||
|                   v-if="systemLog.requestBody" | ||||
|                   :path="'res'" | ||||
|                   :data="JSON.parse(systemLog.requestBody)" | ||||
|                   :show-length="true" /> | ||||
|                   :show-length="true" | ||||
|                 /> | ||||
|                 <span v-else>无</span> | ||||
|               </a-space> | ||||
|             </a-descriptions-item> | ||||
| @@ -206,7 +247,8 @@ | ||||
|                 <VueJsonPretty | ||||
|                   v-if="systemLog.requestHeaders" | ||||
|                   :data="JSON.parse(systemLog.requestHeaders)" | ||||
|                   :show-length="true" /> | ||||
|                   :show-length="true" | ||||
|                 /> | ||||
|                 <span v-else>无</span> | ||||
|               </a-space> | ||||
|             </a-descriptions-item> | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|                 v-model="queryParams.nickname" | ||||
|                 placeholder="输入用户昵称搜索" | ||||
|                 allow-clear | ||||
|                 style="width: 150px;" | ||||
|                 style="width: 150px" | ||||
|                 @press-enter="handleQuery" | ||||
|               /> | ||||
|             </a-form-item> | ||||
| @@ -59,22 +59,34 @@ | ||||
|           </a-table-column> | ||||
|           <a-table-column title="用户昵称"> | ||||
|             <template #cell="{ record }"> | ||||
|               {{ record.nickname }}({{record.username}}) | ||||
|               {{ record.nickname }}({{ record.username }}) | ||||
|             </template> | ||||
|           </a-table-column> | ||||
|           <a-table-column title="登录 IP" data-index="clientIp" /> | ||||
|           <a-table-column title="登录地点" data-index="location" /> | ||||
|           <a-table-column title="浏览器" data-index="browser" /> | ||||
|           <a-table-column title="登录时间" data-index="loginTime" /> | ||||
|           <a-table-column v-if="checkPermission(['monitor:online:user:delete'])" title="操作" align="center"> | ||||
|           <a-table-column | ||||
|             v-if="checkPermission(['monitor:online:user:delete'])" | ||||
|             title="操作" | ||||
|             align="center" | ||||
|           > | ||||
|             <template #cell="{ record }"> | ||||
|               <a-popconfirm content="确定要强退该用户吗?" type="warning" @ok="handleKickout(record.token)"> | ||||
|               <a-popconfirm | ||||
|                 content="确定要强退该用户吗?" | ||||
|                 type="warning" | ||||
|                 @ok="handleKickout(record.token)" | ||||
|               > | ||||
|                 <a-button | ||||
|                   v-permission="['monitor:online:user:delete']" | ||||
|                   type="text" | ||||
|                   size="small" | ||||
|                   :disabled="currentToken === record.token" | ||||
|                   :title="currentToken === record.token ? '不能强退当前登录用户' : '强退'" | ||||
|                   :title=" | ||||
|                     currentToken === record.token | ||||
|                       ? '不能强退当前登录用户' | ||||
|                       : '强退' | ||||
|                   " | ||||
|                 > | ||||
|                   <template #icon><icon-delete /></template>强退 | ||||
|                 </a-button> | ||||
| @@ -124,12 +136,14 @@ | ||||
|    */ | ||||
|   const getList = (params: OnlineUserParam = { ...queryParams.value }) => { | ||||
|     loading.value = true; | ||||
|     listOnlineUser(params).then((res) => { | ||||
|       onlineUserList.value = res.data.list; | ||||
|       total.value = res.data.total; | ||||
|     }).finally(() => { | ||||
|       loading.value = false; | ||||
|     }); | ||||
|     listOnlineUser(params) | ||||
|       .then((res) => { | ||||
|         onlineUserList.value = res.data.list; | ||||
|         total.value = res.data.total; | ||||
|       }) | ||||
|       .finally(() => { | ||||
|         loading.value = false; | ||||
|       }); | ||||
|   }; | ||||
|   getList(); | ||||
|  | ||||
|   | ||||
| @@ -113,23 +113,19 @@ | ||||
|         <template #columns> | ||||
|           <a-table-column title="部门名称"> | ||||
|             <template #cell="{ record }"> | ||||
|               <a-link @click="toDetail(record.id)">{{ | ||||
|                 record.name | ||||
|               }}</a-link> | ||||
|               <a-link @click="toDetail(record.id)">{{ record.name }}</a-link> | ||||
|             </template> | ||||
|           </a-table-column> | ||||
|           <a-table-column | ||||
|             title="部门排序" | ||||
|             align="center" | ||||
|             data-index="sort" | ||||
|           /> | ||||
|           <a-table-column title="部门排序" align="center" data-index="sort" /> | ||||
|           <a-table-column title="状态" align="center" data-index="status"> | ||||
|             <template #cell="{ record }"> | ||||
|               <a-switch | ||||
|                 v-model="record.status" | ||||
|                 :checked-value="1" | ||||
|                 :unchecked-value="2" | ||||
|                 :disabled="record.disabled || !checkPermission(['system:dept:update'])" | ||||
|                 :disabled=" | ||||
|                   record.disabled || !checkPermission(['system:dept:update']) | ||||
|                 " | ||||
|                 @change="handleChangeStatus(record)" | ||||
|               /> | ||||
|             </template> | ||||
| @@ -188,7 +184,11 @@ | ||||
|         @cancel="handleCancel" | ||||
|       > | ||||
|         <a-form ref="formRef" :model="form" :rules="rules" size="large"> | ||||
|           <a-form-item label="上级部门" field="parentId" :disabled="form.disabled"> | ||||
|           <a-form-item | ||||
|             label="上级部门" | ||||
|             field="parentId" | ||||
|             :disabled="form.disabled" | ||||
|           > | ||||
|             <a-tree-select | ||||
|               v-model="form.parentId" | ||||
|               :data="treeData" | ||||
| @@ -527,7 +527,10 @@ | ||||
|       } | ||||
|     } else if (record.children) { | ||||
|       record.children.forEach((r) => { | ||||
|         rowKeys.splice(rowKeys.findIndex((key: number | undefined) => key === r.id), 1); | ||||
|         rowKeys.splice( | ||||
|           rowKeys.findIndex((key: number | undefined) => key === r.id), | ||||
|           1 | ||||
|         ); | ||||
|         proxy.$refs.tableRef.select(r.id, false); | ||||
|         if (r.children) { | ||||
|           handleSelect(rowKeys, rowKey, r); | ||||
|   | ||||
| @@ -307,21 +307,13 @@ | ||||
|               <a-radio :value="false">否</a-radio> | ||||
|             </a-radio-group> | ||||
|           </a-form-item> | ||||
|           <a-form-item | ||||
|             v-if="form.type === 2" | ||||
|             label="是否缓存" | ||||
|             field="isCache" | ||||
|           > | ||||
|           <a-form-item v-if="form.type === 2" label="是否缓存" field="isCache"> | ||||
|             <a-radio-group v-model="form.isCache" type="button"> | ||||
|               <a-radio :value="true">是</a-radio> | ||||
|               <a-radio :value="false">否</a-radio> | ||||
|             </a-radio-group> | ||||
|           </a-form-item> | ||||
|           <a-form-item | ||||
|             v-if="form.type !== 3" | ||||
|             label="是否隐藏" | ||||
|             field="isHidden" | ||||
|           > | ||||
|           <a-form-item v-if="form.type !== 3" label="是否隐藏" field="isHidden"> | ||||
|             <a-radio-group v-model="form.isHidden" type="button"> | ||||
|               <a-radio :value="true">是</a-radio> | ||||
|               <a-radio :value="false">否</a-radio> | ||||
|   | ||||
| @@ -118,33 +118,31 @@ | ||||
|           <a-table-column title="ID" data-index="id" /> | ||||
|           <a-table-column title="角色名称" data-index="name" :width="130"> | ||||
|             <template #cell="{ record }"> | ||||
|               <a-link @click="toDetail(record.id)">{{ | ||||
|                 record.name | ||||
|               }}</a-link> | ||||
|               <a-link @click="toDetail(record.id)">{{ record.name }}</a-link> | ||||
|             </template> | ||||
|           </a-table-column> | ||||
|           <a-table-column title="角色编码" data-index="code" /> | ||||
|           <a-table-column title="数据权限" :width="130"> | ||||
|             <template #cell="{ record }"> | ||||
|               <span v-if="record.dataScope === 1">全部数据权限</span> | ||||
|               <span v-else-if="record.dataScope === 2">本部门及以下数据权限</span> | ||||
|               <span v-else-if="record.dataScope === 2" | ||||
|                 >本部门及以下数据权限</span | ||||
|               > | ||||
|               <span v-else-if="record.dataScope === 3">本部门数据权限</span> | ||||
|               <span v-else-if="record.dataScope === 4">仅本人数据权限</span> | ||||
|               <span v-else>自定义数据权限</span> | ||||
|             </template> | ||||
|           </a-table-column> | ||||
|           <a-table-column | ||||
|             title="角色排序" | ||||
|             align="center" | ||||
|             data-index="sort" | ||||
|           /> | ||||
|           <a-table-column title="角色排序" align="center" data-index="sort" /> | ||||
|           <a-table-column title="状态" align="center" data-index="status"> | ||||
|             <template #cell="{ record }"> | ||||
|               <a-switch | ||||
|                 v-model="record.status" | ||||
|                 :checked-value="1" | ||||
|                 :unchecked-value="2" | ||||
|                 :disabled="record.disabled || !checkPermission(['system:role:update'])" | ||||
|                 :disabled=" | ||||
|                   record.disabled || !checkPermission(['system:role:update']) | ||||
|                 " | ||||
|                 @change="handleChangeStatus(record)" | ||||
|               /> | ||||
|             </template> | ||||
| @@ -204,7 +202,11 @@ | ||||
|         @cancel="handleCancel" | ||||
|       > | ||||
|         <a-form ref="formRef" :model="form" :rules="rules" size="large"> | ||||
|           <a-alert v-if="!form.disabled" type="warning" style="margin-bottom: 15px;"> | ||||
|           <a-alert | ||||
|             v-if="!form.disabled" | ||||
|             type="warning" | ||||
|             style="margin-bottom: 15px" | ||||
|           > | ||||
|             变更角色编码、功能权限或数据权限后,关联在线用户会自动下线! | ||||
|           </a-alert> | ||||
|           <fieldset> | ||||
| @@ -212,7 +214,11 @@ | ||||
|             <a-form-item label="角色名称" field="name"> | ||||
|               <a-input v-model="form.name" placeholder="请输入角色名称" /> | ||||
|             </a-form-item> | ||||
|             <a-form-item label="角色编码" field="code" :disabled="form.disabled"> | ||||
|             <a-form-item | ||||
|               label="角色编码" | ||||
|               field="code" | ||||
|               :disabled="form.disabled" | ||||
|             > | ||||
|               <a-input v-model="form.code" placeholder="请输入角色编码" /> | ||||
|             </a-form-item> | ||||
|             <a-form-item label="角色排序" field="sort"> | ||||
| @@ -239,8 +245,16 @@ | ||||
|             <legend>功能权限</legend> | ||||
|             <a-form-item label="功能权限" :disabled="form.disabled"> | ||||
|               <a-space style="margin-top: 2px"> | ||||
|                 <a-checkbox v-model="menuExpandAll" @change="handleExpandAll('menu')">展开/折叠</a-checkbox> | ||||
|                 <a-checkbox v-model="menuCheckAll" @change="handleCheckAll('menu')">全选/全不选</a-checkbox> | ||||
|                 <a-checkbox | ||||
|                   v-model="menuExpandAll" | ||||
|                   @change="handleExpandAll('menu')" | ||||
|                   >展开/折叠</a-checkbox | ||||
|                 > | ||||
|                 <a-checkbox | ||||
|                   v-model="menuCheckAll" | ||||
|                   @change="handleCheckAll('menu')" | ||||
|                   >全选/全不选</a-checkbox | ||||
|                 > | ||||
|                 <a-checkbox v-model="menuCheckStrictly">父子联动</a-checkbox> | ||||
|               </a-space> | ||||
|               <template #extra> | ||||
| @@ -259,17 +273,33 @@ | ||||
|           </fieldset> | ||||
|           <fieldset> | ||||
|             <legend>数据权限</legend> | ||||
|             <a-form-item label="数据权限" field="dataScope" :disabled="form.disabled"> | ||||
|             <a-form-item | ||||
|               label="数据权限" | ||||
|               field="dataScope" | ||||
|               :disabled="form.disabled" | ||||
|             > | ||||
|               <a-select | ||||
|                 v-model="form.dataScope" | ||||
|                 :options="DataScopeEnum" | ||||
|                 placeholder="请选择数据权限" | ||||
|               /> | ||||
|             </a-form-item> | ||||
|             <a-form-item v-if="form.dataScope === 5" label="权限范围" :disabled="form.disabled"> | ||||
|             <a-form-item | ||||
|               v-if="form.dataScope === 5" | ||||
|               label="权限范围" | ||||
|               :disabled="form.disabled" | ||||
|             > | ||||
|               <a-space style="margin-top: 2px"> | ||||
|                 <a-checkbox v-model="deptExpandAll" @change="handleExpandAll('dept')">展开/折叠</a-checkbox> | ||||
|                 <a-checkbox v-model="deptCheckAll" @change="handleCheckAll('dept')">全选/全不选</a-checkbox> | ||||
|                 <a-checkbox | ||||
|                   v-model="deptExpandAll" | ||||
|                   @change="handleExpandAll('dept')" | ||||
|                   >展开/折叠</a-checkbox | ||||
|                 > | ||||
|                 <a-checkbox | ||||
|                   v-model="deptCheckAll" | ||||
|                   @change="handleCheckAll('dept')" | ||||
|                   >全选/全不选</a-checkbox | ||||
|                 > | ||||
|                 <a-checkbox v-model="deptCheckStrictly">父子联动</a-checkbox> | ||||
|               </a-space> | ||||
|               <template #extra> | ||||
| @@ -328,7 +358,9 @@ | ||||
|               </a-skeleton> | ||||
|               <span v-else> | ||||
|                 <span v-if="role.dataScope === 1">全部数据权限</span> | ||||
|                 <span v-else-if="role.dataScope === 2">本部门及以下数据权限</span> | ||||
|                 <span v-else-if="role.dataScope === 2" | ||||
|                   >本部门及以下数据权限</span | ||||
|                 > | ||||
|                 <span v-else-if="role.dataScope === 3">本部门数据权限</span> | ||||
|                 <span v-else-if="role.dataScope === 4">仅本人数据权限</span> | ||||
|                 <span v-else>自定义数据权限</span> | ||||
| @@ -468,14 +500,15 @@ | ||||
|         { required: true, message: '请输入角色名称' }, | ||||
|         { | ||||
|           match: /^[\u4e00-\u9fa5a-zA-Z0-9_-]{1,20}$/, | ||||
|           message: '长度为 1 到 20 位,可以包含中文、字母、数字、下划线,短横线' | ||||
|           message: | ||||
|             '长度为 1 到 20 位,可以包含中文、字母、数字、下划线,短横线', | ||||
|         }, | ||||
|       ], | ||||
|       code: [ | ||||
|         { required: true, message: '请输入角色编码' }, | ||||
|         { | ||||
|           match: /^[a-zA-Z][a-zA-Z0-9_]{1,15}$/, | ||||
|           message: '长度为 2 到 16 位,可以包含字母、数字,下划线,以字母开头' | ||||
|           message: '长度为 2 到 16 位,可以包含字母、数字,下划线,以字母开头', | ||||
|         }, | ||||
|       ], | ||||
|       dataScope: [{ required: true, message: '请选择数据权限' }], | ||||
|   | ||||
| @@ -8,21 +8,30 @@ | ||||
|     size="large" | ||||
|     class="form" | ||||
|   > | ||||
|     <a-form-item :label="$t('userCenter.basicInfo.form.label.username')" disabled> | ||||
|     <a-form-item | ||||
|       :label="$t('userCenter.basicInfo.form.label.username')" | ||||
|       disabled | ||||
|     > | ||||
|       <a-input | ||||
|         v-model="form.username" | ||||
|         :placeholder="$t('userCenter.basicInfo.form.placeholder.username')" | ||||
|         max-length="16" | ||||
|       /> | ||||
|     </a-form-item> | ||||
|     <a-form-item :label="$t('userCenter.basicInfo.form.label.nickname')" field="nickname"> | ||||
|     <a-form-item | ||||
|       :label="$t('userCenter.basicInfo.form.label.nickname')" | ||||
|       field="nickname" | ||||
|     > | ||||
|       <a-input | ||||
|         v-model="form.nickname" | ||||
|         :placeholder="$t('userCenter.basicInfo.form.placeholder.nickname')" | ||||
|         max-length="20" | ||||
|       /> | ||||
|     </a-form-item> | ||||
|     <a-form-item :label="$t('userCenter.basicInfo.form.label.gender')" field="gender"> | ||||
|     <a-form-item | ||||
|       :label="$t('userCenter.basicInfo.form.label.gender')" | ||||
|       field="gender" | ||||
|     > | ||||
|       <a-radio-group v-model="form.gender"> | ||||
|         <a-radio :value="1">男</a-radio> | ||||
|         <a-radio :value="2">女</a-radio> | ||||
|   | ||||
| @@ -29,7 +29,9 @@ | ||||
|         <a-table-column title="所属模块" data-index="module" /> | ||||
|         <a-table-column title="操作状态" align="center"> | ||||
|           <template #cell="{ record }"> | ||||
|             <a-tag v-if="record.status === 1" color="green"><span class="circle pass" />成功</a-tag> | ||||
|             <a-tag v-if="record.status === 1" color="green" | ||||
|               ><span class="circle pass" />成功</a-tag | ||||
|             > | ||||
|             <a-tooltip v-else :content="record.errorMsg"> | ||||
|               <a-tag color="red" style="cursor: pointer"> | ||||
|                 <span class="circle fail" />失败 | ||||
|   | ||||
| @@ -8,14 +8,25 @@ | ||||
|     <template #description> | ||||
|       <div class="content"> | ||||
|         <a-typography-paragraph v-if="loginStore.email"> | ||||
|           {{ $t('userCenter.securitySettings.updateEmail.placeholder.success.email') }}:{{ loginStore.email }} | ||||
|           {{ | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updateEmail.placeholder.success.email' | ||||
|             ) | ||||
|           }}:{{ loginStore.email }} | ||||
|         </a-typography-paragraph> | ||||
|         <a-typography-paragraph v-else class="tip"> | ||||
|           {{ $t('userCenter.securitySettings.updateEmail.placeholder.error.email') }} | ||||
|           {{ | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updateEmail.placeholder.error.email' | ||||
|             ) | ||||
|           }} | ||||
|         </a-typography-paragraph> | ||||
|       </div> | ||||
|       <div class="operation"> | ||||
|         <a-link :title="$t('userCenter.securitySettings.button.update')" @click="toUpdate"> | ||||
|         <a-link | ||||
|           :title="$t('userCenter.securitySettings.button.update')" | ||||
|           @click="toUpdate" | ||||
|         > | ||||
|           {{ $t('userCenter.securitySettings.button.update') }} | ||||
|         </a-link> | ||||
|       </div> | ||||
| @@ -30,17 +41,35 @@ | ||||
|     @cancel="handleCancel" | ||||
|   > | ||||
|     <a-form ref="formRef" :model="form" :rules="rules" size="large"> | ||||
|       <a-form-item :label="$t('userCenter.securitySettings.updateEmail.form.label.newEmail')" field="newEmail"> | ||||
|       <a-form-item | ||||
|         :label=" | ||||
|           $t('userCenter.securitySettings.updateEmail.form.label.newEmail') | ||||
|         " | ||||
|         field="newEmail" | ||||
|       > | ||||
|         <a-input | ||||
|           v-model="form.newEmail" | ||||
|           :placeholder="$t('userCenter.securitySettings.updateEmail.form.placeholder.newEmail')" | ||||
|           :placeholder=" | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updateEmail.form.placeholder.newEmail' | ||||
|             ) | ||||
|           " | ||||
|           allow-clear | ||||
|         /> | ||||
|       </a-form-item> | ||||
|       <a-form-item :label="$t('userCenter.securitySettings.updateEmail.form.label.captcha')" field="captcha"> | ||||
|       <a-form-item | ||||
|         :label=" | ||||
|           $t('userCenter.securitySettings.updateEmail.form.label.captcha') | ||||
|         " | ||||
|         field="captcha" | ||||
|       > | ||||
|         <a-input | ||||
|           v-model="form.captcha" | ||||
|           :placeholder="$t('userCenter.securitySettings.updateEmail.form.placeholder.captcha')" | ||||
|           :placeholder=" | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updateEmail.form.placeholder.captcha' | ||||
|             ) | ||||
|           " | ||||
|           max-length="6" | ||||
|           allow-clear | ||||
|           style="width: 80%" | ||||
| @@ -55,10 +84,21 @@ | ||||
|           {{ captchaBtnName }} | ||||
|         </a-button> | ||||
|       </a-form-item> | ||||
|       <a-form-item :label="$t('userCenter.securitySettings.updateEmail.form.label.currentPassword')" field="currentPassword"> | ||||
|       <a-form-item | ||||
|         :label=" | ||||
|           $t( | ||||
|             'userCenter.securitySettings.updateEmail.form.label.currentPassword' | ||||
|           ) | ||||
|         " | ||||
|         field="currentPassword" | ||||
|       > | ||||
|         <a-input-password | ||||
|           v-model="form.currentPassword" | ||||
|           :placeholder="$t('userCenter.securitySettings.updateEmail.form.placeholder.currentPassword')" | ||||
|           :placeholder=" | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updateEmail.form.placeholder.currentPassword' | ||||
|             ) | ||||
|           " | ||||
|           max-length="32" | ||||
|           allow-clear | ||||
|         /> | ||||
| @@ -85,7 +125,9 @@ | ||||
|   const captchaLoading = ref(false); | ||||
|   const captchaDisable = ref(false); | ||||
|   const visible = ref(false); | ||||
|   const captchaBtnNameKey = ref('userCenter.securitySettings.updateEmail.form.sendCaptcha'); | ||||
|   const captchaBtnNameKey = ref( | ||||
|     'userCenter.securitySettings.updateEmail.form.sendCaptcha' | ||||
|   ); | ||||
|   const captchaBtnName = computed(() => t(captchaBtnNameKey.value)); | ||||
|  | ||||
|   // 表单数据 | ||||
| @@ -98,24 +140,48 @@ | ||||
|   const rules = computed((): Record<string, FieldRule[]> => { | ||||
|     return { | ||||
|       newEmail: [ | ||||
|         { required: true, message: t('userCenter.securitySettings.updateEmail.form.error.required.newEmail') }, | ||||
|         { type: 'email', message: t('userCenter.securitySettings.updateEmail.form.error.match.newEmail') }, | ||||
|         { | ||||
|           required: true, | ||||
|           message: t( | ||||
|             'userCenter.securitySettings.updateEmail.form.error.required.newEmail' | ||||
|           ), | ||||
|         }, | ||||
|         { | ||||
|           type: 'email', | ||||
|           message: t( | ||||
|             'userCenter.securitySettings.updateEmail.form.error.match.newEmail' | ||||
|           ), | ||||
|         }, | ||||
|         { | ||||
|           validator: (value, callback) => { | ||||
|             if (value === loginStore.email) { | ||||
|               callback(t('userCenter.securitySettings.updateEmail.form.error.validator.newEmail')) | ||||
|               callback( | ||||
|                 t( | ||||
|                   'userCenter.securitySettings.updateEmail.form.error.validator.newEmail' | ||||
|                 ) | ||||
|               ); | ||||
|             } else { | ||||
|               callback() | ||||
|               callback(); | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|       captcha: [ | ||||
|         { required: true, message: t('userCenter.securitySettings.updateEmail.form.error.required.captcha') } | ||||
|         { | ||||
|           required: true, | ||||
|           message: t( | ||||
|             'userCenter.securitySettings.updateEmail.form.error.required.captcha' | ||||
|           ), | ||||
|         }, | ||||
|       ], | ||||
|       currentPassword: [ | ||||
|         { required: true, message: t('userCenter.securitySettings.updateEmail.form.error.required.currentPassword') } | ||||
|       ] | ||||
|         { | ||||
|           required: true, | ||||
|           message: t( | ||||
|             'userCenter.securitySettings.updateEmail.form.error.required.currentPassword' | ||||
|           ), | ||||
|         }, | ||||
|       ], | ||||
|     }; | ||||
|   }); | ||||
|  | ||||
| @@ -125,9 +191,10 @@ | ||||
|   const resetCaptcha = () => { | ||||
|     window.clearInterval(captchaTimer.value); | ||||
|     captchaTime.value = 60; | ||||
|     captchaBtnNameKey.value = 'userCenter.securitySettings.updateEmail.form.sendCaptcha'; | ||||
|     captchaBtnNameKey.value = | ||||
|       'userCenter.securitySettings.updateEmail.form.sendCaptcha'; | ||||
|     captchaDisable.value = false; | ||||
|   } | ||||
|   }; | ||||
|  | ||||
|   /** | ||||
|    * 发送验证码 | ||||
| @@ -137,28 +204,37 @@ | ||||
|     proxy.$refs.formRef.validateField('newEmail', (valid: any) => { | ||||
|       if (!valid) { | ||||
|         captchaLoading.value = true; | ||||
|         captchaBtnNameKey.value = 'userCenter.securitySettings.updateEmail.form.loading.sendCaptcha'; | ||||
|         captchaBtnNameKey.value = | ||||
|           'userCenter.securitySettings.updateEmail.form.loading.sendCaptcha'; | ||||
|         getMailCaptcha({ | ||||
|           email: form.newEmail | ||||
|         }).then((res) => { | ||||
|           captchaLoading.value = false; | ||||
|           captchaDisable.value = true; | ||||
|           captchaBtnNameKey.value = `${t('userCenter.securitySettings.updateEmail.form.reSendCaptcha')}(${captchaTime.value -= 1}s)`; | ||||
|           captchaTimer.value = window.setInterval(() => { | ||||
|             captchaTime.value -= 1; | ||||
|             captchaBtnNameKey.value = `${t('userCenter.securitySettings.updateEmail.form.reSendCaptcha')}(${captchaTime.value}s)`; | ||||
|             if (captchaTime.value < 0) { | ||||
|               window.clearInterval(captchaTimer.value); | ||||
|               captchaTime.value = 60; | ||||
|               captchaBtnNameKey.value = t('userCenter.securitySettings.updateEmail.form.reSendCaptcha'); | ||||
|               captchaDisable.value = false; | ||||
|             } | ||||
|           }, 1000); | ||||
|           proxy.$message.success(res.msg); | ||||
|         }).catch(() => { | ||||
|           resetCaptcha(); | ||||
|           captchaLoading.value = false; | ||||
|         }); | ||||
|           email: form.newEmail, | ||||
|         }) | ||||
|           .then((res) => { | ||||
|             captchaLoading.value = false; | ||||
|             captchaDisable.value = true; | ||||
|             captchaBtnNameKey.value = `${t( | ||||
|               'userCenter.securitySettings.updateEmail.form.reSendCaptcha' | ||||
|             )}(${(captchaTime.value -= 1)}s)`; | ||||
|             captchaTimer.value = window.setInterval(() => { | ||||
|               captchaTime.value -= 1; | ||||
|               captchaBtnNameKey.value = `${t( | ||||
|                 'userCenter.securitySettings.updateEmail.form.reSendCaptcha' | ||||
|               )}(${captchaTime.value}s)`; | ||||
|               if (captchaTime.value < 0) { | ||||
|                 window.clearInterval(captchaTimer.value); | ||||
|                 captchaTime.value = 60; | ||||
|                 captchaBtnNameKey.value = t( | ||||
|                   'userCenter.securitySettings.updateEmail.form.reSendCaptcha' | ||||
|                 ); | ||||
|                 captchaDisable.value = false; | ||||
|               } | ||||
|             }, 1000); | ||||
|             proxy.$message.success(res.msg); | ||||
|           }) | ||||
|           .catch(() => { | ||||
|             resetCaptcha(); | ||||
|             captchaLoading.value = false; | ||||
|           }); | ||||
|       } | ||||
|     }); | ||||
|   }; | ||||
|   | ||||
| @@ -8,10 +8,18 @@ | ||||
|     <template #description> | ||||
|       <div class="content"> | ||||
|         <a-typography-paragraph v-if="loginStore.phone"> | ||||
|           {{ $t('userCenter.securitySettings.updatePhone.placeholder.success.phone') }}:{{ loginStore.phone }} | ||||
|           {{ | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updatePhone.placeholder.success.phone' | ||||
|             ) | ||||
|           }}:{{ loginStore.phone }} | ||||
|         </a-typography-paragraph> | ||||
|         <a-typography-paragraph v-else class="tip"> | ||||
|           {{ $t('userCenter.securitySettings.updatePhone.placeholder.error.phone') }} | ||||
|           {{ | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updatePhone.placeholder.error.phone' | ||||
|             ) | ||||
|           }} | ||||
|         </a-typography-paragraph> | ||||
|       </div> | ||||
|       <div class="operation"> | ||||
|   | ||||
| @@ -8,14 +8,25 @@ | ||||
|     <template #description> | ||||
|       <div class="content"> | ||||
|         <a-typography-paragraph v-if="loginStore.pwdResetTime"> | ||||
|           {{ $t('userCenter.securitySettings.updatePwd.placeholder.success.password') }} | ||||
|           {{ | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updatePwd.placeholder.success.password' | ||||
|             ) | ||||
|           }} | ||||
|         </a-typography-paragraph> | ||||
|         <a-typography-paragraph v-else class="tip"> | ||||
|           {{ $t('userCenter.securitySettings.updatePwd.placeholder.error.password') }} | ||||
|           {{ | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updatePwd.placeholder.error.password' | ||||
|             ) | ||||
|           }} | ||||
|         </a-typography-paragraph> | ||||
|       </div> | ||||
|       <div class="operation"> | ||||
|         <a-link :title="$t('userCenter.securitySettings.button.update')" @click="toUpdate"> | ||||
|         <a-link | ||||
|           :title="$t('userCenter.securitySettings.button.update')" | ||||
|           @click="toUpdate" | ||||
|         > | ||||
|           {{ $t('userCenter.securitySettings.button.update') }} | ||||
|         </a-link> | ||||
|       </div> | ||||
| @@ -30,26 +41,53 @@ | ||||
|     @cancel="handleCancel" | ||||
|   > | ||||
|     <a-form ref="formRef" :model="form" :rules="rules" size="large"> | ||||
|       <a-form-item :label="$t('userCenter.securitySettings.updatePwd.form.label.oldPassword')" field="oldPassword"> | ||||
|       <a-form-item | ||||
|         :label=" | ||||
|           $t('userCenter.securitySettings.updatePwd.form.label.oldPassword') | ||||
|         " | ||||
|         field="oldPassword" | ||||
|       > | ||||
|         <a-input-password | ||||
|           v-model="form.oldPassword" | ||||
|           :placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.oldPassword')" | ||||
|           :placeholder=" | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updatePwd.form.placeholder.oldPassword' | ||||
|             ) | ||||
|           " | ||||
|           max-length="32" | ||||
|           allow-clear | ||||
|         /> | ||||
|       </a-form-item> | ||||
|       <a-form-item :label="$t('userCenter.securitySettings.updatePwd.form.label.newPassword')" field="newPassword"> | ||||
|       <a-form-item | ||||
|         :label=" | ||||
|           $t('userCenter.securitySettings.updatePwd.form.label.newPassword') | ||||
|         " | ||||
|         field="newPassword" | ||||
|       > | ||||
|         <a-input-password | ||||
|           v-model="form.newPassword" | ||||
|           :placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.newPassword')" | ||||
|           :placeholder=" | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updatePwd.form.placeholder.newPassword' | ||||
|             ) | ||||
|           " | ||||
|           max-length="32" | ||||
|           allow-clear | ||||
|         /> | ||||
|       </a-form-item> | ||||
|       <a-form-item :label="$t('userCenter.securitySettings.updatePwd.form.label.rePassword')" field="rePassword"> | ||||
|       <a-form-item | ||||
|         :label=" | ||||
|           $t('userCenter.securitySettings.updatePwd.form.label.rePassword') | ||||
|         " | ||||
|         field="rePassword" | ||||
|       > | ||||
|         <a-input-password | ||||
|           v-model="form.rePassword" | ||||
|           :placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.rePassword')" | ||||
|           :placeholder=" | ||||
|             $t( | ||||
|               'userCenter.securitySettings.updatePwd.form.placeholder.rePassword' | ||||
|             ) | ||||
|           " | ||||
|           max-length="32" | ||||
|           allow-clear | ||||
|         /> | ||||
| @@ -81,31 +119,61 @@ | ||||
|   // 表单验证规则 | ||||
|   const rules = computed((): Record<string, FieldRule[]> => { | ||||
|     return { | ||||
|       oldPassword: [{ required: true, message: t('userCenter.securitySettings.updatePwd.form.error.required.oldPassword') }], | ||||
|       oldPassword: [ | ||||
|         { | ||||
|           required: true, | ||||
|           message: t( | ||||
|             'userCenter.securitySettings.updatePwd.form.error.required.oldPassword' | ||||
|           ), | ||||
|         }, | ||||
|       ], | ||||
|       newPassword: [ | ||||
|         { required: true, message: t('userCenter.securitySettings.updatePwd.form.error.required.newPassword') }, | ||||
|         { match: /^(?=.*\d)(?=.*[a-z]).{6,32}$/, message: t('userCenter.securitySettings.updatePwd.form.error.match.newPassword') }, | ||||
|         { | ||||
|           required: true, | ||||
|           message: t( | ||||
|             'userCenter.securitySettings.updatePwd.form.error.required.newPassword' | ||||
|           ), | ||||
|         }, | ||||
|         { | ||||
|           match: /^(?=.*\d)(?=.*[a-z]).{6,32}$/, | ||||
|           message: t( | ||||
|             'userCenter.securitySettings.updatePwd.form.error.match.newPassword' | ||||
|           ), | ||||
|         }, | ||||
|         { | ||||
|           validator: (value, callback) => { | ||||
|             if (value === form.oldPassword) { | ||||
|               callback(t('userCenter.securitySettings.updatePwd.form.error.validator.newPassword')) | ||||
|               callback( | ||||
|                 t( | ||||
|                   'userCenter.securitySettings.updatePwd.form.error.validator.newPassword' | ||||
|                 ) | ||||
|               ); | ||||
|             } else { | ||||
|               callback() | ||||
|               callback(); | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|       rePassword: [ | ||||
|         { required: true, message: t('userCenter.securitySettings.updatePwd.form.error.required.rePassword') }, | ||||
|         { | ||||
|           required: true, | ||||
|           message: t( | ||||
|             'userCenter.securitySettings.updatePwd.form.error.required.rePassword' | ||||
|           ), | ||||
|         }, | ||||
|         { | ||||
|           validator: (value, callback) => { | ||||
|             if (value !== form.newPassword) { | ||||
|               callback(t('userCenter.securitySettings.updatePwd.form.error.validator.rePassword')) | ||||
|               callback( | ||||
|                 t( | ||||
|                   'userCenter.securitySettings.updatePwd.form.error.validator.rePassword' | ||||
|                 ) | ||||
|               ); | ||||
|             } else { | ||||
|               callback() | ||||
|               callback(); | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }; | ||||
|   }); | ||||
|   | ||||
| @@ -25,9 +25,11 @@ export default { | ||||
|   'userCenter.basicInfo.form.placeholder.nickname': 'Please enter nickname', | ||||
|  | ||||
|   'userCenter.basicInfo.form.error.required.username': 'Please enter username', | ||||
|   'userCenter.basicInfo.form.error.match.username': 'Username are 4 to 16 characters long and can contain letters, numbers, underscores, and start with a letter', | ||||
|   'userCenter.basicInfo.form.error.match.username': | ||||
|     'Username are 4 to 16 characters long and can contain letters, numbers, underscores, and start with a letter', | ||||
|   'userCenter.basicInfo.form.error.required.nickname': 'Please enter nickname', | ||||
|   'userCenter.basicInfo.form.error.match.nickname': 'Nickname are 1 to 20 digits long and can contain Chinese, letters, numbers, underscores, dashes', | ||||
|   'userCenter.basicInfo.form.error.match.nickname': | ||||
|     'Nickname are 1 to 20 digits long and can contain Chinese, letters, numbers, underscores, dashes', | ||||
|  | ||||
|   'userCenter.basicInfo.form.save': 'Save', | ||||
|   'userCenter.basicInfo.form.save.success': 'Save success', | ||||
| @@ -36,55 +38,81 @@ export default { | ||||
|   // security-settings | ||||
|   // update-pwd | ||||
|   'userCenter.securitySettings.updatePwd.label.password': 'Login Password', | ||||
|   'userCenter.securitySettings.updatePwd.placeholder.success.password': 'Has been set', | ||||
|   'userCenter.securitySettings.updatePwd.placeholder.success.password': | ||||
|     'Has been set', | ||||
|   'userCenter.securitySettings.updatePwd.placeholder.error.password': | ||||
|     'You have not set a password yet. The password must contain at least six letters, digits, and special characters except Spaces.', | ||||
|  | ||||
|   'userCenter.securitySettings.updatePwd.modal.title': 'Update login password', | ||||
|   'userCenter.securitySettings.updatePwd.form.label.oldPassword': 'Old password', | ||||
|   'userCenter.securitySettings.updatePwd.form.label.newPassword': 'New password', | ||||
|   'userCenter.securitySettings.updatePwd.form.label.rePassword': 'Confirm password', | ||||
|   'userCenter.securitySettings.updatePwd.form.label.oldPassword': | ||||
|     'Old password', | ||||
|   'userCenter.securitySettings.updatePwd.form.label.newPassword': | ||||
|     'New password', | ||||
|   'userCenter.securitySettings.updatePwd.form.label.rePassword': | ||||
|     'Confirm password', | ||||
|  | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.oldPassword': 'Please enter old password', | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.newPassword': 'Password contains 6 to 32 digits and letters', | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.rePassword': 'Please enter new password again', | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.oldPassword': | ||||
|     'Please enter old password', | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.newPassword': | ||||
|     'Password contains 6 to 32 digits and letters', | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.rePassword': | ||||
|     'Please enter new password again', | ||||
|  | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.oldPassword': 'Please enter old password', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.newPassword': 'Please enter new password', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.match.newPassword': 'Password contains 6 to 32 digits and letters', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.validator.newPassword': 'New password cannot be the same as the old password', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.rePassword': 'Please enter new password again', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.validator.rePassword': 'Two passwords are different', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.oldPassword': | ||||
|     'Please enter old password', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.newPassword': | ||||
|     'Please enter new password', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.match.newPassword': | ||||
|     'Password contains 6 to 32 digits and letters', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.validator.newPassword': | ||||
|     'New password cannot be the same as the old password', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.rePassword': | ||||
|     'Please enter new password again', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.validator.rePassword': | ||||
|     'Two passwords are different', | ||||
|  | ||||
|   // update-phone | ||||
|   'userCenter.securitySettings.updatePhone.label.phone': 'Phone', | ||||
|   'userCenter.securitySettings.updatePhone.placeholder.success.phone': 'Has been bound', | ||||
|   'userCenter.securitySettings.updatePhone.placeholder.success.phone': | ||||
|     'Has been bound', | ||||
|   'userCenter.securitySettings.updatePhone.placeholder.error.phone': | ||||
|     'You have not set a phone yet. The phone binding can be used to retrieve passwords and receive notifications and SMS login.', | ||||
|  | ||||
|   // update-email | ||||
|   'userCenter.securitySettings.updateEmail.label.email': 'Email', | ||||
|   'userCenter.securitySettings.updateEmail.placeholder.success.email': 'Has been bound', | ||||
|   'userCenter.securitySettings.updateEmail.placeholder.success.email': | ||||
|     'Has been bound', | ||||
|   'userCenter.securitySettings.updateEmail.placeholder.error.email': | ||||
|     'You have not set a mailbox yet. The mailbox binding can be used to retrieve passwords and receive notifications.', | ||||
|  | ||||
|   'userCenter.securitySettings.updateEmail.modal.title': 'Update email', | ||||
|   'userCenter.securitySettings.updateEmail.form.label.newEmail': 'New email', | ||||
|   'userCenter.securitySettings.updateEmail.form.label.captcha': 'Captcha', | ||||
|   'userCenter.securitySettings.updateEmail.form.label.currentPassword': 'Current password', | ||||
|   'userCenter.securitySettings.updateEmail.form.label.currentPassword': | ||||
|     'Current password', | ||||
|   'userCenter.securitySettings.updateEmail.form.sendCaptcha': 'Send captcha', | ||||
|   'userCenter.securitySettings.updateEmail.form.reSendCaptcha': 'Resend captcha', | ||||
|   'userCenter.securitySettings.updateEmail.form.loading.sendCaptcha': 'Sending...', | ||||
|   'userCenter.securitySettings.updateEmail.form.reSendCaptcha': | ||||
|     'Resend captcha', | ||||
|   'userCenter.securitySettings.updateEmail.form.loading.sendCaptcha': | ||||
|     'Sending...', | ||||
|  | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.newEmail': 'Please enter new email', | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.captcha': 'Please enter email captcha', | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.currentPassword': 'Please enter current password', | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.newEmail': | ||||
|     'Please enter new email', | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.captcha': | ||||
|     'Please enter email captcha', | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.currentPassword': | ||||
|     'Please enter current password', | ||||
|  | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.newEmail': 'Please enter new email', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.match.newEmail': 'Please enter the correct email', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.validator.newEmail': 'New email cannot be the same as the old email', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.captcha': 'Please enter email captcha', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.currentPassword': 'Please enter current password', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.newEmail': | ||||
|     'Please enter new email', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.match.newEmail': | ||||
|     'Please enter the correct email', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.validator.newEmail': | ||||
|     'New email cannot be the same as the old email', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.captcha': | ||||
|     'Please enter email captcha', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.currentPassword': | ||||
|     'Please enter current password', | ||||
|  | ||||
|   'userCenter.securitySettings.button.update': 'Update', | ||||
| }; | ||||
|   | ||||
| @@ -25,9 +25,11 @@ export default { | ||||
|   'userCenter.basicInfo.form.placeholder.nickname': '请输入昵称', | ||||
|  | ||||
|   'userCenter.basicInfo.form.error.required.username': '请输入用户名', | ||||
|   'userCenter.basicInfo.form.error.match.username': '长度为 4 到 16 位,可以包含字母、数字,下划线,以字母开头', | ||||
|   'userCenter.basicInfo.form.error.match.username': | ||||
|     '长度为 4 到 16 位,可以包含字母、数字,下划线,以字母开头', | ||||
|   'userCenter.basicInfo.form.error.required.nickname': '请输入昵称', | ||||
|   'userCenter.basicInfo.form.error.match.nickname': '长度为 1 到 20 位,可以包含中文、字母、数字、下划线,短横线', | ||||
|   'userCenter.basicInfo.form.error.match.nickname': | ||||
|     '长度为 1 到 20 位,可以包含中文、字母、数字、下划线,短横线', | ||||
|  | ||||
|   'userCenter.basicInfo.form.save': '保存', | ||||
|   'userCenter.basicInfo.form.save.success': '保存成功', | ||||
| @@ -36,7 +38,8 @@ export default { | ||||
|   // security-settings | ||||
|   // update-pwd | ||||
|   'userCenter.securitySettings.updatePwd.label.password': '登录密码', | ||||
|   'userCenter.securitySettings.updatePwd.placeholder.success.password': '已设置', | ||||
|   'userCenter.securitySettings.updatePwd.placeholder.success.password': | ||||
|     '已设置', | ||||
|   'userCenter.securitySettings.updatePwd.placeholder.error.password': | ||||
|     '您暂未设置密码,密码至少6位字符,支持数字、字母和除空格外的特殊字符。', | ||||
|  | ||||
| @@ -45,16 +48,25 @@ export default { | ||||
|   'userCenter.securitySettings.updatePwd.form.label.newPassword': '新密码', | ||||
|   'userCenter.securitySettings.updatePwd.form.label.rePassword': '确认新密码', | ||||
|  | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.oldPassword': '请输入当前密码', | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.newPassword': '长度为 6 到 32 位,同时包含字母和数字', | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.rePassword': '请再次输入新密码', | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.oldPassword': | ||||
|     '请输入当前密码', | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.newPassword': | ||||
|     '长度为 6 到 32 位,同时包含字母和数字', | ||||
|   'userCenter.securitySettings.updatePwd.form.placeholder.rePassword': | ||||
|     '请再次输入新密码', | ||||
|  | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.oldPassword': '请输入当前密码', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.newPassword': '请输入新密码', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.match.newPassword': '长度为 6 到 32 位,同时包含字母和数字', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.validator.newPassword': '新密码不能与当前密码相同', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.rePassword': '请再次输入新密码', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.validator.rePassword': '两次输入的密码不一致', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.oldPassword': | ||||
|     '请输入当前密码', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.newPassword': | ||||
|     '请输入新密码', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.match.newPassword': | ||||
|     '长度为 6 到 32 位,同时包含字母和数字', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.validator.newPassword': | ||||
|     '新密码不能与当前密码相同', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.required.rePassword': | ||||
|     '请再次输入新密码', | ||||
|   'userCenter.securitySettings.updatePwd.form.error.validator.rePassword': | ||||
|     '两次输入的密码不一致', | ||||
|  | ||||
|   // update-phone | ||||
|   'userCenter.securitySettings.updatePhone.label.phone': '安全手机', | ||||
| @@ -71,20 +83,30 @@ export default { | ||||
|   'userCenter.securitySettings.updateEmail.modal.title': '修改邮箱', | ||||
|   'userCenter.securitySettings.updateEmail.form.label.newEmail': '新邮箱', | ||||
|   'userCenter.securitySettings.updateEmail.form.label.captcha': '验证码', | ||||
|   'userCenter.securitySettings.updateEmail.form.label.currentPassword': '当前密码', | ||||
|   'userCenter.securitySettings.updateEmail.form.label.currentPassword': | ||||
|     '当前密码', | ||||
|   'userCenter.securitySettings.updateEmail.form.sendCaptcha': '发送验证码', | ||||
|   'userCenter.securitySettings.updateEmail.form.reSendCaptcha': '重新发送', | ||||
|   'userCenter.securitySettings.updateEmail.form.loading.sendCaptcha': '发送中...', | ||||
|   'userCenter.securitySettings.updateEmail.form.loading.sendCaptcha': | ||||
|     '发送中...', | ||||
|  | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.newEmail': '请输入新邮箱', | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.captcha': '请输入邮箱验证码', | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.currentPassword': '请输入当前密码', | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.newEmail': | ||||
|     '请输入新邮箱', | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.captcha': | ||||
|     '请输入邮箱验证码', | ||||
|   'userCenter.securitySettings.updateEmail.form.placeholder.currentPassword': | ||||
|     '请输入当前密码', | ||||
|  | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.newEmail': '请输入新邮箱', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.match.newEmail': '请输入正确的邮箱', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.validator.newEmail': '新邮箱不能与当前邮箱相同', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.captcha': '请输入邮箱验证码', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.currentPassword': '请输入当前密码', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.newEmail': | ||||
|     '请输入新邮箱', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.match.newEmail': | ||||
|     '请输入正确的邮箱', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.validator.newEmail': | ||||
|     '新邮箱不能与当前邮箱相同', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.captcha': | ||||
|     '请输入邮箱验证码', | ||||
|   'userCenter.securitySettings.updateEmail.form.error.required.currentPassword': | ||||
|     '请输入当前密码', | ||||
|  | ||||
|   'userCenter.securitySettings.button.update': '修改', | ||||
| }; | ||||
|   | ||||
| @@ -3,7 +3,14 @@ | ||||
|     <Breadcrumb :items="['menu.system', 'menu.system.user.list']" /> | ||||
|     <a-card class="general-card" :title="$t('menu.system.user.list')"> | ||||
|       <a-row> | ||||
|         <a-col :xs="9" :sm="6" :md="5" :lg="4" :xl="4" style="margin-right: 10px"> | ||||
|         <a-col | ||||
|           :xs="9" | ||||
|           :sm="6" | ||||
|           :md="5" | ||||
|           :lg="4" | ||||
|           :xl="4" | ||||
|           style="margin-right: 10px" | ||||
|         > | ||||
|           <a-input-search | ||||
|             v-model="deptName" | ||||
|             placeholder="输入部门名称搜索" | ||||
| @@ -157,13 +164,16 @@ | ||||
|               <a-table-column title="头像" align="center"> | ||||
|                 <template #cell="{ record }"> | ||||
|                   <a-avatar> | ||||
|                     <img :src="getAvatar(record.avatar, record.gender)" alt="头像" /> | ||||
|                     <img | ||||
|                       :src="getAvatar(record.avatar, record.gender)" | ||||
|                       alt="头像" | ||||
|                     /> | ||||
|                   </a-avatar> | ||||
|                 </template> | ||||
|               </a-table-column> | ||||
|               <a-table-column title="联系方式" :width="170"> | ||||
|                 <template #cell="{ record }"> | ||||
|                   {{ record.email }}<br v-if="record.email && record.phone"> | ||||
|                   {{ record.email }}<br v-if="record.email && record.phone" /> | ||||
|                   {{ record.phone }} | ||||
|                 </template> | ||||
|               </a-table-column> | ||||
| @@ -173,7 +183,10 @@ | ||||
|                     v-model="record.status" | ||||
|                     :checked-value="1" | ||||
|                     :unchecked-value="2" | ||||
|                     :disabled="record.disabled || !checkPermission(['system:user:update'])" | ||||
|                     :disabled=" | ||||
|                       record.disabled || | ||||
|                       !checkPermission(['system:user:update']) | ||||
|                     " | ||||
|                     @change="handleChangeStatus(record)" | ||||
|                   /> | ||||
|                 </template> | ||||
| @@ -186,7 +199,7 @@ | ||||
|               </a-table-column> | ||||
|               <a-table-column title="创建人/创建时间" :width="175"> | ||||
|                 <template #cell="{ record }"> | ||||
|                   {{ record.createUserString }}<br> | ||||
|                   {{ record.createUserString }}<br /> | ||||
|                   {{ record.createTime }} | ||||
|                 </template> | ||||
|               </a-table-column> | ||||
| @@ -240,7 +253,9 @@ | ||||
|                       size="small" | ||||
|                       title="重置密码" | ||||
|                     > | ||||
|                       <template #icon><svg-icon icon-class="privacy" /></template> | ||||
|                       <template #icon | ||||
|                         ><svg-icon icon-class="privacy" | ||||
|                       /></template> | ||||
|                     </a-button> | ||||
|                   </a-popconfirm> | ||||
|                   <a-button | ||||
| @@ -251,7 +266,9 @@ | ||||
|                     :disabled="record.disabled" | ||||
|                     @click="toUpdateRole(record.id)" | ||||
|                   > | ||||
|                     <template #icon><svg-icon icon-class="reference" /></template> | ||||
|                     <template #icon | ||||
|                       ><svg-icon icon-class="reference" | ||||
|                     /></template> | ||||
|                   </a-button> | ||||
|                 </template> | ||||
|               </a-table-column> | ||||
| @@ -325,7 +342,11 @@ | ||||
|               style="width: 431px" | ||||
|             /> | ||||
|           </a-form-item> | ||||
|           <a-form-item label="所属角色" field="roleIds" :disabled="form.disabled"> | ||||
|           <a-form-item | ||||
|             label="所属角色" | ||||
|             field="roleIds" | ||||
|             :disabled="form.disabled" | ||||
|           > | ||||
|             <a-select | ||||
|               v-model="form.roleIds" | ||||
|               :options="roleOptions" | ||||
|   | ||||
| @@ -34,6 +34,9 @@ import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.RestController; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaIgnore; | ||||
| import cn.hutool.core.convert.Convert; | ||||
| import cn.hutool.core.util.URLUtil; | ||||
| import cn.hutool.extra.spring.SpringUtil; | ||||
|  | ||||
| import top.charles7c.cnadmin.common.config.properties.ContiNewAdminProperties; | ||||
|  | ||||
| @@ -73,10 +76,16 @@ public class ContiNewAdminApplication implements ApplicationRunner { | ||||
|     @Override | ||||
|     public void run(ApplicationArguments args) throws Exception { | ||||
|         String hostAddress = InetAddress.getLocalHost().getHostAddress(); | ||||
|         Integer port = serverProperties.getPort(); | ||||
|         String contextPath = serverProperties.getServlet().getContextPath(); | ||||
|         String baseUrl = URLUtil.normalize(String.format("%s:%s%s", hostAddress, port, contextPath)); | ||||
|         log.info("------------------------------------------------------"); | ||||
|         log.info("{} backend service started successfully.", properties.getName()); | ||||
|         log.info("后端 API 地址:http://{}:{}", hostAddress, serverProperties.getPort()); | ||||
|         log.info("后端 API 文档:http://{}:{}/doc.html", hostAddress, serverProperties.getPort()); | ||||
|         log.info("后端 API 地址:{}", baseUrl); | ||||
|         Boolean docEnabled = Convert.toBool(SpringUtil.getProperty("springdoc.swagger-ui.enabled")); | ||||
|         if (Boolean.TRUE.equals(docEnabled)) { | ||||
|             log.info("后端 API 文档:{}/doc.html", baseUrl); | ||||
|         } | ||||
|         log.info("------------------------------------------------------"); | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user