commit
df5e2f48be
@ -12,7 +12,7 @@ import { useAppStore } from '@/store/modules/app'
|
|||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { XTableProps } from './type'
|
import { XTableProps } from './type'
|
||||||
import { isBoolean, isFunction } from '@/utils/is'
|
import { isBoolean, isFunction } from '@/utils/is'
|
||||||
|
import styleCss from './style/dark.scss'
|
||||||
import download from '@/utils/download'
|
import download from '@/utils/download'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@ -25,15 +25,38 @@ const prefixCls = getPrefixCls('x-vxe-table')
|
|||||||
|
|
||||||
const attrs = useAttrs()
|
const attrs = useAttrs()
|
||||||
const emit = defineEmits(['register'])
|
const emit = defineEmits(['register'])
|
||||||
|
const removeStyles = () => {
|
||||||
|
var filename = 'cssTheme'
|
||||||
|
//移除引入的文件名
|
||||||
|
var targetelement = 'style'
|
||||||
|
var targetattr = 'id'
|
||||||
|
var allsuspects = document.getElementsByTagName(targetelement)
|
||||||
|
for (var i = allsuspects.length; i >= 0; i--) {
|
||||||
|
if (
|
||||||
|
allsuspects[i] &&
|
||||||
|
allsuspects[i].getAttribute(targetattr) != null &&
|
||||||
|
allsuspects[i].getAttribute(targetattr)?.indexOf(filename) != -1
|
||||||
|
) {
|
||||||
|
console.log(allsuspects[i], 'node')
|
||||||
|
allsuspects[i].parentNode?.removeChild(allsuspects[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const reImport = () => {
|
||||||
|
var head = document.getElementsByTagName('head')[0]
|
||||||
|
var style = document.createElement('style')
|
||||||
|
style.innerText = styleCss
|
||||||
|
style.id = 'cssTheme'
|
||||||
|
head.appendChild(style)
|
||||||
|
}
|
||||||
watch(
|
watch(
|
||||||
() => appStore.getIsDark,
|
() => appStore.getIsDark,
|
||||||
() => {
|
() => {
|
||||||
if (appStore.getIsDark == true) {
|
if (appStore.getIsDark == true) {
|
||||||
import('./style/dark.scss')
|
reImport()
|
||||||
}
|
}
|
||||||
if (appStore.getIsDark == false) {
|
if (appStore.getIsDark == false) {
|
||||||
import('./style/light.scss')
|
removeStyles()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
|
@ -3,9 +3,21 @@
|
|||||||
<!-- 表单设计器 -->
|
<!-- 表单设计器 -->
|
||||||
<fc-designer ref="designer" height="780px">
|
<fc-designer ref="designer" height="780px">
|
||||||
<template #handle>
|
<template #handle>
|
||||||
|
<XButton type="primary" title="生成JSON" @click="showJson" />
|
||||||
|
<XButton type="primary" title="生成Options" @click="showOption" />
|
||||||
<XButton type="primary" :title="t('action.save')" @click="handleSave" />
|
<XButton type="primary" :title="t('action.save')" @click="handleSave" />
|
||||||
</template>
|
</template>
|
||||||
</fc-designer>
|
</fc-designer>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible1" maxHeight="600">
|
||||||
|
<div ref="editor" v-if="dialogVisible1">
|
||||||
|
<XTextButton style="float: right" :title="t('common.copy')" @click="copy(formValue)" />
|
||||||
|
<el-scrollbar height="580">
|
||||||
|
<pre>
|
||||||
|
{{ formValue }}
|
||||||
|
</pre>
|
||||||
|
</el-scrollbar>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
<!-- 表单保存的弹窗 -->
|
<!-- 表单保存的弹窗 -->
|
||||||
<XModal v-model="dialogVisible" title="保存表单">
|
<XModal v-model="dialogVisible" title="保存表单">
|
||||||
<el-form ref="formRef" :model="formValues" :rules="formRules" label-width="80px">
|
<el-form ref="formRef" :model="formValues" :rules="formRules" label-width="80px">
|
||||||
@ -48,13 +60,18 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|||||||
import { CommonStatusEnum } from '@/utils/constants'
|
import { CommonStatusEnum } from '@/utils/constants'
|
||||||
import * as FormApi from '@/api/bpm/form'
|
import * as FormApi from '@/api/bpm/form'
|
||||||
import { encodeConf, encodeFields, setConfAndFields } from '@/utils/formCreate'
|
import { encodeConf, encodeFields, setConfAndFields } from '@/utils/formCreate'
|
||||||
|
import { useClipboard } from '@vueuse/core'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息
|
const message = useMessage() // 消息
|
||||||
const { query } = useRoute() // 路由
|
const { query } = useRoute() // 路由
|
||||||
|
|
||||||
const designer = ref() // 表单设计器
|
const designer = ref() // 表单设计器
|
||||||
|
const type = ref(-1)
|
||||||
|
const formValue = ref('')
|
||||||
|
const dialogTitle = ref('')
|
||||||
const dialogVisible = ref(false) // 弹窗是否展示
|
const dialogVisible = ref(false) // 弹窗是否展示
|
||||||
|
const dialogVisible1 = ref(false) // 弹窗是否展示
|
||||||
const dialogLoading = ref(false) // 弹窗的加载中
|
const dialogLoading = ref(false) // 弹窗的加载中
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
@ -98,7 +115,32 @@ const submitForm = async () => {
|
|||||||
dialogLoading.value = false
|
dialogLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const showJson = () => {
|
||||||
|
openModel('生成JSON')
|
||||||
|
type.value = 0
|
||||||
|
formValue.value = designer.value.getRule()
|
||||||
|
}
|
||||||
|
const showOption = () => {
|
||||||
|
openModel('生成Options')
|
||||||
|
type.value = 1
|
||||||
|
formValue.value = designer.value.getOption()
|
||||||
|
}
|
||||||
|
const openModel = (title: string) => {
|
||||||
|
dialogVisible1.value = true
|
||||||
|
dialogTitle.value = title
|
||||||
|
}
|
||||||
|
/** 复制 **/
|
||||||
|
const copy = async (text: string) => {
|
||||||
|
const { copy, copied, isSupported } = useClipboard({ source: text })
|
||||||
|
if (!isSupported) {
|
||||||
|
message.error(t('common.copyError'))
|
||||||
|
} else {
|
||||||
|
await copy()
|
||||||
|
if (unref(copied)) {
|
||||||
|
message.success(t('common.copySuccess'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// ========== 初始化 ==========
|
// ========== 初始化 ==========
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 场景一:新增表单
|
// 场景一:新增表单
|
||||||
|
@ -16,6 +16,7 @@ const crudSchemas = reactive<VxeCrudSchema>({
|
|||||||
primaryType: 'id',
|
primaryType: 'id',
|
||||||
primaryTitle: '编号',
|
primaryTitle: '编号',
|
||||||
action: true,
|
action: true,
|
||||||
|
searchSpan: 8,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
title: '组名',
|
title: '组名',
|
||||||
|
@ -16,6 +16,7 @@ const crudSchemas = reactive<VxeCrudSchema>({
|
|||||||
primaryTitle: '申请编号',
|
primaryTitle: '申请编号',
|
||||||
action: true,
|
action: true,
|
||||||
actionWidth: '260',
|
actionWidth: '260',
|
||||||
|
searchSpan: 8,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
title: t('common.status'),
|
title: t('common.status'),
|
||||||
|
@ -7,6 +7,7 @@ const crudSchemas = reactive<VxeCrudSchema>({
|
|||||||
primaryKey: 'id',
|
primaryKey: 'id',
|
||||||
primaryType: null,
|
primaryType: null,
|
||||||
action: true,
|
action: true,
|
||||||
|
searchSpan: 8,
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
title: '任务编号',
|
title: '任务编号',
|
||||||
|
@ -99,36 +99,41 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 分配角色的菜单权限对话框 -->
|
<!-- 分配角色的菜单权限对话框 -->
|
||||||
<el-form-item
|
<el-row>
|
||||||
label="权限范围"
|
<el-col :span="24">
|
||||||
v-if="
|
<el-form-item
|
||||||
actionScopeType === 'menu' || dataScopeForm.dataScope === SystemDataScopeEnum.DEPT_CUSTOM
|
label="权限范围"
|
||||||
"
|
v-if="
|
||||||
>
|
actionScopeType === 'menu' ||
|
||||||
<el-card shadow="never">
|
dataScopeForm.dataScope === SystemDataScopeEnum.DEPT_CUSTOM
|
||||||
<template #header>
|
"
|
||||||
父子联动(选中父节点,自动选择子节点):
|
style="display: flex"
|
||||||
<el-switch v-model="checkStrictly" inline-prompt active-text="是" inactive-text="否" />
|
>
|
||||||
全选/全不选:
|
<el-card class="card" shadow="never">
|
||||||
<el-switch
|
<template #header>
|
||||||
v-model="treeNodeAll"
|
<!--父子联动(选中父节点,自动选择子节点):-->
|
||||||
inline-prompt
|
<!--<el-switch v-model="checkStrictly" inline-prompt active-text="是" inactive-text="否" />-->
|
||||||
active-text="是"
|
<!--全选/全不选:-->
|
||||||
inactive-text="否"
|
<!--<el-switch-->
|
||||||
@change="handleCheckedTreeNodeAll()"
|
<!-- v-model="treeNodeAll"-->
|
||||||
/>
|
<!-- inline-prompt-->
|
||||||
</template>
|
<!-- active-text="是"-->
|
||||||
<el-tree
|
<!-- inactive-text="否"-->
|
||||||
ref="treeRef"
|
<!-- @change="handleCheckedTreeNodeAll()"-->
|
||||||
node-key="id"
|
<!--/>-->
|
||||||
show-checkbox
|
</template>
|
||||||
:check-strictly="!checkStrictly"
|
<el-tree
|
||||||
:props="defaultProps"
|
ref="treeRef"
|
||||||
:data="treeOptions"
|
node-key="id"
|
||||||
empty-text="加载中,请稍后"
|
show-checkbox
|
||||||
/>
|
:check-strictly="!checkStrictly"
|
||||||
</el-card>
|
:props="defaultProps"
|
||||||
</el-form-item>
|
:data="treeOptions"
|
||||||
|
empty-text="加载中,请稍后"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
</el-form-item> </el-col
|
||||||
|
></el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -245,18 +250,17 @@ const dialogScopeTitle = ref('数据权限')
|
|||||||
const actionScopeType = ref('')
|
const actionScopeType = ref('')
|
||||||
const dataScopeDictDatas = ref()
|
const dataScopeDictDatas = ref()
|
||||||
// 选项
|
// 选项
|
||||||
const checkStrictly = ref(true)
|
const checkStrictly = ref(false)
|
||||||
const treeNodeAll = ref(false)
|
// const treeNodeAll = ref(false)
|
||||||
// 全选/全不选
|
// 全选/全不选
|
||||||
const handleCheckedTreeNodeAll = () => {
|
// const handleCheckedTreeNodeAll = () => {
|
||||||
treeRef.value!.setCheckedNodes(treeNodeAll.value ? treeOptions.value : [])
|
// treeRef.value!.setCheckedNodes(treeNodeAll.value ? treeOptions.value : [])
|
||||||
}
|
// }
|
||||||
// 权限操作
|
// 权限操作
|
||||||
const handleScope = async (type: string, row: RoleApi.RoleVO) => {
|
const handleScope = async (type: string, row: RoleApi.RoleVO) => {
|
||||||
dataScopeForm.id = row.id
|
dataScopeForm.id = row.id
|
||||||
dataScopeForm.name = row.name
|
dataScopeForm.name = row.name
|
||||||
dataScopeForm.code = row.code
|
dataScopeForm.code = row.code
|
||||||
|
|
||||||
actionScopeType.value = type
|
actionScopeType.value = type
|
||||||
dialogScopeVisible.value = true
|
dialogScopeVisible.value = true
|
||||||
if (type === 'menu') {
|
if (type === 'menu') {
|
||||||
@ -265,7 +269,7 @@ const handleScope = async (type: string, row: RoleApi.RoleVO) => {
|
|||||||
const role = await PermissionApi.listRoleMenusApi(row.id)
|
const role = await PermissionApi.listRoleMenusApi(row.id)
|
||||||
if (role) {
|
if (role) {
|
||||||
role?.forEach((item: any) => {
|
role?.forEach((item: any) => {
|
||||||
unref(treeRef)?.setChecked(item, true,false);
|
unref(treeRef)?.setChecked(item, true, false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (type === 'data') {
|
} else if (type === 'data') {
|
||||||
@ -275,11 +279,10 @@ const handleScope = async (type: string, row: RoleApi.RoleVO) => {
|
|||||||
dataScopeForm.dataScope = role.dataScope
|
dataScopeForm.dataScope = role.dataScope
|
||||||
if (role.dataScopeDeptIds) {
|
if (role.dataScopeDeptIds) {
|
||||||
role.dataScopeDeptIds?.forEach((item: any) => {
|
role.dataScopeDeptIds?.forEach((item: any) => {
|
||||||
unref(treeRef)?.setChecked(item, true,false);
|
unref(treeRef)?.setChecked(item, true, false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// 保存权限
|
// 保存权限
|
||||||
const submitScope = async () => {
|
const submitScope = async () => {
|
||||||
@ -314,3 +317,10 @@ onMounted(() => {
|
|||||||
init()
|
init()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.card {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -27,6 +27,24 @@ export const rules = reactive({
|
|||||||
contactMobile: [required],
|
contactMobile: [required],
|
||||||
accountCount: [required],
|
accountCount: [required],
|
||||||
expireTime: [required],
|
expireTime: [required],
|
||||||
|
username: [
|
||||||
|
required,
|
||||||
|
{
|
||||||
|
min: 4,
|
||||||
|
max: 30,
|
||||||
|
trigger: 'blur',
|
||||||
|
message: '用户名称长度为 4-30 个字符'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
required,
|
||||||
|
{
|
||||||
|
min: 4,
|
||||||
|
max: 16,
|
||||||
|
trigger: 'blur',
|
||||||
|
message: '密码长度为 4-16 位'
|
||||||
|
}
|
||||||
|
],
|
||||||
domain: [required],
|
domain: [required],
|
||||||
status: [required]
|
status: [required]
|
||||||
})
|
})
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
ref="formRef"
|
ref="formRef"
|
||||||
>
|
>
|
||||||
<template #menuIds>
|
<template #menuIds>
|
||||||
<el-card class="w-120">
|
<el-card>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
全选/全不选:
|
全选/全不选:
|
||||||
@ -91,6 +91,16 @@ const dialogTitle = ref('edit') // 弹出层标题
|
|||||||
const handleCheckedTreeNodeAll = () => {
|
const handleCheckedTreeNodeAll = () => {
|
||||||
treeRef.value!.setCheckedNodes(treeNodeAll.value ? menuOptions.value : [])
|
treeRef.value!.setCheckedNodes(treeNodeAll.value ? menuOptions.value : [])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const validateCategory = (rule: any, value: any, callback: any) => {
|
||||||
|
if (!treeRef.value!.getCheckedKeys().length) {
|
||||||
|
callback(new Error('该项为必填项'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rules.menuIds = [{ required: true, validator: validateCategory, trigger: 'blur' }]
|
||||||
|
|
||||||
const getTree = async () => {
|
const getTree = async () => {
|
||||||
const res = await listSimpleMenusApi()
|
const res = await listSimpleMenusApi()
|
||||||
menuOptions.value = handleTree(res)
|
menuOptions.value = handleTree(res)
|
||||||
@ -126,7 +136,7 @@ const handleUpdate = async (rowId: number) => {
|
|||||||
unref(formRef)?.setValues(res)
|
unref(formRef)?.setValues(res)
|
||||||
// 设置选中
|
// 设置选中
|
||||||
res.menuIds?.forEach((item: any) => {
|
res.menuIds?.forEach((item: any) => {
|
||||||
unref(treeRef)?.setChecked(item, true,false);
|
unref(treeRef)?.setChecked(item, true, false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,3 +178,10 @@ onMounted(async () => {
|
|||||||
})
|
})
|
||||||
// getList()
|
// getList()
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.el-card {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -33,7 +33,12 @@ const crudSchemas = reactive<VxeCrudSchema>({
|
|||||||
{
|
{
|
||||||
title: '菜单权限',
|
title: '菜单权限',
|
||||||
field: 'menuIds',
|
field: 'menuIds',
|
||||||
isTable: false
|
isTable: false,
|
||||||
|
form: {
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('form.remark'),
|
title: t('form.remark'),
|
||||||
|
@ -159,7 +159,7 @@
|
|||||||
:data="detailData"
|
:data="detailData"
|
||||||
>
|
>
|
||||||
<template #deptId="{ row }">
|
<template #deptId="{ row }">
|
||||||
<span>{{ row.dept?.name }}</span>
|
<el-tag>{{ dataFormater(row.deptId) }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<template #postIds="{ row }">
|
<template #postIds="{ row }">
|
||||||
<template v-if="row.postIds !== ''">
|
<template v-if="row.postIds !== ''">
|
||||||
@ -332,6 +332,28 @@ const getPostOptions = async () => {
|
|||||||
const res = await listSimplePostsApi()
|
const res = await listSimplePostsApi()
|
||||||
postOptions.value.push(...res)
|
postOptions.value.push(...res)
|
||||||
}
|
}
|
||||||
|
const dataFormater = (val) => {
|
||||||
|
return deptFormater(deptOptions.value, val)
|
||||||
|
}
|
||||||
|
//部门回显
|
||||||
|
const deptFormater = (ary, val: any) => {
|
||||||
|
var o = ''
|
||||||
|
if (ary && val) {
|
||||||
|
for (const v of ary) {
|
||||||
|
if (v.id == val) {
|
||||||
|
o = v.name
|
||||||
|
if (o) return o
|
||||||
|
} else if (v.children?.length) {
|
||||||
|
o = deptFormater(v.children, val)
|
||||||
|
if (o) return o
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return o
|
||||||
|
} else {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 设置标题
|
// 设置标题
|
||||||
const setDialogTile = async (type: string) => {
|
const setDialogTile = async (type: string) => {
|
||||||
dialogTitle.value = t('action.' + type)
|
dialogTitle.value = t('action.' + type)
|
||||||
|
Loading…
Reference in New Issue
Block a user