mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-11-04 10:57:10 +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>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								continew-admin-ui/src/hooks/axios.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								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; // 状态码
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 
 | 
			
		||||
@@ -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