form.vue 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272
  1. <template>
  2. <view class="page-container uni-column">
  3. <view class="lot-info uni-column">
  4. <view class="lot-code uni-row">
  5. <text>批次号</text>
  6. <text style="margin-left: 24rpx;">{{ dayworkItem.lotCode }}</text>
  7. </view>
  8. <view class="product-info">
  9. 产品描述: {{ dayworkItem.productDescription }}
  10. </view>
  11. <view class="product-info">
  12. 原材料厂家: {{ dayworkInfo.furnaceNoInfo.factory == "" ? "-":dayworkInfo.furnaceNoInfo.factory }}
  13. </view>
  14. <view class="product-info">
  15. 投产数量: {{ dayworkItem.prodNum }}
  16. </view>
  17. <view class="product-info">
  18. 设备: {{ dayworkItem.equipmentDetailCode }}
  19. </view>
  20. </view>
  21. <!-- 不合格信息 -->
  22. <view class="title unfit-title uni-row">
  23. <text>不合格信息</text>
  24. <view v-if="Number(dayworkItem.status) < 3" class="add-btn" @click="handleAddUnfit">添加</view>
  25. </view>
  26. <view class="unfit-container">
  27. <view class="unfit-item-container uni-column" v-for="(item, index) in unfitInfos" :key="index">
  28. <view class="title uni-row">
  29. <text>检查标准-{{ item.checkStandard }}</text>
  30. <uni-icons v-if="Number(dayworkItem.status) < 3" type="trash" size="24" color="#fc6565"
  31. @click="handleDelUnfit(index)" />
  32. </view>
  33. <!-- <view class="standard">检查标准:{{ item.checkStandard }}</view> -->
  34. <view class="result uni-row" style="display: flex;flex-direction: row;justify-content: space-between;">
  35. <!-- align-items: flex-start; -->
  36. <view class="label" style="padding-right: 16rpx;flex: 0 1 auto; min-width: 118rpx;">
  37. 检查结果</view>
  38. <input v-if="Number(dayworkItem.status) < 3" v-model="item.reason" placeholder="请输入检查结果" />
  39. <span v-else style="flex-grow: 1;">{{ item.reason }}</span>
  40. <view class="label"
  41. style="text-align: right; padding-right: 16rpx;flex: 0 1 auto; min-width: 68rpx;">数量</view>
  42. <input v-if="Number(dayworkItem.status) < 3" class="number" type="number" v-model="item.rejectNum"
  43. @blur="rejectNumberChange" />
  44. <span v-else>{{ item.rejectNum }}</span>
  45. </view>
  46. </view>
  47. </view>
  48. <!-- 咨询部分 -->
  49. <view class="title">咨询</view>
  50. <view class="consultation-container uni-column">
  51. <view class="consultation-item-container" v-for="(item, index) in consultations" :key="index">
  52. <view class="question uni-column">
  53. <view class="label uni-row">
  54. <text>问题描述</text>
  55. <text :style="{ color: showStatusColor(item.status) }">{{item.consultDepartment == 0?'技术':'品管'}}
  56. {{ selectText(item) }}</text>
  57. </view>
  58. <view class="content">{{ item.content }}</view>
  59. </view>
  60. <!-- <view v-if="item.answer !== ''" class="answer"
  61. style="margin-top: 24rpx; padding-top: 24rpx; border-top: 1px dotted #aaaaaa;">
  62. <view class="label">回复</view>
  63. <view class="content">{{ item.answer }}</view>
  64. </view> -->
  65. </view>
  66. </view>
  67. <!-- 零存库部分 -->
  68. <view class="title">零存库</view>
  69. <view class="consultation-container ">
  70. <view class="title unfit-title uni-row">
  71. <view class="title">零取</view>
  72. <view class="add-btn" v-if="Number(dayworkItem.status) < 3" style="background-color: #409eff;"
  73. @click="handleAddLot">添加</view>
  74. </view>
  75. <view style="flex-direction: row;">
  76. <zb-table v-if="Number(dayworkItem.status) < 3" :columns="column1" :stripe="true" :fit="true"
  77. @dele="dele" :data="retrievalInfo"></zb-table>
  78. <zb-table v-else :columns="column2" :stripe="true" :fit="true" @dele="dele"
  79. :data="retrievalInfo"></zb-table>
  80. <!-- <uni-table ref="table" :loading="loading" border stripe emptyText="暂无更多数据" >
  81. <uni-tr >
  82. <uni-th style="font-size: 25rpx;" width="atuo" align="center">批次号</uni-th>
  83. <uni-th style="font-size: 25rpx;" width="120" align="center">数量</uni-th>
  84. <uni-th v-if="Number(dayworkItem.status) < 3" style="font-size: 25rpx;" width="80" align="center">操作</uni-th>
  85. </uni-tr>
  86. <uni-tr v-for="(item, index) in retrievalInfo" :key="index">
  87. <uni-th style="font-size: 24rpx;" width="auto" align="center">{{ item.lotCode }}</uni-th>
  88. <uni-th style="font-size: 25rpx;" width="120" align="center">
  89. {{ item.storageNum }}
  90. </uni-th>
  91. <uni-th v-if="Number(dayworkItem.status) < 3 && item.status == 0" align="center" width="80">
  92. <uni-icons type="closeempty" size="22" @click="handleDelete(item)"></uni-icons>
  93. </uni-th>
  94. </uni-tr>
  95. </uni-table> -->
  96. </view>
  97. <view v-if="saveFlag" class='middle'>
  98. <view class='segment'></view>
  99. <view class='segment'></view>
  100. </view>
  101. <view v-if="saveFlag" class="title unfit-title uni-row">
  102. <view class="title">零存</view>
  103. </view>
  104. <view v-if="saveFlag" class="save uni-row">
  105. <text class="label">存入数量</text>
  106. <input class="number" type="number"
  107. v-if="!(Object.keys(storageInfo).length > 0 || storageInfo.status == 1 || Number(dayworkItem.status) >= 3)"
  108. placeholder="请输入" v-model="storageNum" />
  109. <span style="margin-left: 56rpx;flex: 1;" v-else>{{ storageNum }}</span>
  110. </view>
  111. <view v-if="saveFlag" class="save uni-row">
  112. <view class="label">选别类型</view>
  113. <view v-if="!(storageInfo.status == 1 || Number(dayworkItem.status) >= 3 || storageInfo.id)"
  114. style="width: 60%;align-items: center;">
  115. <uni-data-select v-model="type" :localdata="selectTypeList" :clear="false"
  116. style="outline: 2rpx solid #999999;border-radius: 10rpx;"></uni-data-select>
  117. </view>
  118. <span v-else style="margin-left: 56rpx;flex: 1;">{{ selectType(type) }}</span>
  119. </view>
  120. </view>
  121. <!-- 报工部分 -->
  122. <view class="daywork-container">
  123. <view class="result uni-row">
  124. <view class="label">合格量</view>
  125. <input v-if="Number(dayworkItem.status) < 3" type="number" placeholder="请输入合格量"
  126. v-model="dayworkItem.qualifiedNum" />
  127. <span v-else>{{ dayworkItem.qualifiedNum }}</span>
  128. <view class="label" style="text-align: right; padding-right: 24rpx">废品量</view>
  129. <input v-if="Number(dayworkItem.status) < 3" :disabled="true" type="number" placeholder="请输入废品量"
  130. v-model="dayworkItem.rejectNum" />
  131. <span v-else>{{ dayworkItem.rejectNum }}</span>
  132. </view>
  133. <view class="remark uni-row">
  134. <view class="label">备注</view>
  135. <textarea v-if="Number(dayworkItem.status) < 3" v-model="dayworkItem.remark" maxlength="999" />
  136. <span v-else>{{ dayworkItem.remark }}</span>
  137. </view>
  138. <view class="btns-container uni-row">
  139. <!-- 最后一步完成不能更换载具 -->
  140. <view v-if="dayworkItem.daywork != null && dayworkItem.daywork.status != 2" class="bottom-btn left-btn "
  141. @click="handleChangeCarrier">
  142. 更换载具</view>
  143. <view v-if="checkFinishable()&&Number(dayworkItem.status) < 3" class="finished-btn"
  144. @click.stop="handleFinishDaywork">结束报工</view>
  145. <view v-if="Number(dayworkItem.status) < 3" class="pause-btn" @click.stop="handleUpdateDaywork">暂停
  146. </view>
  147. <view v-if="Number(dayworkItem.status) < 3" class="question-btn uni-column"
  148. @click.stop="handleAddConsultation">
  149. <uni-icons type="headphones" size="24" />
  150. <text>咨询</text>
  151. </view>
  152. </view>
  153. </view>
  154. </view>
  155. </template>
  156. <script setup>
  157. import {
  158. ref
  159. } from 'vue'
  160. import {
  161. onMounted,
  162. getCurrentInstance
  163. } from 'vue';
  164. import {
  165. getSortingDayworkItem,
  166. saveConsult,
  167. finish,
  168. update,
  169. selectInstructionList
  170. } from '@/api/business/sortDaywork.js'
  171. import {
  172. getTakeStockPeriod
  173. } from '@/api/business/taksStackLot.js'
  174. import {
  175. getDictInfoByTypes
  176. } from '@/api/dict/dict.js'
  177. import {
  178. onLoad,
  179. onReady,
  180. onUnload,
  181. onShow
  182. } from '@dcloudio/uni-app'
  183. import {
  184. store
  185. } from '@/store/index.js'
  186. import {
  187. timestampToTime,
  188. toHHmmss
  189. } from '@/utils/common.js'
  190. const isEventTriggered = ref(false); // 创建一个标志位
  191. const unfitInfos = ref([])
  192. const consultations = ref([])
  193. const dayworkInfo = ref({})
  194. const retrievalInfo = ref([])
  195. const qualifiedNumDownRatio = ref(0)
  196. // 创建一个引用来存储最后一次请求的时间戳
  197. const lastRequestTimestamp = ref(0);
  198. const selectTypeList = ref([])
  199. const type = ref(null)
  200. const dayworkItem = ref({})
  201. const saveFlag = ref(false)
  202. const storageNum = ref('')
  203. const storageInfo = ref(null)
  204. const qualifiedNumUpRatio = ref(0)
  205. const isFinish = ref(false)
  206. const column1 = [{
  207. name: 'lotCode',
  208. label: '批次号',
  209. align: 'center'
  210. },
  211. {
  212. name: 'storageNum',
  213. label: '数量',
  214. align: 'center'
  215. },
  216. {
  217. name: 'typeLabel',
  218. label: '选别类型',
  219. align: 'center'
  220. },
  221. {
  222. name: 'operation',
  223. type: 'operation',
  224. label: '操作',
  225. align: 'center',
  226. renders: [{
  227. name: '删除',
  228. type: 'warn',
  229. func: "dele",
  230. class: "buttonOp"
  231. }, ]
  232. },
  233. ]
  234. const column2 = [{
  235. name: 'lotCode',
  236. label: '批次号',
  237. align: 'center'
  238. },
  239. {
  240. name: 'storageNum',
  241. label: '数量',
  242. align: 'center'
  243. },
  244. {
  245. name: 'typeLabel',
  246. label: '选别类型',
  247. align: 'center'
  248. },
  249. ]
  250. /***************************** 页面生命周期函数 *****************************/
  251. onLoad(() => {})
  252. onShow(() => {
  253. uni.$off('addInfoEvent');
  254. uni.$off('addUnfitInfoEvent')
  255. })
  256. onMounted(() => {
  257. const instance = getCurrentInstance().proxy
  258. const eventChannel = instance.getOpenerEventChannel();
  259. eventChannel.on('acceptDataFromOpenerPage', function(data) {
  260. if (data && data.data) {
  261. dayworkInfo.value = data.data
  262. init({
  263. id: data.data.id
  264. })
  265. } else {
  266. let reqParam = {
  267. id: dayworkInfo.value.id
  268. }
  269. init(reqParam);
  270. }
  271. })
  272. })
  273. /***************************** 定义了一些方法 *****************************/
  274. const init = (data) => {
  275. let dics = ['sort_report_up_limit', 'sort_report_down_limit', 'select_type']
  276. //获取当前跟选报工合格数最大值
  277. getDictInfoByTypes(dics).then(res => {
  278. console.log(res.data);
  279. if (res.data) {
  280. // 遍历返回的 Map 对象
  281. Object.entries(res.data).forEach(([key, list]) => {
  282. if (list && list.length > 0) {
  283. // 根据 key 的名称,将 value 存储到对应的数组中
  284. list.forEach(item => {
  285. switch (key) {
  286. case 'sort_report_up_limit':
  287. qualifiedNumUpRatio.value = item.dictValue;
  288. break;
  289. case 'sort_report_down_limit':
  290. qualifiedNumDownRatio.value = item.dictValue;
  291. break;
  292. case 'select_type':
  293. selectTypeList.value.push({
  294. value: item.dictValue,
  295. text: item.dictLabel
  296. })
  297. break;
  298. }
  299. });
  300. }
  301. });
  302. console.log('sortReportUpLimitValues:', qualifiedNumUpRatio.value);
  303. console.log('sortReportDownLimitValues:', qualifiedNumDownRatio.value);
  304. console.log('selectTypeValues:', selectTypeList.value);
  305. }
  306. }).catch(err => {
  307. console.log(err);
  308. console.log('369 err');
  309. });
  310. // 获取当前报工信息
  311. getSortingDayworkItem(data).then(res => {
  312. console.log(res)
  313. if (res.code === 200) {
  314. dayworkItem.value = res.data
  315. //判断是否显示零存
  316. if (dayworkItem.value.processStepNumber == dayworkInfo.value.processSequence[dayworkInfo.value
  317. .processSequence.length - 1].processStepNumber) {
  318. saveFlag.value = true
  319. } else {
  320. saveFlag.value = false
  321. }
  322. console.log(dayworkItem.value)
  323. if (dayworkItem.value.status == 0 && dayworkItem.value.qualifiedNum === 0 && dayworkItem.value
  324. .rejectNum === 0) {
  325. dayworkItem.value.qualifiedNum = res.data.prodNum
  326. }
  327. if (res.data.retrievalInfo != null) {
  328. res.data.retrievalInfo = res.data.retrievalInfo.map(item => {
  329. const typeLabelItem = selectTypeList.value.find(v => v.value == item.type);
  330. return {
  331. ...item,
  332. typeLabel: typeLabelItem.text
  333. };
  334. })
  335. }
  336. retrievalInfo.value = res.data.retrievalInfo
  337. storageInfo.value = res.data.storageInfo
  338. console.log(Object.keys(storageInfo.value).length === 0)
  339. if (Object.keys(storageInfo.value).length !== 0) {
  340. storageNum.value = storageInfo.value.storageNum
  341. type.value = storageInfo.value.type
  342. }
  343. console.log(storageNum.value)
  344. consultations.value = res.data.consults
  345. unfitInfos.value = res.data.rejectList
  346. } else {
  347. uni.showToast({
  348. icon: 'none',
  349. title: res.message
  350. })
  351. }
  352. })
  353. }
  354. const addInfo = (data) => {
  355. data.forEach(item => {
  356. console.log(retrievalInfo.value)
  357. retrievalInfo.value.push(item)
  358. })
  359. console.log(data)
  360. uni.$off('addInfoEvent');
  361. }
  362. //添加零取批次
  363. function handleAddLot() {
  364. console.log('調用 handleAddLot')
  365. uni.$on('addInfoEvent', (data) => {
  366. addInfo(data.data)
  367. })
  368. console.log(dayworkItem.value)
  369. const info = {
  370. deptId: dayworkItem.value.deptId,
  371. productId: dayworkItem.value.daywork.productId,
  372. drawingNumber: dayworkItem.value.drawingNumber,
  373. technologyVersion: dayworkItem.value.technologyVersion,
  374. retrievalLotId: dayworkItem.value.lotId,
  375. hasAddedList: retrievalInfo.value
  376. }
  377. // 将 info 对象转换为 JSON 字符串
  378. const serializedData = JSON.stringify(info);
  379. // 对 JSON 字符串进行 URL 编码
  380. const encodedData = encodeURIComponent(serializedData);
  381. // 构建 URL,确保使用正确编码的数据
  382. uni.navigateTo({
  383. url: `/pages/sorting/storageRetrieval?data=${encodedData}`
  384. });
  385. }
  386. const addUnfitInfo = (data) => {
  387. console.log(data)
  388. if (data && data.length > 0) {
  389. for (var i = 0; i < data.length; i++) {
  390. const info = {
  391. inspectionInstructionId: data[i].id,
  392. title: data[i].title,
  393. standard: data[i].standard,
  394. checkStandard: data[i].standard,
  395. type: data[i].type,
  396. reason: ''
  397. }
  398. unfitInfos.value.push(info)
  399. }
  400. }
  401. }
  402. function dele(ite, index) {
  403. if (ite.status == 1) {
  404. uni.showToast({
  405. icon: 'none',
  406. title: '已被领取,不能删除'
  407. })
  408. } else {
  409. retrievalInfo.value.splice(index, 1);
  410. }
  411. }
  412. const addConsultation = (data) => {
  413. const info = {
  414. dayworkItemId: dayworkItem.value.id,
  415. content: data.content,
  416. userId: store.userInfo.userId,
  417. nickName: store.userInfo.nickName,
  418. dayworkId: dayworkItem.value.dayworkId,
  419. productionPlandetailId: dayworkItem.value.productionPlandetailId,
  420. productionPlanDetailSubDetailId: dayworkItem.value.productionPlanDetailSubDetailId,
  421. lotId: dayworkItem.value.lotId,
  422. lotCode: dayworkItem.value.lotCode,
  423. productId: dayworkItem.value.productId,
  424. productDescription: dayworkItem.value.productDescription,
  425. technologicalProcessId: dayworkItem.value.technologicalProcessId,
  426. technologicalProcessDetailId: dayworkItem.value.technologicalProcessDetailId,
  427. processId: dayworkItem.value.processId,
  428. processAlias: dayworkItem.value.process.processAlias,
  429. // technicianId: dayworkItem.value.technicianId,
  430. technicianId: data.technicianId,
  431. departments: data.departments,
  432. pictures: data.pictures
  433. }
  434. saveConsult(info).then(res => {
  435. if (res.code === 200) {
  436. consultations.value = res.data
  437. console.log(consultations.value)
  438. } else {
  439. uni.showToast({
  440. icon: 'none',
  441. title: res.message
  442. })
  443. }
  444. })
  445. isEventTriggered.value = true; // 更新标志位状态
  446. consultations.value.push(info)
  447. }
  448. /***************************** 定义了一些事件 *****************************/
  449. // 添加不合格信息
  450. async function handleAddUnfit() {
  451. // 监听事件
  452. uni.$once('addUnfitInfoEvent', (data) => {
  453. addUnfitInfo(data)
  454. })
  455. const hasInstruction = await getHasInstruction();
  456. console.log(hasInstruction); // 这将打印 true 或 false
  457. if (!hasInstruction) {
  458. uni.navigateTo({
  459. url: "/pages/sorting/specialOptions",
  460. success: (res) => {
  461. // 通过eventChannel向被打开页面传送数据
  462. res.eventChannel.emit('acceptDataFromOpenerPage', {
  463. data: dayworkItem.value,
  464. query: {
  465. productId: dayworkItem.value.daywork.productId,
  466. processId: dayworkItem.value.process.id,
  467. // technologyVersion: dayworkItem.value.technologicalProcessDetail.technologyVersion
  468. technologyVersion: dayworkItem.value.technologyVersion
  469. },
  470. index: unfitInfos.value.length
  471. })
  472. }
  473. })
  474. } else {
  475. console.log(dayworkItem.value)
  476. uni.navigateTo({
  477. url: "/pages/sorting/options",
  478. success: (res) => {
  479. // 通过eventChannel向被打开页面传送数据
  480. res.eventChannel.emit('acceptDataFromOpenerPage', {
  481. data: dayworkItem.value,
  482. query: {
  483. productId: dayworkItem.value.daywork.productId,
  484. processCode: dayworkItem.value.process.processCode,
  485. // technologyVersion: dayworkItem.value.technologicalProcessDetail.technologyVersion
  486. technologyVersion: dayworkItem.value.technologyVersion
  487. },
  488. index: unfitInfos.value.length
  489. })
  490. }
  491. })
  492. }
  493. }
  494. async function getHasInstruction() {
  495. console.log(dayworkItem.value)
  496. const res = await selectInstructionList({
  497. technologicalProcessId: dayworkItem.value.technologicalProcessId,
  498. processCode: dayworkItem.value.process.processCode,
  499. lotId: dayworkItem.value.lotId
  500. })
  501. return res.data
  502. // .then(res=> {
  503. // console.log(res.data)
  504. // return res.data
  505. // })
  506. }
  507. // 删除不合格信息
  508. const handleDelUnfit = (index) => {
  509. let tempInfo = unfitInfos.value[index]
  510. console.log(tempInfo)
  511. uni.showModal({
  512. title: '提示',
  513. content: '确定删除该项?',
  514. success: function(res) {
  515. if (res.confirm) {
  516. dayworkItem.value.rejectNum = dayworkItem.value.rejectNum - tempInfo.rejectNum
  517. dayworkItem.value.qualifiedNum = parseInt(dayworkItem.value.qualifiedNum) + parseInt(
  518. tempInfo.rejectNum)
  519. unfitInfos.value.splice(index, 1)
  520. } else if (res.cancel) {
  521. return
  522. }
  523. }
  524. })
  525. }
  526. /* 更换载具*/
  527. function handleChangeCarrier(item) {
  528. // uni.$once('refreshQuickReport', () => {
  529. // init()
  530. // })
  531. store.dayworkInfo = null
  532. uni.navigateTo({
  533. url: "/pages/changeBox/index",
  534. success: function(res) {
  535. // 通过eventChannel向被打开页面传送数据
  536. res.eventChannel.emit('sortingFromOpenerPage', {
  537. data: dayworkItem.value
  538. })
  539. }
  540. })
  541. }
  542. // 添加咨询信息
  543. const handleAddConsultation = () => {
  544. isEventTriggered.value = false; // 更新标志位状态
  545. // 监听事件
  546. uni.$once('addConsulttationEvent', (data) => {
  547. if (!isEventTriggered.value) {
  548. // 如果事件尚未触发,则执行事件触发逻辑
  549. addConsultation(data)
  550. }
  551. })
  552. uni.navigateTo({
  553. url: "/pages/sorting/consultation",
  554. success: (res) => {
  555. // 通过eventChannel向被打开页面传送数据
  556. res.eventChannel.emit('acceptDataFromOpenerPage', {
  557. data: dayworkItem.value
  558. })
  559. }
  560. })
  561. }
  562. const checkFinishable = () => {
  563. if (consultations.value.findIndex(v => v.status === 0) >= 0) {
  564. return false
  565. } else {
  566. return true
  567. }
  568. }
  569. const showStatus = (status) => {
  570. // console.log(status)
  571. switch (status) {
  572. case 0:
  573. return '未确认'
  574. case 1:
  575. return '不合格'
  576. case 2:
  577. return '合格'
  578. default:
  579. return ''
  580. }
  581. }
  582. function selectText(item) {
  583. // for (var i = 0; i < consul.length; i++) {
  584. // if (item.status == consul[i].value) {
  585. // return consul[i].text
  586. // }
  587. // }
  588. if (item.consultResultId == 0) {
  589. return '待确认'
  590. } else {
  591. return item.result
  592. }
  593. }
  594. const promiseDownModal = () => new Promise((resolve) => {
  595. uni.showModal({
  596. title: '提示',
  597. content: `合格数过低,最低应为投产量的${qualifiedNumDownRatio.value}%, 是否确定保存`,
  598. showCancel: true,
  599. cancelText: '取消',
  600. confirmText: '确定',
  601. confirmColor: '#ff0000',
  602. cancelColor: '#55aa00',
  603. complete: (res) => { // 使用 complete 回调
  604. console.log("Modal complete callback triggered:", res);
  605. if (res.confirm) {
  606. resolve(true);
  607. } else {
  608. resolve(false);
  609. }
  610. }
  611. });
  612. });
  613. const promiseUpModal = () => new Promise((resolve) => {
  614. uni.showModal({
  615. title: '提示',
  616. content: `合格数过高,最高应为投产量的${qualifiedNumUpRatio.value}%, 是否确定保存`,
  617. showCancel: true,
  618. cancelText: '取消',
  619. confirmText: '确定',
  620. confirmColor: '#ff0000',
  621. cancelColor: '#55aa00',
  622. complete: (res) => { // 使用 complete 回调
  623. console.log("Modal complete callback triggered:", res);
  624. if (res.confirm) {
  625. resolve(true);
  626. } else {
  627. resolve(false);
  628. }
  629. }
  630. });
  631. });
  632. const validDownNum = async () => {
  633. // 只在结束报工的时候判断
  634. if (isFinish.value && dayworkItem.value.qualifiedNum < (dayworkItem.value.prodNum * (qualifiedNumDownRatio
  635. .value / 100))) {
  636. try {
  637. const promiseDown = await promiseDownModal(); // 等待用户确认或取消
  638. console.log(promiseDown);
  639. return promiseDown; // 返回用户的选择
  640. } catch (error) {
  641. console.log("用户取消操作", error);
  642. return false; // 用户取消,返回 false
  643. }
  644. } else {
  645. return true; // 合格数正常,直接返回 true
  646. }
  647. };
  648. const validUpNum = async () => {
  649. // 只在结束报工的时候判断
  650. if (isFinish.value && dayworkItem.value.qualifiedNum > (dayworkItem.value.prodNum * (qualifiedNumUpRatio
  651. .value / 100))) {
  652. try {
  653. const promiseUp = await promiseUpModal(); // 等待用户确认或取消
  654. console.log(promiseUp);
  655. return promiseUp; // 返回用户的选择
  656. } catch (error) {
  657. console.log("用户取消操作", error);
  658. return false; // 用户取消,返回 false
  659. }
  660. } else {
  661. return true; // 合格数正常,直接返回 true
  662. }
  663. };
  664. const showStatusColor = (status) => {
  665. // console.log(status)
  666. switch (status) {
  667. case 0:
  668. return '#fcab53'
  669. case 1:
  670. return '#fc044f'
  671. case 2:
  672. return '#1deb19'
  673. default:
  674. return ''
  675. }
  676. }
  677. const rejectNumberChange = () => {
  678. let sumReject = 0
  679. unfitInfos.value.forEach(v => {
  680. sumReject += v.rejectNum == null ? 0 : Number(v.rejectNum)
  681. })
  682. dayworkItem.value.rejectNum = sumReject
  683. dayworkItem.value.qualifiedNum = dayworkItem.value.prodNum - sumReject
  684. console.log(dayworkItem.value)
  685. }
  686. const validHandle = async () => {
  687. console.log(storageNum.value == "")
  688. if (storageNum.value != null && storageNum.value != "" && storageNum.value <= 0) {
  689. uni.showToast({
  690. icon: 'none',
  691. title: "存入数量应大于0",
  692. duration: 2000
  693. })
  694. return false;
  695. }
  696. if (storageNum.value != null && storageNum.value != "" && storageNum.value > 0 && storageNum.value > 0 &&
  697. type
  698. .value == null) {
  699. uni.showToast({
  700. icon: 'none',
  701. title: "选别类型不能为空",
  702. duration: 2000
  703. })
  704. return false;
  705. }
  706. for (let i = 0; i < unfitInfos.value.length; i++) {
  707. const e = unfitInfos.value[i]
  708. if (e.rejectNum == null || e.rejectNum == 0) {
  709. uni.showToast({
  710. icon: 'none',
  711. title: `第${i + 1}条不合格信息未输入不合格数量`
  712. })
  713. return false
  714. }
  715. }
  716. if (dayworkItem.value.qualifiedNum === null || dayworkItem.value.qualifiedNum === "") {
  717. uni.showToast({
  718. icon: 'none',
  719. title: "合格数不能为空",
  720. duration: 2000
  721. })
  722. return false;
  723. }
  724. if (isFinish.value && dayworkItem.value.qualifiedNum == 0) {
  725. uni.showToast({
  726. icon: 'none',
  727. title: "合格数不能为0",
  728. duration: 2000
  729. })
  730. return false;
  731. }
  732. if (dayworkItem.value.qualifiedNum < 0) {
  733. uni.showToast({
  734. icon: 'none',
  735. title: "合格数不能为负数,请检查不合格信息后提交",
  736. duration: 2000
  737. })
  738. return false;
  739. }
  740. if (isFinish.value && dayworkItem.value.qualifiedNum > (dayworkItem.value.prodNum * (qualifiedNumUpRatio
  741. .value / 100))) {
  742. // let flag = await validUpNum()
  743. // if (!flag) {
  744. // return false
  745. // }
  746. uni.showToast({
  747. icon: 'none',
  748. title: `合格数过高,最高应为投产量的${qualifiedNumUpRatio.value}%`,
  749. duration: 2000
  750. })
  751. return false;
  752. }
  753. if (isFinish.value && dayworkItem.value.qualifiedNum < (dayworkItem.value.prodNum * (qualifiedNumDownRatio
  754. .value / 100))) {
  755. console.log("666")
  756. let flag = await validDownNum()
  757. if (!flag) {
  758. return false
  759. }
  760. // uni.showToast({
  761. // icon: 'none',
  762. // title: `合格数过低,最低应为投产量的${qualifiedNumDownRatio.value}%`,
  763. // duration: 2000
  764. // })
  765. // return false;
  766. }
  767. return true
  768. // unfitInfos.value.forEach((e, i) => {
  769. // if (e.name)
  770. // })
  771. }
  772. //状态文本
  773. function selectType(item) {
  774. for (var i = 0; i < selectTypeList.value.length; i++) {
  775. if (item == selectTypeList.value[i].value) {
  776. return selectTypeList.value[i].text
  777. }
  778. }
  779. }
  780. async function handleCheckStock() {
  781. let currentProcessStepNumber = dayworkInfo.value.currentProcess.processStepNumber;
  782. let lastProcess = dayworkInfo.value.processSequence[dayworkInfo.value.processSequence.length - 1];
  783. // 判断当前工序是否是最后一道序
  784. if (currentProcessStepNumber === lastProcess.processStepNumber) {
  785. // 等待 getTakeStockPeriod() 的 Promise 完成
  786. const res = await getTakeStockPeriod({
  787. dayworkId: dayworkInfo.value.id
  788. });
  789. console.log(res.data.length);
  790. if (res.data.length > 0) {
  791. uni.showToast({
  792. icon: 'none',
  793. title: "此次盘点未结束,不能结束报工",
  794. duration: 2000
  795. });
  796. return false; // 如果盘点未结束,返回 false
  797. }
  798. }
  799. // 如果不是最后一道工序或盘点已结束,返回 true
  800. return true;
  801. }
  802. async function handleFinishDaywork() {
  803. isFinish.value = true
  804. const res = await validHandle()
  805. if (!res) {
  806. return
  807. }
  808. //判断当前批次是否在盘点,如果盘点未结束,则不能结束报工
  809. let checkStockResult = await handleCheckStock();
  810. console.log(checkStockResult)
  811. if (!checkStockResult) {
  812. return;
  813. }
  814. //零存数据
  815. if (storageNum.value != null && storageNum.value != "") {
  816. if (Object.keys(storageInfo.value).length === 0) {
  817. storageInfo.value = {
  818. productionPlanDetailId: dayworkItem.value.productionPlanDetailId,
  819. productDescription: dayworkItem.value.productDescription,
  820. drawingNumber: dayworkItem.value.drawingNumber,
  821. lotId: dayworkItem.value.lotId,
  822. lotCode: dayworkItem.value.lotCode,
  823. deptId: dayworkItem.value.deptId,
  824. productId: dayworkItem.value.daywork.productId,
  825. technologyVersion: dayworkItem.value.technologyVersion,
  826. storageNum: storageNum.value,
  827. storagerId: store.userInfo.userId,
  828. type: type.value
  829. }
  830. } else {
  831. storageInfo.value.storageNum = storageNum.value
  832. storageInfo.value.type = type.value
  833. }
  834. } else {
  835. storageInfo.value = null
  836. }
  837. //零取数据
  838. if (retrievalInfo.value.length > 0) {
  839. retrievalInfo.value.forEach(item => {
  840. item.retrievalLotId = dayworkItem.value.lotId,
  841. item.retrievalLotCode = dayworkItem.value.lotCode,
  842. item.retrievalerId = store.userInfo.userId,
  843. item.retrievalTime = timestampToTime(new Date())
  844. })
  845. }
  846. const saveData = {
  847. rejectList: unfitInfos.value,
  848. consult: consultations.value,
  849. id: dayworkItem.value.id,
  850. prodNum: dayworkItem.value.prodNum,
  851. rejectNum: dayworkItem.value.rejectNum,
  852. qualifiedNum: dayworkItem.value.qualifiedNum,
  853. equipmentDetailId: dayworkItem.value.equipmentDetailId,
  854. equipmentDetailCode: dayworkItem.value.equipmentDetailCode,
  855. remark: dayworkItem.value.remark,
  856. storageInfo: storageInfo.value,
  857. retrievalInfo: retrievalInfo.value
  858. }
  859. const currentTime = Date.now();
  860. // 检查是否已经过去了 2 秒
  861. if (currentTime - lastRequestTimestamp.value < 2000) {
  862. // 如果在 2 秒 内已经点击,那么不执行
  863. uni.showToast({
  864. icon: 'none',
  865. title: `请勿重复点击`,
  866. duration: 2000
  867. })
  868. return;
  869. }
  870. lastRequestTimestamp.value = currentTime;
  871. console.log(saveData)
  872. finish(saveData).then(res => {
  873. if (res.code === 200) {
  874. uni.navigateBack()
  875. } else {
  876. uni.showToast({
  877. icon: 'none',
  878. title: res.message
  879. })
  880. }
  881. })
  882. }
  883. const handleUpdateDaywork = () => {
  884. isFinish.value = false
  885. if (!validHandle()) {
  886. return
  887. }
  888. //零存数据
  889. if (storageNum.value != null && storageNum.value != "") {
  890. if (Object.keys(storageInfo.value).length === 0) {
  891. storageInfo.value = {
  892. productionPlanDetailId: dayworkItem.value.productionPlanDetailId,
  893. productDescription: dayworkItem.value.productDescription,
  894. drawingNumber: dayworkItem.value.drawingNumber,
  895. lotId: dayworkItem.value.lotId,
  896. lotCode: dayworkItem.value.lotCode,
  897. deptId: dayworkItem.value.deptId,
  898. productId: dayworkItem.value.daywork.productId,
  899. technologyVersion: dayworkItem.value.technologyVersion,
  900. storageNum: storageNum.value,
  901. storagerId: store.userInfo.userId,
  902. type: type.value
  903. }
  904. } else {
  905. storageInfo.value.storageNum = storageNum.value
  906. storageInfo.value.type = type.value
  907. }
  908. } else {
  909. storageInfo.value = null
  910. }
  911. //零取数据
  912. if (retrievalInfo.value.length > 0) {
  913. retrievalInfo.value.forEach(item => {
  914. item.retrievalLotId = dayworkItem.value.lotId,
  915. item.retrievalLotCode = dayworkItem.value.lotCode,
  916. item.retrievalerId = store.userInfo.userId,
  917. item.retrievalTime = timestampToTime(new Date())
  918. })
  919. }
  920. const saveData = {
  921. rejectList: unfitInfos.value,
  922. consult: consultations.value,
  923. id: dayworkItem.value.id,
  924. prodNum: dayworkItem.value.prodNum,
  925. rejectNum: dayworkItem.value.rejectNum,
  926. equipmentDetailId: dayworkItem.value.equipmentDetailId,
  927. equipmentDetailCode: dayworkItem.value.equipmentDetailCode,
  928. qualifiedNum: dayworkItem.value.qualifiedNum,
  929. remark: dayworkItem.value.remark,
  930. storageInfo: storageInfo.value,
  931. retrievalInfo: retrievalInfo.value
  932. }
  933. console.log(saveData)
  934. update(saveData).then(res => {
  935. if (res.code === 200) {
  936. uni.$emit("formBack")
  937. uni.navigateBack()
  938. } else {
  939. uni.showToast({
  940. icon: 'none',
  941. title: res.message
  942. })
  943. }
  944. })
  945. }
  946. </script>
  947. <style lang="scss">
  948. .buttonOp {
  949. margin-top: 5px;
  950. }
  951. .page-container {
  952. // height: 100%;
  953. background-color: #ececec;
  954. font-size: 28rpx;
  955. overflow: auto;
  956. >.title {
  957. font-weight: 700;
  958. margin: 24rpx 16rpx;
  959. }
  960. }
  961. .add-btn {
  962. padding: 12rpx 32rpx;
  963. background-color: #a4adb3;
  964. color: #ffffff;
  965. border-radius: 12rpx;
  966. font-size: 24rpx;
  967. }
  968. .lot-info {
  969. margin: 32rpx 16rpx 0 16rpx;
  970. padding: 24rpx;
  971. background-color: #ffffff;
  972. border-radius: 8rpx;
  973. .lot-code {
  974. font-size: 32rpx;
  975. font-weight: 700;
  976. margin-bottom: 16rpx;
  977. }
  978. .product-info {
  979. font-size: 28rpx;
  980. color: #9f9f9f;
  981. }
  982. }
  983. .middle {
  984. display: flex;
  985. flex-direction: row;
  986. align-items: center;
  987. justify-content: center
  988. }
  989. .segment {
  990. width: 80%;
  991. background-color: rgba(213, 213, 213, 1);
  992. border: 1rpx solid rgba(213, 213, 213, 1);
  993. margin: 16px 0;
  994. }
  995. .unfit-title {
  996. margin-bottom: 24rpx;
  997. justify-content: space-between;
  998. align-items: center;
  999. text {
  1000. font-size: 28rpx;
  1001. font-weight: 700;
  1002. }
  1003. .add-btn {
  1004. padding: 12rpx 32rpx;
  1005. background-color: #a4adb3;
  1006. color: #ffffff;
  1007. border-radius: 12rpx;
  1008. font-size: 24rpx;
  1009. }
  1010. }
  1011. .save {
  1012. align-items: center;
  1013. padding-bottom: 32rpx;
  1014. justify-content: space-between;
  1015. input {
  1016. height: 56rpx;
  1017. border: 1px solid #9f9f9f;
  1018. font-size: 28rpx;
  1019. &.number {
  1020. width: 60%;
  1021. text-align: center;
  1022. }
  1023. }
  1024. }
  1025. .unfit-container {
  1026. padding: 24rpx;
  1027. margin: 0 16rpx;
  1028. background-color: #ffffff;
  1029. border-radius: 12rpx;
  1030. .unfit-item-container {
  1031. position: relative;
  1032. >* {
  1033. margin-bottom: 24rpx;
  1034. }
  1035. .title {
  1036. font-weight: 700;
  1037. justify-content: space-between;
  1038. align-items: center;
  1039. image {
  1040. width: 40rpx;
  1041. height: 40rpx;
  1042. }
  1043. }
  1044. .standard {}
  1045. .result {
  1046. align-items: center;
  1047. border-bottom: 1px solid #9f9f9f;
  1048. padding-bottom: 32rpx;
  1049. .label {
  1050. flex: 1;
  1051. }
  1052. input {
  1053. width: 280rpx;
  1054. height: 56rpx;
  1055. border: 1px solid #9f9f9f;
  1056. font-size: 28rpx;
  1057. &.number {
  1058. width: 104rpx;
  1059. text-align: center;
  1060. }
  1061. }
  1062. }
  1063. }
  1064. .unfit-item-container:last-child {
  1065. .result {
  1066. border-bottom: none;
  1067. padding-bottom: 0;
  1068. }
  1069. }
  1070. }
  1071. .consultation-container {
  1072. margin: 0 16rpx;
  1073. padding: 24rpx;
  1074. background-color: #ffffff;
  1075. border-radius: 8rpx;
  1076. .consultation-item-container {
  1077. margin-bottom: 24rpx;
  1078. border-bottom: 2px solid #888888;
  1079. padding-bottom: 24rpx;
  1080. }
  1081. .consultation-item-container:last-child {
  1082. margin-bottom: 0;
  1083. border-bottom: 0;
  1084. padding-bottom: 0;
  1085. }
  1086. .question,
  1087. .answer {
  1088. .label {
  1089. justify-content: space-between;
  1090. margin-bottom: 16rpx;
  1091. font-weight: 700;
  1092. }
  1093. .content {
  1094. line-height: 40rpx;
  1095. }
  1096. }
  1097. .answer {
  1098. margin-top: 24rpx;
  1099. }
  1100. }
  1101. .daywork-container {
  1102. margin-top: 24rpx;
  1103. padding: 24rpx;
  1104. background-color: #ffffff;
  1105. border: 1px solid #bcbcbc;
  1106. .result {
  1107. align-items: center;
  1108. .label {
  1109. width: 112rpx;
  1110. }
  1111. input {
  1112. flex: 1;
  1113. height: 56rpx;
  1114. border: 1px solid #9f9f9f;
  1115. font-size: 28rpx;
  1116. text-align: center;
  1117. }
  1118. }
  1119. .remark {
  1120. margin-top: 24rpx;
  1121. .label {
  1122. width: 112rpx;
  1123. }
  1124. textarea {
  1125. flex: 1;
  1126. border: 1px solid #9f9f9f;
  1127. height: 168rpx;
  1128. }
  1129. }
  1130. .btns-container {
  1131. margin-top: 24rpx;
  1132. .bottom-btn {
  1133. display: flex;
  1134. flex: 1;
  1135. height: 80rpx;
  1136. background-color: #5555ff;
  1137. color: #ffffff;
  1138. text-align: center;
  1139. justify-content: center;
  1140. align-items: center;
  1141. border-radius: 8rpx;
  1142. margin-right: 10rpx;
  1143. &.left-btn {
  1144. background-color: rgba(85, 85, 255, 1.0);
  1145. }
  1146. &.right-btn {
  1147. margin-left: 24rpx;
  1148. }
  1149. }
  1150. .finished-btn {
  1151. display: flex;
  1152. flex: 1;
  1153. height: 80rpx;
  1154. background-color: #fc6565;
  1155. color: #ffffff;
  1156. text-align: center;
  1157. justify-content: center;
  1158. align-items: center;
  1159. border-radius: 8rpx;
  1160. }
  1161. .pause-btn {
  1162. display: flex;
  1163. flex: 1;
  1164. height: 80rpx;
  1165. background-color: #55d90d;
  1166. color: #ffffff;
  1167. text-align: center;
  1168. justify-content: center;
  1169. align-items: center;
  1170. border-radius: 8rpx;
  1171. margin-left: 12rpx;
  1172. }
  1173. .question-btn {
  1174. width: 80rpx;
  1175. align-items: flex-end;
  1176. image {
  1177. width: 48rpx;
  1178. height: 48rpx;
  1179. }
  1180. text {
  1181. font-size: 24rpx;
  1182. }
  1183. }
  1184. }
  1185. }
  1186. .zb-table .item-tr[data-v-336e291f] {
  1187. flex-direction: row;
  1188. }
  1189. </style>