123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- import request from "@/utils/request";
- import { PageOption } from "@smallwei/avue";
- import { ElMessageBox, ElMessage } from "element-plus";
- import { useUserStoreHook } from "@/store/modules/user";
- import { checkPerm } from "@/directive/permission";
- import { configs } from "@typescript-eslint/eslint-plugin";
- interface UseCrudConfig {
- // 模块的url,用来进行增删改查
- src?: string;
- dataListUrl?: string;
- afterDataList?: Function;
- afterAdd?: Function;
- // 需要操作的数据
- row?: any;
- // done用于结束操作
- done?: () => void;
- // 具体操作的行
- index?: number;
- // 用于中断操作
- loading?: () => void;
- // 额外查询参数 一般用search的值就可以了
- params?: object;
- // 是否是编辑,如果是编辑调用更新,否则调用新增
- isEdit?: boolean;
- // 用于多选选中后添加进入,toDeleteIds中的key值。
- multipleSelectKey?: string;
- }
- export const useCrud = (config?: UseCrudConfig) => {
- const url = ref(config?.src);
- const commonConfig = ref(config);
- /** 表格配置属性 */
- const option = ref({
- searchIcon: true,
- // searchSpan: 4,
- searchIndex: 3, //searchIcon是否启用功能按钮, searchIndex配置收缩展示的个数,默认为2个
- index: true, //是否显示第几项
- indexLabel: "序号",
- indexWidth: "55px",
- refreshBtn: false,
- border: true,
- viewBtn: true,
- tip: false, //选中的提示
- });
- const data = ref<any>([]); //表格数据
- const form = ref({}); //新增或者编辑弹出的表单绑定值
- /** 表格顶部搜索的表单的变量 v-model */
- const search = ref({});
- /** 表格的分页数据 v-model */
- const page = ref<PageOption>({
- total: 0,
- currentPage: 1,
- pageSize: 10,
- });
- /** 配置项结构 v-model */
- // defaults ?: AvueCrudDefaults;
- // 多选返回的数组,命名是因为后来增加了很多功能,现在这个数组里面的值是根据multipleSelectKey来决定
- const toDeleteIds = ref<Array<string>>([]);
- // 多选返回的数组,返回每一行的row数据
- const selectedRows = ref<any[]>([]);
- const save = async (config?: UseCrudConfig) => {
- try {
- const path = config?.isEdit ? "/update" : "/add";
- const res = (await request({
- url: `${url.value}${path}`,
- method: "post",
- data: form.value,
- })) as any;
- if (res?.code == 200) {
- Methords.dataList();
- config?.done && config?.done();
- ElMessage.success(res?.msg ?? "");
- if (commonConfig.value?.afterAdd) {
- commonConfig.value?.afterAdd(res?.data);
- }
- } else {
- config?.loading && config?.loading();
- ElMessage.error(res?.msg ?? "");
- }
- } catch (err) {
- config?.loading && config?.loading();
- }
- };
- const handleSearchData = () => {
- // const array = [null, undefined, ""];
- search.value = Object.fromEntries(
- Object.entries(search.value).filter(
- ([key, value]) =>
- value !== null &&
- value !== undefined &&
- Object.keys(value).length !== 0
- )
- );
- };
- /**
- * 表格增删改查等基本方法
- */
- const Methords = {
- /**
- * 查询方法
- */
- dataList: async (config?: UseCrudConfig) => {
- handleSearchData();
- try {
- const res = await request({
- url: commonConfig.value?.dataListUrl ?? `${url.value}/page`,
- method: "post",
- data: {
- pageNo: page.value.currentPage,
- pageSize: page.value.pageSize,
- ...(commonConfig.value?.params ?? {}),
- ...search.value,
- },
- });
- if (res?.data) {
- if (res?.data instanceof Array) {
- data.value = res?.data || [];
- page.value.total = res?.data?.length || 0;
- } else {
- data.value = res?.data?.records || [];
- page.value.total = res?.data?.totalCount || 0;
- }
- if (commonConfig.value?.afterDataList) {
- commonConfig.value?.afterDataList();
- }
- }
- config?.done && config?.done();
- } catch (err) {
- config?.loading && config?.loading();
- } finally {
- config?.done && config?.done();
- }
- },
- dataEditList: async (config?: UseCrudConfig) => {
- handleSearchData();
- try {
- const res = await request({
- url: `${url.value}/page`,
- method: "post",
- data: {
- pageNo: page.value.currentPage,
- pageSize: page.value.pageSize,
- ...search.value,
- ...(commonConfig.value?.params ?? {}),
- },
- });
- if (res?.data) {
- if (res?.data instanceof Array) {
- data.value = res?.data || [];
- page.value.total = res?.data?.length || 0;
- } else {
- data.value = res?.data?.records || [];
- for (let i = 0; i < data.value.length; i++) {
- data.value[i].$cellEdit = true;
- if (
- data.value[i].children != undefined &&
- data.value[i].children != null &&
- data.value[i].children.length > 0
- ) {
- for (let j = 0; j < data.value[i].children.length; j++) {
- data.value[i].children[j].$cellEdit = true;
- }
- }
- }
- page.value.total = res?.data?.totalCount || 0;
- }
- }
- config?.done && config?.done();
- } catch (err) {
- config?.loading && config?.loading();
- } finally {
- config?.done && config?.done();
- }
- },
- dataNoPageList: async (config?: UseCrudConfig) => {
- handleSearchData();
- try {
- const res = await request({
- url: `${url.value}/list`,
- method: "post",
- data: {
- ...search.value,
- },
- });
- if (res?.data) {
- data.value = res?.data || [];
- }
- config?.done && config?.done();
- } catch (err) {
- config?.loading && config?.loading();
- } finally {
- config?.done && config?.done();
- }
- },
- createRow: (row: any, done: () => void, loading: () => void) => {
- save({ row: row, done: done, loading: loading });
- },
- updateRow: (
- row: any,
- index: number,
- done: () => void,
- loading: () => void
- ) => {
- save({
- row: row,
- done: done,
- loading: loading,
- index: index,
- isEdit: true,
- });
- },
- deleteRow: async (row: any, index: number, done: () => void) => {
- ElMessageBox.confirm("是否删除所选中数据?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- }).then(async () => {
- if (row.children && row.children.length > 0) {
- ElMessage.error("请先解绑下级关系");
- return;
- }
- try {
- const res = await request({
- url: `${url.value}/del`,
- method: "post",
- data: row,
- });
- Methords.dataList();
- config?.done && config?.done();
- } catch (err) {
- config?.loading && config?.loading();
- } finally {
- config?.done && config?.done();
- }
- });
- },
- // 设置selection: true,后监听选中改变事件,将Id存入数组
- selectionChange: (rows?: any[]) => {
- toDeleteIds.value = [];
- selectedRows.value = [];
- rows?.forEach((element) => {
- toDeleteIds.value.push(
- element[commonConfig.value?.multipleSelectKey ?? "id"]
- );
- selectedRows.value.push(element);
- });
- },
- /**
- * 表格上方的多选删除方法
- */
- multipleDelete: async () => {
- ElMessageBox.confirm("是否删除所选中数据?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- }).then(async () => {
- try {
- const res = await request({
- url: `${url.value}/batch-del`,
- method: "post",
- data: { ids: toDeleteIds.value },
- });
- Methords.dataList();
- config?.done && config?.done();
- } catch (err) {
- config?.loading && config?.loading();
- } finally {
- config?.done && config?.done();
- }
- });
- },
- /**
- * 表格拖拽后批量保存
- * */
- multipleUpdate: async () => {
- try {
- // 由于数据带有$开头的属性,所以需要处理下,改为只传id和sortNum。
- const dtosArray: { id: string; sortNum: number }[] = [];
- for (let i = 0; i < data.value.length; i++) {
- let cur = page.value.currentPage ?? 1;
- cur = cur - 1;
- const size = page.value.pageSize ?? 10;
- let sortNum = cur * size;
- sortNum = sortNum + i;
- dtosArray.push({ id: data.value[i].id, sortNum: sortNum });
- }
- const res = await request({
- url: `${url.value}/batch-update`,
- method: "post",
- data: dtosArray,
- });
- Methords.dataList();
- config?.done && config?.done();
- } catch (err) {
- config?.loading && config?.loading();
- } finally {
- config?.done && config?.done();
- }
- },
- /**
- * 点击搜索按钮触发
- */
- searchChange: async (params: any, done: () => void) => {
- // 点击搜索的时候重置search的值,要不然会传过去所有的值包括空字符串的值
- search.value = params;
- page.value.currentPage = 1;
- Methords.dataList({ done: done });
- },
- /**
- * 点击清空按钮触发
- */
- resetChange: async (item: any) => {
- page.value.currentPage = 1;
- Methords.dataList();
- },
- };
- /**
- * 表格辅助方法,按钮权限,导入导出
- */
- const Utils = {
- checkBtnPerm: (str: string) => {
- // 「超级管理员」拥有所有的按钮权限
- const { roles, perms } = useUserStoreHook().user;
- if (roles.includes("ROOT")) {
- return true;
- }
- const hasPerm = perms?.some((perm) => {
- return str.includes(perm);
- });
- return hasPerm;
- },
- /**
- * 根据返回的数据下载文件
- */
- downloadFile: (response: any) => {
- const fileData = response.data;
- const fileName = decodeURI(
- response.headers["content-disposition"].split(";")[1].split("=")[1]
- );
- const fileType =
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
- const blob = new Blob([fileData], { type: fileType });
- const downloadUrl = window.URL.createObjectURL(blob);
- const downloadLink = document.createElement("a");
- downloadLink.href = downloadUrl;
- downloadLink.download = fileName;
- document.body.appendChild(downloadLink);
- downloadLink.click();
- document.body.removeChild(downloadLink);
- window.URL.revokeObjectURL(downloadUrl);
- },
- /**
- * 下载模版 传入url
- */
- downloadTemplate: async (urlStr: string) => {
- const response = await request({
- url: urlStr,
- method: "get",
- responseType: "arraybuffer",
- });
- Utils.downloadFile(response);
- },
- /**
- * 根据搜索项导出数据
- */
- exportData: async (urlStr: string) => {
- handleSearchData();
- const response = await request({
- url: urlStr,
- method: "post",
- data: search.value,
- responseType: "arraybuffer",
- });
- Utils.downloadFile(response);
- },
- /**
- * 根据搜索项导出数据
- */
- downloadSPCTemplate: async (urlStr: string, filePath: string) => {
- handleSearchData();
- const response = await request({
- url: urlStr,
- method: "post",
- data: search.value,
- params: { filePath: filePath },
- responseType: "arraybuffer",
- });
- Utils.downloadFile(response);
- },
- };
- return {
- url,
- option,
- data,
- form,
- search,
- page,
- toDeleteIds,
- Methords,
- Utils,
- selectedRows,
- commonConfig,
- };
- };
|