mirror of
				https://github.com/pure-admin/pure-admin-thin.git
				synced 2025-11-04 17:44:48 +08:00 
			
		
		
		
	feat: 完成通知公告页面
This commit is contained in:
		
							parent
							
								
									b0c2c47607
								
							
						
					
					
						commit
						4ebdfd21c4
					
				@ -11,7 +11,7 @@ export type ConfigDTO = {
 | 
			
		||||
  /** 验证码开关 */
 | 
			
		||||
  isCaptchaOn: boolean;
 | 
			
		||||
  /** 系统字典配置(下拉选项之类的) */
 | 
			
		||||
  dictTypes: Map<String, Array<DictionaryData>>;
 | 
			
		||||
  dictionary: Map<String, Array<DictionaryData>>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export type LoginByPasswordDTO = {
 | 
			
		||||
@ -43,7 +43,7 @@ export type CurrentLoginUserDTO = {
 | 
			
		||||
 | 
			
		||||
export type DictionaryData = {
 | 
			
		||||
  label: string;
 | 
			
		||||
  value: Number;
 | 
			
		||||
  value: number;
 | 
			
		||||
  cssTag: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,6 +19,30 @@ type ResultDept = {
 | 
			
		||||
  data?: Array<any>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface SystemNoticeQuery extends BasePageQuery {
 | 
			
		||||
  noticeType: string;
 | 
			
		||||
  noticeTitle: string;
 | 
			
		||||
  creatorName: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type SystemNoticeDTO = {
 | 
			
		||||
  noticeId: string;
 | 
			
		||||
  noticeTitle: string;
 | 
			
		||||
  noticeType: number;
 | 
			
		||||
  noticeContent: string;
 | 
			
		||||
  status: number;
 | 
			
		||||
  createTime: Date;
 | 
			
		||||
  creatorName: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export type SystemNoticeRequest = {
 | 
			
		||||
  noticeId?: number;
 | 
			
		||||
  noticeTitle: string;
 | 
			
		||||
  noticeType: number;
 | 
			
		||||
  noticeContent: string;
 | 
			
		||||
  status: number;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** 获取用户管理列表 */
 | 
			
		||||
export const getUserList = (data?: object) => {
 | 
			
		||||
  return http.request<Result>("post", "/user", { data });
 | 
			
		||||
@ -33,3 +57,35 @@ export const getRoleList = (data?: object) => {
 | 
			
		||||
export const getDeptList = (data?: object) => {
 | 
			
		||||
  return http.request<ResultDept>("post", "/dept", { data });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** 获取系统通知列表 */
 | 
			
		||||
export const getSystemNoticeListApi = (params?: SystemNoticeQuery) => {
 | 
			
		||||
  return http.request<ResponseData<PageDTO<SystemNoticeDTO>>>(
 | 
			
		||||
    "get",
 | 
			
		||||
    "/system/notice/list",
 | 
			
		||||
    {
 | 
			
		||||
      params
 | 
			
		||||
    }
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** 添加系统通知 */
 | 
			
		||||
export const addSystemNoticeApi = (data: SystemNoticeRequest) => {
 | 
			
		||||
  return http.request<ResponseData<any>>("post", "/system/notice/", {
 | 
			
		||||
    data
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** 修改系统通知 */
 | 
			
		||||
export const updateSystemNoticeApi = (data: SystemNoticeRequest) => {
 | 
			
		||||
  return http.request<ResponseData<any>>("put", "/system/notice/", {
 | 
			
		||||
    data
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** 删除系统通知 */
 | 
			
		||||
export const deleteSystemNoticeApi = (data: Array<number>) => {
 | 
			
		||||
  return http.request<ResponseData<any>>("delete", `/system/notice/${data}`, {
 | 
			
		||||
    data
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,12 @@
 | 
			
		||||
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
 | 
			
		||||
import { delay, getKeyList, cloneDeep } from "@pureadmin/utils";
 | 
			
		||||
import { defineComponent, ref, computed, type PropType, nextTick } from "vue";
 | 
			
		||||
import {
 | 
			
		||||
  delay,
 | 
			
		||||
  cloneDeep,
 | 
			
		||||
  isBoolean,
 | 
			
		||||
  isFunction,
 | 
			
		||||
  getKeyList
 | 
			
		||||
} from "@pureadmin/utils";
 | 
			
		||||
 | 
			
		||||
import Sortable from "sortablejs";
 | 
			
		||||
import DragIcon from "./svg/drag.svg?component";
 | 
			
		||||
@ -37,8 +43,13 @@ export default defineComponent({
 | 
			
		||||
    const loading = ref(false);
 | 
			
		||||
    const checkAll = ref(true);
 | 
			
		||||
    const isIndeterminate = ref(false);
 | 
			
		||||
    const filterColumns = cloneDeep(props?.columns).filter(column =>
 | 
			
		||||
      isBoolean(column?.hide)
 | 
			
		||||
        ? !column.hide
 | 
			
		||||
        : !(isFunction(column?.hide) && column?.hide())
 | 
			
		||||
    );
 | 
			
		||||
    let checkColumnList = getKeyList(cloneDeep(props?.columns), "label");
 | 
			
		||||
    const checkedColumns = ref(checkColumnList);
 | 
			
		||||
    const checkedColumns = ref(getKeyList(cloneDeep(filterColumns), "label"));
 | 
			
		||||
    const dynamicColumns = ref(cloneDeep(props?.columns));
 | 
			
		||||
 | 
			
		||||
    const getDropdownItemStyle = computed(() => {
 | 
			
		||||
@ -120,7 +131,7 @@ export default defineComponent({
 | 
			
		||||
      dynamicColumns.value = cloneDeep(props?.columns);
 | 
			
		||||
      checkColumnList = [];
 | 
			
		||||
      checkColumnList = await getKeyList(cloneDeep(props?.columns), "label");
 | 
			
		||||
      checkedColumns.value = checkColumnList;
 | 
			
		||||
      checkedColumns.value = getKeyList(cloneDeep(filterColumns), "label");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const dropdown = {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/main.ts
									
									
									
									
									
								
							@ -8,7 +8,7 @@ import { MotionPlugin } from "@vueuse/motion";
 | 
			
		||||
// import { useEcharts } from "@/plugins/echarts";
 | 
			
		||||
import { injectResponsiveStorage } from "@/utils/responsive";
 | 
			
		||||
 | 
			
		||||
// import Table from "@pureadmin/table";
 | 
			
		||||
import Table from "@pureadmin/table";
 | 
			
		||||
// import PureDescriptions from "@pureadmin/descriptions";
 | 
			
		||||
 | 
			
		||||
// 引入重置样式
 | 
			
		||||
@ -49,9 +49,11 @@ getServerConfig(app).then(async config => {
 | 
			
		||||
  await router.isReady();
 | 
			
		||||
  injectResponsiveStorage(app, config);
 | 
			
		||||
  setupStore(app);
 | 
			
		||||
  app.use(MotionPlugin).use(ElementPlus);
 | 
			
		||||
  // .use(useEcharts);
 | 
			
		||||
  // .use(Table);
 | 
			
		||||
  app
 | 
			
		||||
    .use(MotionPlugin)
 | 
			
		||||
    .use(ElementPlus)
 | 
			
		||||
    // .use(useEcharts);
 | 
			
		||||
    .use(Table);
 | 
			
		||||
  // .use(PureDescriptions);
 | 
			
		||||
  app.mount("#app");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
import { RouteRecordName } from "vue-router";
 | 
			
		||||
import { DictionaryData } from "../../api/common";
 | 
			
		||||
 | 
			
		||||
export type cacheType = {
 | 
			
		||||
  mode: string;
 | 
			
		||||
@ -38,4 +39,8 @@ export type setType = {
 | 
			
		||||
export type userType = {
 | 
			
		||||
  username?: string;
 | 
			
		||||
  roles?: Array<string>;
 | 
			
		||||
  /** 字典ListMap 用于下拉框直接展示 */
 | 
			
		||||
  dictionaryList: Map<String, Array<DictionaryData>>;
 | 
			
		||||
  /** 字典MapMap 用于匹配值展示 */
 | 
			
		||||
  dictionaryMap: Map<String, Map<String, DictionaryData>>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -5,8 +5,12 @@ import { routerArrays } from "@/layout/types";
 | 
			
		||||
import { router, resetRouter } from "@/router";
 | 
			
		||||
import { storageSession } from "@pureadmin/utils";
 | 
			
		||||
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 | 
			
		||||
import { type removeToken, sessionKey } from "@/utils/auth";
 | 
			
		||||
import { TokenDTO } from "@/api/common";
 | 
			
		||||
import { removeToken, sessionKey } from "@/utils/auth";
 | 
			
		||||
import { DictionaryData, TokenDTO } from "@/api/common";
 | 
			
		||||
import { storageLocal } from "@pureadmin/utils";
 | 
			
		||||
 | 
			
		||||
const dictionaryListKey = "ag-dictionary-list";
 | 
			
		||||
const dictionaryMapKey = "ag-dictionary-map";
 | 
			
		||||
 | 
			
		||||
export const useUserStore = defineStore({
 | 
			
		||||
  id: "ag-user",
 | 
			
		||||
@ -18,17 +22,53 @@ export const useUserStore = defineStore({
 | 
			
		||||
    // 页面级别权限
 | 
			
		||||
    roles: storageSession().getItem<TokenDTO>(sessionKey)?.currentUser.roleKey
 | 
			
		||||
      ? [storageSession().getItem<TokenDTO>(sessionKey)?.currentUser.roleKey]
 | 
			
		||||
      : []
 | 
			
		||||
      : [],
 | 
			
		||||
    dictionaryList:
 | 
			
		||||
      storageLocal().getItem<Map<String, Array<DictionaryData>>>(
 | 
			
		||||
        dictionaryListKey
 | 
			
		||||
      ) ?? new Map(),
 | 
			
		||||
    dictionaryMap:
 | 
			
		||||
      storageLocal().getItem<Map<String, Map<String, DictionaryData>>>(
 | 
			
		||||
        dictionaryMapKey
 | 
			
		||||
      ) ?? new Map()
 | 
			
		||||
  }),
 | 
			
		||||
  actions: {
 | 
			
		||||
    /** 存储用户名 */
 | 
			
		||||
    SET_USERNAME(username: string) {
 | 
			
		||||
      /** TODO 这里不是应该再进一步存到sessionStorage中吗 */
 | 
			
		||||
      this.username = username;
 | 
			
		||||
    },
 | 
			
		||||
    /** 存储角色 */
 | 
			
		||||
    SET_ROLES(roles: Array<string>) {
 | 
			
		||||
      this.roles = roles;
 | 
			
		||||
    },
 | 
			
		||||
    /** 存储系统内的字典值 并拆分为Map形式和List形式 */
 | 
			
		||||
    SET_DICTIONARY(dictionary: Map<String, Array<DictionaryData>>) {
 | 
			
		||||
      /** 由于localStorage不能存储Map对象,所以用Obj来装载数据 */
 | 
			
		||||
      const dictionaryMapTmp = {};
 | 
			
		||||
 | 
			
		||||
      for (const obj in dictionary) {
 | 
			
		||||
        dictionaryMapTmp[obj] = dictionary[obj].reduce((map, dict) => {
 | 
			
		||||
          map[dict.value] = dict;
 | 
			
		||||
          return map;
 | 
			
		||||
        }, {});
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /** 将字典分成List形式和Map形式 List便于下拉框展示 Map便于匹配值 */
 | 
			
		||||
      this.dictionaryList = dictionary;
 | 
			
		||||
      this.dictionaryMap = dictionaryMapTmp;
 | 
			
		||||
 | 
			
		||||
      storageLocal().setItem<Map<String, Array<DictionaryData>>>(
 | 
			
		||||
        dictionaryListKey,
 | 
			
		||||
        dictionary
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      storageLocal().setItem<Map<String, Map<String, DictionaryData>>>(
 | 
			
		||||
        dictionaryMapKey,
 | 
			
		||||
        dictionaryMapTmp as Map<String, Map<String, DictionaryData>>
 | 
			
		||||
      );
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /** 前端登出(不调用接口) */
 | 
			
		||||
    logOut() {
 | 
			
		||||
      this.username = "";
 | 
			
		||||
 | 
			
		||||
@ -128,6 +128,8 @@ class PureHttp {
 | 
			
		||||
          } else {
 | 
			
		||||
            // 其余情况弹出错误提示框
 | 
			
		||||
            message(response.data.msg, { type: "error" });
 | 
			
		||||
            NProgress.done();
 | 
			
		||||
            return Promise.reject(response.data.msg);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,7 @@ import Lock from "@iconify-icons/ri/lock-fill";
 | 
			
		||||
import User from "@iconify-icons/ri/user-3-fill";
 | 
			
		||||
import * as CommonAPI from "@/api/common";
 | 
			
		||||
import { setTokenFromBackend } from "../../utils/auth";
 | 
			
		||||
import { useUserStoreHook } from "../../store/modules/user";
 | 
			
		||||
 | 
			
		||||
defineOptions({
 | 
			
		||||
  name: "Login"
 | 
			
		||||
@ -128,6 +129,7 @@ watch(isRememberMe, newVal => {
 | 
			
		||||
onBeforeMount(async () => {
 | 
			
		||||
  await CommonAPI.getConfig().then(res => {
 | 
			
		||||
    isCaptchaOn.value = res.data.isCaptchaOn;
 | 
			
		||||
    useUserStoreHook().SET_DICTIONARY(res.data.dictionary);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (isCaptchaOn.value) {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										39
									
								
								src/views/monitor/hooks.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/views/monitor/hooks.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
// 抽离可公用的工具函数等用于系统管理页面逻辑
 | 
			
		||||
import { computed } from "vue";
 | 
			
		||||
import { useDark } from "@pureadmin/utils";
 | 
			
		||||
 | 
			
		||||
export function usePublicHooks() {
 | 
			
		||||
  const { isDark } = useDark();
 | 
			
		||||
 | 
			
		||||
  const switchStyle = computed(() => {
 | 
			
		||||
    return {
 | 
			
		||||
      "--el-switch-on-color": "#6abe39",
 | 
			
		||||
      "--el-switch-off-color": "#e84749"
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const tagStyle = computed(() => {
 | 
			
		||||
    return (status: number) => {
 | 
			
		||||
      return status === 1
 | 
			
		||||
        ? {
 | 
			
		||||
            "--el-tag-text-color": isDark.value ? "#6abe39" : "#389e0d",
 | 
			
		||||
            "--el-tag-bg-color": isDark.value ? "#172412" : "#f6ffed",
 | 
			
		||||
            "--el-tag-border-color": isDark.value ? "#274a17" : "#b7eb8f"
 | 
			
		||||
          }
 | 
			
		||||
        : {
 | 
			
		||||
            "--el-tag-text-color": isDark.value ? "#e84749" : "#cf1322",
 | 
			
		||||
            "--el-tag-bg-color": isDark.value ? "#2b1316" : "#fff1f0",
 | 
			
		||||
            "--el-tag-border-color": isDark.value ? "#58191c" : "#ffa39e"
 | 
			
		||||
          };
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    /** 当前网页是否为`dark`模式 */
 | 
			
		||||
    isDark,
 | 
			
		||||
    /** 表现更鲜明的`el-switch`组件  */
 | 
			
		||||
    switchStyle,
 | 
			
		||||
    /** 表现更鲜明的`el-tag`组件  */
 | 
			
		||||
    tagStyle
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@ -2,52 +2,81 @@
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
import { formRules } from "./utils/rule";
 | 
			
		||||
import { FormProps } from "./utils/types";
 | 
			
		||||
import { useUserStoreHook } from "@/store/modules/user";
 | 
			
		||||
 | 
			
		||||
/** TODO 有其他方式  来换掉这个props 父子组件传值吗? */
 | 
			
		||||
const props = withDefaults(defineProps<FormProps>(), {
 | 
			
		||||
  formInline: () => ({
 | 
			
		||||
    name: "",
 | 
			
		||||
    code: "",
 | 
			
		||||
    remark: ""
 | 
			
		||||
    noticeTitle: "",
 | 
			
		||||
    noticeType: "",
 | 
			
		||||
    status: "",
 | 
			
		||||
    noticeContent: ""
 | 
			
		||||
  })
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const ruleFormRef = ref();
 | 
			
		||||
const newFormInline = ref(props.formInline);
 | 
			
		||||
const noticeData = ref(props.formInline);
 | 
			
		||||
 | 
			
		||||
function getRef() {
 | 
			
		||||
  return ruleFormRef.value;
 | 
			
		||||
const formRuleRef = ref();
 | 
			
		||||
 | 
			
		||||
function getFormRuleRef() {
 | 
			
		||||
  return formRuleRef.value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
defineExpose({ getRef });
 | 
			
		||||
defineExpose({ getFormRuleRef });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <el-form
 | 
			
		||||
    ref="ruleFormRef"
 | 
			
		||||
    :model="newFormInline"
 | 
			
		||||
    ref="formRuleRef"
 | 
			
		||||
    :model="noticeData"
 | 
			
		||||
    :rules="formRules"
 | 
			
		||||
    label-width="82px"
 | 
			
		||||
  >
 | 
			
		||||
    <el-form-item label="角色名称" prop="name">
 | 
			
		||||
    <el-form-item label="公告标题" prop="noticeTitle">
 | 
			
		||||
      <el-input
 | 
			
		||||
        v-model="newFormInline.name"
 | 
			
		||||
        v-model="noticeData.noticeTitle"
 | 
			
		||||
        clearable
 | 
			
		||||
        placeholder="请输入角色名称"
 | 
			
		||||
        placeholder="请输入公告标题"
 | 
			
		||||
      />
 | 
			
		||||
    </el-form-item>
 | 
			
		||||
 | 
			
		||||
    <el-form-item label="角色标识" prop="code">
 | 
			
		||||
      <el-input
 | 
			
		||||
        v-model="newFormInline.code"
 | 
			
		||||
    <el-form-item label="公告类型" prop="noticeType">
 | 
			
		||||
      <el-select
 | 
			
		||||
        v-model="noticeData.noticeType"
 | 
			
		||||
        placeholder="请选择类型"
 | 
			
		||||
        clearable
 | 
			
		||||
        placeholder="请输入角色标识"
 | 
			
		||||
      />
 | 
			
		||||
        class="!w-[180px]"
 | 
			
		||||
      >
 | 
			
		||||
        <el-option
 | 
			
		||||
          v-for="dict in useUserStoreHook().dictionaryList['sys_notice_type']"
 | 
			
		||||
          :key="dict.value"
 | 
			
		||||
          :label="dict.label"
 | 
			
		||||
          :value="dict.value"
 | 
			
		||||
        />
 | 
			
		||||
      </el-select>
 | 
			
		||||
    </el-form-item>
 | 
			
		||||
    <el-form-item label="公告类型" prop="status">
 | 
			
		||||
      <el-select
 | 
			
		||||
        v-model="noticeData.status"
 | 
			
		||||
        placeholder="请选择状态"
 | 
			
		||||
        clearable
 | 
			
		||||
        class="!w-[180px]"
 | 
			
		||||
      >
 | 
			
		||||
        <el-option
 | 
			
		||||
          v-for="dict in useUserStoreHook().dictionaryList['sys_notice_status']"
 | 
			
		||||
          :key="dict.value"
 | 
			
		||||
          :label="dict.label"
 | 
			
		||||
          :value="dict.value"
 | 
			
		||||
        />
 | 
			
		||||
      </el-select>
 | 
			
		||||
    </el-form-item>
 | 
			
		||||
 | 
			
		||||
    <el-form-item label="备注">
 | 
			
		||||
    <el-form-item label="公告内容" prop="noticeContent">
 | 
			
		||||
      <el-input
 | 
			
		||||
        v-model="newFormInline.remark"
 | 
			
		||||
        placeholder="请输入备注信息"
 | 
			
		||||
        v-model="noticeData.noticeContent"
 | 
			
		||||
        clearable
 | 
			
		||||
        placeholder="请输入公告内容"
 | 
			
		||||
        rows="6"
 | 
			
		||||
        type="textarea"
 | 
			
		||||
      />
 | 
			
		||||
    </el-form-item>
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
import { useRole } from "./utils/hook";
 | 
			
		||||
import { useNoticeHook } from "./utils/hook";
 | 
			
		||||
import { PureTableBar } from "@/components/RePureTableBar";
 | 
			
		||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 | 
			
		||||
 | 
			
		||||
@ -10,104 +10,122 @@ import Delete from "@iconify-icons/ep/delete";
 | 
			
		||||
import EditPen from "@iconify-icons/ep/edit-pen";
 | 
			
		||||
import Search from "@iconify-icons/ep/search";
 | 
			
		||||
import Refresh from "@iconify-icons/ep/refresh";
 | 
			
		||||
import Menu from "@iconify-icons/ep/menu";
 | 
			
		||||
import AddFill from "@iconify-icons/ri/add-circle-line";
 | 
			
		||||
import { useUserStoreHook } from "@/store/modules/user";
 | 
			
		||||
 | 
			
		||||
/** 组件name最好和菜单表中的router_name一致 */
 | 
			
		||||
defineOptions({
 | 
			
		||||
  name: "Role"
 | 
			
		||||
  name: "SystemNotice"
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const formRef = ref();
 | 
			
		||||
const sys_notice_type = useUserStoreHook().dictionaryList["sys_notice_type"];
 | 
			
		||||
const tableRef = ref();
 | 
			
		||||
 | 
			
		||||
const searchFormRef = ref();
 | 
			
		||||
const {
 | 
			
		||||
  form,
 | 
			
		||||
  loading,
 | 
			
		||||
  searchFormParams,
 | 
			
		||||
  pageLoading,
 | 
			
		||||
  columns,
 | 
			
		||||
  dataList,
 | 
			
		||||
  pagination,
 | 
			
		||||
  // buttonClass,
 | 
			
		||||
  onSearch,
 | 
			
		||||
  resetForm,
 | 
			
		||||
  openDialog,
 | 
			
		||||
  handleMenu,
 | 
			
		||||
  handleDelete,
 | 
			
		||||
  // handleDatabase,
 | 
			
		||||
  handleSizeChange,
 | 
			
		||||
  handleCurrentChange,
 | 
			
		||||
  handleSelectionChange
 | 
			
		||||
} = useRole();
 | 
			
		||||
  handleSortChange,
 | 
			
		||||
  handleSelectionChange,
 | 
			
		||||
  handleBulkDelete
 | 
			
		||||
} = useNoticeHook();
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="main">
 | 
			
		||||
    <!-- 搜索栏 -->
 | 
			
		||||
    <el-form
 | 
			
		||||
      ref="formRef"
 | 
			
		||||
      ref="searchFormRef"
 | 
			
		||||
      :inline="true"
 | 
			
		||||
      :model="form"
 | 
			
		||||
      :model="searchFormParams"
 | 
			
		||||
      class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]"
 | 
			
		||||
    >
 | 
			
		||||
      <el-form-item label="角色名称:" prop="name">
 | 
			
		||||
      <el-form-item label="公告标题:" prop="noticeTitle">
 | 
			
		||||
        <el-input
 | 
			
		||||
          v-model="form.name"
 | 
			
		||||
          placeholder="请输入角色名称"
 | 
			
		||||
          v-model="searchFormParams.noticeTitle"
 | 
			
		||||
          placeholder="请输入公告标题"
 | 
			
		||||
          clearable
 | 
			
		||||
          class="!w-[200px]"
 | 
			
		||||
        />
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <el-form-item label="角色标识:" prop="code">
 | 
			
		||||
        <el-input
 | 
			
		||||
          v-model="form.code"
 | 
			
		||||
          placeholder="请输入角色标识"
 | 
			
		||||
          clearable
 | 
			
		||||
          class="!w-[180px]"
 | 
			
		||||
        />
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <el-form-item label="状态:" prop="status">
 | 
			
		||||
 | 
			
		||||
      <el-form-item label="公告类型:" prop="noticeType">
 | 
			
		||||
        <el-select
 | 
			
		||||
          v-model="form.status"
 | 
			
		||||
          v-model="searchFormParams.noticeType"
 | 
			
		||||
          placeholder="请选择状态"
 | 
			
		||||
          clearable
 | 
			
		||||
          class="!w-[180px]"
 | 
			
		||||
        >
 | 
			
		||||
          <el-option label="已启用" value="1" />
 | 
			
		||||
          <el-option label="已停用" value="0" />
 | 
			
		||||
          <el-option
 | 
			
		||||
            v-for="dict in sys_notice_type"
 | 
			
		||||
            :key="dict.value"
 | 
			
		||||
            :label="dict.label"
 | 
			
		||||
            :value="dict.value"
 | 
			
		||||
          />
 | 
			
		||||
        </el-select>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <el-form-item label="创建者:" prop="creatorName">
 | 
			
		||||
        <el-input
 | 
			
		||||
          v-model="searchFormParams.creatorName"
 | 
			
		||||
          placeholder="请输入创建者"
 | 
			
		||||
          clearable
 | 
			
		||||
          class="!w-[180px]"
 | 
			
		||||
        />
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <el-form-item>
 | 
			
		||||
        <el-button
 | 
			
		||||
          type="primary"
 | 
			
		||||
          :icon="useRenderIcon(Search)"
 | 
			
		||||
          :loading="loading"
 | 
			
		||||
          :loading="pageLoading"
 | 
			
		||||
          @click="onSearch"
 | 
			
		||||
        >
 | 
			
		||||
          搜索
 | 
			
		||||
        </el-button>
 | 
			
		||||
        <el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
 | 
			
		||||
        <el-button
 | 
			
		||||
          :icon="useRenderIcon(Refresh)"
 | 
			
		||||
          @click="resetForm(searchFormRef)"
 | 
			
		||||
        >
 | 
			
		||||
          重置
 | 
			
		||||
        </el-button>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
    </el-form>
 | 
			
		||||
 | 
			
		||||
    <PureTableBar
 | 
			
		||||
      title="角色列表(仅演示,操作后不生效)"
 | 
			
		||||
      :columns="columns"
 | 
			
		||||
      @refresh="onSearch"
 | 
			
		||||
    >
 | 
			
		||||
    <!-- table bar 包裹  table -->
 | 
			
		||||
    <PureTableBar title="通知列表" :columns="columns" @refresh="onSearch">
 | 
			
		||||
      <!-- 表格操作栏 -->
 | 
			
		||||
      <template #buttons>
 | 
			
		||||
        <el-button
 | 
			
		||||
          type="primary"
 | 
			
		||||
          :icon="useRenderIcon(AddFill)"
 | 
			
		||||
          @click="openDialog()"
 | 
			
		||||
        >
 | 
			
		||||
          新增角色
 | 
			
		||||
          添加公告
 | 
			
		||||
        </el-button>
 | 
			
		||||
        <el-button
 | 
			
		||||
          type="danger"
 | 
			
		||||
          :icon="useRenderIcon(Delete)"
 | 
			
		||||
          @click="handleBulkDelete(tableRef)"
 | 
			
		||||
        >
 | 
			
		||||
          批量删除
 | 
			
		||||
        </el-button>
 | 
			
		||||
      </template>
 | 
			
		||||
      <template v-slot="{ size, dynamicColumns }">
 | 
			
		||||
        <pure-table
 | 
			
		||||
          border
 | 
			
		||||
          ref="tableRef"
 | 
			
		||||
          align-whole="center"
 | 
			
		||||
          showOverflowTooltip
 | 
			
		||||
          table-layout="auto"
 | 
			
		||||
          :loading="loading"
 | 
			
		||||
          :loading="pageLoading"
 | 
			
		||||
          :size="size"
 | 
			
		||||
          adaptive
 | 
			
		||||
          :data="dataList"
 | 
			
		||||
@ -118,9 +136,10 @@ const {
 | 
			
		||||
            background: 'var(--el-table-row-hover-bg-color)',
 | 
			
		||||
            color: 'var(--el-text-color-primary)'
 | 
			
		||||
          }"
 | 
			
		||||
          @selection-change="handleSelectionChange"
 | 
			
		||||
          @page-size-change="handleSizeChange"
 | 
			
		||||
          @page-current-change="handleCurrentChange"
 | 
			
		||||
          @sort-change="handleSortChange"
 | 
			
		||||
          @selection-change="handleSelectionChange"
 | 
			
		||||
        >
 | 
			
		||||
          <template #operation="{ row }">
 | 
			
		||||
            <el-button
 | 
			
		||||
@ -133,25 +152,15 @@ const {
 | 
			
		||||
            >
 | 
			
		||||
              修改
 | 
			
		||||
            </el-button>
 | 
			
		||||
            <el-button
 | 
			
		||||
              class="reset-margin"
 | 
			
		||||
              link
 | 
			
		||||
              type="primary"
 | 
			
		||||
              :size="size"
 | 
			
		||||
              :icon="useRenderIcon(Menu)"
 | 
			
		||||
              @click="handleMenu"
 | 
			
		||||
            >
 | 
			
		||||
              菜单权限
 | 
			
		||||
            </el-button>
 | 
			
		||||
            <el-popconfirm
 | 
			
		||||
              :title="`是否确认删除角色名称为${row.name}的这条数据`"
 | 
			
		||||
              :title="`是否确认删除编号为${row.noticeId}的这条数据`"
 | 
			
		||||
              @confirm="handleDelete(row)"
 | 
			
		||||
            >
 | 
			
		||||
              <template #reference>
 | 
			
		||||
                <el-button
 | 
			
		||||
                  class="reset-margin"
 | 
			
		||||
                  link
 | 
			
		||||
                  type="primary"
 | 
			
		||||
                  type="danger"
 | 
			
		||||
                  :size="size"
 | 
			
		||||
                  :icon="useRenderIcon(Delete)"
 | 
			
		||||
                >
 | 
			
		||||
@ -159,43 +168,6 @@ const {
 | 
			
		||||
                </el-button>
 | 
			
		||||
              </template>
 | 
			
		||||
            </el-popconfirm>
 | 
			
		||||
            <!-- <el-dropdown>
 | 
			
		||||
              <el-button
 | 
			
		||||
                class="ml-3 mt-[2px]"
 | 
			
		||||
                link
 | 
			
		||||
                type="primary"
 | 
			
		||||
                :size="size"
 | 
			
		||||
                :icon="useRenderIcon(More)"
 | 
			
		||||
              />
 | 
			
		||||
              <template #dropdown>
 | 
			
		||||
                <el-dropdown-menu>
 | 
			
		||||
                  <el-dropdown-item>
 | 
			
		||||
                    <el-button
 | 
			
		||||
                      :class="buttonClass"
 | 
			
		||||
                      link
 | 
			
		||||
                      type="primary"
 | 
			
		||||
                      :size="size"
 | 
			
		||||
                      :icon="useRenderIcon(Menu)"
 | 
			
		||||
                      @click="handleMenu"
 | 
			
		||||
                    >
 | 
			
		||||
                      菜单权限
 | 
			
		||||
                    </el-button>
 | 
			
		||||
                  </el-dropdown-item>
 | 
			
		||||
                  <el-dropdown-item>
 | 
			
		||||
                    <el-button
 | 
			
		||||
                      :class="buttonClass"
 | 
			
		||||
                      link
 | 
			
		||||
                      type="primary"
 | 
			
		||||
                      :size="size"
 | 
			
		||||
                      :icon="useRenderIcon(Database)"
 | 
			
		||||
                      @click="handleDatabase"
 | 
			
		||||
                    >
 | 
			
		||||
                      数据权限
 | 
			
		||||
                    </el-button>
 | 
			
		||||
                  </el-dropdown-item>
 | 
			
		||||
                </el-dropdown-menu>
 | 
			
		||||
              </template>
 | 
			
		||||
            </el-dropdown> -->
 | 
			
		||||
          </template>
 | 
			
		||||
        </pure-table>
 | 
			
		||||
      </template>
 | 
			
		||||
 | 
			
		||||
@ -1,74 +1,104 @@
 | 
			
		||||
import dayjs from "dayjs";
 | 
			
		||||
import editForm from "../form.vue";
 | 
			
		||||
import { message } from "@/utils/message";
 | 
			
		||||
import { getRoleList } from "@/api/system";
 | 
			
		||||
import { ElMessageBox } from "element-plus";
 | 
			
		||||
import { usePublicHooks } from "../../hooks";
 | 
			
		||||
import { getSystemNoticeListApi } from "@/api/system";
 | 
			
		||||
import { addDialog } from "@/components/ReDialog";
 | 
			
		||||
import { type FormItemProps } from "../utils/types";
 | 
			
		||||
import { ElMessageBox } from "element-plus";
 | 
			
		||||
import { AddNoticeRequest } from "../utils/types";
 | 
			
		||||
import { type PaginationProps } from "@pureadmin/table";
 | 
			
		||||
import {
 | 
			
		||||
  addSystemNoticeApi,
 | 
			
		||||
  updateSystemNoticeApi,
 | 
			
		||||
  deleteSystemNoticeApi,
 | 
			
		||||
  SystemNoticeRequest
 | 
			
		||||
} from "@/api/system";
 | 
			
		||||
import { reactive, ref, onMounted, h, toRaw } from "vue";
 | 
			
		||||
import { useUserStoreHook } from "@/store/modules/user";
 | 
			
		||||
 | 
			
		||||
export function useRole() {
 | 
			
		||||
  const form = reactive({
 | 
			
		||||
    name: "",
 | 
			
		||||
    code: "",
 | 
			
		||||
    status: ""
 | 
			
		||||
  });
 | 
			
		||||
  const formRef = ref();
 | 
			
		||||
  const dataList = ref([]);
 | 
			
		||||
  const loading = ref(true);
 | 
			
		||||
  const switchLoadMap = ref({});
 | 
			
		||||
  const { switchStyle } = usePublicHooks();
 | 
			
		||||
const sysNoticeTypeMap = useUserStoreHook().dictionaryMap["sys_notice_type"];
 | 
			
		||||
const sysNoticeStatusMap =
 | 
			
		||||
  useUserStoreHook().dictionaryMap["sys_notice_status"];
 | 
			
		||||
 | 
			
		||||
export function useNoticeHook() {
 | 
			
		||||
  const pagination = reactive<PaginationProps>({
 | 
			
		||||
    total: 0,
 | 
			
		||||
    pageSize: 10,
 | 
			
		||||
    currentPage: 1,
 | 
			
		||||
    background: true
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const searchFormParams = reactive({
 | 
			
		||||
    noticeTitle: "",
 | 
			
		||||
    noticeType: "",
 | 
			
		||||
    creatorName: "",
 | 
			
		||||
    pageNum: pagination.currentPage,
 | 
			
		||||
    pageSize: pagination.pageSize,
 | 
			
		||||
    orderColumn: "createTime",
 | 
			
		||||
    orderDirection: "descending"
 | 
			
		||||
  });
 | 
			
		||||
  const formRef = ref();
 | 
			
		||||
  const dataList = ref([]);
 | 
			
		||||
  const pageLoading = ref(true);
 | 
			
		||||
  const multipleSelection = ref([]);
 | 
			
		||||
 | 
			
		||||
  const columns: TableColumnList = [
 | 
			
		||||
    {
 | 
			
		||||
      label: "角色编号",
 | 
			
		||||
      prop: "id",
 | 
			
		||||
      type: "selection",
 | 
			
		||||
      align: "left"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "通知编号",
 | 
			
		||||
      prop: "noticeId",
 | 
			
		||||
      minWidth: 100
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "角色名称",
 | 
			
		||||
      prop: "name",
 | 
			
		||||
      label: "通知标题",
 | 
			
		||||
      prop: "noticeTitle",
 | 
			
		||||
      minWidth: 120
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "角色标识",
 | 
			
		||||
      prop: "code",
 | 
			
		||||
      minWidth: 150
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "状态",
 | 
			
		||||
      minWidth: 130,
 | 
			
		||||
      cellRenderer: scope => (
 | 
			
		||||
        <el-switch
 | 
			
		||||
          size={scope.props.size === "small" ? "small" : "default"}
 | 
			
		||||
          loading={switchLoadMap.value[scope.index]?.loading}
 | 
			
		||||
          v-model={scope.row.status}
 | 
			
		||||
          active-value={1}
 | 
			
		||||
          inactive-value={0}
 | 
			
		||||
          active-text="已启用"
 | 
			
		||||
          inactive-text="已停用"
 | 
			
		||||
          inline-prompt
 | 
			
		||||
          style={switchStyle.value}
 | 
			
		||||
          onChange={() => onChange(scope as any)}
 | 
			
		||||
        />
 | 
			
		||||
      label: "通知类型",
 | 
			
		||||
      prop: "noticeType",
 | 
			
		||||
      minWidth: 120,
 | 
			
		||||
      cellRenderer: ({ row, props }) => (
 | 
			
		||||
        <el-tag
 | 
			
		||||
          size={props.size}
 | 
			
		||||
          type={sysNoticeTypeMap[row.noticeType].cssTag}
 | 
			
		||||
          effect="plain"
 | 
			
		||||
        >
 | 
			
		||||
          {sysNoticeTypeMap[row.noticeType].label}
 | 
			
		||||
        </el-tag>
 | 
			
		||||
      )
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "备注",
 | 
			
		||||
      prop: "remark",
 | 
			
		||||
      label: "状态",
 | 
			
		||||
      prop: "status",
 | 
			
		||||
      minWidth: 120,
 | 
			
		||||
      cellRenderer: ({ row, props }) => (
 | 
			
		||||
        <el-tag
 | 
			
		||||
          size={props.size}
 | 
			
		||||
          type={sysNoticeStatusMap[row.status].cssTag}
 | 
			
		||||
          effect="plain"
 | 
			
		||||
        >
 | 
			
		||||
          {sysNoticeStatusMap[row.status].label}
 | 
			
		||||
        </el-tag>
 | 
			
		||||
      )
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "通知详情",
 | 
			
		||||
      prop: "noticeContent",
 | 
			
		||||
      minWidth: 150
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "创建者",
 | 
			
		||||
      prop: "creatorName",
 | 
			
		||||
      minWidth: 120
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "创建时间",
 | 
			
		||||
      minWidth: 180,
 | 
			
		||||
      prop: "createTime",
 | 
			
		||||
      sortable: "custom",
 | 
			
		||||
      formatter: ({ createTime }) =>
 | 
			
		||||
        dayjs(createTime).format("YYYY-MM-DD HH:mm:ss")
 | 
			
		||||
    },
 | 
			
		||||
@ -79,23 +109,23 @@ export function useRole() {
 | 
			
		||||
      slot: "operation"
 | 
			
		||||
    }
 | 
			
		||||
  ];
 | 
			
		||||
  // const buttonClass = computed(() => {
 | 
			
		||||
  //   return [
 | 
			
		||||
  //     "!h-[20px]",
 | 
			
		||||
  //     "reset-margin",
 | 
			
		||||
  //     "!text-gray-500",
 | 
			
		||||
  //     "dark:!text-white",
 | 
			
		||||
  //     "dark:hover:!text-primary"
 | 
			
		||||
  //   ];
 | 
			
		||||
  // });
 | 
			
		||||
 | 
			
		||||
  function onChange({ row, index }) {
 | 
			
		||||
  async function handleDelete(row) {
 | 
			
		||||
    await deleteSystemNoticeApi([row.noticeId]).then(() => {
 | 
			
		||||
      message(`您删除了通知标题为${row.name}的这条数据`, { type: "success" });
 | 
			
		||||
      // 刷新列表
 | 
			
		||||
      onSearch();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async function handleBulkDelete(tableRef) {
 | 
			
		||||
    if (multipleSelection.value.length === 0) {
 | 
			
		||||
      message("请选择需要删除的数据", { type: "warning" });
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ElMessageBox.confirm(
 | 
			
		||||
      `确认要<strong>${
 | 
			
		||||
        row.status === 0 ? "停用" : "启用"
 | 
			
		||||
      }</strong><strong style='color:var(--el-color-primary)'>${
 | 
			
		||||
        row.name
 | 
			
		||||
      }</strong>吗?`,
 | 
			
		||||
      `确认要<strong>删除</strong>编号为<strong style='color:var(--el-color-primary)'>[ ${multipleSelection.value} ]</strong>的通知吗?`,
 | 
			
		||||
      "系统提示",
 | 
			
		||||
      {
 | 
			
		||||
        confirmButtonText: "确定",
 | 
			
		||||
@ -105,59 +135,81 @@ export function useRole() {
 | 
			
		||||
        draggable: true
 | 
			
		||||
      }
 | 
			
		||||
    )
 | 
			
		||||
      .then(() => {
 | 
			
		||||
        switchLoadMap.value[index] = Object.assign(
 | 
			
		||||
          {},
 | 
			
		||||
          switchLoadMap.value[index],
 | 
			
		||||
          {
 | 
			
		||||
            loading: true
 | 
			
		||||
          }
 | 
			
		||||
        );
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          switchLoadMap.value[index] = Object.assign(
 | 
			
		||||
            {},
 | 
			
		||||
            switchLoadMap.value[index],
 | 
			
		||||
            {
 | 
			
		||||
              loading: false
 | 
			
		||||
            }
 | 
			
		||||
          );
 | 
			
		||||
          message(`已${row.status === 0 ? "停用" : "启用"}${row.name}`, {
 | 
			
		||||
      .then(async () => {
 | 
			
		||||
        await deleteSystemNoticeApi(multipleSelection.value).then(() => {
 | 
			
		||||
          message(`您删除了通知编号为[ ${multipleSelection.value} ]的条数据`, {
 | 
			
		||||
            type: "success"
 | 
			
		||||
          });
 | 
			
		||||
        }, 300);
 | 
			
		||||
          // 刷新列表
 | 
			
		||||
          onSearch();
 | 
			
		||||
        });
 | 
			
		||||
      })
 | 
			
		||||
      .catch(() => {
 | 
			
		||||
        row.status === 0 ? (row.status = 1) : (row.status = 0);
 | 
			
		||||
        message("取消删除", {
 | 
			
		||||
          type: "info"
 | 
			
		||||
        });
 | 
			
		||||
        tableRef.getTableRef().clearSelection();
 | 
			
		||||
      });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function handleDelete(row) {
 | 
			
		||||
    message(`您删除了角色名称为${row.name}的这条数据`, { type: "success" });
 | 
			
		||||
  function handleSortChange(sort) {
 | 
			
		||||
    searchFormParams.pageNum = 1;
 | 
			
		||||
    searchFormParams.orderColumn = sort.prop;
 | 
			
		||||
    searchFormParams.orderDirection = sort.order;
 | 
			
		||||
    onSearch();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function handleSelectionChange(rows) {
 | 
			
		||||
    multipleSelection.value = rows.map(item => item.noticeId);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async function handleAdd(row, done) {
 | 
			
		||||
    await addSystemNoticeApi(row as SystemNoticeRequest).then(() => {
 | 
			
		||||
      message(`您新增了通知标题为${row.noticeTitle}的这条数据`, {
 | 
			
		||||
        type: "success"
 | 
			
		||||
      });
 | 
			
		||||
      // 关闭弹框
 | 
			
		||||
      done();
 | 
			
		||||
      // 刷新列表
 | 
			
		||||
      onSearch();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async function handleUpdate(row, done) {
 | 
			
		||||
    await updateSystemNoticeApi(row as SystemNoticeRequest).then(() => {
 | 
			
		||||
      message(`您新增了通知标题为${row.noticeTitle}的这条数据`, {
 | 
			
		||||
        type: "success"
 | 
			
		||||
      });
 | 
			
		||||
      // 关闭弹框
 | 
			
		||||
      done();
 | 
			
		||||
      // 刷新列表
 | 
			
		||||
      onSearch();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function handleSizeChange(val: number) {
 | 
			
		||||
    console.log(`${val} items per page`);
 | 
			
		||||
    pagination.currentPage = 1;
 | 
			
		||||
    pagination.pageSize = val;
 | 
			
		||||
    searchFormParams.pageNum = pagination.currentPage;
 | 
			
		||||
    searchFormParams.pageSize = pagination.pageSize;
 | 
			
		||||
    onSearch();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function handleCurrentChange(val: number) {
 | 
			
		||||
    console.log(`current page: ${val}`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function handleSelectionChange(val) {
 | 
			
		||||
    console.log("handleSelectionChange", val);
 | 
			
		||||
    pagination.currentPage = val;
 | 
			
		||||
    searchFormParams.pageNum = pagination.currentPage;
 | 
			
		||||
    onSearch();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async function onSearch() {
 | 
			
		||||
    loading.value = true;
 | 
			
		||||
    const { data } = await getRoleList(toRaw(form));
 | 
			
		||||
    dataList.value = data.list;
 | 
			
		||||
    pageLoading.value = true;
 | 
			
		||||
    const { data } = await getSystemNoticeListApi(toRaw(searchFormParams));
 | 
			
		||||
 | 
			
		||||
    dataList.value = data.rows;
 | 
			
		||||
    pagination.total = data.total;
 | 
			
		||||
    pagination.pageSize = data.pageSize;
 | 
			
		||||
    pagination.currentPage = data.currentPage;
 | 
			
		||||
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      loading.value = false;
 | 
			
		||||
      pageLoading.value = false;
 | 
			
		||||
    }, 500);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -167,14 +219,15 @@ export function useRole() {
 | 
			
		||||
    onSearch();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  function openDialog(title = "新增", row?: FormItemProps) {
 | 
			
		||||
  function openDialog(title = "新增", row?: AddNoticeRequest) {
 | 
			
		||||
    addDialog({
 | 
			
		||||
      title: `${title}角色`,
 | 
			
		||||
      title: `${title}公告`,
 | 
			
		||||
      props: {
 | 
			
		||||
        formInline: {
 | 
			
		||||
          name: row?.name ?? "",
 | 
			
		||||
          code: row?.code ?? "",
 | 
			
		||||
          remark: row?.remark ?? ""
 | 
			
		||||
          noticeTitle: row?.noticeTitle ?? "",
 | 
			
		||||
          noticeType: row?.noticeType ?? "",
 | 
			
		||||
          status: row?.status ?? "",
 | 
			
		||||
          noticeContent: row?.noticeContent ?? ""
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      width: "40%",
 | 
			
		||||
@ -183,25 +236,19 @@ export function useRole() {
 | 
			
		||||
      closeOnClickModal: false,
 | 
			
		||||
      contentRenderer: () => h(editForm, { ref: formRef }),
 | 
			
		||||
      beforeSure: (done, { options }) => {
 | 
			
		||||
        const FormRef = formRef.value.getRef();
 | 
			
		||||
        const curData = options.props.formInline as FormItemProps;
 | 
			
		||||
        function chores() {
 | 
			
		||||
          message(`您${title}了角色名称为${curData.name}的这条数据`, {
 | 
			
		||||
            type: "success"
 | 
			
		||||
          });
 | 
			
		||||
          done(); // 关闭弹框
 | 
			
		||||
          onSearch(); // 刷新表格数据
 | 
			
		||||
        }
 | 
			
		||||
        FormRef.validate(valid => {
 | 
			
		||||
        const formRuleRef = formRef.value.getFormRuleRef();
 | 
			
		||||
 | 
			
		||||
        const curData = options.props.formInline as AddNoticeRequest;
 | 
			
		||||
 | 
			
		||||
        formRuleRef.validate(valid => {
 | 
			
		||||
          if (valid) {
 | 
			
		||||
            console.log("curData", curData);
 | 
			
		||||
            // 表单规则校验通过
 | 
			
		||||
            if (title === "新增") {
 | 
			
		||||
              // 实际开发先调用新增接口,再进行下面操作
 | 
			
		||||
              chores();
 | 
			
		||||
              handleAdd(curData, done);
 | 
			
		||||
            } else {
 | 
			
		||||
              // 实际开发先调用编辑接口,再进行下面操作
 | 
			
		||||
              chores();
 | 
			
		||||
              curData.noticeId = row.noticeId;
 | 
			
		||||
              handleUpdate(curData, done);
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
@ -209,33 +256,24 @@ export function useRole() {
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** 菜单权限 */
 | 
			
		||||
  function handleMenu() {
 | 
			
		||||
    message("等菜单管理页面开发后完善");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** 数据权限 可自行开发 */
 | 
			
		||||
  // function handleDatabase() {}
 | 
			
		||||
 | 
			
		||||
  onMounted(() => {
 | 
			
		||||
    onSearch();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    form,
 | 
			
		||||
    loading,
 | 
			
		||||
    searchFormParams,
 | 
			
		||||
    pageLoading,
 | 
			
		||||
    columns,
 | 
			
		||||
    dataList,
 | 
			
		||||
    pagination,
 | 
			
		||||
    // buttonClass,
 | 
			
		||||
    onSearch,
 | 
			
		||||
    resetForm,
 | 
			
		||||
    openDialog,
 | 
			
		||||
    handleMenu,
 | 
			
		||||
    handleDelete,
 | 
			
		||||
    // handleDatabase,
 | 
			
		||||
    handleSizeChange,
 | 
			
		||||
    handleCurrentChange,
 | 
			
		||||
    handleSelectionChange
 | 
			
		||||
    handleSortChange,
 | 
			
		||||
    handleSelectionChange,
 | 
			
		||||
    handleBulkDelete
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,17 @@
 | 
			
		||||
// 虽然字段很少 但是抽离出来 后续有扩展字段需求就很方便了
 | 
			
		||||
 | 
			
		||||
interface FormItemProps {
 | 
			
		||||
  /** 角色名称 */
 | 
			
		||||
  name: string;
 | 
			
		||||
interface AddNoticeRequest {
 | 
			
		||||
  noticeId?: number;
 | 
			
		||||
  /** 公告标题 */
 | 
			
		||||
  noticeTitle: string;
 | 
			
		||||
  /** 角色编号 */
 | 
			
		||||
  code: string;
 | 
			
		||||
  noticeType: string;
 | 
			
		||||
  /** 备注 */
 | 
			
		||||
  remark: string;
 | 
			
		||||
}
 | 
			
		||||
interface FormProps {
 | 
			
		||||
  formInline: FormItemProps;
 | 
			
		||||
  status: string;
 | 
			
		||||
  /** 备注 */
 | 
			
		||||
  noticeContent: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type { FormItemProps, FormProps };
 | 
			
		||||
interface FormProps {
 | 
			
		||||
  formInline: AddNoticeRequest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type { AddNoticeRequest, FormProps };
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								src/views/system/role/form.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/views/system/role/form.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
import { formRules } from "./utils/rule";
 | 
			
		||||
import { FormProps } from "./utils/types";
 | 
			
		||||
 | 
			
		||||
const props = withDefaults(defineProps<FormProps>(), {
 | 
			
		||||
  formInline: () => ({
 | 
			
		||||
    name: "",
 | 
			
		||||
    code: "",
 | 
			
		||||
    remark: ""
 | 
			
		||||
  })
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const ruleFormRef = ref();
 | 
			
		||||
const newFormInline = ref(props.formInline);
 | 
			
		||||
 | 
			
		||||
function getRef() {
 | 
			
		||||
  return ruleFormRef.value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
defineExpose({ getRef });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <el-form
 | 
			
		||||
    ref="ruleFormRef"
 | 
			
		||||
    :model="newFormInline"
 | 
			
		||||
    :rules="formRules"
 | 
			
		||||
    label-width="82px"
 | 
			
		||||
  >
 | 
			
		||||
    <el-form-item label="角色名称" prop="name">
 | 
			
		||||
      <el-input
 | 
			
		||||
        v-model="newFormInline.name"
 | 
			
		||||
        clearable
 | 
			
		||||
        placeholder="请输入角色名称"
 | 
			
		||||
      />
 | 
			
		||||
    </el-form-item>
 | 
			
		||||
 | 
			
		||||
    <el-form-item label="角色标识" prop="code">
 | 
			
		||||
      <el-input
 | 
			
		||||
        v-model="newFormInline.code"
 | 
			
		||||
        clearable
 | 
			
		||||
        placeholder="请输入角色标识"
 | 
			
		||||
      />
 | 
			
		||||
    </el-form-item>
 | 
			
		||||
 | 
			
		||||
    <el-form-item label="备注">
 | 
			
		||||
      <el-input
 | 
			
		||||
        v-model="newFormInline.remark"
 | 
			
		||||
        placeholder="请输入备注信息"
 | 
			
		||||
        type="textarea"
 | 
			
		||||
      />
 | 
			
		||||
    </el-form-item>
 | 
			
		||||
  </el-form>
 | 
			
		||||
</template>
 | 
			
		||||
							
								
								
									
										216
									
								
								src/views/system/role/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								src/views/system/role/index.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,216 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
import { useRole } from "./utils/hook";
 | 
			
		||||
import { PureTableBar } from "@/components/RePureTableBar";
 | 
			
		||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 | 
			
		||||
 | 
			
		||||
// import Database from "@iconify-icons/ri/database-2-line";
 | 
			
		||||
// import More from "@iconify-icons/ep/more-filled";
 | 
			
		||||
import Delete from "@iconify-icons/ep/delete";
 | 
			
		||||
import EditPen from "@iconify-icons/ep/edit-pen";
 | 
			
		||||
import Search from "@iconify-icons/ep/search";
 | 
			
		||||
import Refresh from "@iconify-icons/ep/refresh";
 | 
			
		||||
import Menu from "@iconify-icons/ep/menu";
 | 
			
		||||
import AddFill from "@iconify-icons/ri/add-circle-line";
 | 
			
		||||
 | 
			
		||||
defineOptions({
 | 
			
		||||
  name: "Role"
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const formRef = ref();
 | 
			
		||||
const {
 | 
			
		||||
  form,
 | 
			
		||||
  loading,
 | 
			
		||||
  columns,
 | 
			
		||||
  dataList,
 | 
			
		||||
  pagination,
 | 
			
		||||
  // buttonClass,
 | 
			
		||||
  onSearch,
 | 
			
		||||
  resetForm,
 | 
			
		||||
  openDialog,
 | 
			
		||||
  handleMenu,
 | 
			
		||||
  handleDelete,
 | 
			
		||||
  // handleDatabase,
 | 
			
		||||
  handleSizeChange,
 | 
			
		||||
  handleCurrentChange,
 | 
			
		||||
  handleSelectionChange
 | 
			
		||||
} = useRole();
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="main">
 | 
			
		||||
    <el-form
 | 
			
		||||
      ref="formRef"
 | 
			
		||||
      :inline="true"
 | 
			
		||||
      :model="form"
 | 
			
		||||
      class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]"
 | 
			
		||||
    >
 | 
			
		||||
      <el-form-item label="角色名称:" prop="name">
 | 
			
		||||
        <el-input
 | 
			
		||||
          v-model="form.name"
 | 
			
		||||
          placeholder="请输入角色名称"
 | 
			
		||||
          clearable
 | 
			
		||||
          class="!w-[200px]"
 | 
			
		||||
        />
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <el-form-item label="角色标识:" prop="code">
 | 
			
		||||
        <el-input
 | 
			
		||||
          v-model="form.code"
 | 
			
		||||
          placeholder="请输入角色标识"
 | 
			
		||||
          clearable
 | 
			
		||||
          class="!w-[180px]"
 | 
			
		||||
        />
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <el-form-item label="状态:" prop="status">
 | 
			
		||||
        <el-select
 | 
			
		||||
          v-model="form.status"
 | 
			
		||||
          placeholder="请选择状态"
 | 
			
		||||
          clearable
 | 
			
		||||
          class="!w-[180px]"
 | 
			
		||||
        >
 | 
			
		||||
          <el-option label="已启用" value="1" />
 | 
			
		||||
          <el-option label="已停用" value="0" />
 | 
			
		||||
        </el-select>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      <el-form-item>
 | 
			
		||||
        <el-button
 | 
			
		||||
          type="primary"
 | 
			
		||||
          :icon="useRenderIcon(Search)"
 | 
			
		||||
          :loading="loading"
 | 
			
		||||
          @click="onSearch"
 | 
			
		||||
        >
 | 
			
		||||
          搜索
 | 
			
		||||
        </el-button>
 | 
			
		||||
        <el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
 | 
			
		||||
          重置
 | 
			
		||||
        </el-button>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
    </el-form>
 | 
			
		||||
 | 
			
		||||
    <PureTableBar
 | 
			
		||||
      title="角色列表(仅演示,操作后不生效)"
 | 
			
		||||
      :columns="columns"
 | 
			
		||||
      @refresh="onSearch"
 | 
			
		||||
    >
 | 
			
		||||
      <template #buttons>
 | 
			
		||||
        <el-button
 | 
			
		||||
          type="primary"
 | 
			
		||||
          :icon="useRenderIcon(AddFill)"
 | 
			
		||||
          @click="openDialog()"
 | 
			
		||||
        >
 | 
			
		||||
          新增角色
 | 
			
		||||
        </el-button>
 | 
			
		||||
      </template>
 | 
			
		||||
      <template v-slot="{ size, dynamicColumns }">
 | 
			
		||||
        <pure-table
 | 
			
		||||
          border
 | 
			
		||||
          align-whole="center"
 | 
			
		||||
          showOverflowTooltip
 | 
			
		||||
          table-layout="auto"
 | 
			
		||||
          :loading="loading"
 | 
			
		||||
          :size="size"
 | 
			
		||||
          adaptive
 | 
			
		||||
          :data="dataList"
 | 
			
		||||
          :columns="dynamicColumns"
 | 
			
		||||
          :pagination="pagination"
 | 
			
		||||
          :paginationSmall="size === 'small' ? true : false"
 | 
			
		||||
          :header-cell-style="{
 | 
			
		||||
            background: 'var(--el-table-row-hover-bg-color)',
 | 
			
		||||
            color: 'var(--el-text-color-primary)'
 | 
			
		||||
          }"
 | 
			
		||||
          @selection-change="handleSelectionChange"
 | 
			
		||||
          @page-size-change="handleSizeChange"
 | 
			
		||||
          @page-current-change="handleCurrentChange"
 | 
			
		||||
        >
 | 
			
		||||
          <template #operation="{ row }">
 | 
			
		||||
            <el-button
 | 
			
		||||
              class="reset-margin"
 | 
			
		||||
              link
 | 
			
		||||
              type="primary"
 | 
			
		||||
              :size="size"
 | 
			
		||||
              :icon="useRenderIcon(EditPen)"
 | 
			
		||||
              @click="openDialog('编辑', row)"
 | 
			
		||||
            >
 | 
			
		||||
              修改
 | 
			
		||||
            </el-button>
 | 
			
		||||
            <el-button
 | 
			
		||||
              class="reset-margin"
 | 
			
		||||
              link
 | 
			
		||||
              type="primary"
 | 
			
		||||
              :size="size"
 | 
			
		||||
              :icon="useRenderIcon(Menu)"
 | 
			
		||||
              @click="handleMenu"
 | 
			
		||||
            >
 | 
			
		||||
              菜单权限
 | 
			
		||||
            </el-button>
 | 
			
		||||
            <el-popconfirm
 | 
			
		||||
              :title="`是否确认删除角色名称为${row.name}的这条数据`"
 | 
			
		||||
              @confirm="handleDelete(row)"
 | 
			
		||||
            >
 | 
			
		||||
              <template #reference>
 | 
			
		||||
                <el-button
 | 
			
		||||
                  class="reset-margin"
 | 
			
		||||
                  link
 | 
			
		||||
                  type="primary"
 | 
			
		||||
                  :size="size"
 | 
			
		||||
                  :icon="useRenderIcon(Delete)"
 | 
			
		||||
                >
 | 
			
		||||
                  删除
 | 
			
		||||
                </el-button>
 | 
			
		||||
              </template>
 | 
			
		||||
            </el-popconfirm>
 | 
			
		||||
            <!-- <el-dropdown>
 | 
			
		||||
              <el-button
 | 
			
		||||
                class="ml-3 mt-[2px]"
 | 
			
		||||
                link
 | 
			
		||||
                type="primary"
 | 
			
		||||
                :size="size"
 | 
			
		||||
                :icon="useRenderIcon(More)"
 | 
			
		||||
              />
 | 
			
		||||
              <template #dropdown>
 | 
			
		||||
                <el-dropdown-menu>
 | 
			
		||||
                  <el-dropdown-item>
 | 
			
		||||
                    <el-button
 | 
			
		||||
                      :class="buttonClass"
 | 
			
		||||
                      link
 | 
			
		||||
                      type="primary"
 | 
			
		||||
                      :size="size"
 | 
			
		||||
                      :icon="useRenderIcon(Menu)"
 | 
			
		||||
                      @click="handleMenu"
 | 
			
		||||
                    >
 | 
			
		||||
                      菜单权限
 | 
			
		||||
                    </el-button>
 | 
			
		||||
                  </el-dropdown-item>
 | 
			
		||||
                  <el-dropdown-item>
 | 
			
		||||
                    <el-button
 | 
			
		||||
                      :class="buttonClass"
 | 
			
		||||
                      link
 | 
			
		||||
                      type="primary"
 | 
			
		||||
                      :size="size"
 | 
			
		||||
                      :icon="useRenderIcon(Database)"
 | 
			
		||||
                      @click="handleDatabase"
 | 
			
		||||
                    >
 | 
			
		||||
                      数据权限
 | 
			
		||||
                    </el-button>
 | 
			
		||||
                  </el-dropdown-item>
 | 
			
		||||
                </el-dropdown-menu>
 | 
			
		||||
              </template>
 | 
			
		||||
            </el-dropdown> -->
 | 
			
		||||
          </template>
 | 
			
		||||
        </pure-table>
 | 
			
		||||
      </template>
 | 
			
		||||
    </PureTableBar>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
:deep(.el-dropdown-menu__item i) {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.search-form {
 | 
			
		||||
  :deep(.el-form-item) {
 | 
			
		||||
    margin-bottom: 12px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										241
									
								
								src/views/system/role/utils/hook.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								src/views/system/role/utils/hook.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,241 @@
 | 
			
		||||
import dayjs from "dayjs";
 | 
			
		||||
import editForm from "../form.vue";
 | 
			
		||||
import { message } from "@/utils/message";
 | 
			
		||||
import { getRoleList } from "@/api/system";
 | 
			
		||||
import { ElMessageBox } from "element-plus";
 | 
			
		||||
import { usePublicHooks } from "../../hooks";
 | 
			
		||||
import { addDialog } from "@/components/ReDialog";
 | 
			
		||||
import { type FormItemProps } from "../utils/types";
 | 
			
		||||
import { type PaginationProps } from "@pureadmin/table";
 | 
			
		||||
import { reactive, ref, onMounted, h, toRaw } from "vue";
 | 
			
		||||
 | 
			
		||||
export function useRole() {
 | 
			
		||||
  const form = reactive({
 | 
			
		||||
    name: "",
 | 
			
		||||
    code: "",
 | 
			
		||||
    status: ""
 | 
			
		||||
  });
 | 
			
		||||
  const formRef = ref();
 | 
			
		||||
  const dataList = ref([]);
 | 
			
		||||
  const loading = ref(true);
 | 
			
		||||
  const switchLoadMap = ref({});
 | 
			
		||||
  const { switchStyle } = usePublicHooks();
 | 
			
		||||
  const pagination = reactive<PaginationProps>({
 | 
			
		||||
    total: 0,
 | 
			
		||||
    pageSize: 10,
 | 
			
		||||
    currentPage: 1,
 | 
			
		||||
    background: true
 | 
			
		||||
  });
 | 
			
		||||
  const columns: TableColumnList = [
 | 
			
		||||
    {
 | 
			
		||||
      label: "角色编号",
 | 
			
		||||
      prop: "id",
 | 
			
		||||
      minWidth: 100
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "角色名称",
 | 
			
		||||
      prop: "name",
 | 
			
		||||
      minWidth: 120
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "角色标识",
 | 
			
		||||
      prop: "code",
 | 
			
		||||
      minWidth: 150
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "状态",
 | 
			
		||||
      minWidth: 130,
 | 
			
		||||
      cellRenderer: scope => (
 | 
			
		||||
        <el-switch
 | 
			
		||||
          size={scope.props.size === "small" ? "small" : "default"}
 | 
			
		||||
          loading={switchLoadMap.value[scope.index]?.loading}
 | 
			
		||||
          v-model={scope.row.status}
 | 
			
		||||
          active-value={1}
 | 
			
		||||
          inactive-value={0}
 | 
			
		||||
          active-text="已启用"
 | 
			
		||||
          inactive-text="已停用"
 | 
			
		||||
          inline-prompt
 | 
			
		||||
          style={switchStyle.value}
 | 
			
		||||
          onChange={() => onChange(scope as any)}
 | 
			
		||||
        />
 | 
			
		||||
      )
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "备注",
 | 
			
		||||
      prop: "remark",
 | 
			
		||||
      minWidth: 150
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "创建时间",
 | 
			
		||||
      minWidth: 180,
 | 
			
		||||
      prop: "createTime",
 | 
			
		||||
      formatter: ({ createTime }) =>
 | 
			
		||||
        dayjs(createTime).format("YYYY-MM-DD HH:mm:ss")
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "操作",
 | 
			
		||||
      fixed: "right",
 | 
			
		||||
      width: 240,
 | 
			
		||||
      slot: "operation"
 | 
			
		||||
    }
 | 
			
		||||
  ];
 | 
			
		||||
  // const buttonClass = computed(() => {
 | 
			
		||||
  //   return [
 | 
			
		||||
  //     "!h-[20px]",
 | 
			
		||||
  //     "reset-margin",
 | 
			
		||||
  //     "!text-gray-500",
 | 
			
		||||
  //     "dark:!text-white",
 | 
			
		||||
  //     "dark:hover:!text-primary"
 | 
			
		||||
  //   ];
 | 
			
		||||
  // });
 | 
			
		||||
 | 
			
		||||
  function onChange({ row, index }) {
 | 
			
		||||
    ElMessageBox.confirm(
 | 
			
		||||
      `确认要<strong>${
 | 
			
		||||
        row.status === 0 ? "停用" : "启用"
 | 
			
		||||
      }</strong><strong style='color:var(--el-color-primary)'>${
 | 
			
		||||
        row.name
 | 
			
		||||
      }</strong>吗?`,
 | 
			
		||||
      "系统提示",
 | 
			
		||||
      {
 | 
			
		||||
        confirmButtonText: "确定",
 | 
			
		||||
        cancelButtonText: "取消",
 | 
			
		||||
        type: "warning",
 | 
			
		||||
        dangerouslyUseHTMLString: true,
 | 
			
		||||
        draggable: true
 | 
			
		||||
      }
 | 
			
		||||
    )
 | 
			
		||||
      .then(() => {
 | 
			
		||||
        switchLoadMap.value[index] = Object.assign(
 | 
			
		||||
          {},
 | 
			
		||||
          switchLoadMap.value[index],
 | 
			
		||||
          {
 | 
			
		||||
            loading: true
 | 
			
		||||
          }
 | 
			
		||||
        );
 | 
			
		||||
        setTimeout(() => {
 | 
			
		||||
          switchLoadMap.value[index] = Object.assign(
 | 
			
		||||
            {},
 | 
			
		||||
            switchLoadMap.value[index],
 | 
			
		||||
            {
 | 
			
		||||
              loading: false
 | 
			
		||||
            }
 | 
			
		||||
          );
 | 
			
		||||
          message(`已${row.status === 0 ? "停用" : "启用"}${row.name}`, {
 | 
			
		||||
            type: "success"
 | 
			
		||||
          });
 | 
			
		||||
        }, 300);
 | 
			
		||||
      })
 | 
			
		||||
      .catch(() => {
 | 
			
		||||
        row.status === 0 ? (row.status = 1) : (row.status = 0);
 | 
			
		||||
      });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function handleDelete(row) {
 | 
			
		||||
    message(`您删除了角色名称为${row.name}的这条数据`, { type: "success" });
 | 
			
		||||
    onSearch();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function handleSizeChange(val: number) {
 | 
			
		||||
    console.log(`${val} items per page`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function handleCurrentChange(val: number) {
 | 
			
		||||
    console.log(`current page: ${val}`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function handleSelectionChange(val) {
 | 
			
		||||
    console.log("handleSelectionChange", val);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async function onSearch() {
 | 
			
		||||
    loading.value = true;
 | 
			
		||||
    const { data } = await getRoleList(toRaw(form));
 | 
			
		||||
    dataList.value = data.list;
 | 
			
		||||
    pagination.total = data.total;
 | 
			
		||||
    pagination.pageSize = data.pageSize;
 | 
			
		||||
    pagination.currentPage = data.currentPage;
 | 
			
		||||
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      loading.value = false;
 | 
			
		||||
    }, 500);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const resetForm = formEl => {
 | 
			
		||||
    if (!formEl) return;
 | 
			
		||||
    formEl.resetFields();
 | 
			
		||||
    onSearch();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  function openDialog(title = "新增", row?: FormItemProps) {
 | 
			
		||||
    addDialog({
 | 
			
		||||
      title: `${title}角色`,
 | 
			
		||||
      props: {
 | 
			
		||||
        formInline: {
 | 
			
		||||
          name: row?.name ?? "",
 | 
			
		||||
          code: row?.code ?? "",
 | 
			
		||||
          remark: row?.remark ?? ""
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      width: "40%",
 | 
			
		||||
      draggable: true,
 | 
			
		||||
      fullscreenIcon: true,
 | 
			
		||||
      closeOnClickModal: false,
 | 
			
		||||
      contentRenderer: () => h(editForm, { ref: formRef }),
 | 
			
		||||
      beforeSure: (done, { options }) => {
 | 
			
		||||
        const FormRef = formRef.value.getRef();
 | 
			
		||||
        const curData = options.props.formInline as FormItemProps;
 | 
			
		||||
        function chores() {
 | 
			
		||||
          message(`您${title}了角色名称为${curData.name}的这条数据`, {
 | 
			
		||||
            type: "success"
 | 
			
		||||
          });
 | 
			
		||||
          done(); // 关闭弹框
 | 
			
		||||
          onSearch(); // 刷新表格数据
 | 
			
		||||
        }
 | 
			
		||||
        FormRef.validate(valid => {
 | 
			
		||||
          if (valid) {
 | 
			
		||||
            console.log("curData", curData);
 | 
			
		||||
            // 表单规则校验通过
 | 
			
		||||
            if (title === "新增") {
 | 
			
		||||
              // 实际开发先调用新增接口,再进行下面操作
 | 
			
		||||
              chores();
 | 
			
		||||
            } else {
 | 
			
		||||
              // 实际开发先调用编辑接口,再进行下面操作
 | 
			
		||||
              chores();
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** 菜单权限 */
 | 
			
		||||
  function handleMenu() {
 | 
			
		||||
    message("等菜单管理页面开发后完善");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** 数据权限 可自行开发 */
 | 
			
		||||
  // function handleDatabase() {}
 | 
			
		||||
 | 
			
		||||
  onMounted(() => {
 | 
			
		||||
    onSearch();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    form,
 | 
			
		||||
    loading,
 | 
			
		||||
    columns,
 | 
			
		||||
    dataList,
 | 
			
		||||
    pagination,
 | 
			
		||||
    // buttonClass,
 | 
			
		||||
    onSearch,
 | 
			
		||||
    resetForm,
 | 
			
		||||
    openDialog,
 | 
			
		||||
    handleMenu,
 | 
			
		||||
    handleDelete,
 | 
			
		||||
    // handleDatabase,
 | 
			
		||||
    handleSizeChange,
 | 
			
		||||
    handleCurrentChange,
 | 
			
		||||
    handleSelectionChange
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								src/views/system/role/utils/rule.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/views/system/role/utils/rule.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
import { reactive } from "vue";
 | 
			
		||||
import type { FormRules } from "element-plus";
 | 
			
		||||
 | 
			
		||||
/** 自定义表单规则校验 */
 | 
			
		||||
export const formRules = reactive(<FormRules>{
 | 
			
		||||
  name: [{ required: true, message: "角色名称为必填项", trigger: "blur" }],
 | 
			
		||||
  code: [{ required: true, message: "角色标识为必填项", trigger: "blur" }]
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										15
									
								
								src/views/system/role/utils/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/views/system/role/utils/types.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
// 虽然字段很少 但是抽离出来 后续有扩展字段需求就很方便了
 | 
			
		||||
 | 
			
		||||
interface FormItemProps {
 | 
			
		||||
  /** 角色名称 */
 | 
			
		||||
  name: string;
 | 
			
		||||
  /** 角色编号 */
 | 
			
		||||
  code: string;
 | 
			
		||||
  /** 备注 */
 | 
			
		||||
  remark: string;
 | 
			
		||||
}
 | 
			
		||||
interface FormProps {
 | 
			
		||||
  formInline: FormItemProps;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type { FormItemProps, FormProps };
 | 
			
		||||
							
								
								
									
										39
									
								
								src/views/tool/hooks.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/views/tool/hooks.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
// 抽离可公用的工具函数等用于系统管理页面逻辑
 | 
			
		||||
import { computed } from "vue";
 | 
			
		||||
import { useDark } from "@pureadmin/utils";
 | 
			
		||||
 | 
			
		||||
export function usePublicHooks() {
 | 
			
		||||
  const { isDark } = useDark();
 | 
			
		||||
 | 
			
		||||
  const switchStyle = computed(() => {
 | 
			
		||||
    return {
 | 
			
		||||
      "--el-switch-on-color": "#6abe39",
 | 
			
		||||
      "--el-switch-off-color": "#e84749"
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const tagStyle = computed(() => {
 | 
			
		||||
    return (status: number) => {
 | 
			
		||||
      return status === 1
 | 
			
		||||
        ? {
 | 
			
		||||
            "--el-tag-text-color": isDark.value ? "#6abe39" : "#389e0d",
 | 
			
		||||
            "--el-tag-bg-color": isDark.value ? "#172412" : "#f6ffed",
 | 
			
		||||
            "--el-tag-border-color": isDark.value ? "#274a17" : "#b7eb8f"
 | 
			
		||||
          }
 | 
			
		||||
        : {
 | 
			
		||||
            "--el-tag-text-color": isDark.value ? "#e84749" : "#cf1322",
 | 
			
		||||
            "--el-tag-bg-color": isDark.value ? "#2b1316" : "#fff1f0",
 | 
			
		||||
            "--el-tag-border-color": isDark.value ? "#58191c" : "#ffa39e"
 | 
			
		||||
          };
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    /** 当前网页是否为`dark`模式 */
 | 
			
		||||
    isDark,
 | 
			
		||||
    /** 表现更鲜明的`el-switch`组件  */
 | 
			
		||||
    switchStyle,
 | 
			
		||||
    /** 表现更鲜明的`el-tag`组件  */
 | 
			
		||||
    tagStyle
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							@ -55,6 +55,16 @@ type ResponseData<T> = {
 | 
			
		||||
  data: T;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
type PageDTO<T> = {
 | 
			
		||||
  total: number;
 | 
			
		||||
  rows: Array<T>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface BasePageQuery {
 | 
			
		||||
  pageNumber?: number;
 | 
			
		||||
  pageSize?: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Effect = "light" | "dark";
 | 
			
		||||
 | 
			
		||||
interface ChangeEvent extends Event {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user