mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-11-04 12:18:43 +08:00 
			
		
		
		
	@@ -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 }
 | 
			
		||||
 
 | 
			
		||||
@@ -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(() => {
 | 
			
		||||
  // 场景一:新增表单
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ const crudSchemas = reactive<VxeCrudSchema>({
 | 
			
		||||
  primaryType: 'id',
 | 
			
		||||
  primaryTitle: '编号',
 | 
			
		||||
  action: true,
 | 
			
		||||
  searchSpan: 8,
 | 
			
		||||
  columns: [
 | 
			
		||||
    {
 | 
			
		||||
      title: '组名',
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ const crudSchemas = reactive<VxeCrudSchema>({
 | 
			
		||||
  primaryTitle: '申请编号',
 | 
			
		||||
  action: true,
 | 
			
		||||
  actionWidth: '260',
 | 
			
		||||
  searchSpan: 8,
 | 
			
		||||
  columns: [
 | 
			
		||||
    {
 | 
			
		||||
      title: t('common.status'),
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ const crudSchemas = reactive<VxeCrudSchema>({
 | 
			
		||||
  primaryKey: 'id',
 | 
			
		||||
  primaryType: null,
 | 
			
		||||
  action: true,
 | 
			
		||||
  searchSpan: 8,
 | 
			
		||||
  columns: [
 | 
			
		||||
    {
 | 
			
		||||
      title: '任务编号',
 | 
			
		||||
 
 | 
			
		||||
@@ -99,24 +99,28 @@
 | 
			
		||||
        </el-select>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <!-- 分配角色的菜单权限对话框 -->
 | 
			
		||||
      <el-row>
 | 
			
		||||
        <el-col :span="24">
 | 
			
		||||
          <el-form-item
 | 
			
		||||
            label="权限范围"
 | 
			
		||||
            v-if="
 | 
			
		||||
          actionScopeType === 'menu' || dataScopeForm.dataScope === SystemDataScopeEnum.DEPT_CUSTOM
 | 
			
		||||
              actionScopeType === 'menu' ||
 | 
			
		||||
              dataScopeForm.dataScope === SystemDataScopeEnum.DEPT_CUSTOM
 | 
			
		||||
            "
 | 
			
		||||
            style="display: flex"
 | 
			
		||||
          >
 | 
			
		||||
        <el-card shadow="never">
 | 
			
		||||
            <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()"
 | 
			
		||||
            />
 | 
			
		||||
                <!--父子联动(选中父节点,自动选择子节点):-->
 | 
			
		||||
                <!--<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"
 | 
			
		||||
@@ -128,7 +132,8 @@
 | 
			
		||||
                empty-text="加载中,请稍后"
 | 
			
		||||
              />
 | 
			
		||||
            </el-card>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
          </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>
 | 
			
		||||
 
 | 
			
		||||
@@ -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]
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,12 @@ const crudSchemas = reactive<VxeCrudSchema>({
 | 
			
		||||
    {
 | 
			
		||||
      title: '菜单权限',
 | 
			
		||||
      field: 'menuIds',
 | 
			
		||||
      isTable: false
 | 
			
		||||
      isTable: false,
 | 
			
		||||
      form: {
 | 
			
		||||
        colProps: {
 | 
			
		||||
          span: 24
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      title: t('form.remark'),
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user