userCrud.ts 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. import request from "@/utils/request";
  2. import { PageOption } from "@smallwei/avue";
  3. import { ElMessageBox, ElMessage } from "element-plus";
  4. import { useUserStoreHook } from "@/store/modules/user";
  5. import { checkPerm } from "@/directive/permission";
  6. interface UseCrudConfig {
  7. // 模块的url,用来进行增删改查
  8. src?: string;
  9. // 需要操作的数据
  10. row?: any;
  11. // done用于结束操作
  12. done?: () => void;
  13. // 具体操作的行
  14. index?: number;
  15. // 用于中断操作
  16. loading?: () => void;
  17. // 查询参数 一般用search的值就可以了
  18. params?: object;
  19. // 是否是编辑,如果是编辑调用更新,否则调用新增
  20. isEdit?: boolean;
  21. }
  22. export const useCrud = (config?: UseCrudConfig) => {
  23. const url = ref(config?.src);
  24. /** 表格配置属性 */
  25. const option = ref({
  26. searchIcon: true,
  27. searchIndex: 3, //searchIcon是否启用功能按钮, searchIndex配置收缩展示的个数,默认为2个
  28. index: true, //是否显示第几项
  29. refreshBtn: false,
  30. border: true,
  31. viewBtn: true,
  32. });
  33. const data = ref<any>([]); //表格数据
  34. const form = ref({}); //新增或者编辑弹出的表单绑定值
  35. /** 表格顶部搜索的表单的变量 v-model */
  36. const search = ref({});
  37. /** 表格的分页数据 v-model */
  38. const page = ref<PageOption>({
  39. total: 12220,
  40. currentPage: 1,
  41. pageSize: 10,
  42. });
  43. /** 配置项结构 v-model */
  44. // defaults ?: AvueCrudDefaults;
  45. const toDeleteIds = ref<Array<string>>([]);
  46. const save = async (config?: UseCrudConfig) => {
  47. const path = config?.isEdit ? "/update" : "/add";
  48. try {
  49. const res = await request({
  50. url: `${url.value}${path}`,
  51. method: "post",
  52. data: form.value,
  53. });
  54. if (res?.data?.code == 200) {
  55. Methords.dataList();
  56. config?.done && config?.done();
  57. } else {
  58. ElMessage.error(res?.data?.msg ?? "");
  59. }
  60. } catch (err) {
  61. ElMessage.error("Oops, this is a error message.");
  62. // config?.loading && config?.loading();
  63. } finally {
  64. ElMessage.error("Oops, this is a error message.");
  65. // config?.done && config?.done();
  66. }
  67. };
  68. const handleSearchData = () => {
  69. // const array = [null, undefined, ""];
  70. search.value = Object.fromEntries(
  71. Object.entries(search.value).filter(
  72. ([key, value]) =>
  73. value !== null &&
  74. value !== undefined &&
  75. Object.keys(value).length !== 0
  76. )
  77. );
  78. };
  79. /**
  80. * 表格增删改查等基本方法
  81. */
  82. const Methords = {
  83. /**
  84. * 查询方法
  85. */
  86. dataList: async (config?: UseCrudConfig) => {
  87. handleSearchData();
  88. try {
  89. const res = await request({
  90. url: `${url.value}/page`,
  91. method: "post",
  92. data: {
  93. pageNo: page.value.currentPage,
  94. pageSize: page.value.pageSize,
  95. ...search.value,
  96. },
  97. });
  98. if (res?.data) {
  99. data.value = res?.data?.records || [];
  100. page.value.total = res?.data?.totalCount || 0;
  101. }
  102. config?.done && config?.done();
  103. } catch (err) {
  104. config?.loading && config?.loading();
  105. } finally {
  106. config?.done && config?.done();
  107. }
  108. },
  109. createRow: (row: any, done: () => void, loading: () => void) => {
  110. save({ row: row, done: done, loading: loading });
  111. },
  112. updateRow: (
  113. row: any,
  114. index: number,
  115. done: () => void,
  116. loading: () => void
  117. ) => {
  118. save({
  119. row: row,
  120. done: done,
  121. loading: loading,
  122. index: index,
  123. isEdit: true,
  124. });
  125. },
  126. deleteRow: async (row: any, index: number, done: () => void) => {
  127. ElMessageBox.confirm("是否删除所选中数据?", "提示", {
  128. confirmButtonText: "确定",
  129. cancelButtonText: "取消",
  130. type: "warning",
  131. }).then(async () => {
  132. try {
  133. const res = await request({
  134. url: `${url.value}/del`,
  135. method: "post",
  136. data: { id: row.id ?? "" },
  137. });
  138. Methords.dataList();
  139. config?.done && config?.done();
  140. } catch (err) {
  141. config?.loading && config?.loading();
  142. } finally {
  143. config?.done && config?.done();
  144. }
  145. });
  146. },
  147. // 设置selection: true,后监听选中改变事件,将Id存入数组
  148. selectionChange: (rows?: any[]) => {
  149. toDeleteIds.value = [];
  150. rows?.forEach((element) => {
  151. toDeleteIds.value.push(element.id);
  152. });
  153. },
  154. /**
  155. * 表格上方的多选删除方法
  156. */
  157. multipleDelete: async () => {
  158. ElMessageBox.confirm("是否删除所选中数据?", "提示", {
  159. confirmButtonText: "确定",
  160. cancelButtonText: "取消",
  161. type: "warning",
  162. }).then(async () => {
  163. try {
  164. const res = await request({
  165. url: `${url.value}/batch-del`,
  166. method: "post",
  167. data: { ids: toDeleteIds.value },
  168. });
  169. Methords.dataList();
  170. config?.done && config?.done();
  171. } catch (err) {
  172. config?.loading && config?.loading();
  173. } finally {
  174. config?.done && config?.done();
  175. }
  176. });
  177. },
  178. /**
  179. * 点击搜索按钮触发
  180. */
  181. searchChange: async (params: any, done: () => void) => {
  182. // 点击搜索的时候重置search的值,要不然会传过去所有的值包括空字符串的值
  183. search.value = params;
  184. page.value.currentPage = 1;
  185. Methords.dataList({ done: done });
  186. },
  187. /**
  188. * 点击清空按钮触发
  189. */
  190. resetChange: async (item: any) => {
  191. page.value.currentPage = 1;
  192. Methords.dataList();
  193. },
  194. };
  195. /**
  196. * 表格辅助方法,按钮权限,导入导出
  197. */
  198. const Utils = {
  199. checkBtnPerm: (str: string) => {
  200. // 「超级管理员」拥有所有的按钮权限
  201. const { roles, perms } = useUserStoreHook().user;
  202. if (roles.includes("ROOT")) {
  203. return true;
  204. }
  205. const hasPerm = perms?.some((perm) => {
  206. return str.includes(perm);
  207. });
  208. return hasPerm;
  209. },
  210. /**
  211. * 根据返回的数据下载文件
  212. */
  213. downloadFile: (response: any) => {
  214. const fileData = response.data;
  215. const fileName = decodeURI(
  216. response.headers["content-disposition"].split(";")[1].split("=")[1]
  217. );
  218. const fileType =
  219. "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
  220. const blob = new Blob([fileData], { type: fileType });
  221. const downloadUrl = window.URL.createObjectURL(blob);
  222. const downloadLink = document.createElement("a");
  223. downloadLink.href = downloadUrl;
  224. downloadLink.download = fileName;
  225. document.body.appendChild(downloadLink);
  226. downloadLink.click();
  227. document.body.removeChild(downloadLink);
  228. window.URL.revokeObjectURL(downloadUrl);
  229. },
  230. /**
  231. * 下载模版 传入url
  232. */
  233. downloadTemplate: async (urlStr: string) => {
  234. const response = await request({
  235. url: urlStr,
  236. method: "get",
  237. responseType: "arraybuffer",
  238. });
  239. Utils.downloadFile(response);
  240. },
  241. /**
  242. * 根据搜索项导出数据
  243. */
  244. exportData: async (urlStr: string) => {
  245. const response = await request({
  246. url: urlStr,
  247. method: "post",
  248. data: search.value,
  249. responseType: "arraybuffer",
  250. });
  251. Utils.downloadFile(response);
  252. },
  253. };
  254. return {
  255. url,
  256. option,
  257. data,
  258. form,
  259. search,
  260. page,
  261. toDeleteIds,
  262. Methords,
  263. Utils,
  264. };
  265. };