index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. <template>
  2. <div class="mainContentBox">
  3. <avue-crud
  4. ref="crudRef"
  5. v-model:search="search"
  6. v-model="form"
  7. :data="data"
  8. :option="option"
  9. v-model:page="page"
  10. @row-save="createRowSave"
  11. @row-update="updateRow"
  12. @row-del="deleteRow"
  13. :table-loading="loading"
  14. @search-change="searchChange"
  15. @search-reset="resetChange"
  16. @size-change="dataList"
  17. @current-change="dataList"
  18. @selection-change="selectionChange"
  19. >
  20. <!-- <template #menu-right="{}">
  21. <el-button
  22. class="ml-3"
  23. @click="handleExport"
  24. >
  25. <template #icon> <i-ep-download /> </template>导出
  26. </el-button>
  27. </template>-->
  28. <template #menu="{ size, row, index }">
  29. <!-- <el-button
  30. icon="el-icon-edit"
  31. text
  32. @click="openDialog(1, row.id)"
  33. type="primary"
  34. :size="size"
  35. >编辑</el-button
  36. >-->
  37. <el-button
  38. icon="el-icon-view"
  39. text
  40. @click="openDialog(0, row)"
  41. type="primary"
  42. :size="size"
  43. >详情</el-button
  44. >
  45. </template>
  46. </avue-crud>
  47. <el-dialog
  48. v-model="dialog.visible"
  49. :title="dialog.title"
  50. width="1600px"
  51. @close="dialog.visible = false"
  52. >
  53. <el-table :data="itemList" border style="width: 100%">
  54. <el-table-column show-overflow-tooltip prop="operationName" label="工序" width="90"/>
  55. <el-table-column show-overflow-tooltip prop="materialModel" label="物料型号" width="90"/>
  56. <el-table-column show-overflow-tooltip prop="workOrderCode" label="产品批号" width="90"/>
  57. <el-table-column prop="reReceiveUser" label="操作人" width="140">
  58. <template v-if="dialog.type === 1" #default="scope">
  59. <el-input v-model="scope.row.reReceiveUser"></el-input>
  60. </template>
  61. </el-table-column>
  62. <el-table-column prop="reDate" label="时间" width="120">
  63. <template v-if="dialog.type === 1" #default="scope">
  64. <el-date-picker value-format="YYYY-MM-DD" type="date" v-model="scope.row.reDate"></el-date-picker>
  65. </template>
  66. </el-table-column>
  67. <el-table-column prop="reNum" label="接收数量" width="80">
  68. <template v-if="dialog.type === 1" #default="scope">
  69. <el-input v-model="scope.row.reNum"></el-input>
  70. </template>
  71. </el-table-column>
  72. <el-table-column prop="next0Num" label="合格品数" width="80">
  73. <template v-if="dialog.type === 1" #default="scope">
  74. <el-input v-model="scope.row.next0Num"></el-input>
  75. </template>
  76. </el-table-column>
  77. <el-table-column prop="next1Num" label="不合格品数" width="80">
  78. <template v-if="dialog.type === 1" #default="scope">
  79. <el-input v-model="scope.row.next1Num"></el-input>
  80. </template>
  81. </el-table-column>
  82. <el-table-column prop="passRate" label="合格品率" width="80">
  83. <template v-if="dialog.type === 1" #default="scope">
  84. <el-input v-model="scope.row.passRate"></el-input>
  85. </template>
  86. </el-table-column>
  87. <el-table-column prop="useDevice" label="使用设备及编号" width="150">
  88. <template v-if="dialog.type === 1" #default="scope">
  89. <el-input v-model="scope.row.useDevice"></el-input>
  90. </template>
  91. </el-table-column>
  92. <el-table-column prop="craftCondition" label="工艺条件" width="160">
  93. <template v-if="dialog.type === 1" #default="scope">
  94. <el-input v-model="scope.row.craftCondition"></el-input>
  95. </template>
  96. </el-table-column>
  97. <el-table-column prop="temperature" label="温度" width="85">
  98. <template v-if="dialog.type === 1" #default="scope">
  99. <el-input v-model="scope.row.temperature"></el-input>
  100. </template>
  101. </el-table-column>
  102. <el-table-column prop="humidity" label="湿度" width="85">
  103. <template v-if="dialog.type === 1" #default="scope">
  104. <el-input v-model="scope.row.humidity"></el-input>
  105. </template>
  106. </el-table-column>
  107. <el-table-column prop="remark" label="备注" width="100">
  108. <template v-if="dialog.type === 1" #default="scope">
  109. <el-input v-model="scope.row.remark"></el-input>
  110. </template>
  111. </el-table-column>
  112. <el-table-column prop="none" label="H级记录表">
  113. <!-- <template #default="scope">
  114. <el-button v-if="scope.row.type == 1" @click="clickH(scope.row)" type="primary" link>
  115. 工作记录表
  116. </el-button>
  117. </template>-->
  118. <template #default="scope">
  119. <el-button
  120. icon="el-icon-setting"
  121. text
  122. @click="formList(scope.row)"
  123. type="primary"
  124. size="small"
  125. >表单列表</el-button>
  126. </template>
  127. </el-table-column>
  128. </el-table>
  129. <div
  130. class="dialog-footer"
  131. align="center"
  132. style="margin-top: 10px;"
  133. >
  134. <el-button @click="dialog.visible = false">取 消</el-button>
  135. <el-button type="primary" @click="handleExport" v-if="itemList.value !== 0">导 出</el-button>
  136. </div>
  137. </el-dialog>
  138. <el-dialog
  139. v-model="dialog1.visible"
  140. :title="dialog1.title"
  141. width="800px"
  142. @close="dialog1.visible = false"
  143. >
  144. <el-form label-width="120px" size="large" :model="hInfo" ref="applyFormRef">
  145. <el-row>
  146. <el-col :span="12">
  147. <el-form-item
  148. label="电路型号"
  149. prop="materialModel"
  150. >
  151. <el-input v-model="hInfo.materialModel" />
  152. </el-form-item>
  153. </el-col>
  154. <el-col :span="12">
  155. <el-form-item
  156. label="生产批号"
  157. prop="workOrderCode"
  158. >
  159. <el-input v-model="hInfo.workOrderCode" />
  160. </el-form-item>
  161. </el-col>
  162. </el-row>
  163. <el-row>
  164. <el-col :span="24">
  165. <el-form-item label="工艺规程" prop="craft" >
  166. <el-input v-model="hInfo.craft" />
  167. </el-form-item>
  168. </el-col>
  169. </el-row>
  170. <el-row>
  171. <el-col :span="24">
  172. <el-form-item label="产品装配图" prop="drawing" >
  173. <el-input v-model="hInfo.drawing" />
  174. </el-form-item>
  175. </el-col>
  176. </el-row>
  177. <el-row>
  178. <el-col :span="8">
  179. <el-form-item
  180. label="温度"
  181. prop="temperature"
  182. >
  183. <el-input v-model="hInfo.temperature" />
  184. </el-form-item>
  185. </el-col>
  186. <el-col :span="8">
  187. <el-form-item
  188. label="相对湿度"
  189. prop="humidity"
  190. >
  191. <el-input v-model="hInfo.humidity" />
  192. </el-form-item>
  193. </el-col>
  194. </el-row>
  195. <el-row>
  196. <el-col :span="8">
  197. <el-form-item
  198. label="烤箱温度设置"
  199. prop="temperatureSet"
  200. >
  201. <el-input v-model="hInfo.temperatureSet" />
  202. </el-form-item>
  203. </el-col>
  204. <el-col :span="8">
  205. <el-form-item
  206. label="烘烤时间"
  207. prop="bakeTime"
  208. >
  209. <el-input v-model="hInfo.bakeTime" />
  210. </el-form-item>
  211. </el-col>
  212. <el-col :span="8">
  213. <el-form-item
  214. label="烘箱真空度"
  215. prop="vacuum"
  216. >
  217. <el-input v-model="hInfo.vacuum" />
  218. </el-form-item>
  219. </el-col>
  220. </el-row>
  221. <el-row>
  222. <el-col :span="8">
  223. <el-form-item
  224. label="氦气流量"
  225. prop="nitrogen"
  226. >
  227. <el-input v-model="hInfo.nitrogen" />
  228. </el-form-item>
  229. </el-col>
  230. <el-col :span="8">
  231. <el-form-item
  232. label="氧含量"
  233. prop="oxygen"
  234. >
  235. <el-input v-model="hInfo.oxygen" />
  236. </el-form-item>
  237. </el-col>
  238. <el-col :span="8">
  239. <el-form-item
  240. label="封前箱内相对湿度监控值"
  241. prop="frontHumidity"
  242. >
  243. <el-input v-model="hInfo.frontHumidity" />
  244. </el-form-item>
  245. </el-col>
  246. </el-row>
  247. <el-row>
  248. <el-col :span="8">
  249. <el-form-item
  250. label="封焊功率"
  251. prop="sealPower"
  252. >
  253. <el-input v-model="hInfo.sealPower" />
  254. </el-form-item>
  255. </el-col>
  256. <el-col :span="8">
  257. <el-form-item
  258. label="封焊压力"
  259. prop="sealPressure"
  260. >
  261. <el-input v-model="hInfo.sealPressure" />
  262. </el-form-item>
  263. </el-col>
  264. <el-col :span="8">
  265. <el-form-item
  266. label="封焊速度"
  267. prop="sealSpeed"
  268. >
  269. <el-input v-model="hInfo.sealSpeed" />
  270. </el-form-item>
  271. </el-col>
  272. </el-row>
  273. <el-row>
  274. <el-col :span="8">
  275. <el-form-item
  276. label="封装数"
  277. prop="num"
  278. >
  279. <el-input v-model="hInfo.num" />
  280. </el-form-item>
  281. </el-col>
  282. <el-col :span="8">
  283. <el-form-item label="合格数" prop="passNum" >
  284. <el-input v-model="hInfo.passNum" />
  285. </el-form-item>
  286. </el-col>
  287. </el-row>
  288. <el-row>
  289. <el-col :span="8">
  290. <el-form-item label="操作者" prop="operator">
  291. <el-input v-model="hInfo.operator" />
  292. </el-form-item>
  293. </el-col>
  294. <el-col :span="8">
  295. <el-form-item label="日期" prop="operatorTime">
  296. <el-date-picker value-format="YYYY-MM-DD" type="date" v-model="hInfo.operatorTime"></el-date-picker>
  297. </el-form-item>
  298. </el-col>
  299. </el-row>
  300. </el-form>
  301. <div
  302. class="dialog-footer"
  303. align="center"
  304. style="margin-top: 10px"
  305. >
  306. <el-button @click="dialog1.visible = false">取 消</el-button>
  307. <el-button type="primary" @click="handleExport1">导 出</el-button>
  308. </div>
  309. </el-dialog>
  310. <el-dialog
  311. v-model="dialog8.visible"
  312. :title="dialog8.title"
  313. width="950px"
  314. @close="dialog8.visible = false"
  315. >
  316. <el-card
  317. style="cursor: pointer; font-size: 20px"
  318. shadow="always"
  319. :key="index"
  320. @click="toShowExcel(item)"
  321. v-for="(item, index) in showProList"
  322. >{{ item.formName }}-{{item.formCode}}({{item.seqs}})</el-card
  323. >
  324. </el-dialog>
  325. <el-dialog
  326. v-model="excelShow"
  327. title="详情"
  328. @close="excelShow = false"
  329. width="1600"
  330. destroy-on-close
  331. >
  332. <ExcelDataBbox :data="ExDataObj" @close="excelShow = false" />
  333. </el-dialog>
  334. </div>
  335. </template>
  336. <script setup>
  337. import { ref, getCurrentInstance } from "vue";
  338. import { useCrud } from "@/hooks/userCrud";
  339. import { exportOperationRecord,exportOperationRecord1 ,queryFormList,addProRecord,queryProductHandover,updateHandoverList,queryHInfo,saveOpDetails} from "@/api/process";
  340. import { useCommonStoreHook } from "@/store";
  341. import dictDataUtil from "@/common/configs/dictDataUtil";
  342. const { isShowTable, tableType } = toRefs(useCommonStoreHook());
  343. import ExcelDataBbox from "@/views/base/apply/excelDataBbox.vue";
  344. const test = () => {
  345. isShowTable.value = true;
  346. tableType.value = tableType.value == 1 ? 2 : 1;
  347. };
  348. const radio = ref(0);
  349. // 传入一个url,后面不带/
  350. const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
  351. useCrud({
  352. dataListUrl: "/api/v1/proRecord/queryCompleteOpList",
  353. });
  354. const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
  355. Methords; //增删改查
  356. const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
  357. const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
  358. const loading = ref(false);
  359. const crudRef = ref(null); //crudRef.value 获取avue-crud对象
  360. const dialog = reactive({
  361. title: "产品交接",
  362. visible: false,
  363. type: 0,
  364. });
  365. const dialog1 = reactive({
  366. title: "工作记录",
  367. visible: false,
  368. });
  369. const dialog8 = reactive({
  370. title: "表单列表",
  371. visible: false,
  372. });
  373. const showProList = ref([]);
  374. const formList = (row) => {
  375. queryFormList({...search.value,workOrderId: row.workOrderId,operationId: row.operationId}).then((data)=>{
  376. if(data.data.length > 0){
  377. showProList.value = data.data;
  378. dialog8.visible = true;
  379. }else{
  380. ElMessage.error("未关联到表单");
  381. }
  382. })
  383. };
  384. const excelShow = ref(false);
  385. const ExDataObj = ref({});
  386. const toShowExcel = (item) => {
  387. ExDataObj.value = item;
  388. excelShow.value = true;
  389. };
  390. const createRowSave = (row,done,loading) =>{
  391. form.value.type = "1"
  392. addProRecord(form.value).then((data) =>{
  393. ElMessage.success(data.msg);
  394. form.value.startDate = "";
  395. form.value.endDate = "";
  396. done();
  397. dialog.visible = true;
  398. dialog.type = 1
  399. itemList.value = data.data
  400. dataList()
  401. }).catch(() => {
  402. loading()
  403. });
  404. }
  405. const itemList = ref([])
  406. const hInfo = ref({
  407. operator: '',
  408. materialModel: ''
  409. })
  410. const clickOperationType = ref(null)
  411. const openDialog = (type, row) => {
  412. clickOperationType.value = row.operationType
  413. row.type = 1
  414. queryProductHandover(row).then((data) => {
  415. itemList.value = data.data;
  416. dialog.visible = true;
  417. dialog.type = type;
  418. });
  419. };
  420. const clickH = (row) =>{
  421. if(null === row.detailId){
  422. hInfo.value = JSON.parse(JSON.stringify(row))
  423. hInfo.value.operator = row.reReceiveUser
  424. hInfo.value.operatorTime = row.reDate
  425. hInfo.value.handoverId = row.id
  426. hInfo.value.num = row.reNum
  427. }else{
  428. queryHInfo(row.detailId).then((data)=>{
  429. hInfo.value = data.data
  430. });
  431. }
  432. dialog1.visible = true
  433. }
  434. const saveDetails = ()=>{
  435. saveOpDetails(hInfo.value).then((data)=>{
  436. ElMessage.success("操作成功");
  437. dialog1.visible = false
  438. })
  439. }
  440. const saveItemList = () => {
  441. updateHandoverList(itemList.value).then((data) => {
  442. if (data.code === "200") {
  443. ElMessage.success("操作成功");
  444. dialog.visible = false;
  445. form.value.type = "1"
  446. search.value.type = "1"
  447. dataList();
  448. } else {
  449. ElMessage.error(data.msg);
  450. }
  451. });
  452. };
  453. // 设置表格列或者其他自定义的option
  454. option.value = Object.assign(option.value, {
  455. searchEnter: true,
  456. editBtn: false,
  457. viewBtn: false,
  458. delBtn: false,
  459. addBtn: false,
  460. selection: false,
  461. column: [
  462. {
  463. label: "开始日期",
  464. prop: "startDate",
  465. type: "date",
  466. format: "YYYY-MM-DD", //前端展示格式
  467. valueFormat: "YYYY-MM-DD", //设置后端接收的日期格式
  468. overHidden: true,
  469. search: true,
  470. },
  471. {
  472. label: "结束日期",
  473. prop: "endDate",
  474. type: "date",
  475. format: "YYYY-MM-DD", //前端展示格式
  476. valueFormat: "YYYY-MM-DD", //设置后端接收的日期格式
  477. search: true,
  478. overHidden: true,
  479. },
  480. {
  481. label: "工序类型",
  482. overHidden: true,
  483. prop: "operationType",
  484. search: true,
  485. type: 'select',
  486. dicUrl: dictDataUtil.request_url + dictDataUtil.TYPE_CODE.process_type,
  487. props: {
  488. label: "dictLabel",
  489. value: "dictValue",
  490. },
  491. addDisplay: false,
  492. editDisplay: false,
  493. },
  494. {
  495. label: "完工数量",
  496. overHidden: true,
  497. prop: "completeNum",
  498. addDisplay: false,
  499. editDisplay: false,
  500. },
  501. ],
  502. });
  503. const handleExport = () => {
  504. exportOperationRecord({...search.value,operationType: clickOperationType.value,type: 1}).then((response) => {
  505. try {
  506. const decoder = new TextDecoder("utf-8");
  507. const jsonString = decoder.decode(response.data);
  508. const jsonObject = JSON.parse(jsonString);
  509. const { code, msg } = jsonObject;
  510. if (code != "200") {
  511. ElMessage.error(msg);
  512. }
  513. } catch (e) {
  514. downFile(response);
  515. }
  516. });
  517. };
  518. const handleExport1 = () => {
  519. exportOperationRecord1(hInfo.value).then((response) => {
  520. try {
  521. const decoder = new TextDecoder("utf-8");
  522. const jsonString = decoder.decode(response.data);
  523. const jsonObject = JSON.parse(jsonString);
  524. const { code, msg } = jsonObject;
  525. if (code != "200") {
  526. ElMessage.error(msg);
  527. }
  528. } catch (e) {
  529. downFile(response);
  530. }
  531. });
  532. };
  533. const downFile = (response) => {
  534. const fileData = response.data;
  535. const fileName = decodeURI(
  536. response.headers["content-disposition"].split(";")[1].split("=")[1]
  537. );
  538. const fileType =
  539. "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
  540. const blob = new Blob([fileData], { type: fileType });
  541. const downloadUrl = window.URL.createObjectURL(blob);
  542. const downloadLink = document.createElement("a");
  543. downloadLink.href = downloadUrl;
  544. downloadLink.download = fileName;
  545. document.body.appendChild(downloadLink);
  546. downloadLink.click();
  547. document.body.removeChild(downloadLink);
  548. window.URL.revokeObjectURL(downloadUrl);
  549. };
  550. onMounted(() => {
  551. form.value.type = "1"
  552. search.value.type = "1"
  553. const now = new Date();
  554. const year = now.getFullYear();
  555. let month = now.getMonth() + 1; // 从0开始的月份
  556. // 当月结束日期
  557. const daysInMonth = new Date(year, now.getMonth() + 1, 0).getDate();
  558. month = month.toLocaleString().length === 1 ? "0" + month : month;
  559. search.value.startDate = year + "-" + month + "-" + "01"
  560. search.value.endDate = year + "-" + month + "-" + daysInMonth
  561. dataList();
  562. });
  563. </script>
  564. <style>
  565. .gray-header-table .el-table__header-wrapper {
  566. background-color: #f2f2f2; /* 灰色背景 */
  567. }
  568. </style>