Merge branch 'master' of https://gitee.com/yudaocode/yudao-ui-admin-vue3 into feature/bpm
This commit is contained in:
@@ -88,6 +88,9 @@
|
||||
/>
|
||||
</el-tooltip>
|
||||
<el-image v-if="row.icon" :src="row.icon" class="h-38px w-38px mr-10px rounded" />
|
||||
<div v-else class="flow-icon">
|
||||
<span style="font-size: 12px; color: #fff">{{ sliceName(row.name,0,2) }}</span>
|
||||
</div>
|
||||
{{ row.name }}
|
||||
</div>
|
||||
</template>
|
||||
@@ -249,6 +252,11 @@
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
|
||||
<!-- 弹窗:表单详情 -->
|
||||
<Dialog title="表单详情" :fullscreen="true" v-model="formDetailVisible">
|
||||
<form-create :rule="formDetailPreview.rule" :option="formDetailPreview.option" />
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -265,6 +273,7 @@ import { useAppStore } from '@/store/modules/app'
|
||||
import { cloneDeep, isEqual } from 'lodash-es'
|
||||
import { useTagsView } from '@/hooks/web/useTagsView'
|
||||
import { useDebounceFn } from '@vueuse/core'
|
||||
import { sliceName } from '@/utils/index'
|
||||
|
||||
defineOptions({ name: 'BpmModel' })
|
||||
|
||||
@@ -437,11 +446,10 @@ const handleChangeState = async (row: any) => {
|
||||
/** 发布流程 */
|
||||
const handleDeploy = async (row: any) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.confirm('是否部署该流程!!')
|
||||
await message.confirm('是否确认发布该流程?')
|
||||
// 发起部署
|
||||
await ModelApi.deployModel(row.id)
|
||||
message.success(t('部署成功'))
|
||||
message.success(t('发布成功'))
|
||||
// 刷新列表
|
||||
emit('success')
|
||||
} catch {}
|
||||
@@ -464,7 +472,7 @@ const formDetailPreview = ref({
|
||||
option: {}
|
||||
})
|
||||
const handleFormDetail = async (row: any) => {
|
||||
if (row.formType == 10) {
|
||||
if (row.formType == BpmModelFormType.NORMAL) {
|
||||
// 设置表单
|
||||
const data = await FormApi.getForm(row.formId)
|
||||
setConfAndFields2(formDetailPreview, data.conf, data.fields)
|
||||
@@ -617,6 +625,17 @@ watchEffect(() => {
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.flow-icon {
|
||||
display: flex;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
margin-right: 10px;
|
||||
background-color: var(--el-color-primary);
|
||||
border-radius: 0.25rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.category-draggable-model {
|
||||
:deep(.el-table__cell) {
|
||||
overflow: hidden;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
class="!w-440px"
|
||||
v-model="modelData.key"
|
||||
:disabled="!!modelData.id"
|
||||
placeholder="请输入流标标识"
|
||||
placeholder="请输入流程标识,以字母或下划线开头"
|
||||
/>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
@@ -41,7 +41,7 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="流程图标" prop="icon" class="mb-20px">
|
||||
<el-form-item label="流程图标" class="mb-20px">
|
||||
<UploadImg v-model="modelData.icon" :limit="1" height="64px" width="64px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程描述" prop="description" class="mb-20px">
|
||||
@@ -155,7 +155,6 @@ const rules = {
|
||||
name: [{ required: true, message: '流程名称不能为空', trigger: 'blur' }],
|
||||
key: [{ required: true, message: '流程标识不能为空', trigger: 'blur' }],
|
||||
category: [{ required: true, message: '流程分类不能为空', trigger: 'blur' }],
|
||||
icon: [{ required: true, message: '流程图标不能为空', trigger: 'blur' }],
|
||||
type: [{ required: true, message: '是否可见不能为空', trigger: 'blur' }],
|
||||
visible: [{ required: true, message: '是否可见不能为空', trigger: 'blur' }],
|
||||
managerUserIds: [{ required: true, message: '流程管理员不能为空', trigger: 'blur' }]
|
||||
|
||||
@@ -285,9 +285,8 @@ const handleSave = async () => {
|
||||
} else {
|
||||
// 新增场景
|
||||
formData.value.id = await ModelApi.createModel(modelData)
|
||||
message.success('新增成功')
|
||||
try {
|
||||
await message.confirm('创建流程成功,是否继续编辑?')
|
||||
await message.confirm('流程创建成功,是否继续编辑?')
|
||||
// 用户点击继续编辑,跳转到编辑页面
|
||||
await nextTick()
|
||||
// 先删除当前页签
|
||||
@@ -317,7 +316,6 @@ const handleDeploy = async () => {
|
||||
if (!formData.value.id) {
|
||||
await message.confirm('是否确认发布该流程?')
|
||||
}
|
||||
|
||||
// 校验所有步骤
|
||||
await validateAllSteps()
|
||||
|
||||
|
||||
@@ -58,7 +58,16 @@
|
||||
>
|
||||
<template #default>
|
||||
<div class="flex">
|
||||
<el-image :src="definition.icon" class="w-32px h-32px" />
|
||||
<el-image
|
||||
v-if="definition.icon"
|
||||
:src="definition.icon"
|
||||
class="w-32px h-32px"
|
||||
/>
|
||||
<div v-else class="flow-icon">
|
||||
<span style="font-size: 12px; color: #fff">{{
|
||||
sliceName(definition.name,0,2)
|
||||
}}</span>
|
||||
</div>
|
||||
<el-text class="!ml-10px" size="large">{{ definition.name }}</el-text>
|
||||
</div>
|
||||
</template>
|
||||
@@ -88,6 +97,7 @@ import * as ProcessInstanceApi from '@/api/bpm/processInstance'
|
||||
import { CategoryApi, CategoryVO } from '@/api/bpm/category'
|
||||
import ProcessDefinitionDetail from './ProcessDefinitionDetail.vue'
|
||||
import { groupBy } from 'lodash-es'
|
||||
import { sliceName } from '@/utils/index'
|
||||
|
||||
defineOptions({ name: 'BpmProcessInstanceCreate' })
|
||||
|
||||
@@ -282,13 +292,25 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.flow-icon {
|
||||
display: flex;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-right: 10px;
|
||||
background-color: var(--el-color-primary);
|
||||
border-radius: 0.25rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.process-definition-container::before {
|
||||
content: '';
|
||||
border-left: 1px solid #e6e6e6;
|
||||
position: absolute;
|
||||
left: 20.8%;
|
||||
height: 100%;
|
||||
border-left: 1px solid #e6e6e6;
|
||||
content: '';
|
||||
}
|
||||
|
||||
:deep() {
|
||||
.definition-item-card {
|
||||
.el-card__body {
|
||||
|
||||
@@ -66,7 +66,11 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="产品单价" fixed="right" min-width="120">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.productPrice`" class="mb-0px!">
|
||||
<el-form-item
|
||||
:prop="`${$index}.productPrice`"
|
||||
:rules="formRules.productPrice"
|
||||
class="mb-0px!"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="row.productPrice"
|
||||
controls-position="right"
|
||||
@@ -153,6 +157,7 @@ const formLoading = ref(false) // 表单的加载中
|
||||
const formData = ref([])
|
||||
const formRules = reactive({
|
||||
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
|
||||
productPrice: [{ required: true, message: '产品单价不能为空', trigger: 'blur' }],
|
||||
count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref([]) // 表单 Ref
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<el-descriptions-item label="任务名称">
|
||||
{{ detailData.name }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="任务名称">
|
||||
<el-descriptions-item label="任务状态">
|
||||
<dict-tag :type="DICT_TYPE.INFRA_JOB_STATUS" :value="detailData.status" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="处理器的名字">
|
||||
|
||||
@@ -52,7 +52,9 @@ const formLoading = ref(false) // 表单的加载中:1)修改时的数据加
|
||||
const formData = ref<DiyTemplateApi.DiyTemplatePropertyVO>()
|
||||
const formRef = ref() // 表单 Ref
|
||||
// 当前编辑的属性
|
||||
const currentFormData = ref<DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO>()
|
||||
const currentFormData = ref<DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO>({
|
||||
property: ''
|
||||
} as DiyPageApi.DiyPageVO)
|
||||
// templateItem 对应的缓存
|
||||
const currentFormDataMap = ref<
|
||||
Map<string, DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO>
|
||||
@@ -92,17 +94,21 @@ const handleTemplateItemChange = (val: number) => {
|
||||
// 编辑模板
|
||||
if (val === 0) {
|
||||
libs.value = templateLibs
|
||||
currentFormData.value = isEmpty(data) ? formData.value : data
|
||||
currentFormData.value = (isEmpty(data) ? formData.value : data) as
|
||||
| DiyTemplateApi.DiyTemplatePropertyVO
|
||||
| DiyPageApi.DiyPageVO
|
||||
return
|
||||
}
|
||||
|
||||
// 编辑页面
|
||||
libs.value = PAGE_LIBS
|
||||
currentFormData.value = isEmpty(data)
|
||||
? formData.value!.pages.find(
|
||||
(page: DiyPageApi.DiyPageVO) => page.name === templateItems[val].name
|
||||
)
|
||||
: data
|
||||
currentFormData.value = (
|
||||
isEmpty(data)
|
||||
? formData.value!.pages.find(
|
||||
(page: DiyPageApi.DiyPageVO) => page.name === templateItems[val].name
|
||||
)
|
||||
: data
|
||||
) as DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
@@ -170,7 +176,9 @@ const recoverPageIndex = () => {
|
||||
sessionStorage.removeItem(DIY_PAGE_INDEX_KEY)
|
||||
|
||||
// 重新初始化数据
|
||||
currentFormData.value = formData.value
|
||||
currentFormData.value = formData.value as
|
||||
| DiyTemplateApi.DiyTemplatePropertyVO
|
||||
| DiyPageApi.DiyPageVO
|
||||
currentFormDataMap.value = new Map<
|
||||
string,
|
||||
DiyTemplateApi.DiyTemplatePropertyVO | DiyPageApi.DiyPageVO
|
||||
|
||||
@@ -279,8 +279,9 @@ const handleSendMessage = async (event: any) => {
|
||||
return
|
||||
}
|
||||
// 1. 校验消息是否为空
|
||||
if (isEmpty(unref(message.value))) {
|
||||
if (isEmpty(unref(message.value)?.trim())) {
|
||||
messageTool.notifyWarning('请输入消息后再发送哦!')
|
||||
message.value = ''
|
||||
return
|
||||
}
|
||||
// 2. 组织发送消息
|
||||
|
||||
@@ -37,40 +37,45 @@ const { data, close, open } = useWebSocket(server.value, {
|
||||
})
|
||||
|
||||
/** 监听 WebSocket 数据 */
|
||||
watchEffect(() => {
|
||||
if (!data.value) {
|
||||
return
|
||||
watch(
|
||||
() => data.value,
|
||||
(newData) => {
|
||||
if (!newData) return
|
||||
try {
|
||||
// 1. 收到心跳
|
||||
if (newData === 'pong') return
|
||||
|
||||
// 2.1 解析 type 消息类型
|
||||
const jsonMessage = JSON.parse(newData)
|
||||
const type = jsonMessage.type
|
||||
if (!type) {
|
||||
message.error('未知的消息类型:' + newData)
|
||||
return
|
||||
}
|
||||
|
||||
// 2.2 消息类型:KEFU_MESSAGE_TYPE
|
||||
if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_TYPE) {
|
||||
const message = JSON.parse(jsonMessage.content)
|
||||
// 刷新会话列表
|
||||
kefuStore.updateConversation(message.conversationId)
|
||||
// 刷新消息列表
|
||||
keFuChatBoxRef.value?.refreshMessageList(message)
|
||||
return
|
||||
}
|
||||
|
||||
// 2.3 消息类型:KEFU_MESSAGE_ADMIN_READ
|
||||
if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_ADMIN_READ) {
|
||||
// 更新会话已读
|
||||
kefuStore.updateConversationStatus(jsonParse(jsonMessage.content))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: false // 不立即执行
|
||||
}
|
||||
try {
|
||||
// 1. 收到心跳
|
||||
if (data.value === 'pong') {
|
||||
return
|
||||
}
|
||||
// 2.1 解析 type 消息类型
|
||||
const jsonMessage = JSON.parse(data.value)
|
||||
const type = jsonMessage.type
|
||||
if (!type) {
|
||||
message.error('未知的消息类型:' + data.value)
|
||||
return
|
||||
}
|
||||
// 2.2 消息类型:KEFU_MESSAGE_TYPE
|
||||
if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_TYPE) {
|
||||
const message = JSON.parse(jsonMessage.content)
|
||||
// 刷新会话列表
|
||||
kefuStore.updateConversation(message.conversationId)
|
||||
// 刷新消息列表
|
||||
keFuChatBoxRef.value?.refreshMessageList(message)
|
||||
return
|
||||
}
|
||||
// 2.3 消息类型:KEFU_MESSAGE_ADMIN_READ
|
||||
if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_ADMIN_READ) {
|
||||
// 更新会话已读
|
||||
kefuStore.updateConversationStatus(jsonParse(jsonMessage.content))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
})
|
||||
)
|
||||
// ======================= WebSocket end =======================
|
||||
|
||||
/** 加载指定会话的消息列表 */
|
||||
|
||||
@@ -26,9 +26,23 @@
|
||||
placeholder="请输入微信 APPID"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label-width="180px">
|
||||
<a
|
||||
href="https://pay.weixin.qq.com/index.php/extend/merchant_appid/mapay_platform/account_manage"
|
||||
target="_blank"
|
||||
>
|
||||
前往微信商户平台查看 APPID
|
||||
</a>
|
||||
</el-form-item>
|
||||
<el-form-item label="商户号" label-width="180px" prop="config.mchId">
|
||||
<el-input v-model="formData.config.mchId" :style="{ width: '100%' }" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label-width="180px">
|
||||
<a href="https://pay.weixin.qq.com/index.php/extend/pay_setting" target="_blank">
|
||||
前往微信商户平台查看商户号
|
||||
</a>
|
||||
</el-form-item>
|
||||
<el-form-item label="渠道状态" label-width="180px" prop="status">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio
|
||||
@@ -123,6 +137,14 @@
|
||||
placeholder="请输入证书序列号"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label-width="180px">
|
||||
<a
|
||||
href="https://pay.weixin.qq.com/index.php/core/cert/api_cert#/api-cert-manage"
|
||||
target="_blank"
|
||||
>
|
||||
前往微信商户平台查看证书序列号
|
||||
</a>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="备注" label-width="180px" prop="remark">
|
||||
<el-input v-model="formData.remark" :style="{ width: '100%' }" />
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
<Icon class="mr-5px" icon="ep:plus" />
|
||||
新增
|
||||
</el-button>
|
||||
<el-button plain type="danger" @click="toggleExpandAll">
|
||||
<Icon class="mr-5px" icon="ep:sort" />
|
||||
展开/折叠
|
||||
</el-button>
|
||||
<el-button plain @click="refreshMenu">
|
||||
<Icon class="mr-5px" icon="ep:refresh" />
|
||||
刷新菜单缓存
|
||||
@@ -63,149 +67,169 @@
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<div style="height: 700px">
|
||||
<!-- AutoResizer 自动调节大小 -->
|
||||
<el-auto-resizer>
|
||||
<template #default="{ height, width }">
|
||||
<!-- Virtualized Table 虚拟化表格:高性能,解决表格在大数据量下的卡顿问题 -->
|
||||
<el-table-v2
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="list"
|
||||
:width="width"
|
||||
:height="height"
|
||||
expand-column-key="name"
|
||||
/>
|
||||
</template>
|
||||
</el-auto-resizer>
|
||||
</div>
|
||||
<el-auto-resizer>
|
||||
<template #default="{ width }">
|
||||
<el-table-v2
|
||||
v-model:expanded-row-keys="expandedRowKeys"
|
||||
:columns="columns"
|
||||
:data="list"
|
||||
:expand-column-key="columns[0].key"
|
||||
:height="1000"
|
||||
:width="width"
|
||||
fixed
|
||||
row-key="id"
|
||||
/>
|
||||
</template>
|
||||
</el-auto-resizer>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<MenuForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
<script lang="tsx" setup>
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { handleTree } from '@/utils/tree'
|
||||
import * as MenuApi from '@/api/system/menu'
|
||||
import { MenuVO } from '@/api/system/menu'
|
||||
import MenuForm from './MenuForm.vue'
|
||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
||||
import { h } from 'vue'
|
||||
import { Column, ElButton } from 'element-plus'
|
||||
import DictTag from '@/components/DictTag/src/DictTag.vue'
|
||||
import { Icon } from '@/components/Icon'
|
||||
import { hasPermission } from '@/directives/permission/hasPermi'
|
||||
import { ElButton, TableV2FixedDir } from 'element-plus'
|
||||
import { checkPermi } from '@/utils/permission'
|
||||
import { CommonStatusEnum } from '@/utils/constants'
|
||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
||||
|
||||
defineOptions({ name: 'SystemMenu' })
|
||||
|
||||
// 虚拟列表表格
|
||||
const columns = [
|
||||
{
|
||||
key: 'name',
|
||||
title: '菜单名称',
|
||||
dataKey: 'name',
|
||||
width: 250,
|
||||
fixed: TableV2FixedDir.LEFT
|
||||
},
|
||||
{
|
||||
key: 'icon',
|
||||
title: '图标',
|
||||
dataKey: 'icon',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
cellRenderer: ({ cellData: icon }) => <Icon icon={icon} />
|
||||
},
|
||||
{
|
||||
key: 'sort',
|
||||
title: '排序',
|
||||
dataKey: 'sort',
|
||||
width: 60
|
||||
},
|
||||
{
|
||||
key: 'permission',
|
||||
title: '权限标识',
|
||||
dataKey: 'permission',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
key: 'component',
|
||||
title: '组件路径',
|
||||
dataKey: 'component',
|
||||
width: 500
|
||||
},
|
||||
{
|
||||
key: 'componentName',
|
||||
title: '组件名称',
|
||||
dataKey: 'componentName',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
key: 'status',
|
||||
title: '状态',
|
||||
dataKey: 'status',
|
||||
width: 60,
|
||||
fixed: TableV2FixedDir.RIGHT,
|
||||
cellRenderer: ({ rowData }) => {
|
||||
// 检查权限
|
||||
if (!checkPermi(['system:menu:update'])) {
|
||||
return <DictTag type={DICT_TYPE.COMMON_STATUS} value={rowData.status} />
|
||||
}
|
||||
|
||||
// 如果有权限,渲染 ElSwitch
|
||||
return (
|
||||
<ElSwitch
|
||||
v-model={rowData.status}
|
||||
active-value={CommonStatusEnum.ENABLE}
|
||||
inactive-value={CommonStatusEnum.DISABLE}
|
||||
loading={menuStatusUpdating[rowData.id]}
|
||||
class="ml-4px"
|
||||
onChange={(val) => handleStatusChanged(rowData, val)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'operations',
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
width: 160,
|
||||
fixed: TableV2FixedDir.RIGHT,
|
||||
cellRenderer: ({ rowData }) => {
|
||||
// 定义按钮列表
|
||||
const buttons = []
|
||||
|
||||
// 检查权限并添加按钮
|
||||
if (checkPermi(['system:menu:update'])) {
|
||||
buttons.push(
|
||||
<ElButton key="edit" link type="primary" onClick={() => openForm('update', rowData.id)}>
|
||||
修改
|
||||
</ElButton>
|
||||
)
|
||||
}
|
||||
if (checkPermi(['system:menu:create'])) {
|
||||
buttons.push(
|
||||
<ElButton
|
||||
key="create"
|
||||
link
|
||||
type="primary"
|
||||
onClick={() => openForm('create', undefined, rowData.id)}
|
||||
>
|
||||
新增
|
||||
</ElButton>
|
||||
)
|
||||
}
|
||||
if (checkPermi(['system:menu:delete'])) {
|
||||
buttons.push(
|
||||
<ElButton key="delete" link type="danger" onClick={() => handleDelete(rowData.id)}>
|
||||
删除
|
||||
</ElButton>
|
||||
)
|
||||
}
|
||||
// 如果没有权限,返回 null
|
||||
if (buttons.length === 0) {
|
||||
return null
|
||||
}
|
||||
// 渲染按钮列表
|
||||
return <>{buttons}</>
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const { wsCache } = useCache()
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
// 表格的 column 字段
|
||||
const columns: Column[] = [
|
||||
{
|
||||
dataKey: 'name',
|
||||
title: '菜单名称',
|
||||
width: 250
|
||||
},
|
||||
{
|
||||
dataKey: 'icon',
|
||||
title: '图标',
|
||||
width: 150,
|
||||
cellRenderer: ({ rowData }) => {
|
||||
return h(Icon, {
|
||||
icon: rowData.icon
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
dataKey: 'sort',
|
||||
title: '排序',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
dataKey: 'permission',
|
||||
title: '权限标识',
|
||||
width: 240
|
||||
},
|
||||
{
|
||||
dataKey: 'component',
|
||||
title: '组件路径',
|
||||
width: 240
|
||||
},
|
||||
{
|
||||
dataKey: 'componentName',
|
||||
title: '组件名称',
|
||||
width: 240
|
||||
},
|
||||
{
|
||||
dataKey: 'status',
|
||||
title: '状态',
|
||||
width: 160,
|
||||
cellRenderer: ({ rowData }) => {
|
||||
return h(ElSwitch, {
|
||||
modelValue: rowData.status,
|
||||
activeValue: CommonStatusEnum.ENABLE,
|
||||
inactiveValue: CommonStatusEnum.DISABLE,
|
||||
loading: menuStatusUpdating.value[rowData.id],
|
||||
disabled: !hasPermission(['system:menu:update']),
|
||||
onChange: (val) => handleStatusChanged(rowData, val as number)
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
dataKey: 'operation',
|
||||
title: '操作',
|
||||
width: 200,
|
||||
cellRenderer: ({ rowData }) => {
|
||||
return h(
|
||||
'div',
|
||||
{},
|
||||
[
|
||||
hasPermission(['system:menu:update']) &&
|
||||
h(
|
||||
ElButton,
|
||||
{
|
||||
link: true,
|
||||
type: 'primary',
|
||||
onClick: () => openForm('update', rowData.id)
|
||||
},
|
||||
() => '修改'
|
||||
),
|
||||
hasPermission(['system:menu:create']) &&
|
||||
h(
|
||||
ElButton,
|
||||
{
|
||||
link: true,
|
||||
type: 'primary',
|
||||
onClick: () => openForm('create', undefined, rowData.id)
|
||||
},
|
||||
() => '新增'
|
||||
),
|
||||
hasPermission(['system:menu:delete']) &&
|
||||
h(
|
||||
ElButton,
|
||||
{
|
||||
link: true,
|
||||
type: 'danger',
|
||||
onClick: () => handleDelete(rowData.id)
|
||||
},
|
||||
() => '删除'
|
||||
)
|
||||
].filter(Boolean)
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<any>([]) // 列表的数据
|
||||
const list = ref<any[]>([]) // 列表的数据
|
||||
const queryParams = reactive({
|
||||
name: undefined,
|
||||
status: undefined
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const isExpandAll = ref(false) // 是否展开,默认全部折叠
|
||||
const refreshTable = ref(true) // 重新渲染表格状态
|
||||
|
||||
// 添加展开行控制
|
||||
const expandedRowKeys = ref<number[]>([])
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
@@ -235,6 +259,18 @@ const openForm = (type: string, id?: number, parentId?: number) => {
|
||||
formRef.value.open(type, id, parentId)
|
||||
}
|
||||
|
||||
/** 展开/折叠操作 */
|
||||
const toggleExpandAll = () => {
|
||||
if (!isExpandAll.value) {
|
||||
// 展开所有
|
||||
expandedRowKeys.value = list.value.map((item) => item.id)
|
||||
} else {
|
||||
// 折叠所有
|
||||
expandedRowKeys.value = []
|
||||
}
|
||||
isExpandAll.value = !isExpandAll.value
|
||||
}
|
||||
|
||||
/** 刷新菜单缓存按钮操作 */
|
||||
const refreshMenu = async () => {
|
||||
try {
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
@change="handleStatusChange(scope.row)"
|
||||
:disabled="!checkPermi(['system:user:update'])"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
Reference in New Issue
Block a user