mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-26 09:11:52 +08:00
!238 新增 todo done 页面,优化redis页面
* chore: update deps * feat: add todo done pages * chore: update deps * docs: update * feat: redis dialog
This commit is contained in:
parent
35413b52c9
commit
f3e1fc4f9b
@ -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 |
|
||||||
|
@ -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 等开发的后台管理系统
|
||||||
@ -13,18 +25,18 @@
|
|||||||
### 前端依赖
|
### 前端依赖
|
||||||
|
|
||||||
| 框架 | 说明 | 版本 |
|
| 框架 | 说明 | 版本 |
|
||||||
| --- | --- | --- |
|
| --- | --- |--------|
|
||||||
| [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 |
|
| [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/) | JavaScript 的超集 | 4.7.4 |
|
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.7.4 |
|
||||||
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.16 |
|
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.17 |
|
||||||
| [vueuse](https://vueuse.org//) | 常用工具集 | 8.9.4 |
|
| [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 |
|
| [vue-router](https://router.vuejs.org/) | vue 路由 | 4.1.3 |
|
||||||
| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 |
|
| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 |
|
||||||
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.1 |
|
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.1 |
|
||||||
| [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.10 |
|
| [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.14 |
|
||||||
|
|
||||||
### 推荐 VScode 开发,插件如下
|
### 推荐 VScode 开发,插件如下
|
||||||
|
|
||||||
|
@ -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": "^3.5.6"
|
||||||
"windicss-analysis": "^0.3.5"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 14.18.0"
|
"node": ">= 14.18.0"
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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
yudao-ui-admin-vue3/src/views/bpm/task/done/done.data.ts
Normal file
94
yudao-ui-admin-vue3/src/views/bpm/task/done/done.data.ts
Normal file
@ -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)
|
@ -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
yudao-ui-admin-vue3/src/views/bpm/task/todo/done.data.ts
Normal file
76
yudao-ui-admin-vue3/src/views/bpm/task/todo/done.data.ts
Normal file
@ -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)
|
@ -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>
|
|
||||||
|
@ -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>
|
||||||
|
@ -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) => {
|
const handleCheckedTreeNodeAll = () => {
|
||||||
treeRef.value?.setCheckedNodes(value ? dataScopeForm.checkList : [])
|
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"
|
<el-switch v-model="checkStrictly" inline-prompt active-text="是" inactive-text="否" />
|
||||||
@change="handleCheckedTreeConnect($event)"
|
全选/全不选:
|
||||||
>父子联动(选中父节点,自动选择子节点)
|
<el-switch
|
||||||
</el-checkbox>
|
v-model="treeNodeAll"
|
||||||
<el-checkbox v-model="treeNodeAll" @change="handleCheckedTreeNodeAll($event)">
|
inline-prompt
|
||||||
全选/全不选
|
active-text="是"
|
||||||
</el-checkbox>
|
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,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 }) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user