diff --git a/src/components/XTable/src/XTable.vue b/src/components/XTable/src/XTable.vue index 34f91ce0..e5c503ec 100644 --- a/src/components/XTable/src/XTable.vue +++ b/src/components/XTable/src/XTable.vue @@ -12,7 +12,7 @@ import { useAppStore } from '@/store/modules/app' import { useDesign } from '@/hooks/web/useDesign' import { XTableProps } from './type' import { isBoolean, isFunction } from '@/utils/is' - +import styleCss from './style/dark.scss' import download from '@/utils/download' const { t } = useI18n() @@ -25,15 +25,38 @@ const prefixCls = getPrefixCls('x-vxe-table') const attrs = useAttrs() 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( () => appStore.getIsDark, () => { if (appStore.getIsDark == true) { - import('./style/dark.scss') + reImport() } if (appStore.getIsDark == false) { - import('./style/light.scss') + removeStyles() } }, { immediate: true } diff --git a/src/views/bpm/form/formEditor.vue b/src/views/bpm/form/formEditor.vue index 52b3709d..1070739e 100644 --- a/src/views/bpm/form/formEditor.vue +++ b/src/views/bpm/form/formEditor.vue @@ -3,9 +3,21 @@ <!-- 表单设计器 --> <fc-designer ref="designer" height="780px"> <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" /> </template> </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="保存表单"> <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 * as FormApi from '@/api/bpm/form' import { encodeConf, encodeFields, setConfAndFields } from '@/utils/formCreate' +import { useClipboard } from '@vueuse/core' + const { t } = useI18n() // 国际化 const message = useMessage() // 消息 const { query } = useRoute() // 路由 const designer = ref() // 表单设计器 - +const type = ref(-1) +const formValue = ref('') +const dialogTitle = ref('') const dialogVisible = ref(false) // 弹窗是否展示 +const dialogVisible1 = ref(false) // 弹窗是否展示 const dialogLoading = ref(false) // 弹窗的加载中 const formRef = ref<FormInstance>() const formRules = reactive({ @@ -98,7 +115,32 @@ const submitForm = async () => { 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(() => { // 场景一:新增表单 diff --git a/src/views/bpm/group/group.data.ts b/src/views/bpm/group/group.data.ts index 9d30f3b2..613a7290 100644 --- a/src/views/bpm/group/group.data.ts +++ b/src/views/bpm/group/group.data.ts @@ -16,6 +16,7 @@ const crudSchemas = reactive<VxeCrudSchema>({ primaryType: 'id', primaryTitle: '编号', action: true, + searchSpan: 8, columns: [ { title: '组名', diff --git a/src/views/bpm/oa/leave/leave.data.ts b/src/views/bpm/oa/leave/leave.data.ts index da113baf..5b6f2c52 100644 --- a/src/views/bpm/oa/leave/leave.data.ts +++ b/src/views/bpm/oa/leave/leave.data.ts @@ -16,6 +16,7 @@ const crudSchemas = reactive<VxeCrudSchema>({ primaryTitle: '申请编号', action: true, actionWidth: '260', + searchSpan: 8, columns: [ { title: t('common.status'), diff --git a/src/views/bpm/task/todo/todo.data.ts b/src/views/bpm/task/todo/todo.data.ts index 85c58ce9..419a80fe 100644 --- a/src/views/bpm/task/todo/todo.data.ts +++ b/src/views/bpm/task/todo/todo.data.ts @@ -7,6 +7,7 @@ const crudSchemas = reactive<VxeCrudSchema>({ primaryKey: 'id', primaryType: null, action: true, + searchSpan: 8, columns: [ { title: '任务编号', diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index b2f12af3..97993f5f 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -99,36 +99,41 @@ </el-select> </el-form-item> <!-- 分配角色的菜单权限对话框 --> - <el-form-item - label="权限范围" - v-if=" - actionScopeType === 'menu' || dataScopeForm.dataScope === SystemDataScopeEnum.DEPT_CUSTOM - " - > - <el-card shadow="never"> - <template #header> - 父子联动(选中父节点,自动选择子节点): - <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> - <el-tree - ref="treeRef" - node-key="id" - show-checkbox - :check-strictly="!checkStrictly" - :props="defaultProps" - :data="treeOptions" - empty-text="加载中,请稍后" - /> - </el-card> - </el-form-item> + <el-row> + <el-col :span="24"> + <el-form-item + label="权限范围" + v-if=" + actionScopeType === 'menu' || + dataScopeForm.dataScope === SystemDataScopeEnum.DEPT_CUSTOM + " + style="display: flex" + > + <el-card class="card" shadow="never"> + <template #header> + <!--父子联动(选中父节点,自动选择子节点):--> + <!--<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> + <el-tree + ref="treeRef" + node-key="id" + show-checkbox + :check-strictly="!checkStrictly" + :props="defaultProps" + :data="treeOptions" + empty-text="加载中,请稍后" + /> + </el-card> + </el-form-item> </el-col + ></el-row> </el-form> <!-- 操作按钮 --> <template #footer> @@ -245,18 +250,17 @@ const dialogScopeTitle = ref('数据权限') const actionScopeType = ref('') const dataScopeDictDatas = ref() // 选项 -const checkStrictly = ref(true) -const treeNodeAll = ref(false) +const checkStrictly = ref(false) +// const treeNodeAll = ref(false) // 全选/全不选 -const handleCheckedTreeNodeAll = () => { - treeRef.value!.setCheckedNodes(treeNodeAll.value ? treeOptions.value : []) -} +// const handleCheckedTreeNodeAll = () => { +// treeRef.value!.setCheckedNodes(treeNodeAll.value ? treeOptions.value : []) +// } // 权限操作 const handleScope = async (type: string, row: RoleApi.RoleVO) => { dataScopeForm.id = row.id dataScopeForm.name = row.name dataScopeForm.code = row.code - actionScopeType.value = type dialogScopeVisible.value = true if (type === 'menu') { @@ -265,7 +269,7 @@ const handleScope = async (type: string, row: RoleApi.RoleVO) => { const role = await PermissionApi.listRoleMenusApi(row.id) if (role) { role?.forEach((item: any) => { - unref(treeRef)?.setChecked(item, true,false); + unref(treeRef)?.setChecked(item, true, false) }) } } else if (type === 'data') { @@ -275,11 +279,10 @@ const handleScope = async (type: string, row: RoleApi.RoleVO) => { dataScopeForm.dataScope = role.dataScope if (role.dataScopeDeptIds) { role.dataScopeDeptIds?.forEach((item: any) => { - unref(treeRef)?.setChecked(item, true,false); + unref(treeRef)?.setChecked(item, true, false) }) } } - } // 保存权限 const submitScope = async () => { @@ -314,3 +317,10 @@ onMounted(() => { init() }) </script> +<style scoped> +.card { + width: 100%; + max-height: 400px; + overflow-y: scroll; +} +</style> diff --git a/src/views/system/tenant/tenant.data.ts b/src/views/system/tenant/tenant.data.ts index 7e81138c..110bfbb3 100644 --- a/src/views/system/tenant/tenant.data.ts +++ b/src/views/system/tenant/tenant.data.ts @@ -27,6 +27,24 @@ export const rules = reactive({ contactMobile: [required], accountCount: [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], status: [required] }) diff --git a/src/views/system/tenantPackage/index.vue b/src/views/system/tenantPackage/index.vue index f8b81171..9222365b 100644 --- a/src/views/system/tenantPackage/index.vue +++ b/src/views/system/tenantPackage/index.vue @@ -25,7 +25,7 @@ ref="formRef" > <template #menuIds> - <el-card class="w-120"> + <el-card> <template #header> <div class="card-header"> 全选/全不选: @@ -91,6 +91,16 @@ const dialogTitle = ref('edit') // 弹出层标题 const handleCheckedTreeNodeAll = () => { 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 res = await listSimpleMenusApi() menuOptions.value = handleTree(res) @@ -126,7 +136,7 @@ const handleUpdate = async (rowId: number) => { unref(formRef)?.setValues(res) // 设置选中 res.menuIds?.forEach((item: any) => { - unref(treeRef)?.setChecked(item, true,false); + unref(treeRef)?.setChecked(item, true, false) }) } @@ -168,3 +178,10 @@ onMounted(async () => { }) // getList() </script> +<style scoped> +.el-card { + width: 100%; + max-height: 400px; + overflow-y: scroll; +} +</style> diff --git a/src/views/system/tenantPackage/tenantPackage.data.ts b/src/views/system/tenantPackage/tenantPackage.data.ts index e28ea842..de06c2cb 100644 --- a/src/views/system/tenantPackage/tenantPackage.data.ts +++ b/src/views/system/tenantPackage/tenantPackage.data.ts @@ -33,7 +33,12 @@ const crudSchemas = reactive<VxeCrudSchema>({ { title: '菜单权限', field: 'menuIds', - isTable: false + isTable: false, + form: { + colProps: { + span: 24 + } + } }, { title: t('form.remark'), diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index bccab852..5568ca2a 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -159,7 +159,7 @@ :data="detailData" > <template #deptId="{ row }"> - <span>{{ row.dept?.name }}</span> + <el-tag>{{ dataFormater(row.deptId) }}</el-tag> </template> <template #postIds="{ row }"> <template v-if="row.postIds !== ''"> @@ -332,6 +332,28 @@ const getPostOptions = async () => { const res = await listSimplePostsApi() 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) => { dialogTitle.value = t('action.' + type)