crud.ts 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. import type { CreateCrudOptionsRet, CreateCrudOptionsProps } from '@fast-crud/fast-crud';
  2. import type { FsUploaderFormRequestOptions } from '@fast-crud/fast-extends';
  3. import dayjs from 'dayjs';
  4. import { dict } from '@fast-crud/fast-crud';
  5. import axios from 'axios';
  6. import { getServiceEnvConfig } from '~/.env-config';
  7. import type { AddArchivesParams } from './api';
  8. import { getArchives, getFile, addArchives, deleteArchives, downloadArchives } from './api';
  9. const { url, proxyPattern } = getServiceEnvConfig(import.meta.env);
  10. const isHttpProxy = import.meta.env.VITE_HTTP_PROXY === 'Y';
  11. export default function createCrudOptions(crudOptionsProps: CreateCrudOptionsProps): CreateCrudOptionsRet {
  12. return {
  13. crudOptions: {
  14. pagination: {
  15. show: false
  16. },
  17. request: {
  18. pageRequest: async ({ page, query }) => {
  19. query.studentNumber = crudOptionsProps.context?.studentNumber;
  20. const { data } = await getArchives(query);
  21. return { records: data, total: 0, currentPage: page.offset, pageSize: page.limit };
  22. },
  23. addRequest: ({ form }) => {
  24. if (!crudOptionsProps.context) {
  25. return Promise.resolve(true);
  26. }
  27. if (!crudOptionsProps.context.studentNumber) {
  28. crudOptionsProps.context.message.info('没有筛选人员的情况下 , 不允许上传档案!');
  29. throw new Error('没有筛选人员的情况下 , 不允许上传档案');
  30. }
  31. return addArchives({
  32. studentNumber: form.studentNumber,
  33. filePath: form.filePath,
  34. remarks: form.remarks,
  35. filetype: form.filetype
  36. });
  37. },
  38. editRequest: () => {
  39. return Promise.resolve(true);
  40. },
  41. delRequest: (ctx: { row: AddArchivesParams }) => {
  42. const { row } = ctx;
  43. if (!crudOptionsProps.context || !row.id) {
  44. return Promise.resolve(true);
  45. }
  46. if (row.filetype === 'attendance' || row.filetype === 'scores' || row.filetype === 'prefile') {
  47. crudOptionsProps.context.message.info('基础信息自动生成, 不能删除或者编辑!');
  48. return Promise.resolve(true);
  49. }
  50. return deleteArchives(row.id);
  51. }
  52. },
  53. rowHandle: {
  54. show: true,
  55. buttons: {
  56. remove: {
  57. show: true
  58. },
  59. edit: {
  60. show: false
  61. },
  62. view: {
  63. show: false
  64. },
  65. review: {
  66. text: null,
  67. size: 'small',
  68. icon: 'lucide:view',
  69. tooltip: {
  70. slots: {
  71. default() {
  72. return '查看文件';
  73. }
  74. }
  75. },
  76. click: async ({ row }) => {
  77. const { data } = await getFile(row.archiveNumber);
  78. crudOptionsProps.context?.viewActiveFunc(row.arctype, data);
  79. }
  80. }
  81. }
  82. },
  83. toolbar: {
  84. show: false
  85. },
  86. actionbar: {
  87. show: true,
  88. buttons: {
  89. download: {
  90. text: '打包下载档案',
  91. title: '下载当前学员所有档案',
  92. circle: false,
  93. tooltip: {
  94. slots: {
  95. default() {
  96. return '下载当前学员所有档案';
  97. }
  98. }
  99. },
  100. click: async () => {
  101. if (!crudOptionsProps.context) {
  102. return;
  103. }
  104. const { data } = await downloadArchives(crudOptionsProps.context.studentNumber);
  105. const fileUrl = `http://localhost:3200/proxy-pattern/archive/getFileByToken?archiveToken=${data}`;
  106. window.location.href = fileUrl;
  107. }
  108. }
  109. }
  110. },
  111. form: {
  112. wrapper: {
  113. draggable: false,
  114. onOpen: () => {
  115. if (!crudOptionsProps.context) {
  116. return;
  117. }
  118. if (!crudOptionsProps.context.studentNumber) {
  119. crudOptionsProps.context.message.info('没有筛选人员的情况下 , 不允许上传档案!');
  120. throw new Error('没有筛选人员的情况下 , 不允许上传档案');
  121. }
  122. },
  123. onOpened: async context => {
  124. if (crudOptionsProps.context) {
  125. crudOptionsProps.context.archivesForm = context.form;
  126. }
  127. if (!context.form.studentNumber) {
  128. context.form.studentNumber = crudOptionsProps.context?.studentNumber;
  129. }
  130. }
  131. }
  132. },
  133. search: {
  134. show: false
  135. },
  136. columns: {
  137. studentNumber: {
  138. title: '学员编号',
  139. search: {
  140. show: true
  141. },
  142. type: 'text',
  143. column: {
  144. align: 'center'
  145. },
  146. form: {
  147. show: true
  148. }
  149. },
  150. arctype: {
  151. title: '档案类型',
  152. type: 'text',
  153. column: {
  154. align: 'center'
  155. },
  156. form: {
  157. show: false
  158. }
  159. },
  160. filetype: {
  161. title: '类别',
  162. type: 'dict-select',
  163. dict: dict({
  164. data: [
  165. { value: 'avatar', label: '头像' },
  166. { value: 'prefile', disabled: true, label: '个人资料' },
  167. { value: 'scores', disabled: true, label: '考核' },
  168. { value: 'attendance', disabled: true, label: '出勤' },
  169. { value: 'other', label: '其他' }
  170. ]
  171. })
  172. },
  173. filePath: {
  174. title: '档案文件',
  175. type: 'file-uploader',
  176. form: {
  177. component: {
  178. limit: 1,
  179. uploader: {
  180. uploadRequest: async (props: FsUploaderFormRequestOptions) => {
  181. if (!crudOptionsProps.context) {
  182. return false;
  183. }
  184. if (!crudOptionsProps.context.archivesForm.filetype) {
  185. crudOptionsProps.context.message.info('请先选择类别, 在上传档案!');
  186. throw new Error('请先选择类别, 在上传档案!');
  187. }
  188. const action = isHttpProxy
  189. ? `${proxyPattern}/student/upload?fileType`
  190. : `${url}/student/upload?fileType`;
  191. const { file, onProgress } = props;
  192. const data = new FormData();
  193. data.append('file', file);
  194. data.append('fileType', crudOptionsProps.context.archivesForm.filetype);
  195. data.append('studentNumber', crudOptionsProps.context.archivesForm.studentNumber);
  196. const res = await axios.post(action, data, {
  197. headers: {
  198. 'Content-Type': 'multipart/form-data'
  199. },
  200. timeout: 60000,
  201. onUploadProgress(progress) {
  202. onProgress({ percent: Math.round((progress.loaded / progress.total!) * 100) });
  203. }
  204. });
  205. // 上传完成后的结果,一般返回个url 或者key,具体看你的后台返回啥
  206. return res.data.data;
  207. }
  208. }
  209. }
  210. },
  211. column: {
  212. show: false
  213. }
  214. },
  215. remarks: {
  216. title: '备注',
  217. type: 'text',
  218. column: {
  219. align: 'center'
  220. }
  221. },
  222. validityTime: {
  223. title: '档案有效期',
  224. type: 'datetime',
  225. column: {
  226. align: 'center'
  227. },
  228. form: {
  229. show: false
  230. },
  231. search: { show: false },
  232. valueBuilder(context) {
  233. const { value, row, key } = context;
  234. if (value) {
  235. row[key] = dayjs(value).valueOf();
  236. }
  237. },
  238. valueResolve(context) {
  239. const { value, form, key } = context;
  240. if (value) {
  241. form[key] = dayjs(value).format('YYYY-MM-DD HH:mm:ss');
  242. }
  243. }
  244. },
  245. createTime: {
  246. key: 'createTime',
  247. title: '创建时间',
  248. type: 'datetime',
  249. column: {
  250. align: 'center'
  251. },
  252. form: {
  253. show: false
  254. },
  255. search: { show: false },
  256. valueBuilder(context) {
  257. const { value, row, key } = context;
  258. if (value) {
  259. row[key] = dayjs(value).valueOf();
  260. }
  261. },
  262. valueResolve(context) {
  263. const { value, form, key } = context;
  264. if (value) {
  265. form[key] = dayjs(value).format('YYYY-MM-DD HH:mm:ss');
  266. }
  267. }
  268. },
  269. modifyTime: {
  270. title: '修改时间',
  271. key: 'modifyTime',
  272. type: 'datetime',
  273. align: 'center',
  274. column: {
  275. align: 'center'
  276. },
  277. form: {
  278. show: false
  279. },
  280. valueBuilder(context) {
  281. const { value, row, key } = context;
  282. if (value) {
  283. row[key] = dayjs(value).valueOf();
  284. }
  285. },
  286. valueResolve(context) {
  287. const { value, form, key } = context;
  288. if (value) {
  289. form[key] = dayjs(value).format('YYYY-MM-DD HH:mm:ss');
  290. }
  291. }
  292. }
  293. }
  294. }
  295. };
  296. }