Browse Source

!238 新增 todo done 页面,优化redis页面
* chore: update deps
* feat: add todo done pages
* chore: update deps
* docs: update
* feat: redis dialog

xingyu 2 years ago
parent
commit
f3e1fc4f9b

+ 1 - 1
README.md

@@ -193,7 +193,7 @@ ps:核心功能已经实现,正在对接微信小程序中...
 |----------------------------------------------------------------------|------------------|--------|
 |----------------------------------------------------------------------|------------------|--------|
 | [Vue](https://staging-cn.vuejs.org/)                                 | Vue 框架           | 3.2.37 |
 | [Vue](https://staging-cn.vuejs.org/)                                 | Vue 框架           | 3.2.37 |
 | [Vite](https://cn.vitejs.dev//)                                      | 开发与构建工具          | 3.0.3  |
 | [Vite](https://cn.vitejs.dev//)                                      | 开发与构建工具          | 3.0.3  |
-| [Element Plus](https://element-plus.org/zh-CN/)                      | Element Plus     | 2.2.9  |
+| [Element Plus](https://element-plus.org/zh-CN/)                      | Element Plus     | 2.2.11 |
 | [TypeScript](https://www.typescriptlang.org/docs/)                   | TypeScript       | 4.7.4  |
 | [TypeScript](https://www.typescriptlang.org/docs/)                   | TypeScript       | 4.7.4  |
 | [pinia](https://pinia.vuejs.org/)                                    | Vue 存储库 替代 vuex5 | 2.0.17 |
 | [pinia](https://pinia.vuejs.org/)                                    | Vue 存储库 替代 vuex5 | 2.0.17 |
 | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化              | 9.1.10 |
 | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化              | 9.1.10 |

+ 24 - 12
yudao-ui-admin-vue3/README.md

@@ -1,5 +1,17 @@
 <h1>🌈 yudao-ui-admin-vue3</h1>
 <h1>🌈 yudao-ui-admin-vue3</h1>
-
+<p align="center">
+    <img src="https://img.shields.io/badge/-Vue3.2-34495e?logo=vue.j" />
+    <img src="https://img.shields.io/badge/-Vite3-646cff?logo=vite&logoColor=white" />
+    <img src="https://img.shields.io/badge/-TypeScript4.7-blue?logo=typescript&logoColor=white" />
+    <img src="https://img.shields.io/badge/-Pinia2-yellow?logo=picpay&logoColor=white" />
+    <img src="https://img.shields.io/badge/-ESLint-4b32c3?logo=eslint&logoColor=white" />
+    <img src="https://img.shields.io/badge/-pnpm7-F69220?logo=pnpm&logoColor=white" />
+    <img src="https://img.shields.io/badge/-Axios-008fc7?logo=axios.js&logoColor=white" />
+    <img src="https://img.shields.io/badge/-Prettier-ef9421?logo=Prettier&logoColor=white" alt="Prettier">
+    <img src="https://img.shields.io/badge/-Less-1D365D?logo=less&logoColor=white" alt="Less">
+    <img src="https://img.shields.io/badge/-Wind%20CSS-06B6D4?logo=Tailwind%20CSS&logoColor=white" alt="Taiwind">
+    <img src="" alt="">
+</p>
 ## 介绍
 ## 介绍
 
 
 - 基于 vue3.2+ ,TypeScript ,Element Plus 2.2.0+ ,Vite3 ,Pinia ,Windicss 等开发的后台管理系统
 - 基于 vue3.2+ ,TypeScript ,Element Plus 2.2.0+ ,Vite3 ,Pinia ,Windicss 等开发的后台管理系统
@@ -12,19 +24,19 @@
 
 
 ### 前端依赖
 ### 前端依赖
 
 
-| 框架 | 说明 | 版本 |
-| --- | --- | --- |
+| 框架 | 说明 | 版本     |
+| --- | --- |--------|
 | [Vue](https://staging-cn.vuejs.org/) | vue 框架 | 3.2.37 |
 | [Vue](https://staging-cn.vuejs.org/) | vue 框架 | 3.2.37 |
-| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 3.0.2 |
-| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.9 |
-| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.7.4 |
-| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.16 |
-| [vueuse](https://vueuse.org//) | 常用工具集 | 8.9.4 |
+| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 3.0.3  |
+| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.11 |
+| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.7.4  |
+| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.17 |
+| [vueuse](https://vueuse.org//) | 常用工具集 | 9.0.0  |
 | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.1.10 |
 | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.1.10 |
-| [vue-router](https://router.vuejs.org/) | vue 路由 | 4.1.2 |
-| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 |
-| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.1 |
-| [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.10 |
+| [vue-router](https://router.vuejs.org/) | vue 路由 | 4.1.3  |
+| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6  |
+| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.1  |
+| [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.14 |
 
 
 ### 推荐 VScode 开发,插件如下
 ### 推荐 VScode 开发,插件如下
 
 

+ 3 - 4
yudao-ui-admin-vue3/package.json

@@ -56,12 +56,12 @@
   "devDependencies": {
   "devDependencies": {
     "@commitlint/cli": "^17.0.3",
     "@commitlint/cli": "^17.0.3",
     "@commitlint/config-conventional": "^17.0.3",
     "@commitlint/config-conventional": "^17.0.3",
-    "@iconify/json": "^2.1.84",
+    "@iconify/json": "^2.1.85",
     "@intlify/vite-plugin-vue-i18n": "^5.0.1",
     "@intlify/vite-plugin-vue-i18n": "^5.0.1",
     "@purge-icons/generated": "^0.8.1",
     "@purge-icons/generated": "^0.8.1",
     "@types/intro.js": "^5.1.0",
     "@types/intro.js": "^5.1.0",
     "@types/lodash-es": "^4.17.6",
     "@types/lodash-es": "^4.17.6",
-    "@types/node": "^18.6.1",
+    "@types/node": "^18.6.2",
     "@types/nprogress": "^0.2.0",
     "@types/nprogress": "^0.2.0",
     "@types/qrcode": "^1.4.2",
     "@types/qrcode": "^1.4.2",
     "@types/qs": "^6.9.7",
     "@types/qs": "^6.9.7",
@@ -101,8 +101,7 @@
     "vite-plugin-svg-icons": "^2.0.1",
     "vite-plugin-svg-icons": "^2.0.1",
     "vite-plugin-windicss": "^1.8.7",
     "vite-plugin-windicss": "^1.8.7",
     "vue-tsc": "^0.39.2",
     "vue-tsc": "^0.39.2",
-    "windicss": "^3.5.6",
-    "windicss-analysis": "^0.3.5"
+    "windicss": "^3.5.6"
   },
   },
   "engines": {
   "engines": {
     "node": ">= 14.18.0"
     "node": ">= 14.18.0"

+ 30 - 0
yudao-ui-admin-vue3/src/api/bpm/task/types.ts

@@ -7,3 +7,33 @@ export type FormVO = {
   remark: string
   remark: string
   createTime: string
   createTime: string
 }
 }
+
+export type TaskProcessVO = {
+  id: string
+  name: string
+  startUserId: number
+  startUserNickname: string
+  processDefinitionId: string
+}
+
+export type TaskTodoVO = {
+  id: string
+  name: string
+  claimTime: string
+  createTime: string
+  suspensionState: number
+  processInstance: TaskProcessVO
+}
+
+export type TaskDoneVO = {
+  id: string
+  name: string
+  claimTime: string
+  createTime: string
+  endTime: string
+  durationInMillis: number
+  suspensionState: number
+  result: number
+  reason: string
+  processInstance: TaskProcessVO
+}

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

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

+ 94 - 0
yudao-ui-admin-vue3/src/views/bpm/task/done/done.data.ts

@@ -0,0 +1,94 @@
+import { reactive } from 'vue'
+import { useI18n } from '@/hooks/web/useI18n'
+import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
+import { DICT_TYPE } from '@/utils/dict'
+const { t } = useI18n() // 国际化
+
+// CrudSchema
+const crudSchemas = reactive<CrudSchema[]>([
+  {
+    label: t('common.index'),
+    field: 'id',
+    type: 'index'
+  },
+  {
+    label: '任务名称',
+    field: 'name',
+    search: {
+      show: true
+    }
+  },
+  {
+    label: '所属流程',
+    field: 'processInstance.name'
+  },
+  {
+    label: '流程发起人',
+    field: 'processInstance.startUserNickname'
+  },
+  {
+    label: '结果',
+    field: 'result',
+    dictType: DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT
+  },
+  {
+    label: '审批意见',
+    field: 'reason'
+  },
+  {
+    label: t('common.createTime'),
+    field: 'createTime',
+    search: {
+      show: true,
+      component: 'DatePicker',
+      componentProps: {
+        type: 'datetimerange',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss',
+        defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)],
+        shortcuts: [
+          {
+            text: '近一周',
+            value: () => {
+              const end = new Date()
+              const start = new Date()
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
+              return [start, end]
+            }
+          },
+          {
+            text: '近一个月',
+            value: () => {
+              const end = new Date()
+              const start = new Date()
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
+              return [start, end]
+            }
+          },
+          {
+            text: '近三个月',
+            value: () => {
+              const end = new Date()
+              const start = new Date()
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
+              return [start, end]
+            }
+          }
+        ]
+      }
+    }
+  },
+  {
+    label: '审批时间',
+    field: 'endTime'
+  },
+  {
+    label: '耗时',
+    field: 'durationInMillis'
+  },
+  {
+    label: t('table.action'),
+    field: 'action',
+    width: '100px'
+  }
+])
+export const { allSchemas } = useCrudSchemas(crudSchemas)

+ 64 - 4
yudao-ui-admin-vue3/src/views/bpm/task/done/index.vue

@@ -1,7 +1,67 @@
-<script setup lang="ts"></script>
+<script setup lang="ts">
+import dayjs from 'dayjs'
+import duration from 'dayjs/plugin/duration'
+import { DICT_TYPE } from '@/utils/dict'
+import { useTable } from '@/hooks/web/useTable'
+import { useI18n } from '@/hooks/web/useI18n'
+import type { TaskDoneVO } from '@/api/bpm/task/types'
+import { allSchemas } from './done.data'
+import * as TaskDoneApi from '@/api/bpm/task'
+import { useRouter } from 'vue-router'
+dayjs.extend(duration)
+const { t } = useI18n() // 国际化
+const { push } = useRouter()
+// ========== 列表相关 ==========
+const { register, tableObject, methods } = useTable<TaskDoneVO>({
+  getListApi: TaskDoneApi.getDoneTaskPage
+})
+const { getList, setSearchParams } = methods
+
+// 审批操作
+const handleAudit = async (row: TaskDoneVO) => {
+  push('/bpm/process-instance/detail?id=' + row.processInstance.id)
+}
+
+// ========== 初始化 ==========
+getList()
+</script>
 
 
 <template>
 <template>
-  <div>index</div>
+  <!-- 搜索工作区 -->
+  <ContentWrap>
+    <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
+  </ContentWrap>
+  <ContentWrap>
+    <!-- 列表 -->
+    <Table
+      :columns="allSchemas.tableColumns"
+      :selection="false"
+      :data="tableObject.tableList"
+      :loading="tableObject.loading"
+      :pagination="{
+        total: tableObject.total
+      }"
+      v-model:pageSize="tableObject.pageSize"
+      v-model:currentPage="tableObject.currentPage"
+      @register="register"
+    >
+      <template #status="{ row }">
+        <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
+      </template>
+      <template #createTime="{ row }">
+        <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
+      </template>
+      <template #endTime="{ row }">
+        <span>{{ dayjs(row.endTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
+      </template>
+      <template #durationInMillis="{ row }">
+        <span>{{ dayjs.duration(row.durationInMillis).asMilliseconds() }}</span>
+      </template>
+      <template #action="{ row }">
+        <el-button link type="primary" v-hasPermi="['bpm:task:query']" @click="handleAudit(row)">
+          <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
+        </el-button>
+      </template>
+    </Table>
+  </ContentWrap>
 </template>
 </template>
-
-<style scoped></style>

+ 76 - 0
yudao-ui-admin-vue3/src/views/bpm/task/todo/done.data.ts

@@ -0,0 +1,76 @@
+import { reactive } from 'vue'
+import { useI18n } from '@/hooks/web/useI18n'
+import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
+const { t } = useI18n() // 国际化
+
+// CrudSchema
+const crudSchemas = reactive<CrudSchema[]>([
+  {
+    label: t('common.index'),
+    field: 'id',
+    type: 'index'
+  },
+  {
+    label: '任务名称',
+    field: 'name',
+    search: {
+      show: true
+    }
+  },
+  {
+    label: '所属流程',
+    field: 'processInstance.name'
+  },
+  {
+    label: '流程发起人',
+    field: 'processInstance.startUserNickname'
+  },
+  {
+    label: t('common.createTime'),
+    field: 'createTime',
+    search: {
+      show: true,
+      component: 'DatePicker',
+      componentProps: {
+        type: 'datetimerange',
+        valueFormat: 'YYYY-MM-DD HH:mm:ss',
+        defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)],
+        shortcuts: [
+          {
+            text: '近一周',
+            value: () => {
+              const end = new Date()
+              const start = new Date()
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
+              return [start, end]
+            }
+          },
+          {
+            text: '近一个月',
+            value: () => {
+              const end = new Date()
+              const start = new Date()
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
+              return [start, end]
+            }
+          },
+          {
+            text: '近三个月',
+            value: () => {
+              const end = new Date()
+              const start = new Date()
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
+              return [start, end]
+            }
+          }
+        ]
+      }
+    }
+  },
+  {
+    label: t('table.action'),
+    field: 'action',
+    width: '100px'
+  }
+])
+export const { allSchemas } = useCrudSchemas(crudSchemas)

+ 54 - 4
yudao-ui-admin-vue3/src/views/bpm/task/todo/index.vue

@@ -1,7 +1,57 @@
-<script setup lang="ts"></script>
+<script setup lang="ts">
+import dayjs from 'dayjs'
+import { DICT_TYPE } from '@/utils/dict'
+import { useTable } from '@/hooks/web/useTable'
+import type { TaskTodoVO } from '@/api/bpm/task/types'
+import { allSchemas } from './done.data'
+import * as TaskTodoApi from '@/api/bpm/task'
+import { useRouter } from 'vue-router'
+const { push } = useRouter()
+// ========== 列表相关 ==========
+const { register, tableObject, methods } = useTable<TaskTodoVO>({
+  getListApi: TaskTodoApi.getTodoTaskPage
+})
+const { getList, setSearchParams } = methods
+
+// 审批操作
+const handleAudit = async (row: TaskTodoVO) => {
+  push('/bpm/process-instance/detail?id=' + row.processInstance.id)
+}
+
+// ========== 初始化 ==========
+getList()
+</script>
 
 
 <template>
 <template>
-  <div>index</div>
+  <!-- 搜索工作区 -->
+  <ContentWrap>
+    <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
+  </ContentWrap>
+  <ContentWrap>
+    <!-- 列表 -->
+    <Table
+      :columns="allSchemas.tableColumns"
+      :selection="false"
+      :data="tableObject.tableList"
+      :loading="tableObject.loading"
+      :pagination="{
+        total: tableObject.total
+      }"
+      v-model:pageSize="tableObject.pageSize"
+      v-model:currentPage="tableObject.currentPage"
+      @register="register"
+    >
+      <template #status="{ row }">
+        <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
+      </template>
+      <template #createTime="{ row }">
+        <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
+      </template>
+      <template #action="{ row }">
+        <el-button link type="primary" v-hasPermi="['bpm:task:update']" @click="handleAudit(row)">
+          <Icon icon="ep:edit" class="mr-1px" /> 审批
+        </el-button>
+      </template>
+    </Table>
+  </ContentWrap>
 </template>
 </template>
-
-<style scoped></style>

+ 89 - 3
yudao-ui-admin-vue3/src/views/infra/redis/index.vue

@@ -13,7 +13,8 @@ import {
   ElTableColumn,
   ElTableColumn,
   ElScrollbar,
   ElScrollbar,
   ElDescriptions,
   ElDescriptions,
-  ElDescriptionsItem
+  ElDescriptionsItem,
+  ElMessage
 } from 'element-plus'
 } from 'element-plus'
 const cache = ref<RedisMonitorInfoVO>()
 const cache = ref<RedisMonitorInfoVO>()
 const keyListLoad = ref(true)
 const keyListLoad = ref(true)
@@ -121,7 +122,33 @@ const loadEchartOptions = (stats) => {
     ]
     ]
   })
   })
 }
 }
-
+const dialogVisible = ref(false)
+const keyTemplate = ref('')
+const cacheKeys = ref()
+const cacheForm = ref<{
+  key: string
+  value: string
+}>({
+  key: '',
+  value: ''
+})
+const openKeyTemplate = async (row: RedisKeyInfo) => {
+  keyTemplate.value = row.keyTemplate
+  cacheKeys.value = await RedisApi.getKeyListApi(row.keyTemplate)
+  dialogVisible.value = true
+}
+const handleDeleteKey = async (row) => {
+  RedisApi.deleteKeyApi(row)
+  ElMessage.success('删除成功')
+}
+const handleDeleteKeys = async (row) => {
+  RedisApi.deleteKeysApi(row)
+  ElMessage.success('删除成功')
+}
+const handleKeyValue = async (row) => {
+  const res = await RedisApi.getKeyValueApi(row)
+  cacheForm.value = res
+}
 onBeforeMount(() => {
 onBeforeMount(() => {
   readRedisInfo()
   readRedisInfo()
 })
 })
@@ -186,7 +213,12 @@ onBeforeMount(() => {
     <el-row style="margin-top: 10px">
     <el-row style="margin-top: 10px">
       <el-col :span="24" class="card-box" shadow="hover">
       <el-col :span="24" class="card-box" shadow="hover">
         <el-card>
         <el-card>
-          <el-table v-loading="keyListLoad" :data="keyList" row-key="id">
+          <el-table
+            v-loading="keyListLoad"
+            :data="keyList"
+            row-key="id"
+            @row-click="openKeyTemplate"
+          >
             <el-table-column prop="keyTemplate" label="Key 模板" width="200" />
             <el-table-column prop="keyTemplate" label="Key 模板" width="200" />
             <el-table-column prop="keyType" label="Key 类型" width="100" />
             <el-table-column prop="keyType" label="Key 类型" width="100" />
             <el-table-column prop="valueType" label="Value 类型" />
             <el-table-column prop="valueType" label="Value 类型" />
@@ -202,4 +234,58 @@ onBeforeMount(() => {
       </el-col>
       </el-col>
     </el-row>
     </el-row>
   </el-scrollbar>
   </el-scrollbar>
+  <Dialog v-model="dialogVisible" :title="keyTemplate + ' 模板'" width="60%" maxHeight="800px">
+    <el-row>
+      <el-col :span="14" style="margin-top: 10px">
+        <el-card shadow="always">
+          <template #header>
+            <div class="card-header">
+              <span>键名列表</span>
+            </div>
+          </template>
+          <el-table :data="cacheKeys" style="width: 100%" @row-click="handleKeyValue">
+            <el-table-column label="缓存键名" align="center" :show-overflow-tooltip="true">
+              <template #default="{ row }">
+                {{ row }}
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" align="right" width="60">
+              <template #default="{ row }">
+                <el-button link type="primary" @click="handleDeleteKey(row)">
+                  <Icon icon="ep:delete" />
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-card>
+      </el-col>
+      <el-col :span="10" style="margin-top: 10px">
+        <el-card shadow="always">
+          <template #header>
+            <div class="card-header">
+              <span>缓存内容</span>
+              <el-button
+                link
+                type="primary"
+                @click="handleDeleteKeys(keyTemplate)"
+                style="float: right; padding: 3px 0"
+              >
+                <Icon icon="ep:refresh" />清理全部
+              </el-button>
+            </div>
+          </template>
+          <el-descriptions :column="1">
+            <el-descriptions-item label="缓存键名:">{{ cacheForm.key }}</el-descriptions-item>
+            <el-descriptions-item label="缓存内容:">{{ cacheForm.value }}</el-descriptions-item>
+          </el-descriptions>
+        </el-card>
+      </el-col>
+    </el-row>
+  </Dialog>
 </template>
 </template>
+<style scoped>
+.redis {
+  height: 600px;
+  max-height: 860px;
+}
+</style>

+ 27 - 21
yudao-ui-admin-vue3/src/views/system/role/index.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
 <script setup lang="ts">
-import { reactive, ref, unref } from 'vue'
+import { onMounted, reactive, ref, unref } from 'vue'
 import dayjs from 'dayjs'
 import dayjs from 'dayjs'
 import { DICT_TYPE, getDictOptions } from '@/utils/dict'
 import { DICT_TYPE, getDictOptions } from '@/utils/dict'
 import { useTable } from '@/hooks/web/useTable'
 import { useTable } from '@/hooks/web/useTable'
@@ -18,7 +18,7 @@ import {
   ElMessage,
   ElMessage,
   ElTree,
   ElTree,
   ElCard,
   ElCard,
-  ElCheckbox
+  ElSwitch
 } from 'element-plus'
 } from 'element-plus'
 import { listSimpleMenusApi } from '@/api/system/menu'
 import { listSimpleMenusApi } from '@/api/system/menu'
 import { listSimpleDeptApi } from '@/api/system/dept'
 import { listSimpleDeptApi } from '@/api/system/dept'
@@ -98,7 +98,6 @@ const dataScopeForm = reactive({
   name: '',
   name: '',
   code: '',
   code: '',
   dataScope: 0,
   dataScope: 0,
-  checkStrictly: true,
   checkList: []
   checkList: []
 })
 })
 const defaultProps = {
 const defaultProps = {
@@ -113,15 +112,18 @@ const dialogScopeTitle = ref('数据权限')
 const actionScopeType = ref('')
 const actionScopeType = ref('')
 const dataScopeDictDatas = ref()
 const dataScopeDictDatas = ref()
 // 选项
 // 选项
+const checkStrictly = ref(true)
 const treeNodeAll = ref(false)
 const treeNodeAll = ref(false)
 // 权限操作
 // 权限操作
 const handleScope = async (type: string, row: RoleVO) => {
 const handleScope = async (type: string, row: RoleVO) => {
+  checkStrictly.value = true
+  treeNodeAll.value = false
+  dataScopeForm.dataScope = 0
   dataScopeForm.name = row.name
   dataScopeForm.name = row.name
   dataScopeForm.code = row.code
   dataScopeForm.code = row.code
   if (type === 'menu') {
   if (type === 'menu') {
     const menuRes = await listSimpleMenusApi()
     const menuRes = await listSimpleMenusApi()
     treeOptions.value = handleTree(menuRes)
     treeOptions.value = handleTree(menuRes)
-    dataScopeDictDatas.value = getDictOptions(DICT_TYPE.SYSTEM_DATA_SCOPE)
   } else if (type === 'dept') {
   } else if (type === 'dept') {
     const deptRes = await listSimpleDeptApi()
     const deptRes = await listSimpleDeptApi()
     treeOptions.value = handleTree(deptRes)
     treeOptions.value = handleTree(deptRes)
@@ -129,20 +131,22 @@ const handleScope = async (type: string, row: RoleVO) => {
   actionScopeType.value = type
   actionScopeType.value = type
   dialogScopeVisible.value = true
   dialogScopeVisible.value = true
 }
 }
-// 树权限(父子联动)
-const handleCheckedTreeConnect = (value) => {
-  dataScopeForm.checkStrictly = value ? true : false
-}
 // 全选/全不选
 // 全选/全不选
-const handleCheckedTreeNodeAll = (value) => {
-  treeRef.value?.setCheckedNodes(value ? dataScopeForm.checkList : [])
+const handleCheckedTreeNodeAll = () => {
+  treeRef.value?.setCheckedNodes(treeNodeAll.value ? treeOptions.value : [])
 }
 }
 // TODO:保存
 // TODO:保存
 const submitScope = () => {
 const submitScope = () => {
   console.info()
   console.info()
 }
 }
+const init = () => {
+  dataScopeDictDatas.value = getDictOptions(DICT_TYPE.SYSTEM_DATA_SCOPE)
+}
 // ========== 初始化 ==========
 // ========== 初始化 ==========
-getList()
+onMounted(() => {
+  getList()
+  init()
+})
 </script>
 </script>
 
 
 <template>
 <template>
@@ -261,7 +265,7 @@ getList()
       <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
       <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
     </template>
     </template>
   </Dialog>
   </Dialog>
-  <Dialog v-model="dialogScopeVisible" :title="dialogScopeTitle">
+  <Dialog v-model="dialogScopeVisible" :title="dialogScopeTitle" max-height="600px">
     <el-form :model="dataScopeForm">
     <el-form :model="dataScopeForm">
       <el-form-item label="角色名称">
       <el-form-item label="角色名称">
         <el-input v-model="dataScopeForm.name" :disabled="true" />
         <el-input v-model="dataScopeForm.name" :disabled="true" />
@@ -289,21 +293,23 @@ getList()
       >
       >
         <el-card class="box-card">
         <el-card class="box-card">
           <template #header>
           <template #header>
-            <el-checkbox
-              :checked="!dataScopeForm.checkStrictly"
-              @change="handleCheckedTreeConnect($event)"
-              >父子联动(选中父节点,自动选择子节点)
-            </el-checkbox>
-            <el-checkbox v-model="treeNodeAll" @change="handleCheckedTreeNodeAll($event)">
-              全选/全不选
-            </el-checkbox>
+            父子联动(选中父节点,自动选择子节点):
+            <el-switch v-model="checkStrictly" inline-prompt active-text="是" inactive-text="否" />
+            全选/全不选:
+            <el-switch
+              v-model="treeNodeAll"
+              inline-prompt
+              active-text="是"
+              inactive-text="否"
+              @change="handleCheckedTreeNodeAll()"
+            />
           </template>
           </template>
           <el-tree
           <el-tree
             ref="treeRef"
             ref="treeRef"
             node-key="id"
             node-key="id"
             show-checkbox
             show-checkbox
             default-expand-all
             default-expand-all
-            :check-strictly="dataScopeForm.checkStrictly"
+            :check-strictly="!checkStrictly"
             :props="defaultProps"
             :props="defaultProps"
             :data="treeOptions"
             :data="treeOptions"
             empty-text="加载中,请稍后"
             empty-text="加载中,请稍后"

+ 1 - 16
yudao-ui-admin-vue3/windi.config.ts

@@ -1,4 +1,4 @@
-import { defineConfig } from 'windicss/helpers'
+import { defineConfig } from 'vite-plugin-windicss'
 import plugin from 'windicss/plugin'
 import plugin from 'windicss/plugin'
 
 
 function range(size, startAt = 1) {
 function range(size, startAt = 1) {
@@ -18,22 +18,7 @@ export default defineConfig({
         // 暗黑背景色
         // 暗黑背景色
         'v-dark': 'var(--dark-bg-color)'
         'v-dark': 'var(--dark-bg-color)'
       }
       }
-      // screens: {
-      //   sm: '768px',
-      //   md: '992px',
-      //   lg: '1200px',
-      //   xl: '1920px'
-      // }
     }
     }
-    // height: {
-    //   ...range(50).map((i) => `h-${i}px`)
-    // },
-    // margin: {
-    //   // ...range(50).map((i) => `mt-${i}px`),
-    //   // ...range(50).map((i) => `mr-${i}px`),
-    //   // ...range(50).map((i) => `mb-${i}px`),
-    //   // ...range(50).map((i) => `ml-${i}px`)
-    // }
   },
   },
   plugins: [
   plugins: [
     plugin(({ addComponents }) => {
     plugin(({ addComponents }) => {