Jelajahi Sumber

!222 vue3
Merge pull request !222 from xingyu/master

芋道源码 2 tahun lalu
induk
melakukan
6691c08585
28 mengubah file dengan 254 tambahan dan 216 penghapusan
  1. 13 0
      yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java
  2. 4 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java
  3. 2 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java
  4. 2 2
      yudao-ui-admin-vue3/package.json
  5. 18 0
      yudao-ui-admin-vue3/src/api/infra/redis/index.ts
  6. 6 11
      yudao-ui-admin-vue3/src/components/Form/src/helper.ts
  7. 1 1
      yudao-ui-admin-vue3/src/components/Logo/src/Logo.vue
  8. 1 1
      yudao-ui-admin-vue3/src/components/UserInfo/src/UserInfo.vue
  9. 14 10
      yudao-ui-admin-vue3/src/config/axios/index.ts
  10. 71 0
      yudao-ui-admin-vue3/src/hooks/web/useMessage.ts
  11. 1 1
      yudao-ui-admin-vue3/src/router/modules/remaining.ts
  12. 5 7
      yudao-ui-admin-vue3/src/views/infra/apiErrorLog/index.vue
  13. 8 9
      yudao-ui-admin-vue3/src/views/infra/codegen/index.vue
  14. 6 9
      yudao-ui-admin-vue3/src/views/infra/fileConfig/index.vue
  15. 8 14
      yudao-ui-admin-vue3/src/views/infra/job/index.vue
  16. 9 9
      yudao-ui-admin-vue3/src/views/system/dept/index.vue
  17. 2 15
      yudao-ui-admin-vue3/src/views/system/errorCode/errorCode.data.ts
  18. 2 15
      yudao-ui-admin-vue3/src/views/system/loginlog/loginLog.data.ts
  19. 20 21
      yudao-ui-admin-vue3/src/views/system/menu/index.vue
  20. 11 1
      yudao-ui-admin-vue3/src/views/system/oauth2/client/index.vue
  21. 1 1
      yudao-ui-admin-vue3/src/views/system/operatelog/index.vue
  22. 21 21
      yudao-ui-admin-vue3/src/views/system/operatelog/operatelog.data.ts
  23. 5 2
      yudao-ui-admin-vue3/src/views/system/role/role.data.ts
  24. 2 15
      yudao-ui-admin-vue3/src/views/system/sms/smsChannel/sms.channel.data.ts
  25. 2 12
      yudao-ui-admin-vue3/src/views/system/sms/smsLog/sms.log.data.ts
  26. 2 15
      yudao-ui-admin-vue3/src/views/system/sms/smsTemplate/sms.template.data.ts
  27. 15 21
      yudao-ui-admin-vue3/src/views/system/user/index.vue
  28. 2 2
      yudao-ui-admin-vue3/src/views/system/user/user.data.ts

+ 13 - 0
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java

@@ -94,6 +94,19 @@ public class LambdaQueryWrapperX<T> extends LambdaQueryWrapper<T> {
         return this;
     }
 
+    public LambdaQueryWrapperX<T> betweenIfPresent(SFunction<T, ?> column, Object[] values) {
+        if (values!= null && values.length >0 && values[0] != null && values[1] != null) {
+            return (LambdaQueryWrapperX<T>) super.between(column, values[0], values[1]);
+        }
+        if (values != null && values[0] != null) {
+            return (LambdaQueryWrapperX<T>) ge(column, values[0]);
+        }
+        if (values != null && values[1] != null) {
+            return (LambdaQueryWrapperX<T>) le(column, values[2]);
+        }
+        return this;
+    }
+
     // ========== 重写父类方法,方便链式调用 ==========
 
     @Override

+ 4 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java

@@ -37,6 +37,10 @@ public class UserPageReqVO extends PageParam {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private Date endTime;
 
+    @ApiModelProperty(value = "开始时间", example = "2020-10-24")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private Date[] createTime;
+
     @ApiModelProperty(value = "部门编号", example = "1024", notes = "同时筛选子部门")
     private Long deptId;
 

+ 2 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java

@@ -33,7 +33,8 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
                 .likeIfPresent(AdminUserDO::getUsername, reqVO.getUsername())
                 .likeIfPresent(AdminUserDO::getMobile, reqVO.getMobile())
                 .eqIfPresent(AdminUserDO::getStatus, reqVO.getStatus())
-                .betweenIfPresent(AdminUserDO::getCreateTime, reqVO.getBeginTime(), reqVO.getEndTime())
+                .betweenIfPresent(AdminUserDO::getCreateTime, reqVO.getBeginTime(),reqVO.getEndTime())
+                .betweenIfPresent(AdminUserDO::getCreateTime, reqVO.getCreateTime())
                 .inIfPresent(AdminUserDO::getDeptId, deptIds)
                 .orderByDesc(AdminUserDO::getId));
 

+ 2 - 2
yudao-ui-admin-vue3/package.json

@@ -1,6 +1,6 @@
 {
   "name": "ruoyi-vue-pro-vue3",
-  "version": "1.0.160",
+  "version": "1.6.2.1601",
   "description": "基于vue3、element-plus、typesScript、vite3",
   "author": "xingyu",
   "private": false,
@@ -56,7 +56,7 @@
   "devDependencies": {
     "@commitlint/cli": "^17.0.3",
     "@commitlint/config-conventional": "^17.0.3",
-    "@iconify/json": "^2.1.79",
+    "@iconify/json": "^2.1.80",
     "@intlify/vite-plugin-vue-i18n": "^5.0.0",
     "@purge-icons/generated": "^0.8.1",
     "@types/intro.js": "^5.1.0",

+ 18 - 0
yudao-ui-admin-vue3/src/api/infra/redis/index.ts

@@ -23,3 +23,21 @@ export const getKeyListApi = (keyTemplate: string) => {
     }
   })
 }
+// 获取缓存内容
+export const getKeyValue = (key: string) => {
+  return request.get({ url: '/infra/redis/get-key-value?key=' + key })
+}
+
+// 根据键名删除缓存
+export const deleteKey = (key: string) => {
+  return request.delete({ url: '/infra/redis/delete-key?key=' + key })
+}
+
+export const deleteKeys = (keyTemplate: string) => {
+  return request.delete({
+    url: '/infra/redis/delete-keys?',
+    params: {
+      keyTemplate
+    }
+  })
+}

+ 6 - 11
yudao-ui-admin-vue3/src/components/Form/src/helper.ts

@@ -1,10 +1,8 @@
-// import { useI18n } from '@/hooks/web/useI18n'
+import { useI18n } from '@/hooks/web/useI18n'
 import type { Slots } from 'vue'
 import { getSlot } from '@/utils/tsxHelper'
 import { PlaceholderMoel } from './types'
 
-// const { t } = useI18n()
-
 /**
  *
  * @param schema 对应组件数据
@@ -12,12 +10,12 @@ import { PlaceholderMoel } from './types'
  * @description 用于自动设置placeholder
  */
 export const setTextPlaceholder = (schema: FormSchema): PlaceholderMoel => {
+  const { t } = useI18n()
   const textMap = ['Input', 'Autocomplete', 'InputNumber', 'InputPassword']
   const selectMap = ['Select', 'TimePicker', 'DatePicker', 'TimeSelect', 'TimeSelect']
   if (textMap.includes(schema?.component as string)) {
     return {
-      // placeholder: t('common.inputText')
-      placeholder: '请输入'
+      placeholder: t('common.inputText')
     }
   }
   if (selectMap.includes(schema?.component as string)) {
@@ -29,16 +27,13 @@ export const setTextPlaceholder = (schema: FormSchema): PlaceholderMoel => {
       )
     ) {
       return {
-        // startPlaceholder: t('common.startTimeText'),
-        // endPlaceholder: t('common.endTimeText'),
-        startPlaceholder: '开始时间',
-        endPlaceholder: '结束时间',
+        startPlaceholder: t('common.startTimeText'),
+        endPlaceholder: t('common.endTimeText'),
         rangeSeparator: '-'
       }
     } else {
       return {
-        // placeholder: t('common.selectText')
-        placeholder: '请选择'
+        placeholder: t('common.selectText')
       }
     }
   }

+ 1 - 1
yudao-ui-admin-vue3/src/components/Logo/src/Logo.vue

@@ -59,7 +59,7 @@ watch(
     :class="[
       prefixCls,
       layout !== 'classic' ? `${prefixCls}__Top` : '',
-      'flex !h-[var(--logo-height)] items-center cursor-pointer pl-8px relative',
+      'flex !h-[var(--logo-height)] items-center cursor-pointer justify-center relative',
       'dark:bg-[var(--el-bg-color)]'
     ]"
     to="/"

+ 1 - 1
yudao-ui-admin-vue3/src/components/UserInfo/src/UserInfo.vue

@@ -43,7 +43,7 @@ const loginOut = () => {
     .catch(() => {})
 }
 const toProfile = async () => {
-  push('/user/profile')
+  push('/userinfo/profile')
 }
 const toDocument = () => {
   window.open('https://doc.iocoder.cn/')

+ 14 - 10
yudao-ui-admin-vue3/src/config/axios/index.ts

@@ -5,7 +5,6 @@ import { config } from '@/config/axios/config'
 import { getAccessToken, getRefreshToken, getTenantId } from '@/utils/auth'
 import errorCode from './errorCode'
 import { useI18n } from '@/hooks/web/useI18n'
-const { t } = useI18n()
 
 const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE
 const BASE_URL = import.meta.env.VITE_BASE_URL
@@ -46,25 +45,27 @@ service.interceptors.request.use(
       const tenantId = getTenantId()
       if (tenantId) (config as Recordable).headers.common['tenant-id'] = tenantId
     }
+    const params = config.params || {}
+    const data = config.data || false
     if (
-      config.method === 'post' &&
+      config.method?.toUpperCase() === 'POST' &&
       config!.headers!['Content-Type'] === 'application/x-www-form-urlencoded'
     ) {
-      config.data = qs.stringify(config.data)
+      config.data = qs.stringify(data)
     }
     // get参数编码
-    if (config.method === 'get' && config.params) {
+    if (config.method?.toUpperCase() === 'GET' && config.params) {
       let url = config.url as string
+      // 给 get 请求加上时间戳参数,避免从缓存中拿数据
+      // const now = new Date().getTime()
+      // params = params.substring(0, url.length - 1) + `?_t=${now}`
       url += '?'
-      const keys = Object.keys(config.params)
+      const keys = Object.keys(params)
       for (const key of keys) {
-        if (config.params[key] !== void 0 && config.params[key] !== null) {
-          url += `${key}=${encodeURIComponent(config.params[key])}&`
+        if (params[key] !== void 0 && params[key] !== null) {
+          url += `${key}=${encodeURIComponent(params[key])}&`
         }
       }
-      // 给 get 请求加上时间戳参数,避免从缓存中拿数据
-      // const now = new Date().getTime()
-      // url = url.substring(0, url.length - 1) + `?_t=${now}`
       config.params = {}
       config.url = url
     }
@@ -85,6 +86,7 @@ service.interceptors.response.use(
       // 返回“[HTTP]请求没有返回值”;
       throw new Error()
     }
+    const { t } = useI18n()
     // 未设置状态码则默认成功状态
     const code = data.code || result_code
     // 获取错误信息
@@ -134,6 +136,7 @@ service.interceptors.response.use(
   (error: AxiosError) => {
     console.log('err' + error) // for debug
     let { message } = error
+    const { t } = useI18n()
     if (message === 'Network Error') {
       message = t('sys.api.errorMessage')
     } else if (message.includes('timeout')) {
@@ -146,6 +149,7 @@ service.interceptors.response.use(
   }
 )
 function handleAuthorized() {
+  const { t } = useI18n()
   if (!isRelogin.show) {
     isRelogin.show = true
     ElMessageBox.confirm(t('sys.api.timeoutMessage'), t('common.confirmTitle'), {

+ 71 - 0
yudao-ui-admin-vue3/src/hooks/web/useMessage.ts

@@ -0,0 +1,71 @@
+import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
+import { useI18n } from './useI18n'
+export const useMessage = () => {
+  const { t } = useI18n()
+  return {
+    // 消息提示
+    info(content: string) {
+      ElMessage.info(content)
+    },
+    // 错误消息
+    error(content: string) {
+      ElMessage.error(content)
+    },
+    // 成功消息
+    success(content: string) {
+      ElMessage.success(content)
+    },
+    // 警告消息
+    warning(content: string) {
+      ElMessage.warning(content)
+    },
+    // 弹出提示
+    alert(content: string) {
+      ElMessageBox.alert(content, t('common.confirmTitle'))
+    },
+    // 错误提示
+    alertError(content: string) {
+      ElMessageBox.alert(content, t('common.confirmTitle'), { type: 'error' })
+    },
+    // 成功提示
+    alertSuccess(content: string) {
+      ElMessageBox.alert(content, t('common.confirmTitle'), { type: 'success' })
+    },
+    // 警告提示
+    alertWarning(content: string) {
+      ElMessageBox.alert(content, t('common.confirmTitle'), { type: 'warning' })
+    },
+    // 通知提示
+    notify(content: string) {
+      ElNotification.info(content)
+    },
+    // 错误通知
+    notifyError(content: string) {
+      ElNotification.error(content)
+    },
+    // 成功通知
+    notifySuccess(content: string) {
+      ElNotification.success(content)
+    },
+    // 警告通知
+    notifyWarning(content: string) {
+      ElNotification.warning(content)
+    },
+    // 确认窗体
+    confirm(content: string, tip: string) {
+      return ElMessageBox.confirm(content, tip, {
+        confirmButtonText: t('common.ok'),
+        cancelButtonText: t('common.cancel'),
+        type: 'warning'
+      })
+    },
+    // 提交内容
+    prompt(content: string, tip: string) {
+      return ElMessageBox.prompt(content, tip, {
+        confirmButtonText: t('common.ok'),
+        cancelButtonText: t('common.cancel'),
+        type: 'warning'
+      })
+    }
+  }
+}

+ 1 - 1
yudao-ui-admin-vue3/src/router/modules/remaining.ts

@@ -41,7 +41,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
     ]
   },
   {
-    path: '/user',
+    path: '/userinfo',
     component: Layout,
     name: 'UserInfo',
     meta: {

+ 5 - 7
yudao-ui-admin-vue3/src/views/infra/apiErrorLog/index.vue

@@ -8,7 +8,8 @@ import type { ApiErrorLogVO } from '@/api/infra/apiErrorLog/types'
 import { allSchemas } from './apiErrorLog.data'
 import * as ApiErrorLogApi from '@/api/infra/apiErrorLog'
 import { InfraApiErrorLogProcessStatusEnum } from '@/utils/constants'
-import { ElMessage, ElMessageBox } from 'element-plus'
+import { useMessage } from '@/hooks/web/useMessage'
+const message = useMessage()
 const { t } = useI18n() // 国际化
 
 // ========== 列表相关 ==========
@@ -36,14 +37,11 @@ const handleDetail = (row: ApiErrorLogVO) => {
 }
 // 异常处理操作
 const handleProcessClick = (row: ApiErrorLogVO, processSttatus: number, type: string) => {
-  ElMessageBox.confirm('确认标记为' + type + '?', t('common.reminder'), {
-    confirmButtonText: t('common.ok'),
-    cancelButtonText: t('common.cancel'),
-    type: 'warning'
-  })
+  message
+    .confirm('确认标记为' + type + '?', t('common.reminder'))
     .then(async () => {
       ApiErrorLogApi.updateApiErrorLogPageApi(row.id, processSttatus).then(() => {
-        ElMessage.success(t('common.updateSuccess'))
+        message.success(t('common.updateSuccess'))
         getList()
       })
     })

+ 8 - 9
yudao-ui-admin-vue3/src/views/infra/codegen/index.vue

@@ -10,7 +10,8 @@ import ImportTable from './components/ImportTable.vue'
 import Preview from './components/Preview.vue'
 import download from '@/utils/download'
 import { useRouter } from 'vue-router'
-import { ElMessage, ElMessageBox } from 'element-plus'
+import { useMessage } from '@/hooks/web/useMessage'
+const message = useMessage()
 const { t } = useI18n() // 国际化
 const { push } = useRouter()
 // ========== 列表相关 ==========
@@ -37,14 +38,12 @@ const handleEditTable = (row: CodegenTableVO) => {
 const handleSynchDb = (row: CodegenTableVO) => {
   // 基于 DB 同步
   const tableName = row.tableName
-  ElMessageBox.confirm('确认要强制同步' + tableName + '表结构吗?', t('common.reminder'), {
-    confirmButtonText: t('common.ok'),
-    cancelButtonText: t('common.cancel'),
-    type: 'warning'
-  }).then(async () => {
-    await CodegenApi.syncCodegenFromDBApi(row.id)
-    ElMessage.success('同步成功')
-  })
+  message
+    .confirm('确认要强制同步' + tableName + '表结构吗?', t('common.reminder'))
+    .then(async () => {
+      await CodegenApi.syncCodegenFromDBApi(row.id)
+      message.success('同步成功')
+    })
 }
 // 生成代码操作
 const handleGenTable = (row: CodegenTableVO) => {

+ 6 - 9
yudao-ui-admin-vue3/src/views/infra/fileConfig/index.vue

@@ -1,7 +1,6 @@
 <script setup lang="ts">
 import { ref, unref } from 'vue'
 import dayjs from 'dayjs'
-import { ElMessage, ElMessageBox } from 'element-plus'
 import { DICT_TYPE } from '@/utils/dict'
 import { useTable } from '@/hooks/web/useTable'
 import { useI18n } from '@/hooks/web/useI18n'
@@ -9,6 +8,8 @@ import { FormExpose } from '@/components/Form'
 import type { FileConfigVO } from '@/api/infra/fileConfig/types'
 import { rules, allSchemas } from './fileConfig.data'
 import * as FileConfigApi from '@/api/infra/fileConfig'
+import { useMessage } from '@/hooks/web/useMessage'
+const message = useMessage()
 const { t } = useI18n() // 国际化
 
 // ========== 列表相关 ==========
@@ -49,16 +50,12 @@ const handleUpdate = async (row: FileConfigVO) => {
 
 // 主配置操作
 const handleMaster = (row: FileConfigVO) => {
-  ElMessageBox.confirm('是否确认修改配置【 ' + row.name + ' 】为主配置?', t('common.reminder'), {
-    confirmButtonText: t('common.ok'),
-    cancelButtonText: t('common.cancel'),
-    type: 'warning'
-  })
+  message
+    .confirm('是否确认修改配置【 ' + row.name + ' 】为主配置?', t('common.reminder'))
     .then(async () => {
       await FileConfigApi.updateFileConfigMasterApi(row.id)
       await getList()
     })
-    .catch(() => {})
 }
 
 // 提交按钮
@@ -69,10 +66,10 @@ const submitForm = async () => {
     const data = unref(formRef)?.formModel as FileConfigVO
     if (actionType.value === 'create') {
       await FileConfigApi.createFileConfigApi(data)
-      ElMessage.success(t('common.createSuccess'))
+      message.success(t('common.createSuccess'))
     } else {
       await FileConfigApi.updateFileConfigApi(data)
-      ElMessage.success(t('common.updateSuccess'))
+      message.success(t('common.updateSuccess'))
     }
     // 操作成功,重新加载列表
     dialogVisible.value = false

+ 8 - 14
yudao-ui-admin-vue3/src/views/infra/job/index.vue

@@ -9,8 +9,9 @@ import { useTable } from '@/hooks/web/useTable'
 import { useI18n } from '@/hooks/web/useI18n'
 import { FormExpose } from '@/components/Form'
 import { rules, allSchemas } from './job.data'
-import { ElMessage, ElMessageBox } from 'element-plus'
 import { useRouter } from 'vue-router'
+import { useMessage } from '@/hooks/web/useMessage'
+const message = useMessage()
 const { t } = useI18n() // 国际化
 const { push } = useRouter()
 // ========== 列表相关 ==========
@@ -64,18 +65,11 @@ const handleJobLog = (row: JobVO) => {
 }
 // 执行一次
 const handleRun = (row: JobVO) => {
-  ElMessageBox.confirm('确认要立即执行一次' + row.name + '?', t('common.reminder'), {
-    confirmButtonText: t('common.ok'),
-    cancelButtonText: t('common.cancel'),
-    type: 'warning'
+  message.confirm('确认要立即执行一次' + row.name + '?', t('common.reminder')).then(async () => {
+    await JobApi.runJobApi(row.id)
+    message.success('执行成功')
+    getList()
   })
-    .then(async () => {
-      JobApi.runJobApi(row.id).then(() => {
-        ElMessage.success('执行成功')
-        getList()
-      })
-    })
-    .catch(() => {})
 }
 // 提交按钮
 const submitForm = async () => {
@@ -85,10 +79,10 @@ const submitForm = async () => {
     const data = unref(formRef)?.formModel as JobVO
     if (actionType.value === 'create') {
       await JobApi.createJobApi(data)
-      ElMessage.success(t('common.createSuccess'))
+      message.success(t('common.createSuccess'))
     } else {
       await JobApi.updateJobApi(data)
-      ElMessage.success(t('common.updateSuccess'))
+      message.success(t('common.updateSuccess'))
     }
     // 操作成功,重新加载列表
     dialogVisible.value = false

+ 9 - 9
yudao-ui-admin-vue3/src/views/system/dept/index.vue

@@ -1,12 +1,14 @@
 <script setup lang="ts">
 import { useI18n } from '@/hooks/web/useI18n'
-import { ElInput, ElCard, ElTree, ElTreeSelect, ElMessage, ElMessageBox } from 'element-plus'
+import { ElInput, ElCard, ElTree, ElTreeSelect } from 'element-plus'
 import { handleTree } from '@/utils/tree'
 import { onMounted, ref, unref, watch } from 'vue'
 import * as DeptApi from '@/api/system/dept'
 import { Form, FormExpose } from '@/components/Form'
 import { modelSchema } from './dept.data'
 import { DeptVO } from '@/api/system/dept/types'
+import { useMessage } from '@/hooks/web/useMessage'
+const message = useMessage()
 interface Tree {
   id: number
   name: string
@@ -29,10 +31,10 @@ const formRef = ref<FormExpose>()
 
 // ========== 创建部门树结构 ==========
 const filterText = ref('')
-const deptOptions = ref([]) // 树形结构
+const deptOptions = ref() // 树形结构
 const treeRef = ref<InstanceType<typeof ElTree>>()
 const getTree = async () => {
-  const res = await DeptApi.listSimpleDeptApi()
+  const res = await DeptApi.getDeptPageApi(null)
   deptOptions.value = handleTree(res)
 }
 const filterNode = (value: string, data: Tree) => {
@@ -60,14 +62,11 @@ const handleUpdate = async (data: { id: number }) => {
 }
 // 删除
 const handleDelete = async (data: { id: number }) => {
-  ElMessageBox.confirm(t('common.delDataMessage'), t('common.confirmTitle'), {
-    confirmButtonText: t('common.ok'),
-    cancelButtonText: t('common.cancel'),
-    type: 'warning'
-  })
+  message
+    .confirm(t('common.delDataMessage'), t('common.confirmTitle'))
     .then(async () => {
       await DeptApi.deleteDeptApi(data.id)
-      ElMessage.success(t('common.delSuccess'))
+      message.success(t('common.delSuccess'))
     })
     .catch(() => {})
   await getTree()
@@ -118,6 +117,7 @@ onMounted(async () => {
           :highlight-current="true"
           default-expand-all
           :filter-node-method="filterNode"
+          :expand-on-click-node="false"
         >
           <template #default="{ node, data }">
             <span class="custom-tree-node">

+ 2 - 15
yudao-ui-admin-vue3/src/views/system/errorCode/errorCode.data.ts

@@ -56,26 +56,13 @@ const crudSchemas = reactive<CrudSchema[]>([
     field: 'createTime',
     form: {
       show: false
-    }
-  },
-  {
-    label: t('common.createTime'),
-    field: 'daterange',
-    table: {
-      show: false
-    },
-    form: {
-      show: false
-    },
-    detail: {
-      show: false
     },
     search: {
       show: true,
       component: 'DatePicker',
       componentProps: {
-        type: 'daterange',
-        valueFormat: 'YYYY-MM-DD'
+        type: 'datetimerange',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss'
       }
     }
   },

+ 2 - 15
yudao-ui-admin-vue3/src/views/system/loginlog/loginLog.data.ts

@@ -54,26 +54,13 @@ const crudSchemas = reactive<CrudSchema[]>([
     field: 'createTime',
     form: {
       show: false
-    }
-  },
-  {
-    label: t('common.createTime'),
-    field: 'daterange',
-    table: {
-      show: false
-    },
-    form: {
-      show: false
-    },
-    detail: {
-      show: false
     },
     search: {
       show: true,
       component: 'DatePicker',
       componentProps: {
-        type: 'daterange',
-        valueFormat: 'YYYY-MM-DD'
+        type: 'datetimerange',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss'
       }
     }
   },

+ 20 - 21
yudao-ui-admin-vue3/src/views/system/menu/index.vue

@@ -16,16 +16,16 @@ import {
   ElInput,
   ElInputNumber,
   ElSelect,
+  ElTreeSelect,
   ElOption,
-  ElMessageBox,
-  ElMessage,
-  ElCascader,
   ElRadioGroup,
   ElRadioButton
 } from 'element-plus'
 import { MenuVO } from '@/api/system/menu/types'
 import { SystemMenuTypeEnum, CommonStatusEnum } from '@/utils/constants'
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
+import { useMessage } from '@/hooks/web/useMessage'
+const message = useMessage()
 const { t } = useI18n() // 国际化
 // ========== 创建菜单树结构 ==========
 const loading = ref(true)
@@ -41,10 +41,13 @@ const menuProps = {
   label: 'name',
   value: 'id'
 }
-const menuOptions = ref([]) // 树形结构
+const menuOptions = ref() // 树形结构
 const getTree = async () => {
   const res = await MenuApi.listSimpleMenusApi()
-  menuOptions.value = handleTree(res)
+  const menu = { id: 0, name: '主类目', children: [] }
+  menu.children = handleTree(res)
+  console.info(menu)
+  menuOptions.value = menu
 }
 // ========== 查询 ==========
 const queryParams = reactive({
@@ -108,14 +111,11 @@ const handleUpdate = async (row: MenuVO) => {
 }
 // 删除操作
 const handleDelete = async (row: MenuVO) => {
-  ElMessageBox.confirm(t('common.delDataMessage'), t('common.confirmTitle'), {
-    confirmButtonText: t('common.ok'),
-    cancelButtonText: t('common.cancel'),
-    type: 'warning'
-  })
+  message
+    .confirm(t('common.delDataMessage'), t('common.confirmTitle'))
     .then(async () => {
       await MenuApi.deleteMenuApi(row.id)
-      ElMessage.success(t('common.delSuccess'))
+      message.success(t('common.delSuccess'))
     })
     .catch(() => {})
   await getList()
@@ -134,20 +134,20 @@ const submitForm = async () => {
     ) {
       if (!isExternal(menuForm.value.path)) {
         if (menuForm.value.parentId === 0 && menuForm.value.path.charAt(0) !== '/') {
-          ElMessage.error('路径必须以 / 开头')
+          message.error('路径必须以 / 开头')
           return
         } else if (menuForm.value.parentId !== 0 && menuForm.value.path.charAt(0) === '/') {
-          ElMessage.error('路径不能以 / 开头')
+          message.error('路径不能以 / 开头')
           return
         }
       }
     }
     if (actionType.value === 'create') {
       await MenuApi.createMenuApi(menuForm.value)
-      ElMessage.success(t('common.createSuccess'))
+      message.success(t('common.createSuccess'))
     } else {
       await MenuApi.updateMenuApi(menuForm.value)
-      ElMessage.success(t('common.updateSuccess'))
+      message.success(t('common.updateSuccess'))
     }
     // 操作成功,重新加载列表
     dialogVisible.value = false
@@ -264,13 +264,12 @@ onMounted(async () => {
       <el-row :gutter="24">
         <el-col :span="24">
           <el-form-item label="上级菜单">
-            <el-cascader
-              :options="menuData"
-              :props="menuProps"
-              placeholder="请选择上级菜单"
+            <el-tree-select
+              node-key="id"
               v-model="menuForm.parentId"
-              class="w-100"
-              clearable
+              :props="menuProps"
+              :data="menuData"
+              check-strictly
             />
           </el-form-item>
         </el-col>

+ 11 - 1
yudao-ui-admin-vue3/src/views/system/oauth2/client/index.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import { ref, unref } from 'vue'
 import dayjs from 'dayjs'
-import { ElMessage, ElImage } from 'element-plus'
+import { ElMessage, ElImage, ElTag } from 'element-plus'
 import { DICT_TYPE } from '@/utils/dict'
 import { useTable } from '@/hooks/web/useTable'
 import { useI18n } from '@/hooks/web/useI18n'
@@ -118,6 +118,16 @@ getList()
       <template #status="{ row }">
         <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
       </template>
+      <template #authorizedGrantTypes="{ row }">
+        <el-tag
+          :disable-transitions="true"
+          :key="index"
+          v-for="(authorizedGrantType, index) in row.authorizedGrantTypes"
+          :index="index"
+        >
+          {{ authorizedGrantType }}
+        </el-tag>
+      </template>
       <template #createTime="{ row }">
         <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
       </template>

+ 1 - 1
yudao-ui-admin-vue3/src/views/system/operatelog/index.vue

@@ -68,7 +68,7 @@ getList()
         <span>{{ row.resultCode === 0 ? '成功' : '失败' }}</span>
       </template>
       <template #startTime="{ row }">
-        <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
+        <span>{{ dayjs(row.startTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
       </template>
       <template #action="{ row }">
         <el-button link type="primary" @click="handleDetail(row)">

+ 21 - 21
yudao-ui-admin-vue3/src/views/system/operatelog/operatelog.data.ts

@@ -41,7 +41,10 @@ const crudSchemas = reactive<CrudSchema[]>([
   },
   {
     label: '操作人员',
-    field: 'userNickname'
+    field: 'userNickname',
+    search: {
+      show: true
+    }
   },
   {
     label: '操作明细',
@@ -63,40 +66,37 @@ const crudSchemas = reactive<CrudSchema[]>([
   },
   {
     label: '操作结果',
-    field: 'resultCode'
-  },
-  {
-    label: '操作日期',
-    field: 'startTime',
-    form: {
-      show: false
+    field: 'resultCode',
+    search: {
+      show: true,
+      component: 'Select',
+      componentProps: {
+        options: [
+          { label: '成功', value: true },
+          { label: '失败', value: false }
+        ]
+      }
     }
   },
-  {
-    label: '执行时长',
-    field: 'duration'
-  },
   {
     label: '操作日期',
-    field: 'daterange',
-    table: {
-      show: false
-    },
+    field: 'startTime',
     form: {
       show: false
     },
-    detail: {
-      show: false
-    },
     search: {
       show: true,
       component: 'DatePicker',
       componentProps: {
-        type: 'daterange',
-        valueFormat: 'YYYY-MM-DD'
+        type: 'datetimerange',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss'
       }
     }
   },
+  {
+    label: '执行时长',
+    field: 'duration'
+  },
   {
     label: t('table.action'),
     field: 'action',

+ 5 - 2
yudao-ui-admin-vue3/src/views/system/role/role.data.ts

@@ -65,12 +65,15 @@ const crudSchemas = reactive<CrudSchema[]>([
     form: {
       show: false
     },
+    detail: {
+      show: false
+    },
     search: {
       show: true,
       component: 'DatePicker',
       componentProps: {
-        type: 'daterange',
-        valueFormat: 'YYYY-MM-DD'
+        type: 'datetimerange',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss'
       }
     }
   },

+ 2 - 15
yudao-ui-admin-vue3/src/views/system/sms/smsChannel/sms.channel.data.ts

@@ -66,26 +66,13 @@ const crudSchemas = reactive<CrudSchema[]>([
     field: 'createTime',
     form: {
       show: false
-    }
-  },
-  {
-    label: t('common.createTime'),
-    field: 'daterange',
-    table: {
-      show: false
-    },
-    form: {
-      show: false
-    },
-    detail: {
-      show: false
     },
     search: {
       show: true,
       component: 'DatePicker',
       componentProps: {
-        type: 'daterange',
-        valueFormat: 'YYYY-MM-DD'
+        type: 'datetimerange',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss'
       }
     }
   },

+ 2 - 12
yudao-ui-admin-vue3/src/views/system/sms/smsLog/sms.log.data.ts

@@ -77,16 +77,6 @@ const crudSchemas = reactive<CrudSchema[]>([
   {
     label: t('common.createTime'),
     field: 'createTime',
-    form: {
-      show: false
-    }
-  },
-  {
-    label: '接收时间',
-    field: 'daterange',
-    table: {
-      show: false
-    },
     form: {
       show: false
     },
@@ -94,8 +84,8 @@ const crudSchemas = reactive<CrudSchema[]>([
       show: true,
       component: 'DatePicker',
       componentProps: {
-        type: 'daterange',
-        valueFormat: 'YYYY-MM-DD'
+        type: 'datetimerange',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss'
       }
     }
   },

+ 2 - 15
yudao-ui-admin-vue3/src/views/system/sms/smsTemplate/sms.template.data.ts

@@ -77,26 +77,13 @@ const crudSchemas = reactive<CrudSchema[]>([
     field: 'createTime',
     form: {
       show: false
-    }
-  },
-  {
-    label: t('common.createTime'),
-    field: 'daterange',
-    table: {
-      show: false
-    },
-    form: {
-      show: false
-    },
-    detail: {
-      show: false
     },
     search: {
       show: true,
       component: 'DatePicker',
       componentProps: {
-        type: 'daterange',
-        valueFormat: 'YYYY-MM-DD'
+        type: 'datetimerange',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss'
       }
     }
   },

+ 15 - 21
yudao-ui-admin-vue3/src/views/system/user/index.vue

@@ -3,7 +3,6 @@ import { onMounted, ref, unref, watch } from 'vue'
 import dayjs from 'dayjs'
 import {
   ElInput,
-  ElMessage,
   ElCard,
   ElTree,
   ElTreeSelect,
@@ -14,7 +13,6 @@ import {
   ElUpload,
   ElSwitch,
   ElCheckbox,
-  ElMessageBox,
   UploadInstance,
   UploadRawFile
 } from 'element-plus'
@@ -32,6 +30,8 @@ import * as UserApi from '@/api/system/user'
 import download from '@/utils/download'
 import { CommonStatusEnum } from '@/utils/constants'
 import { getAccessToken, getTenantId } from '@/utils/auth'
+import { useMessage } from '@/hooks/web/useMessage'
+const message = useMessage()
 interface Tree {
   id: number
   name: string
@@ -127,10 +127,10 @@ const submitForm = async () => {
     data.postIds = postIds.value
     if (actionType.value === 'create') {
       await UserApi.createUserApi(data)
-      ElMessage.success(t('common.createSuccess'))
+      message.success(t('common.createSuccess'))
     } else {
       await UserApi.updateUserApi(data)
-      ElMessage.success(t('common.updateSuccess'))
+      message.success(t('common.updateSuccess'))
     }
     // 操作成功,重新加载列表
     dialogVisible.value = false
@@ -142,16 +142,13 @@ const submitForm = async () => {
 // 改变用户状态操作
 const handleStatusChange = async (row: UserVO) => {
   const text = row.status === CommonStatusEnum.ENABLE ? '启用' : '停用'
-  ElMessageBox.confirm('确认要"' + text + '""' + row.username + '"用户吗?', t('common.reminder'), {
-    confirmButtonText: t('common.ok'),
-    cancelButtonText: t('common.cancel'),
-    type: 'warning'
-  })
+  message
+    .confirm('确认要"' + text + '""' + row.username + '"用户吗?', t('common.reminder'))
     .then(async () => {
       row.status =
         row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.ENABLE : CommonStatusEnum.DISABLE
       await UserApi.updateUserStatusApi(row.id, row.status)
-      ElMessage.success(text + '成功')
+      message.success(text + '成功')
       await getList()
     })
     .catch(() => {
@@ -161,12 +158,9 @@ const handleStatusChange = async (row: UserVO) => {
 }
 // 重置密码
 const handleResetPwd = (row: UserVO) => {
-  ElMessageBox.prompt('请输入"' + row.username + '"的新密码', t('common.reminder'), {
-    confirmButtonText: t('common.ok'),
-    cancelButtonText: t('common.cancel')
-  }).then(({ value }) => {
+  message.prompt('请输入"' + row.username + '"的新密码', t('common.reminder')).then(({ value }) => {
     UserApi.resetUserPwdApi(row.id, value).then(() => {
-      ElMessage.success('修改成功,新密码是:' + value)
+      message.success('修改成功,新密码是:' + value)
     })
   })
 }
@@ -207,8 +201,8 @@ const beforeExcelUpload = (file: UploadRawFile) => {
     file.type === 'application/vnd.ms-excel' ||
     file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
   const isLt5M = file.size / 1024 / 1024 < 5
-  if (!isExcel) ElMessage.error('上传文件只能是 xls / xlsx 格式!')
-  if (!isLt5M) ElMessage.error('上传文件大小不能超过 5MB!')
+  if (!isExcel) message.error('上传文件只能是 xls / xlsx 格式!')
+  if (!isLt5M) message.error('上传文件大小不能超过 5MB!')
   return isExcel && isLt5M
 }
 // 文件上传
@@ -224,7 +218,7 @@ const submitFileForm = () => {
 // 文件上传成功
 const handleFileSuccess = (response: any): void => {
   if (response.code !== 0) {
-    ElMessage.error(response.msg)
+    message.error(response.msg)
     return
   }
   importDialogVisible.value = false
@@ -242,15 +236,15 @@ const handleFileSuccess = (response: any): void => {
   for (const username in data.failureUsernames) {
     text += '< ' + username + ': ' + data.failureUsernames[username] + ' >'
   }
-  ElMessageBox.alert(text)
+  message.alert(text)
 }
 // 文件数超出提示
 const handleExceed = (): void => {
-  ElMessage.error('最多只能上传一个文件!')
+  message.error('最多只能上传一个文件!')
 }
 // 上传错误提示
 const excelUploadError = (): void => {
-  ElMessage.error('导入数据失败,请您重新上传!')
+  message.error('导入数据失败,请您重新上传!')
 }
 // ========== 初始化 ==========
 onMounted(async () => {

+ 2 - 2
yudao-ui-admin-vue3/src/views/system/user/user.data.ts

@@ -101,7 +101,7 @@ const crudSchemas = reactive<CrudSchema[]>([
   },
   {
     label: t('common.createTime'),
-    field: 'daterange',
+    field: 'createTime',
     table: {
       show: false
     },
@@ -115,7 +115,7 @@ const crudSchemas = reactive<CrudSchema[]>([
       show: true,
       component: 'DatePicker',
       componentProps: {
-        type: 'daterange',
+        type: 'datetimerange',
         valueFormat: 'YYYY-MM-DD HH:mm:ss'
       }
     }