crud.tsx 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897
  1. import { AddReq, compute,useCrud ,useExpose, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, uiContext, UserPageQuery, } from '@fast-crud/fast-crud';
  2. import dayjs from 'dayjs';
  3. import * as api from './api';
  4. import { uploadFile } from './api';
  5. import { auth } from '/@/utils/authFunction';
  6. import {request} from '/@/utils/service';
  7. import {getBaseURL} from '/@/utils/baseUrl';
  8. import Cookies from 'js-cookie';
  9. import { successMessage } from '/@/utils/message';
  10. import { dictionary } from '/@/utils/dictionary';
  11. import { APIResponseData } from '../columns/types';
  12. import { computed, h,defineComponent, ref, onMounted, watch } from 'vue';
  13. import { ElTable, ElTableColumn, ElLoading } from 'element-plus';
  14. const BorrowRecords = defineComponent({
  15. props: { form: Object },
  16. setup(props) {
  17. try {
  18. const records = ref([]);
  19. const loading = ref(false);
  20. const filteredRecords = computed(() =>
  21. (records.value || [])/* .filter((item: any) => item?.record_type === 0) */
  22. );
  23. const loadData = async () => {
  24. if (!props.form?.id) return;
  25. loading.value = true;
  26. try {
  27. const res = await api.getBorrowRecords(props.form.id);
  28. records.value = res.data || [];
  29. } finally {
  30. loading.value = false;
  31. }
  32. };
  33. watch(() => props.form?.id, loadData, { immediate: true });
  34. return () => (
  35. <ElTable data={filteredRecords.value} v-loading={loading.value} style="width: 100%">
  36. <ElTableColumn prop="application_no" label="借用编号" />
  37. <ElTableColumn prop="borrower_name" label="借用人" />
  38. <ElTableColumn prop="borrower_code" label="学号/工号"/>
  39. <ElTableColumn prop="record_type_label" label="状态" />
  40. <ElTableColumn prop="borrow_type_display" label="借用类型" />
  41. </ElTable>
  42. );
  43. } catch (e) {
  44. console.error("BorrowRecords setup error:", e);
  45. return () => <div>组件加载失败</div>;
  46. }
  47. }
  48. });
  49. const MaintenanceHistory = defineComponent({
  50. props: { form: Object },
  51. setup(props) {
  52. try {
  53. const records = ref([]);
  54. const loading = ref(false);
  55. const loadData = async () => {
  56. if (!props.form?.id) return;
  57. loading.value = true;
  58. try {
  59. const res = await api.getMaintenanceHistory(props.form.id);
  60. records.value = res.data || [];
  61. } finally {
  62. loading.value = false;
  63. }
  64. };
  65. watch(() => props.form?.id, loadData, { immediate: true });
  66. return () => (
  67. <ElTable data={records.value} v-loading={loading.value} style="width: 100%">
  68. <ElTableColumn prop="damage_no" label="维修编号" />
  69. <ElTableColumn prop="device_name" label="设备名称" />
  70. <ElTableColumn prop="damage_reason" label="损坏原因" />
  71. <ElTableColumn prop="estimated_loss" label="损失价格" />
  72. </ElTable>
  73. );
  74. } catch (e) {
  75. console.error("MaintenanceHistory setup error:", e);
  76. return () => <div>组件加载失败</div>;
  77. }
  78. }
  79. });
  80. const MaintenanceRecords = defineComponent({
  81. props: { form: Object },
  82. setup(props) {
  83. try {
  84. const records = ref([]);
  85. const loading = ref(false);
  86. const loadData = async () => {
  87. if (!props.form?.id) return;
  88. loading.value = true;
  89. try {
  90. const res = await api.getMaintenanceRecords(props.form.id);
  91. records.value = res.data || [];
  92. } finally {
  93. loading.value = false;
  94. }
  95. };
  96. watch(() => props.form?.id, loadData, { immediate: true });
  97. return () => (
  98. <ElTable data={records.value} v-loading={loading.value} style="width: 100%">
  99. <ElTableColumn prop="record_no" label="保养编号" />
  100. <ElTableColumn prop="plan_name" label="保养计划" />
  101. <ElTableColumn prop="planned_date" label="保养日期" />
  102. <ElTableColumn prop="maintenance_person" label="保养人员" />
  103. <ElTableColumn prop="maintenance_content" label="保养内容" />
  104. </ElTable>
  105. );
  106. } catch (e) {
  107. console.error("MaintenanceRecords setup error:", e);
  108. return () => <div>组件加载失败</div>;
  109. }
  110. }
  111. });
  112. const DeviceStatistics = defineComponent({
  113. props: { form: Object },
  114. setup(props) {
  115. try {
  116. const statistics = ref<any>({});
  117. const loading = ref(false);
  118. const loadData = async () => {
  119. if (!props.form?.id) return;
  120. loading.value = true;
  121. try {
  122. const res = await api.getDeviceStatistics(props.form.id);
  123. statistics.value = res.data || {};
  124. } finally {
  125. loading.value = false;
  126. }
  127. };
  128. watch(() => props.form?.id, loadData, { immediate: true });
  129. return () => (
  130. <div v-loading={loading.value} style={{ padding: '20px' }}>
  131. <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '20px' }}>
  132. <div style={{ background: '#f5f7fa', padding: '20px', borderRadius: '8px', textAlign: 'center' }}>
  133. <div style={{ fontSize: '24px', fontWeight: 'bold', color: '#409eff' }}>{statistics.value.total_borrow_count || 0}</div>
  134. <div style={{ color: '#606266', marginTop: '8px' }}>总借用次数</div>
  135. </div>
  136. <div style={{ background: '#f5f7fa', padding: '20px', borderRadius: '8px', textAlign: 'center' }}>
  137. <div style={{ fontSize: '24px', fontWeight: 'bold', color: '#67c23a' }}>{statistics.value.total_maintenance_count || 0}</div>
  138. <div style={{ color: '#606266', marginTop: '8px' }}>总保养次数</div>
  139. </div>
  140. <div style={{ background: '#f5f7fa', padding: '20px', borderRadius: '8px', textAlign: 'center' }}>
  141. <div style={{ fontSize: '24px', fontWeight: 'bold', color: '#e6a23c' }}>{statistics.value.total_repair_count || 0}</div>
  142. <div style={{ color: '#606266', marginTop: '8px' }}>总维修次数</div>
  143. </div>
  144. {/* <div style={{ background: '#f5f7fa', padding: '20px', borderRadius: '8px', textAlign: 'center' }}>
  145. <div style={{ fontSize: '24px', fontWeight: 'bold', color: '#f56c6c' }}>{statistics.value.availability_rate || '0%'}</div>
  146. <div style={{ color: '#606266', marginTop: '8px' }}>设备可用率</div>
  147. </div> */}
  148. </div>
  149. {statistics.value.recent_activities && (
  150. <div style={{ marginTop: '30px' }}>
  151. <h3 style={{ marginBottom: '20px', color: '#303133' }}>最近活动</h3>
  152. <ElTable data={statistics.value.recent_activities} style={{ width: '100%' }}>
  153. <ElTableColumn prop="activity_type" label="活动类型" />
  154. <ElTableColumn prop="activity_date" label="活动日期" />
  155. <ElTableColumn prop="description" label="描述" />
  156. </ElTable>
  157. </div>
  158. )}
  159. </div>
  160. );
  161. } catch (e) {
  162. console.error("DeviceStatistics setup error:", e);
  163. return () => <div>组件加载失败</div>;
  164. }
  165. }
  166. });
  167. export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
  168. const pageRequest = async (query: UserPageQuery) => {
  169. return await api.GetList(query);
  170. };
  171. const editRequest = async ({ form, row }: EditReq) => {
  172. form.id = row.id;
  173. return await api.UpdateObj(form);
  174. };
  175. const delRequest = async ({ row }: DelReq) => {
  176. return await api.DelObj(row.id);
  177. };
  178. const addRequest = async ({ form }: AddReq) => {
  179. return await api.AddObj(form);
  180. };
  181. const selectedIds = ref<any[]>([]);
  182. const onSelectionChange = (changed: any[]) => {
  183. console.log("selection", changed);
  184. selectedIds.value = changed.map((item: any) => item.id);
  185. };
  186. (crudExpose as any).selectedIds = selectedIds;
  187. return {
  188. // selectedIds,
  189. crudOptions: {
  190. request: {
  191. pageRequest,
  192. addRequest,
  193. editRequest,
  194. delRequest,
  195. },
  196. table: {
  197. rowKey: "id",
  198. onSelectionChange
  199. },
  200. toolbar:{
  201. show:true,
  202. },
  203. rowHandle: {
  204. fixed: 'right',
  205. width: 220,
  206. view: {
  207. show: true,
  208. },
  209. edit: {
  210. show: true,
  211. },
  212. remove: {
  213. show: true,
  214. },
  215. },
  216. actionbar: {
  217. buttons: {
  218. add: {
  219. show: auth('user:Create')
  220. },
  221. // batchimport:{
  222. // text: "批量导入",
  223. // title: "导入",
  224. // // show: auth('user:batchimport'),
  225. // },
  226. // export: {
  227. // text: "导出",
  228. // title: "导出",
  229. // show: auth('user:Export'),
  230. // },
  231. // downloadtemplate: {
  232. // text: "下载模板",
  233. // title: "下载模板",
  234. // // show: auth('user:Export'),
  235. // },
  236. // batchdelete: {
  237. // text: "批量删除",
  238. // title: "批量删除",
  239. // // show: auth('user:Export'),
  240. // },
  241. }
  242. },
  243. columns: {
  244. $checked: {
  245. title: "选择",
  246. form: { show: false },
  247. column: {
  248. type: "selection",
  249. align: "center",
  250. width: "55px",
  251. columnSetDisabled: true, //禁止在列设置中选择
  252. selectable(row, index) {
  253. // return row.id !== 1; //设置第一行不允许选择
  254. return row.id;
  255. }
  256. }
  257. },
  258. _index: {
  259. title: '序号',
  260. form: { show: false },
  261. column: {
  262. align: 'center',
  263. width: '70px',
  264. columnSetDisabled: true,
  265. formatter: (context) => {
  266. let index = context.index ?? 1;
  267. let pagination = crudExpose!.crudBinding.value.pagination;
  268. return ((pagination!.currentPage ?? 1) - 1) * pagination!.pageSize + index + 1;
  269. },
  270. },
  271. },
  272. search:{
  273. title: '关键字搜索',
  274. search: { show: true,type: 'input', },
  275. type: 'input',
  276. form: {
  277. component: { placeholder: '请输入' },
  278. show:false},
  279. column: {show:false}
  280. },
  281. code: {
  282. title: '设备编号',
  283. search: { show: true },
  284. type: 'input',
  285. column: { minWidth: 120 },
  286. form: {
  287. component: { placeholder: '请输入设备编号' },
  288. rules: [{ required: true, message: '请输入设备编号' }],
  289. },
  290. viewForm:{
  291. component: { placeholder: '' },
  292. rules: [{ required: true, message: '' }],
  293. },
  294. },
  295. category_name: {
  296. title: '设备分类',
  297. search: { show: true },
  298. type: 'dict-select',
  299. dict: dict({
  300. url: '/api/system/device/category/?page=1&limit=100',
  301. value: 'id',
  302. label: 'name',
  303. }),
  304. column: { minWidth: 100 },
  305. form: {
  306. show:false,
  307. component: { placeholder: '请选择设备分类' },
  308. rules: [{ required: true, message: '请选择设备分类' }],
  309. },
  310. viewForm:{
  311. component: { placeholder: '' },
  312. rules: [{ required: true, message: '' }],
  313. }
  314. },
  315. name: {
  316. title: '设备名称',
  317. search: { show: false },
  318. type: 'input',
  319. column: { minWidth: 120 },
  320. form: {
  321. component: { placeholder: '请输入设备名称' },
  322. rules: [{ required: true, message: '请输入设备名称' }]
  323. },
  324. viewForm:{
  325. component: { placeholder: '' },
  326. rules: [{ required: true, message: '' }],
  327. }
  328. },
  329. "inventory.borrowed_quantity":{
  330. title: '设备状态',
  331. type: 'text',
  332. search: { show: false },
  333. column: {
  334. show: true,
  335. minWidth: 100,
  336. formatter: ({ row }) => {
  337. const isBorrowed = row.borrowed_quantity > 0;
  338. const label = isBorrowed ? row.total_quantity-row.borrowed_quantity==0?'在借':'在借' : row.total_quantity==0?'在借':'空闲';
  339. const color = isBorrowed ? '#FFA500' : '#4CAF50';
  340. return h(
  341. 'span',
  342. {
  343. style: {
  344. display: 'inline-block',
  345. padding: '2px 8px',
  346. border: `1px solid ${color}`,
  347. borderRadius: '4px',
  348. backgroundColor: color,
  349. color: 'white',
  350. fontWeight: 'bold',
  351. }
  352. },
  353. label
  354. );
  355. }
  356. },
  357. form: {
  358. show:false,
  359. component: { placeholder: '请选择设备状态' },
  360. rules: [{ required: true, message: '请选择设备状态' }],
  361. },
  362. },
  363. borrowed_quantity:{
  364. title:"已借出",
  365. type:'input',
  366. search:{show:false},
  367. column: { minWidth: 100 },
  368. form: {
  369. show:false,
  370. component: { placeholder: '请输入已借出' },
  371. rules: [{ required: true, message: '请输入已借出' }],
  372. },
  373. viewForm:{
  374. component: { placeholder: '' },
  375. rules: [{ required: true, message: '' }],
  376. }
  377. },
  378. brand:{
  379. title:'品牌',
  380. type:"input",
  381. column: { minWidth: 100 },
  382. form: {
  383. component: { placeholder: '请输入品牌' }
  384. },
  385. viewForm:{
  386. component: { placeholder: '' },
  387. rules: [{ required: true, message: '' }],
  388. },
  389. },
  390. specification: {
  391. title: '规格型号',
  392. search: { show: false },
  393. type: 'input',
  394. column: { minWidth: 100 },
  395. form: {
  396. component: { placeholder: '请输入规格型号' }
  397. },
  398. viewForm:{
  399. component: { placeholder: '' },
  400. rules: [{ required: true, message: '' }],
  401. },
  402. },
  403. serial_number:{
  404. title:'序列号',
  405. type:"input",
  406. column: { minWidth: 100 },
  407. form: {
  408. component: { placeholder: '请输入序列号' }
  409. },
  410. viewForm:{
  411. component: { placeholder: '' },
  412. rules: [{ required: true, message: '' }],
  413. },
  414. },
  415. total_quantity:{
  416. title:'库存数量',
  417. type:"input",
  418. column: { minWidth: 100 },
  419. addForm:{
  420. show:false,
  421. },
  422. viewForm:{
  423. show:false,
  424. },
  425. editForm:{show:false},
  426. from:{
  427. show:false,
  428. component: { placeholder: '请输入库存数量' },
  429. rules: [{ required: false, message: '请输入库存数量' }],
  430. }
  431. },
  432. /* warehouse:{
  433. title:'存放仓库',
  434. search: { show: true },
  435. type:"dict-select",
  436. column: { minWidth: 150 },
  437. dict: dict({
  438. url: '/api/system/warehouse/',
  439. value: 'id',
  440. label: 'name'
  441. }),
  442. form: {
  443. component: { placeholder: '请选择存放仓库' },
  444. rules: [{ required: true, message: '请选择存放仓库' }],
  445. }
  446. }, */
  447. status:{
  448. title:'是否可见',
  449. type: 'dict-switch',
  450. column: {
  451. show:false,
  452. minWidth: 90,
  453. component: {
  454. name: 'fs-dict-switch',
  455. activeText: '',
  456. inactiveText: '',
  457. style: '--el-switch-on-color: var(--el-color-primary); --el-switch-off-color: #dcdfe6',
  458. onChange: compute((context) => {
  459. return () => {
  460. api.UpdateObjStatus(context.row).then((res:APIResponseData) => {
  461. successMessage(res.msg as string);
  462. });
  463. };
  464. }),
  465. },
  466. },
  467. dict: dict({
  468. data: dictionary('device_button_status_bool'),
  469. }),
  470. form: {
  471. show:false,
  472. rules: [{ required: true, message: '请选择是否可见' }],
  473. },
  474. viewForm:{
  475. component: { placeholder: '' },
  476. rules: [{ required: true, message: '' }],
  477. }
  478. },
  479. status_label:{
  480. title: '当前状态',
  481. search: { show: false },
  482. form: {
  483. show:false,
  484. }
  485. },
  486. department: {
  487. title: '所属部门',
  488. search: { show: false },
  489. type: 'input',
  490. column: { minWidth: 120 },
  491. form: {
  492. component: { placeholder: '请输入所属部门' }
  493. },
  494. viewForm:{
  495. component: { placeholder: '' },
  496. rules: [{ required: true, message: '' }],
  497. }
  498. },
  499. purchase_date: {
  500. title: '采购时间',
  501. type: 'date',
  502. search: { show: false },
  503. column: {
  504. minWidth: 120,
  505. formatter: ({ value }) => (value ? dayjs(value).format('YYYY-MM-DD') : ''),
  506. },
  507. form: {
  508. component: { placeholder: '请选择采购时间' },
  509. rules: [{ required: false, message: '请选择采购时间' }],
  510. },
  511. viewForm:{
  512. component: { placeholder: '' },
  513. rules: [{ required: true, message: '' }],
  514. },
  515. valueResolve({ form, value }) {
  516. form.purchase_date = value ? dayjs(value).format('YYYY-MM-DD') : null;
  517. },
  518. valueBuilder({ form, value }) {
  519. form.purchase_date = value;
  520. },
  521. },
  522. supplier: {
  523. title: '供应商',
  524. type: 'dict-select',
  525. search: { show: true },
  526. column: {
  527. minWidth: 120,
  528. },
  529. dict: dict({
  530. url: '/api/system/supplier/',
  531. value: 'id',
  532. label: 'name'
  533. }),
  534. form: {
  535. component: { placeholder: '请输入供应商' },
  536. },
  537. viewForm:{
  538. component: { placeholder: '' },
  539. rules: [{ required: true, message: '' }],
  540. }
  541. },
  542. price: {
  543. title: '价格',
  544. type: 'number',
  545. search: { show: false },
  546. column: { minWidth: 100 },
  547. form: {
  548. component: { placeholder: '请输入设备购入价格' },
  549. rules: [{ required: false, message: '请输入设备购入价格' }],
  550. },
  551. viewForm:{
  552. component: { placeholder: '' },
  553. rules: [{ required: true, message: '' }],
  554. }
  555. },
  556. warranty_expiration: {
  557. title: '质保到期',
  558. type: 'date',
  559. search: { show: false },
  560. column: { minWidth: 120 ,
  561. formatter: ({ value }) => (value ? dayjs(value).format('YYYY-MM-DD') : ''),
  562. },
  563. viewForm: {
  564. title: '质保到期',
  565. component: {
  566. render({ value }) {
  567. // eslint-disable-next-line no-console
  568. console.log("valuevaluevalue:::",value);
  569. if (!value) return '';
  570. const formatted = dayjs(value).format('YYYY-MM-DD');
  571. const isExpired = dayjs(value).isBefore(dayjs(), 'day');
  572. return h(
  573. 'span',
  574. {
  575. style: {
  576. color: isExpired ? 'red' : 'inherit',
  577. fontWeight: isExpired ? 'bold' : 'normal'
  578. }
  579. },
  580. isExpired ? `${formatted}(已过期)` : formatted
  581. );
  582. },
  583. showHtml: true,
  584. }
  585. },
  586. form: {
  587. component: { placeholder: '请选择质保到期' },
  588. rules: [{ required: false, message: '请选择质保到期' }],
  589. },
  590. valueResolve({ form, value }) {
  591. form.warranty_expiration = value ? dayjs(value).format('YYYY-MM-DD') : null;
  592. },
  593. valueBuilder({ form, value }) {
  594. form.warranty_expiration = value;
  595. },
  596. },
  597. tenant_id:{
  598. title: '租户id',
  599. type: 'input',
  600. value: 1,
  601. column: {
  602. show:false,
  603. minWidth: 120,
  604. },
  605. // dict: dict({
  606. // url: '/api/system/tenant/list/',
  607. // value: 'id',
  608. // label: 'name'
  609. // }),
  610. form: {
  611. value:1,
  612. show:false,
  613. component: { placeholder: '请填租户id' },
  614. rules: [{ required: false, message: '请填租户id' }],
  615. },
  616. viewForm:{
  617. component: { placeholder: '' },
  618. rules: [{ required: true, message: '' }],
  619. }
  620. },
  621. category:{
  622. show: false,
  623. title: '设备类别',
  624. search: { show: false },
  625. type: 'dict-select',
  626. column: { show: false,minWidth: 120 },
  627. dict: dict({
  628. url: '/api/system/device/category/?page=1&limit=100',
  629. value: 'id',
  630. label: 'name'
  631. }),
  632. form: {
  633. component: {
  634. placeholder: '请输入设备类别',
  635. filterable: true
  636. },
  637. rules: [{ required: true, message: '请输入设备类别' }],
  638. },
  639. viewForm:{
  640. component: { placeholder: '' },
  641. rules: [{ required: true, message: '' }],
  642. }
  643. },
  644. quantity:{
  645. show: false,
  646. title: '库存数量',
  647. search: { show: false },
  648. type: 'input',
  649. column: { show: false,minWidth: 120 },
  650. viewForm:{
  651. component:{placeholder:""}
  652. },
  653. form: {
  654. component: { placeholder: '请输入库存数量' },
  655. rules: [{ required: true, message: '请输入库存数量' }],
  656. valueResolve({ form, value }) {
  657. form.quantity = Number(value ?? 0);
  658. },
  659. valueBuilder({ form, value }) {
  660. // form.tags =Array.from(String(value), Number);
  661. form.quantity = form.total_quantity;
  662. }
  663. }
  664. },
  665. tags:{
  666. show: false,
  667. title: '设备标签',
  668. search: { show: false },
  669. type: 'dict-select',
  670. column: { show: false,minWidth: 120 },
  671. dict: dict({
  672. url: '/api/system/device_tags/?page=1&limit=100',
  673. value: 'id',
  674. label: 'name'
  675. }),
  676. viewForm:{
  677. component:{placeholder:""}
  678. },
  679. form: {
  680. component: { placeholder: '请选择设备标签',
  681. filterable: true
  682. },
  683. rules: [{ required: true, message: '请选择设备标签' }],
  684. valueResolve({ form, value }) {
  685. form.tags = Array.from(String(value), Number);
  686. },
  687. valueBuilder({ form, value }) {
  688. if(value){
  689. form.tags = Array.isArray(value)? value.length > 0 ? Number(value[0]) : '': Number(value);
  690. }
  691. },
  692. }
  693. },
  694. image:{
  695. title: '设备图片',
  696. type: 'image-uploader',
  697. column: {
  698. minWidth: 120,
  699. show:false,
  700. },
  701. form: {
  702. show: auth('image:upload'),
  703. component: {
  704. uploader: {
  705. type: 'form',
  706. limit: 1,
  707. action: '/api/system/device/upload-image/',
  708. accept: ".jpg,.png",
  709. uploadRequest: async ({ action, file, onProgress }) => {
  710. const token = Cookies.get('token');
  711. const data = new FormData();
  712. data.append("image", file);
  713. return await request({
  714. url: action,
  715. method: "post",
  716. timeout: 60000,
  717. headers: {
  718. "Content-Type": "multipart/form-data",
  719. "Authorization": token ? `JWT ${token}` : ''
  720. },
  721. data,
  722. onUploadProgress: (p) => {
  723. onProgress({ percent: Math.round((p.loaded / p.total) * 100) });
  724. }
  725. });
  726. },
  727. successHandle(ret) {
  728. // eslint-disable-next-line no-console
  729. // console.log("ret.data.image_url:::",ret.data.image_url);
  730. return {
  731. url: getBaseURL(ret.data.image_url),
  732. key: ret.data.id,
  733. ...ret.data
  734. };
  735. },
  736. }
  737. },
  738. },
  739. valueBuilder({ row, key }) {
  740. return row[key] ? [row[key]] : [];
  741. },
  742. valueResolve({ form, key }) {
  743. // eslint-disable-next-line no-console
  744. console.log("form[key]:::",form[key]);
  745. form[key] = Array.isArray(form[key]) ? form[key][0] : form[key];
  746. }
  747. },
  748. id: {
  749. title: 'deviceid',
  750. search: { show: false },
  751. type: 'input',
  752. column: { show:false,minWidth: 120 },
  753. form: {
  754. show:false,
  755. component: { placeholder: '请输入维修' }
  756. },
  757. viewForm:{
  758. show:true,
  759. component: { placeholder: '' },
  760. rules: [{ required: true, message: '' }],
  761. }
  762. },
  763. },
  764. viewForm: {
  765. wrapper: {
  766. buttons: {
  767. ok:{
  768. text:'提交',
  769. show:false
  770. }
  771. }
  772. },
  773. row: { gutter: 20 },
  774. group: {
  775. groupType: "tabs",
  776. groups: {
  777. base: {
  778. slots: {
  779. label: (scope) => {
  780. return (
  781. <span style={{ color: scope.hasError ? "red" : "green" }}>
  782. <fs-icon icon={"ion:checkmark-circle"} />
  783. 基础信息
  784. </span>
  785. );
  786. }
  787. },
  788. icon: "el-icon-goods",
  789. columns: ["code","category_name", "name", "status","borrowed_quantity","brand","specification","serial_number","warehouse","is_visible","department","purchase_date","supplier","price","warranty_expiration","tenant_id","category","quantity","tags","image"]
  790. },
  791. borrow: {
  792. show:true,
  793. label: "借用记录",
  794. icon: "el-icon-price-tag",
  795. columns: ["id"],
  796. slots: {
  797. default: (scope) => {
  798. const currentRow = crudExpose.getFormData();
  799. console.log("currentRow::",currentRow);
  800. return <BorrowRecords form={currentRow || {}}/>;
  801. }
  802. }
  803. },
  804. maintenance: {
  805. show:true,
  806. label: "维修记录",
  807. icon: "el-icon-warning-outline",
  808. columns: ["id"],
  809. slots: {
  810. default: (scope) => {
  811. const currentRowwx = crudExpose.getFormData();
  812. console.log("currentRowwx::",currentRowwx);
  813. return <MaintenanceHistory form={currentRowwx || {}} />
  814. }
  815. }
  816. },
  817. maintain: {
  818. show: true,
  819. label: "保养记录",
  820. icon: "el-icon-warning-outline",
  821. columns: ["id"],
  822. slots: {
  823. default: (scope) => {
  824. const currentRowMaintain = crudExpose.getFormData();
  825. console.log("currentRowMaintain::",currentRowMaintain);
  826. return <MaintenanceRecords form={currentRowMaintain || {}} />
  827. }
  828. }
  829. },
  830. datastatis: {
  831. show: true,
  832. label: "数据统计",
  833. icon: "el-icon-data-analysis",
  834. columns: ["id"],
  835. slots: {
  836. default: (scope) => {
  837. const currentRowStats = crudExpose.getFormData();
  838. console.log("currentRowStats::",currentRowStats);
  839. return <DeviceStatistics form={currentRowStats || {}} />
  840. }
  841. }
  842. },
  843. }
  844. }
  845. },
  846. },
  847. };
  848. };