detail.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. <!-- 应急物资分类表 -->
  2. <template>
  3. <basic-container class="container">
  4. <el-form :inline="true" :model="QueryForm" :rules="formRules" ref="queryForms" label-suffix=":">
  5. <el-form-item label="物资名称" prop="materialTree">
  6. <el-cascader
  7. :options="wzOptions"
  8. :disabled="props.type == 'look'"
  9. v-model="QueryForm.materialTree"
  10. style="width: 350px"
  11. @change="handleChange"
  12. :props="{ value: 'id', label: 'name' }"
  13. placeholder="请选择物资名称"
  14. clearable
  15. ></el-cascader>
  16. </el-form-item>
  17. <el-form-item label="入库日期" prop="entryDate">
  18. <el-select
  19. v-model="QueryForm.entryDate"
  20. :disabled="props.type == 'look'"
  21. @change="handleChangeDate"
  22. style="width: 200px"
  23. >
  24. <el-option
  25. v-for="item in TimeOptions"
  26. :key="item.deptId"
  27. placeholder="请选择入库日期"
  28. :label="item.inboundTime"
  29. :value="item.inboundTime"
  30. clearable
  31. />
  32. </el-select>
  33. </el-form-item>
  34. <el-form-item label="单价(元)" prop="unitPrice">
  35. <el-select
  36. v-model="QueryForm.unitPrice"
  37. :disabled="props.type == 'look'"
  38. @change="handleChangePrice"
  39. style="width: 200px"
  40. >
  41. <el-option
  42. v-for="item in dj_Options"
  43. :key="item.deptId"
  44. placeholder="请选择单价"
  45. :label="item.unitPrice"
  46. :value="item.unitPrice"
  47. clearable
  48. />
  49. </el-select>
  50. </el-form-item>
  51. </el-form>
  52. <el-form label-width="0" :rules="formRules1" :model="formData" ref="queryForms1">
  53. <el-table :data="formData.tableData" border>
  54. <el-table-column prop="inboundTime" label="维护保养时间" align="center">
  55. <template #default="scope">
  56. <el-form-item
  57. v-if="props.type != 'look'"
  58. :prop="'tableData.' + scope.$index + '.maintenanceTime'"
  59. :rules="formRules1.maintenanceTime"
  60. >
  61. <el-date-picker
  62. clearable
  63. size="small"
  64. style="width: 100%"
  65. v-model="scope.row.maintenanceTime"
  66. type="date"
  67. placeholder="请选择维护保养时间"
  68. format="YYYY-MM-DD"
  69. value-format="YYYY-MM-DD"
  70. >
  71. </el-date-picker>
  72. </el-form-item>
  73. <span v-else>{{ scope.row.maintenanceTime }}</span>
  74. </template>
  75. </el-table-column>
  76. <el-table-column prop="maintenanceUnit" label="维护保养单位" align="center">
  77. <template #default="scope">
  78. <el-form-item
  79. v-if="props.type != 'look'"
  80. :prop="'tableData.' + scope.$index + '.maintenanceUnit'"
  81. :rules="formRules1.maintenanceUnit"
  82. >
  83. <el-input
  84. v-model="scope.row.maintenanceUnit"
  85. size="small"
  86. placeholder="请输入维护保养单位"
  87. clearable
  88. ></el-input>
  89. </el-form-item>
  90. <span v-else>{{ scope.row.maintenanceUnit }}</span>
  91. </template>
  92. </el-table-column>
  93. <el-table-column prop="maintenancePerson" label="维护保养人" align="center">
  94. <template #default="scope">
  95. <el-form-item
  96. v-if="props.type != 'look'"
  97. :prop="'tableData.' + scope.$index + '.maintenancePerson'"
  98. :rules="formRules1.maintenancePerson"
  99. >
  100. <el-input
  101. v-model="scope.row.maintenancePerson"
  102. size="small"
  103. placeholder="请输入维护保养人"
  104. :disabled="props.type == 'look'"
  105. ></el-input>
  106. </el-form-item>
  107. <span v-else>{{ scope.row.maintenancePerson }}</span>
  108. </template>
  109. </el-table-column>
  110. <el-table-column prop="fileName" label="附件上传" align="center">
  111. <template #default="scope">
  112. <el-form-item
  113. v-if="props.type != 'look'"
  114. :prop="'materialMaintenanceStatuses.' + scope.$index + '.fileName'"
  115. >
  116. <el-upload
  117. :disabled="props.type == 'look'"
  118. v-model:file-list="scope.row.filePartList"
  119. class="upload-demo"
  120. style="width: 100%"
  121. :action="fileUrl"
  122. :data="paramsData"
  123. :headers="myHeader"
  124. :on-preview="handlePreview"
  125. multiple
  126. :on-remove="handleRemove"
  127. :before-remove="(response:any, file:any, index:number) => beforeRemove(response, file, scope.$index)"
  128. :on-success="(response:any, file:any, index:number) => getFileInfo(response, file, scope.$index)"
  129. :on-error="errorUpload"
  130. :before-upload="beforeUpload"
  131. :limit="1"
  132. :on-exceed="handleExceed"
  133. >
  134. <el-button v-if="props.type != 'look'" size="small" type="primary">选择文件</el-button>
  135. </el-upload>
  136. </el-form-item>
  137. <p v-else @click="handlePreviewDetail(scope.row.filePart)" style="cursor: pointer; color: #409eff">
  138. {{ scope.row.fileName }}
  139. </p>
  140. </template>
  141. </el-table-column>
  142. <el-table-column v-if="props.type != 'look'" label="操作" align="center" fixed="right" width="102">
  143. <template #default="scope">
  144. <el-button @click="deleteTableData(scope.$index)" type="danger" :icon="Delete" circle />
  145. <el-button @click="addTableData(scope.$index)" type="success" :icon="Plus" circle />
  146. </template>
  147. </el-table-column>
  148. </el-table>
  149. </el-form>
  150. <!---审核记录-->
  151. <el-table
  152. :data="materialMaintenanceStatuses"
  153. v-if="props.type === 'look'"
  154. style="width: 100%; margin-top: 30px"
  155. stripe
  156. border
  157. >
  158. <el-table-column prop="warehouse" label="审核部门" align="center" />
  159. <el-table-column prop="opinion" label="审核意见" align="center" />
  160. <el-table-column prop="auditingTime" label="审核时间" align="center" />
  161. <el-table-column prop="status" label="审核状态" align="center">
  162. <template #default="scope">
  163. {{ scope.row.status ? showCh(scope.row.status, maintenance_auditing_status) : scope.row.status }}
  164. </template>
  165. </el-table-column>
  166. <el-table-column prop="fileName" :label="props.type == 'look' ? '附件' : '附件上传'" align="center">
  167. <template #default="scope">
  168. <p @click="handlePreviewDetail(scope.row.filePart)" style="cursor: pointer; color: #409eff">
  169. {{ scope.row.fileName }}
  170. </p>
  171. </template>
  172. </el-table-column>
  173. </el-table>
  174. <div class="operationbox">
  175. <el-button type="success" @click="saveSubmit('1')" v-if="props.type != 'look'">保存</el-button>
  176. <el-button type="primary" @click="saveSubmit('2')" v-if="props.type != 'look'">提交</el-button>
  177. <el-button @click="returnPage">返回</el-button>
  178. </div>
  179. </basic-container>
  180. </template>
  181. <script setup lang="ts">
  182. import { ref, reactive, onMounted } from "vue";
  183. import { Delete, Plus } from "@element-plus/icons-vue";
  184. import { ElMessage, ElMessageBox } from "element-plus";
  185. import type { UploadProps, FormRules } from "element-plus";
  186. import router from "@/router";
  187. import { dictTree, sysFile } from "@/api/inAndOut/formationFilling/in";
  188. import { getInOptions, addInData, lookInData, updateInData } from "@/api/upkeep/in";
  189. import { useDict } from "@/hooks/dict";
  190. // import { closeTagAndOpenLastTag } from '@/router/Routermethods';
  191. import store from "@/store";
  192. import { getQuery } from "@/hooks/detailQuery/index";
  193. import { useGetters } from "@/hooks/storeHooks";
  194. const { access_token } = useGetters(["access_token"]);
  195. const { maintenance_auditing_status } = useDict("maintenance_auditing_status");
  196. const props = getQuery("/upkeep/ReportDetail");
  197. let materialMaintenanceStatuses = ref([]);
  198. const queryForms = ref();
  199. const queryForms1 = ref();
  200. const wzOptions = ref([]);
  201. const TimeOptions: any = ref([{}]);
  202. const dj_Options: any = ref([]);
  203. const QueryForm = reactive({
  204. materialGroup: "",
  205. materialTree: [],
  206. inboundTime: "",
  207. entryDate: "",
  208. unitPrice: ""
  209. });
  210. const queryInfo = reactive({
  211. materialGroup: "",
  212. materialType: "",
  213. materialName: "",
  214. entryDate: "",
  215. materialUnit: "",
  216. unitPrice: "",
  217. materialTree: []
  218. });
  219. const formRules = reactive({
  220. materialTree: [{ required: true, message: "请选择物资名称", trigger: "change" }],
  221. unitPrice: [{ required: true, message: "请选择单价", trigger: "change" }],
  222. entryDate: [{ required: true, message: "请选择入库日期", trigger: "change" }]
  223. });
  224. const formRules1 = reactive({
  225. maintenanceUnit: [{ required: true, message: "请填写单位", trigger: "blur" }],
  226. maintenancePerson: [{ required: true, message: "请填写保养人", trigger: "blur" }],
  227. maintenanceTime: [{ required: true, message: "请选择维护保养日期", trigger: "change" }],
  228. fileName: [{ required: true, message: "请上传附件", trigger: "change" }]
  229. });
  230. const formData = reactive({
  231. tableData: [
  232. {
  233. maintenanceTime: "",
  234. maintenancePerson: "",
  235. maintenanceUnit: "",
  236. filePart: "",
  237. fileName: "",
  238. filePartList: [{ url: "", name: "" }]
  239. }
  240. ]
  241. });
  242. // 根据码回显中文
  243. const showCh = (value, option) => {
  244. const filterItem = option.filter((item) => item.value == value);
  245. return filterItem.length ? filterItem[0].label : "-";
  246. };
  247. // 下拉数据
  248. const getSelect = () => {
  249. dictTree().then((res: any) => {
  250. if (res.code === 0) {
  251. wzOptions.value = res.data;
  252. }
  253. });
  254. };
  255. //获取物资下拉数据
  256. const getOption = (data: any) => {
  257. getInOptions(data).then((res: any) => {
  258. if (res.code === 0) {
  259. if (data.entryDate) {
  260. dj_Options.value = res.data;
  261. } else {
  262. TimeOptions.value = res.data;
  263. }
  264. }
  265. });
  266. };
  267. const handleChange = (value: string) => {
  268. let wz_name = JSON.parse(JSON.stringify(value));
  269. console.log(wz_name, "wz_name");
  270. if (wz_name && wz_name.length == 4) {
  271. queryInfo.materialGroup = wz_name[0];
  272. queryInfo.materialType = wz_name[1];
  273. queryInfo.materialName = wz_name[2];
  274. queryInfo.materialUnit = wz_name[3];
  275. queryInfo.materialTree = wz_name;
  276. QueryForm.entryDate = "";
  277. queryInfo.entryDate = "";
  278. queryInfo.unitPrice = "";
  279. QueryForm.unitPrice = "";
  280. getOption(queryInfo);
  281. } else {
  282. ElMessage({
  283. message: "物资名称选择有误!",
  284. type: "warning"
  285. });
  286. }
  287. };
  288. const handleChangeDate = (value: string) => {
  289. queryInfo.entryDate = value;
  290. queryInfo.unitPrice = "";
  291. QueryForm.unitPrice = "";
  292. getOption(queryInfo);
  293. };
  294. const handleChangePrice = (value: string) => {
  295. queryInfo.unitPrice = value;
  296. QueryForm.unitPrice = value;
  297. };
  298. // 计算
  299. // const handleChangeNum = (value: string) => {
  300. // if (value) {
  301. // let num = decimalMul(value, QueryForm.unitPrice);
  302. // formData.tableData[0].maintenanceUnit = num;
  303. // }
  304. // };
  305. // 新增一行
  306. const addTableData = (rowIndex: number) => {
  307. const newRow = {};
  308. formData.tableData.splice(rowIndex + 1, 0, newRow);
  309. };
  310. // 删除
  311. const deleteTableData = (rowIndex: number) => {
  312. if (formData.tableData.length > 1) {
  313. formData.tableData.splice(rowIndex, 1);
  314. } else {
  315. ElMessage({
  316. message: "最后一条不可删除!",
  317. type: "warning"
  318. });
  319. }
  320. };
  321. // 详情获取数据
  322. const lookData = () => {
  323. lookInData(props.id).then((res: any) => {
  324. if (res.code === 0) {
  325. let getData = res.data.materialMaintenanceDetails;
  326. formData.tableData = getData.map((item: any) => ({
  327. ...item,
  328. filePartList: item.filePart ? [{ name: item.fileName, filePart: item.filePart }] : []
  329. }));
  330. QueryForm.materialGroup = res.data.materialGroup;
  331. QueryForm.materialType = res.data.materialType;
  332. QueryForm.materialName = res.data.materialName;
  333. QueryForm.materialUnit = res.data.materialUnit;
  334. QueryForm.unitPrice = res.data.unitPrice;
  335. QueryForm.entryDate = res.data.entryDate;
  336. QueryForm.materialTree = res.data.materialTree;
  337. queryInfo.materialGroup = res.data.materialGroup;
  338. queryInfo.materialType = res.data.materialType;
  339. queryInfo.materialName = res.data.materialName;
  340. queryInfo.entryDate = res.data.entryDate;
  341. queryInfo.materialUnit = res.data.materialUnit;
  342. queryInfo.unitPrice = res.data.unitPrice;
  343. queryInfo.materialTree = res.data.materialTree;
  344. materialMaintenanceStatuses.value = res.data.materialMaintenanceStatuses;
  345. console.log(materialMaintenanceStatuses, "materialMaintenanceStatuses");
  346. }
  347. });
  348. };
  349. /** 保存、提交 */
  350. const saveSubmit = (status: any) => {
  351. queryForms.value.validate((valid: any) => {
  352. queryForms1.value.validate((valid1: any) => {
  353. if (valid && valid1) {
  354. let postData = {
  355. ...queryInfo,
  356. status,
  357. id: props.id,
  358. materialMaintenanceDetails: formData.tableData
  359. };
  360. if (props.id) {
  361. updateInData(postData).then((res: any) => {
  362. if (res.code === 0) {
  363. returnPage();
  364. ElMessage({
  365. message: "修改成功!",
  366. type: "success"
  367. });
  368. }
  369. });
  370. } else {
  371. addInData(postData).then((res: any) => {
  372. if (res.code === 0) {
  373. returnPage();
  374. ElMessage({
  375. message: status === "1" ? "新增成功!" : "提交成功!",
  376. type: "success"
  377. });
  378. }
  379. });
  380. }
  381. } else {
  382. console.log("error submit!");
  383. }
  384. });
  385. });
  386. };
  387. /** 返回 */
  388. const returnPage = () => {
  389. store.commit("DEL_TAG", store.getters.tag);
  390. router.push({
  391. path: "/upkeep/report"
  392. });
  393. };
  394. //附件部分
  395. const fileUrl = "/admin/sysFile/uploadVoucher";
  396. let paramsData = reactive({
  397. bucket: "bound"
  398. });
  399. const myHeader = { Authorization: "Bearer " + access_token.value };
  400. // 附件相关
  401. const getFileInfo = (res: any, file: any, index: number) => {
  402. formData.tableData[index].filePart = res.data.fileName;
  403. formData.tableData[index].fileName = file.name;
  404. formData.tableData[index].filePartList = [{ url: res.data.fileName, name: file.name }];
  405. };
  406. const handleRemove = (file: any, uploadFiles: any) => {
  407. console.log(file, uploadFiles);
  408. };
  409. const handlePreview = (file: any) => {
  410. if (file.url) {
  411. sysFile(file.url).then((res: any) => {
  412. const blob = new Blob([res], { type: "application/pdf;charset=UTF-8" });
  413. const bFile = URL.createObjectURL(blob);
  414. window.open(bFile);
  415. });
  416. }
  417. };
  418. const handlePreviewDetail = (url: string) => {
  419. sysFile(url).then((res: any) => {
  420. const blob = new Blob([res], { type: "application/pdf;charset=UTF-8" });
  421. const bFile = URL.createObjectURL(blob);
  422. window.open(bFile);
  423. });
  424. };
  425. const handleExceed = (files: any, uploadFiles: any) => {
  426. ElMessage.warning(`限制上传一个文件`);
  427. };
  428. const beforeRemove = (uploadFile: any, uploadFiles: any, index: number) => {
  429. formData.tableData[index].filePart = "";
  430. formData.tableData[index].fileName = "";
  431. };
  432. const errorUpload = (err: any, file: any, fileList: any) => {
  433. ElMessage.error("文件上传失败,UploadAjaxError:" + JSON.parse(JSON.stringify(err)).status);
  434. };
  435. // 上传前对附件进行的操作
  436. const beforeUpload: UploadProps["beforeUpload"] = (file) => {
  437. // const typeList = ".pdf.jpg.png.gif.jpeg.PDF.JPG.PNG.GIF.JPEG";
  438. const typeList = ".pdf"; //限制为pdf格式
  439. const { name, type } = fileNameDispose(file.name);
  440. if (!typeList.includes(type)) {
  441. ElMessage.error("仅支持pdf类型文件,请重新上传。");
  442. return false;
  443. }
  444. if (name.length > 30) {
  445. ElMessage.error("文件名不可超30字,请重新命名后再上传。");
  446. return false;
  447. }
  448. const isLt20M = file.size / 1024 / 1024 < 100;
  449. if (!isLt20M) {
  450. ElMessage.error("文件大小不可超过 100MB。");
  451. return false;
  452. }
  453. return true;
  454. };
  455. // 获取上传附件的名字和类型
  456. const fileNameDispose = (name: string) => {
  457. const arr = name.split(".");
  458. if (arr.length === 2) {
  459. return { name: arr[0], type: arr[1] };
  460. } else {
  461. const type = arr.splice(arr.length - 1, 1)[0];
  462. const name = arr.join(".");
  463. return { name, type };
  464. }
  465. };
  466. /** -----------------附件结束--------------- */
  467. /** 初始化 **/
  468. onMounted(() => {
  469. getSelect();
  470. if (props.type) {
  471. lookData();
  472. } else {
  473. formData.tableData = [{}];
  474. }
  475. });
  476. </script>
  477. <style lang="scss" scoped>
  478. .operationbox {
  479. text-align: center;
  480. margin-top: 30px;
  481. }
  482. >>> .whole_form .w-200 {
  483. width: 200px !important;
  484. }
  485. </style>