fqcCheckout.vue 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. <template>
  2. <gui-page
  3. :custom-header="true"
  4. :is-header-sized="false"
  5. :header-class="['gui-theme-background-color', isLandscapeScreen ? 'width: 100vmax;' : '']"
  6. :style="[isLandscapeScreen ? 'width: 100vmax' : '']"
  7. >
  8. <template #gHeader>
  9. <view
  10. :style="[isLandscapeScreen ? 'height:44px;width: 100vmax' : 'height:44px;']"
  11. class="gui-flex gui-nowrap gui-rows gui-align-items-center"
  12. >
  13. <!-- 使用组件实现返回按钮及返回首页按钮 -->
  14. <text
  15. style="font-size:44rpx;"
  16. class="gui-header-leader-btns gui-color-white font-icons"
  17. @tap="goBack"
  18. >
  19. &#xe6c5;
  20. </text>
  21. <!-- <text
  22. style="font-size:44rpx;"
  23. class="gui-header-leader-btns gui-color-white font-icons"
  24. @tap="goHome"
  25. >
  26. &#xe6c5;
  27. </text> -->
  28. <!-- 导航文本此处也可以是其他自定义内容 -->
  29. <text
  30. :style="[isPad ? 'font-size: 18px' : 'font-size: 14px']"
  31. class="gui-h4 gui-blod gui-flex1 gui-text-center gui-color-white gui-ellipsis gui-primary-text"
  32. >
  33. IQC检验
  34. </text>
  35. <!-- 此处加一个右侧展位元素与左侧同宽,实现标题居中 -->
  36. <!-- 实际宽度请根据自己情况设置 -->
  37. <view style="width:40px;" />
  38. </view>
  39. </template>
  40. <template #gBody>
  41. <view class="oqc-checkout">
  42. <view class="card-list-flexbox">
  43. <!-- <text class="card-list-title" :style="[isPad?'font-size: 18px':'font-size: 14px']">FQC检验信息</text> -->
  44. <!-- <view class="card-list-item">
  45. <text>日期</text>
  46. <text>{{ $parseTime(OQCParams.produceDateStr) }}</text>
  47. </view> -->
  48. <!-- <view class="card-list-item">
  49. <text>订单号</text>
  50. <text>{{ OQCParams.saleOutNo }}</text>
  51. </view>
  52. <view class="card-list-item">
  53. <text>客户名称</text>
  54. <text>{{ OQCParams.customerName }}</text>
  55. </view> -->
  56. <!-- <view class="card-list-item">
  57. <text>产品批号</text>
  58. <text>{{ OQCParams.materialLotsStr }}</text>
  59. </view> -->
  60. <!-- <view class="card-list-item">
  61. <text>产品名称</text>
  62. <text>{{ OQCParams.materialName }}</text>
  63. </view> -->
  64. <!-- <view class="card-list-item">
  65. <text>出货数量</text>
  66. <text>{{ OQCParams.deliveredQty }}</text>
  67. </view> -->
  68. <!-- <view class="card-list-item">
  69. <text>产品阶段</text>
  70. <text>{{ OQCParams.productPhase }}</text>
  71. </view> -->
  72. <!-- <view class="card-list-item">
  73. <text>班别</text>
  74. <text>{{ OQCParams.classFlag }}</text>
  75. </view> -->
  76. <!-- <view class="card-list-item">
  77. <text>有效期</text>
  78. <text>{{ OQCParams.expirationDate }}</text>
  79. </view> -->
  80. <view class="card-list-item">
  81. <text>采购订单</text>
  82. <text>{{ OQCParams.purchaseOrderNo }}</text>
  83. </view>
  84. <view class="card-list-item">
  85. <text>物料批次</text>
  86. <text>{{ OQCParams.materialLots }}</text>
  87. </view>
  88. <view class="card-list-item">
  89. <text>物料名称</text>
  90. <text>{{ OQCParams.materialName }}</text>
  91. </view>
  92. <view class="card-list-item">
  93. <text>物料编码</text>
  94. <text>{{ OQCParams.materialNo }}</text>
  95. </view>
  96. <view class="card-list-item">
  97. <text>检验数量</text>
  98. <text>{{ OQCParams.receiptQty }}</text>
  99. </view>
  100. <view class="card-list-item">
  101. <text>图号</text>
  102. <text>{{ OQCParams.drawingNo }}</text>
  103. </view>
  104. <view class="card-list-item">
  105. <text>客户料号</text>
  106. <text>{{ OQCParams.customerMaterialNo }}</text>
  107. </view>
  108. </view>
  109. <!-- 表格 -->
  110. <view class="custom-table">
  111. <uni-table border stripe empty-text="暂无更多数据">
  112. <!-- 表头行 -->
  113. <uni-tr class="custom-table-head">
  114. <uni-th align="center" width="60px">序号</uni-th>
  115. <uni-th align="center" width="140px">是否检验</uni-th>
  116. <uni-th align="center" width="240px">检验名称</uni-th>
  117. <uni-th align="center" width="140px">巡检频次</uni-th>
  118. <uni-th align="center" width="140px">检验工具</uni-th>
  119. <uni-th align="center" width="140px">标准值</uni-th>
  120. <uni-th align="center" width="140px">修饰符</uni-th>
  121. </uni-tr>
  122. <!-- 表格数据行 -->
  123. <uni-tr
  124. v-for="(item, key) in OQCItemList"
  125. :key="key"
  126. @click="handleShowModal(item)"
  127. >
  128. <uni-td align="center" width="120px">{{ ++key }}</uni-td>
  129. <uni-td align="center">
  130. <view style="display: flex;justify-content: center;align-items: center;">
  131. <text
  132. v-if="item.completed"
  133. class="font-icons"
  134. :style="[isPad?'font-size: 24px':'font-size: 22px', 'color: #2dc252']"
  135. >
  136. &#xe6dd;
  137. </text>
  138. <text
  139. v-else
  140. class="font-icons"
  141. :style="[isPad?'font-size: 24px':'font-size: 22px', 'color: #6a6a6a']"
  142. >
  143. &#xe6e0;
  144. </text>
  145. <text v-if="item.voidOrNot*1 === 1" style="margin-left: 4px;">报废</text>
  146. <text v-else style="margin-left: 4px;">{{ item.completed? '已检': '未检' }}</text>
  147. </view>
  148. </uni-td>
  149. <uni-td
  150. align="center"
  151. :style="[item.voidOrNot*1 === 1?'text-decoration: line-through;':'']"
  152. >
  153. {{ item.inspectionName }}
  154. </uni-td>
  155. <uni-td
  156. align="center"
  157. :style="[item.voidOrNot*1 === 1?'text-decoration: line-through;':'']"
  158. >
  159. {{ item.checkQuantity }}
  160. </uni-td>
  161. <uni-td
  162. align="center"
  163. :style="[item.voidOrNot*1 === 1?'text-decoration: line-through;':'']"
  164. >
  165. {{ item.tool }}
  166. </uni-td>
  167. <uni-td
  168. align="center"
  169. :style="[item.voidOrNot*1 === 1?'text-decoration: line-through;':'']"
  170. >
  171. {{ item.standValue }}
  172. </uni-td>
  173. <uni-td
  174. align="center"
  175. :style="[item.voidOrNot*1 === 1?'text-decoration: line-through;':'']"
  176. >
  177. {{ item.standard }}
  178. </uni-td>
  179. </uni-tr>
  180. </uni-table>
  181. </view>
  182. </view>
  183. <!-- 底部弹窗 -->
  184. <uni-popup ref="popup" background-color="#fff" :mask-click="false">
  185. <view class="popup-content">
  186. <view class="card-list-flexbox-popup">
  187. <view class="card-list-item">
  188. <text class="text-1 gui-color-gray">{{ submitOQCItem.inspectionName }}</text>
  189. </view>
  190. <view class="card-list-item">
  191. <text class="text-1 gui-color-gray">检验工具</text>
  192. <text class="text-2 gui-color-gray">{{ submitOQCItem.tool }}</text>
  193. </view>
  194. <view class="card-list-item">
  195. <text class="text-1 gui-color-gray">检验频次</text>
  196. <text class="text-2 gui-color-gray">{{ submitOQCItem.checkQuantity }}</text>
  197. </view>
  198. <view class="card-list-item">
  199. <text class="text-1 gui-color-gray">检验标准</text>
  200. <text class="text-2 gui-color-gray">{{ submitOQCItem.standard }}</text>
  201. </view>
  202. <view class="card-list-item">
  203. <text class="text-1 gui-color-gray">是否合格</text>
  204. <text class="text-2 gui-color-gray">
  205. <radio-group style="width: inherit;" @change="radioChange">
  206. <view style="display: grid;grid-template-rows: 1fr; grid-template-columns: 1fr 1fr;">
  207. <label>
  208. <view style="display: flex;justify-content: center;align-items: center;">
  209. <radio value="1" :checked="submitOQCItem.singleResult*1 === 1?true:false" />
  210. <view>合格</view>
  211. </view>
  212. </label>
  213. <label>
  214. <view style="display: flex;justify-content: center;align-items: center;">
  215. <radio value="0" :checked="submitOQCItem.singleResult*1 === 0?true:false" />
  216. <view>不合格</view>
  217. </view>
  218. </label>
  219. </view>
  220. </radio-group>
  221. </text>
  222. </view>
  223. <!-- 检验模型 0 -->
  224. <view v-if="submitOQCItem.inspectionModel === 0" class="card-list-item-input">
  225. <view
  226. v-for="(item, key) in submitOQCItem.actualCreateReqVOS"
  227. :key="key"
  228. style="margin: 4px 0;"
  229. >
  230. <text
  231. v-if="item.qualified === 1"
  232. class="font-icons"
  233. style="font-size: 22px;height: auto;color: #2dc252;padding: 0 6px;"
  234. >
  235. &#xe6dd;
  236. </text>
  237. <text
  238. v-else
  239. class="font-icons"
  240. style="font-size: 22px;height: auto;color: red;padding: 0 6px;"
  241. >
  242. &#xe6e0;
  243. </text>
  244. <textarea
  245. v-model="submitOQCItem.actualCreateReqVOS[key].actual"
  246. class="text-3 gui-color-gray"
  247. inputmode="decimal"
  248. placeholder="请输入检验内容"
  249. style="border-radius: 4px;border: 1px dotted gray;"
  250. auto-height
  251. maxlength="14"
  252. />
  253. <view
  254. v-if="key === submitOQCItem.actualCreateReqVOS.length - 1"
  255. class="operation-icon"
  256. @click="appendRow(item)"
  257. >
  258. <text class="font-icons" :style="[isPad?'font-size: 18px':'font-size: 14px']">
  259. &#xe664;
  260. </text>
  261. </view>
  262. <view v-else class="operation-icon-2" @click="deleteRow(item, key)">
  263. <text class="font-icons" :style="[isPad?'font-size: 18px':'font-size: 14px']">
  264. &#xe677;
  265. </text>
  266. </view>
  267. </view>
  268. </view>
  269. <!-- 检验模型 1 -->
  270. <view v-if="submitOQCItem.inspectionModel === 1" class="card-list-item-input">
  271. <textarea
  272. v-model="submitOQCItem.measuredResults"
  273. class="text-3 gui-color-gray"
  274. inputmode="text"
  275. placeholder="请输入检验内容"
  276. style="border-radius: 4px;border: 1px dotted gray;margin: 2px 4px;"
  277. auto-height
  278. maxlength="14"
  279. />
  280. </view>
  281. <!-- 图片预览 -->
  282. <view v-if="submitOQCItem.src?.length > 0" class="card-list-item">
  283. <text class="text-1">上传图片预览:</text>
  284. </view>
  285. <view
  286. v-if="submitOQCItem.src?.length > 0"
  287. class="card-list-item grid-image"
  288. style="margin: 12px 0"
  289. >
  290. <image
  291. v-for="(item, key) in submitOQCItem.src"
  292. :key="key"
  293. :src="item"
  294. mode="scaleToFill"
  295. @click="handleRemoveImage(item, key)"
  296. />
  297. </view>
  298. <!-- 拍照 / 提交 -->
  299. <view v-if="OQCParams.auditStatus === -1" class="card-list-item">
  300. <button class="text-1 btn-mg" type="primary" @click="takePhoto">拍照</button>
  301. </view>
  302. <view class="card-list-item" style="margin: 12px 0">
  303. <button
  304. v-if="OQCParams.auditStatus === -1"
  305. class="text-1 btn-mg"
  306. type="primary"
  307. @click="handleSubmit"
  308. >
  309. 提交数据
  310. </button>
  311. <button
  312. class="text-1 btn-mg"
  313. type="default"
  314. @click="$refs['popup'].close()"
  315. >
  316. 关闭
  317. </button>
  318. </view>
  319. </view>
  320. </view>
  321. </uni-popup>
  322. <!-- 右侧悬浮菜单 -->
  323. <gui-right-menus>
  324. <template #menus-more>
  325. <view
  326. v-if="OQCParams.auditStatus === -1"
  327. hover-class="gui-tap"
  328. class="menu-items gui-bg-green gui-flex gui-columns gui-justify-content-center"
  329. @click="handleShowSubmitApprovalModal"
  330. >
  331. <text class="menu-text gui-block gui-text-center gui-color-white">送审</text>
  332. </view>
  333. <view
  334. v-else
  335. hover-class="gui-tap"
  336. class="menu-items gui-flex gui-columns gui-justify-content-center"
  337. style="background-color: #717171;"
  338. >
  339. <text class="menu-text gui-block gui-text-center gui-color-white">送审</text>
  340. </view>
  341. </template>
  342. <template #menus-primary>
  343. <view class="menu-items gui-bg-primary gui-flex gui-columns gui-justify-content-center">
  344. <text class="menu-icon gui-color-white gui-block gui-text-center gui-icons">&#xe614;</text>
  345. <text class="menu-text gui-color-white gui-block gui-text-center">操作</text>
  346. </view>
  347. </template>
  348. </gui-right-menus>
  349. <!-- 送审确认模态框 -->
  350. <gui-modal
  351. ref="modalForm"
  352. :custom-class="['gui-bg-white', 'gui-dark-bg-level-3', 'gui-border-radius']"
  353. title="提示"
  354. >
  355. <template #content>
  356. <view class="gui-padding gui-bg-gray gui-dark-bg-level-2">
  357. <text
  358. class="gui-block gui-text-center gui-text gui-color-gray"
  359. style="line-height:100rpx; padding:10rpx;"
  360. >
  361. 您确定要立即送审吗?
  362. </text>
  363. </view>
  364. </template>
  365. <template #btns>
  366. <view class="gui-flex gui-row gui-space-between operation-flex">
  367. <view hover-class="gui-tap" class="modal-btns gui-flex1" @tap="handleCancelApprovalModal">
  368. <text class="modal-btns gui-color-gray">取消</text>
  369. </view>
  370. <view class="line" />
  371. <view hover-class="gui-tap" class="modal-btns gui-flex1" @tap="handleSubmitApprovalModal">
  372. <text class="modal-btns gui-primary-color">确认</text>
  373. </view>
  374. </view>
  375. </template>
  376. </gui-modal>
  377. <!-- 错误提示 -->
  378. <uni-popup ref="errorTip" type="dialog">
  379. <uni-popup-dialog
  380. type="error"
  381. cancel-text="关闭"
  382. confirm-text="确认"
  383. title="提示"
  384. :content="errorTipMessage"
  385. @confirm="handleCloseErrorTipsModal"
  386. @close="handleCloseErrorTipsModal"
  387. />
  388. </uni-popup>
  389. </template>
  390. </gui-page>
  391. </template>
  392. <script>
  393. import axios from 'axios'
  394. import { computed, defineComponent, ref, onMounted, onBeforeMount } from 'vue'
  395. export default defineComponent({
  396. onLoad() {
  397. // // #ifdef APP-PLUS
  398. // plus.screen.lockOrientation('default');
  399. // // #endif
  400. },
  401. onUnload() {
  402. // // #ifdef APP-PLUS
  403. // plus.screen.lockOrientation('portrait-primary');
  404. // // #endif
  405. },
  406. onResize() {
  407. if ([90, -90].includes(plus.navigator.getOrientation())) {
  408. this.isLandscapeScreen = true
  409. } else {
  410. this.isLandscapeScreen = false
  411. }
  412. },
  413. setup(options) {
  414. const popup = ref()
  415. const modalForm = ref()
  416. const isLandscapeScreen = ref(false)
  417. // 直接从路径中获取id参数,优先从本地存储获取(模仿scanOutPage.vue实现)
  418. let parentRow = {}
  419. let receivedId = null
  420. try {
  421. // 方法1:优先从本地存储获取id
  422. const masterIdStr = uni.getStorageSync('masterId')
  423. if (masterIdStr) {
  424. const masterIdData = JSON.parse(masterIdStr)
  425. receivedId = masterIdData?.id
  426. console.log('从本地存储获取的id:', receivedId)
  427. // 移除已使用的本地存储数据
  428. uni.removeStorageSync('masterId')
  429. } else {
  430. // 方法2:从onLoad的options中直接获取id
  431. if (options?.id) {
  432. receivedId = options.id
  433. console.log('从options获取的id:', receivedId)
  434. } else {
  435. // 方法3:通过getCurrentPages()获取当前页面参数
  436. const pages = getCurrentPages()
  437. const currentPage = pages[pages.length - 1]
  438. if (currentPage?.options?.id) {
  439. receivedId = currentPage.options.id
  440. console.log('从currentPage.options获取的id:', receivedId)
  441. } else {
  442. // 方法4:直接解析URL获取id
  443. const url = window.location.href
  444. console.log('当前页面完整URL:', url)
  445. const idMatch = url.match(/[?&]id=([^&]+)/)
  446. if (idMatch && idMatch[1]) {
  447. receivedId = decodeURIComponent(idMatch[1])
  448. console.log('从URL解析的id:', receivedId)
  449. }
  450. }
  451. }
  452. }
  453. // 将id放入parentRow对象中,保持与原有代码结构兼容
  454. if (receivedId) {
  455. parentRow.id = receivedId
  456. console.log('parentRow对象:', parentRow)
  457. }
  458. } catch (error) {
  459. console.error('获取id参数失败:', error)
  460. }
  461. // 绑定的检查人信息
  462. const OQCParams = ref({
  463. auditStatus: null,
  464. materialLots: '',
  465. materialLotsStr: '',
  466. customerName: '',
  467. deliveredQty: '',
  468. expirationDate: '',
  469. materialName: '',
  470. produceDateStr: '',
  471. saleOutNo: '',
  472. version: 0,
  473. productPhase: '',
  474. processNo: '',
  475. materialNo: '',
  476. classFlag: '', // 班别
  477. wmsSaleOutOrderId: '',
  478. })
  479. const OQCItemList = ref([])
  480. // 待巡检项信息
  481. const submitOQCItem = ref({
  482. src: [],
  483. singleResult: '',
  484. measuredResults: null,
  485. id: '',
  486. inspectionModel: null,
  487. actualCreateReqVOS: [{ id: '', actual: 0 }],
  488. fileIds: [],
  489. })
  490. const errorState = ref(0)
  491. const errorTip = ref('')
  492. const errorTipMessage = ref('')
  493. onBeforeMount(() => {
  494. console.log('parentRow类型:', typeof parentRow)
  495. console.log('parentRow值:', parentRow)
  496. OQCParams.value.wmsSaleOutOrderId = parentRow?.id
  497. console.log('设置的wmsSaleOutOrderId:', OQCParams.value.wmsSaleOutOrderId)
  498. })
  499. onMounted(() => {
  500. handleBindOQCHeader()
  501. })
  502. const goHome = function () {
  503. uni.$goHome()
  504. }
  505. const goBack = function () {
  506. uni.$goBack('/pages/workbranch/production/FQC/fqcList')
  507. }
  508. const appendRow = function (row) {
  509. submitOQCItem.value.actualCreateReqVOS.push({ id: '', actual: '' })
  510. }
  511. const deleteRow = function (row, index) {
  512. submitOQCItem.value.actualCreateReqVOS.splice(index, 1)
  513. }
  514. // 绑定FQC检验表头
  515. const handleBindOQCHeader = async function () {
  516. await uni
  517. .$reqPost('getFQCItem', {
  518. wmsIncomingReceiptInspectionId: OQCParams.value.wmsSaleOutOrderId,
  519. })
  520. .then((data) => {
  521. OQCItemList.value = data?.list
  522. OQCParams.value.customerName = data?.customerName
  523. OQCParams.value.classFlag = data?.classFlag
  524. OQCParams.value.version = data?.version
  525. OQCParams.value.materialNo = data?.materialNo
  526. OQCParams.value.productPhase = data?.productPhase
  527. OQCParams.value.processNo = data?.processNo
  528. OQCParams.value.deliveredQty = data?.deliveredQty
  529. OQCParams.value.expirationDate = data?.expirationDate
  530. OQCParams.value.materialLotsStr = data?.materialLotsStr
  531. OQCParams.value.materialLots = data?.materialLots
  532. OQCParams.value.materialName = data?.materialName
  533. OQCParams.value.auditStatus = data?.auditStatus
  534. OQCParams.value.produceDateStr = data?.produceDateStr
  535. OQCParams.value.saleOutNo = data?.saleOutNo
  536. OQCParams.value.receiptQty = data?.receiptQty
  537. OQCParams.value.purchaseOrderNo = data?.purchaseOrderNo
  538. OQCParams.value.drawingNo = data?.drawingNo
  539. OQCParams.value.customerMaterialNo = data?.customerMaterialNo
  540. })
  541. }
  542. const scinumToFloat = function (num) {
  543. if (isNaN(num)) return num
  544. const str = '' + num
  545. if (!/e/i.test(str)) return num
  546. return num.toFixed(18).replace(/\.?0+$/, '')
  547. }
  548. // 开始检验
  549. const handleShowModal = function (opt) {
  550. if (opt?.voidOrNot * 1 !== 1) {
  551. Object.assign(submitOQCItem.value, opt)
  552. submitOQCItem.value.id = opt?.id
  553. submitOQCItem.value.inspectionModel = opt?.inspectionModel
  554. uni.$reqGet('getResult', { id: opt?.id }).then(({ code, data, msg }) => {
  555. if (code === 0) {
  556. if (popup.value?.showPopup === false) popup.value.open('bottom')
  557. if (
  558. data.actualDOS !== null &&
  559. Object.prototype.toString.call(data.actualDOS) === '[object Array]' &&
  560. data.actualDOS.length > 0
  561. ) {
  562. submitOQCItem.value.actualCreateReqVOS.length = 0
  563. data?.actualDOS.forEach((item) => {
  564. const actual = scinumToFloat(item?.actual)
  565. submitOQCItem.value.actualCreateReqVOS.push({ ...item, actual })
  566. })
  567. } else {
  568. submitOQCItem.value.actualCreateReqVOS = [{ id: '', actual: '' }]
  569. }
  570. if (data.fileIds !== null) submitOQCItem.value.fileIds = data?.fileIds ?? []
  571. submitOQCItem.value.measuredResults = data?.measuredResults ?? ''
  572. submitOQCItem.value.src = data?.urlList ?? []
  573. } else {
  574. // #ifdef APP-PLUS
  575. plus.device.beep(2)
  576. // #endif
  577. errorTipMessage.value = msg
  578. errorTip.value.open()
  579. errorState.value = -1
  580. }
  581. })
  582. }
  583. }
  584. const handleSubmit = async function () {
  585. const actualCreateReqVOS = []
  586. if (submitOQCItem.value.inspectionModel === 0) {
  587. try {
  588. submitOQCItem.value.actualCreateReqVOS.forEach((item) => {
  589. if (isNaN(Number(item.actual))) {
  590. throw new Error('请填写正确的数值!')
  591. } else {
  592. actualCreateReqVOS.push({ id: '', ...item, actual: item.actual })
  593. }
  594. })
  595. } catch (e) {
  596. uni.showToast({ title: e.message, duration: 2000, icon: 'none' })
  597. return
  598. }
  599. }
  600. const params = {
  601. fileIds: submitOQCItem.value.fileIds,
  602. actualCreateReqVOS,
  603. singleResult: submitOQCItem.value.singleResult,
  604. measuredResults: submitOQCItem.value.measuredResults,
  605. id: submitOQCItem.value.id,
  606. materialLots: OQCParams.value.materialLots,
  607. inspectionModel: submitOQCItem.value.inspectionModel,
  608. processNo: OQCParams.value.processNo,
  609. }
  610. if (params.singleResult === '□OK ■NG') params.singleResult = '0'
  611. else if (params.singleResult === '■OK □NG') params.singleResult = '1'
  612. const data = await uni.$reqPut('submitItem', params)
  613. if (data?.code === 0) {
  614. uni.showToast({ title: '数据提交成功!', duration: 2000, icon: 'none' })
  615. popup.value.close()
  616. handleBindOQCHeader()
  617. } else {
  618. // #ifdef APP-PLUS
  619. plus.device.beep(2)
  620. // #endif
  621. errorTipMessage.value = data?.msg ?? ''
  622. errorTip.value.open()
  623. errorState.value = -1
  624. }
  625. }
  626. // 拍照
  627. const takePhoto = function () {
  628. uni.chooseImage({
  629. count: 6,
  630. sizeType: ['original', 'compressed'],
  631. sourceType: ['album', 'camera'],
  632. success: function (res) {
  633. res.tempFilePaths.forEach(async (item) => {
  634. // #ifdef APP-PLUS
  635. await uni.uploadFile({
  636. url: uni.$baseUrl + '/admin-api/minio/files/uploadFiles',
  637. name: 'file',
  638. filePath: item,
  639. header: { Authorization: 'Bearer ' + uni.getStorageSync('token') },
  640. success: function (uploadFileRes) {
  641. const resultJSON = JSON.parse(uploadFileRes.data)
  642. if (submitOQCItem.value.fileIds === null) submitOQCItem.value.fileIds = []
  643. submitOQCItem.value.fileIds.push(resultJSON.data.fileId)
  644. },
  645. })
  646. // #endif
  647. submitOQCItem.value.src.push(item)
  648. })
  649. res.tempFiles.forEach(async (item) => {
  650. // #ifdef H5
  651. const formData = new FormData()
  652. formData.append('file', item)
  653. const { data } = await axios({
  654. url: uni.$baseUrl + '/admin-api/minio/files/uploadFiles',
  655. name: '上传文件',
  656. method: 'post',
  657. headers: {
  658. Authorization: 'Bearer ' + uni.getStorageSync('token'),
  659. 'Content-Type': 'multipart/form-data;',
  660. },
  661. data: formData,
  662. })
  663. if (submitOQCItem.value.fileIds === null) submitOQCItem.value.fileIds = []
  664. submitOQCItem.value.fileIds.push(data.data.fileId)
  665. // #endif
  666. })
  667. },
  668. })
  669. }
  670. const radioChange = function (item) {
  671. submitOQCItem.value.singleResult = item?.detail?.value
  672. }
  673. const handleRemoveImage = function (opt, index) {
  674. submitOQCItem.value.fileIds.splice(index, 1)
  675. submitOQCItem.value.src.splice(index, 1)
  676. }
  677. const handleShowSubmitApprovalModal = function () {
  678. modalForm.value.open()
  679. }
  680. const handleCancelApprovalModal = function () {
  681. modalForm.value.close()
  682. }
  683. const handleSubmitApprovalModal = function () {
  684. const params = {
  685. version: OQCParams.value.version,
  686. materialLots: OQCParams.value.materialLots,
  687. processNo: OQCParams.value.processNo,
  688. materialNo: OQCParams.value.materialNo,
  689. }
  690. uni.$reqPost('submitApproval', params)
  691. .then(({ code, data, msg }) => {
  692. if (code === 0) {
  693. uni.showToast({ title: '送审成功!', duration: 2000, icon: 'none' })
  694. handleBindOQCHeader()
  695. } else {
  696. uni.showToast({ title: msg, duration: 2000, icon: 'none' })
  697. }
  698. })
  699. .finally(() => {
  700. modalForm.value.close()
  701. })
  702. }
  703. const handleCloseErrorTipsModal = async function () {
  704. errorTip.value.close()
  705. }
  706. return {
  707. goHome,
  708. popup,
  709. goBack,
  710. modalForm,
  711. takePhoto,
  712. OQCItemList,
  713. errorState,
  714. errorTip,
  715. errorTipMessage,
  716. appendRow,
  717. deleteRow,
  718. isLandscapeScreen,
  719. OQCParams,
  720. radioChange,
  721. handleBindOQCHeader,
  722. handleShowModal,
  723. handleSubmit,
  724. submitOQCItem,
  725. handleRemoveImage,
  726. handleShowSubmitApprovalModal,
  727. handleCancelApprovalModal,
  728. handleSubmitApprovalModal,
  729. handleCloseErrorTipsModal,
  730. }
  731. },
  732. })
  733. </script>
  734. <style lang="scss" scoped>
  735. .gui-header-leader-btns {
  736. color: black;
  737. font-size: 24px !important;
  738. margin-left: 24rpx;
  739. }
  740. .gui-sbody {
  741. background-color: rgba(234, 239, 242, 1);
  742. }
  743. .gui-relative {
  744. overflow: visible;
  745. height: 100vh;
  746. .oqc-checkout {
  747. width: 100vw;
  748. height: calc(100vh - 75px);
  749. position: absolute;
  750. top: 95px;
  751. overflow: hidden;
  752. }
  753. }
  754. .card-list-flexbox {
  755. width: calc(100vw - 24px);
  756. margin: 0 12px;
  757. display: flex;
  758. justify-content: center;
  759. flex-direction: column;
  760. align-items: center;
  761. overflow-y: scroll;
  762. .card-list-title {
  763. width: 100%;
  764. height: 35px;
  765. line-height: 35px;
  766. margin: 0 4px 0 4px;
  767. border-radius: 4px 4px 0 0;
  768. text-align: center;
  769. color: white;
  770. background-color: rgba(0, 160, 233, 1);
  771. }
  772. .card-list-item,
  773. .card-list-item-operation {
  774. width: 100%;
  775. height: 35px;
  776. margin: 0 4px 3rpx 4px;
  777. border-radius: 4px;
  778. display: flex;
  779. flex-direction: row;
  780. align-items: center;
  781. justify-content: space-between;
  782. background-color: #fff;
  783. uni-text {
  784. font-size: 14px;
  785. height: 50rpx;
  786. text-align: left;
  787. padding: 0 8px;
  788. display: flex;
  789. flex-direction: row;
  790. align-items: center;
  791. }
  792. .text-1 {
  793. flex: 1;
  794. height: 35px;
  795. justify-content: flex-start;
  796. }
  797. .text-2 {
  798. flex: 3;
  799. height: 35px;
  800. justify-content: flex-end;
  801. margin-right: 4px;
  802. padding: 2px 6px;
  803. }
  804. }
  805. }
  806. .popup-content {
  807. width: 100vw;
  808. height: 55vh;
  809. overflow-y: scroll;
  810. }
  811. .card-list-flexbox-popup {
  812. width: 100vw;
  813. display: flex;
  814. flex-direction: row;
  815. align-items: center;
  816. flex-wrap: wrap;
  817. .card-list-item,
  818. .card-list-item-input {
  819. width: 100vw;
  820. height: 100%;
  821. min-height: 40px;
  822. display: flex;
  823. flex-direction: row;
  824. align-items: center;
  825. background-color: #fff;
  826. uni-text {
  827. font-size: 14px;
  828. height: 50rpx;
  829. text-align: left;
  830. padding: 0 12px;
  831. display: flex;
  832. flex-direction: row;
  833. align-items: center;
  834. }
  835. uni-image {
  836. width: calc(100vw / 2 - 4px);
  837. height: calc(100vw / 3.2 - 2px);
  838. pointer-events: none;
  839. }
  840. uni-image::after {
  841. content: '×';
  842. width: 22px;
  843. height: 22px;
  844. position: absolute;
  845. top: 5px;
  846. right: 5px;
  847. display: flex;
  848. justify-content: center;
  849. align-items: center;
  850. color: rgba(255, 255, 255, 0.9);
  851. background-color: rgba(0, 0, 0, 0.5);
  852. border-radius: 50%;
  853. font-size: 24px;
  854. pointer-events: auto;
  855. }
  856. .text-1 {
  857. flex: 1;
  858. height: 40px;
  859. justify-content: flex-start;
  860. }
  861. .text-2 {
  862. flex: 3;
  863. height: 40px;
  864. justify-content: flex-end;
  865. margin-right: 4px;
  866. padding: 2px 6px;
  867. }
  868. .text-3 {
  869. width: calc(100% - 15%);
  870. min-height: 35px;
  871. justify-content: flex-end;
  872. padding: 2px 6px;
  873. }
  874. .btn-mg {
  875. margin: 0 5px;
  876. }
  877. }
  878. .card-list-item {
  879. justify-content: center;
  880. }
  881. .card-list-item-input {
  882. margin: 10px 0 10px 2%;
  883. display: flex;
  884. flex-direction: column;
  885. uni-view {
  886. width: 100%;
  887. height: 100%;
  888. display: flex;
  889. uni-textarea {
  890. flex: 8;
  891. }
  892. uni-view {
  893. flex: 1;
  894. }
  895. .operation-icon,
  896. .operation-icon-2 {
  897. height: auto;
  898. uni-text {
  899. width: 22px;
  900. height: 100%;
  901. padding: 0 !important;
  902. text-align: center;
  903. display: flex;
  904. justify-content: center;
  905. align-items: center;
  906. border-top-right-radius: 4px;
  907. border-bottom-right-radius: 4px;
  908. color: white;
  909. background-color: #80b7ff;
  910. }
  911. }
  912. .operation-icon-2 {
  913. uni-text {
  914. background-color: #ff5962;
  915. }
  916. }
  917. }
  918. }
  919. .grid-image {
  920. display: grid;
  921. grid-template-rows: repeat(auto-fill, 1fr);
  922. grid-template-columns: repeat(2, 1fr);
  923. padding: 0 4px;
  924. }
  925. .card-list-item:nth-of-type(1) {
  926. .text-1 {
  927. flex: 9;
  928. font-weight: bold;
  929. color: black !important;
  930. }
  931. .text-1::before {
  932. content: '';
  933. width: 4px;
  934. height: 20px;
  935. border-radius: 4px;
  936. margin-right: 4px;
  937. background-color: skyblue;
  938. }
  939. .text-2 {
  940. flex: 4;
  941. display: flex;
  942. flex-direction: row;
  943. justify-content: flex-end;
  944. align-items: center;
  945. color: limegreen !important;
  946. }
  947. }
  948. }
  949. .custom-table {
  950. height: calc(100vh - 300px);
  951. margin: 5px 0;
  952. overflow-y: scroll;
  953. }
  954. .uni-list-cell {
  955. width: 100vw;
  956. height: 35px;
  957. margin: 4px 0;
  958. display: flex;
  959. flex-direction: row;
  960. align-items: center;
  961. justify-content: space-between;
  962. border-bottom: 2px solid #eaeff2;
  963. background-color: #fff;
  964. view {
  965. font-size: 14px;
  966. height: 50rpx;
  967. text-align: left;
  968. padding: 0 8px;
  969. display: flex;
  970. flex-direction: row;
  971. align-items: center;
  972. }
  973. .uni-list-cell-left {
  974. flex: 1;
  975. height: 35px;
  976. justify-content: flex-start;
  977. }
  978. .uni-list-cell-db {
  979. flex: 3;
  980. height: 35px;
  981. justify-content: flex-end;
  982. margin-right: 4px;
  983. padding: 2px 6px;
  984. uni-picker {
  985. width: 100%;
  986. display: flex;
  987. flex-direction: row;
  988. justify-content: center;
  989. }
  990. }
  991. }
  992. .modal-btns {
  993. height: 100rpx;
  994. line-height: 100rpx;
  995. display: flex;
  996. justify-content: center;
  997. align-items: center;
  998. }
  999. .line {
  1000. margin-top: 10rpx;
  1001. height: 80rpx;
  1002. width: 1rpx;
  1003. background-color: #dcdcdc;
  1004. }
  1005. </style>