edit.vue 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541
  1. <template>
  2. <view class="page repair">
  3. <scroll-view scroll-y="true" class="detail">
  4. <view class="form-content">
  5. <uni-forms
  6. ref="repairFormRef"
  7. labelWidth="140px"
  8. :modelValue="maintain"
  9. :rules="maintainRules"
  10. err-show-type="toast"
  11. >
  12. <!-- 设备 -->
  13. <uni-forms-item
  14. class="form-item"
  15. :label="$t('maintenanceWorkOrder.equipment')"
  16. name="deviceName"
  17. :required="true"
  18. >
  19. <uni-easyinput
  20. style="text-align: right"
  21. :inputBorder="false"
  22. :clearable="false"
  23. :disabled="true"
  24. :styles="{ disableColor: '#fff' }"
  25. :placeholder="$t('operation.PleaseSelect')"
  26. v-model="maintain.deviceName"
  27. @focus="onAddDevice"
  28. />
  29. </uni-forms-item>
  30. <!-- 维修类型 -->
  31. <uni-forms-item
  32. class="form-item"
  33. :label="$t('equipmentMaintenance.maintenanceType')"
  34. name="type"
  35. :required="true"
  36. >
  37. <uni-data-select
  38. :clear="false"
  39. v-model="maintain.type"
  40. :localdata="typeRange"
  41. >
  42. </uni-data-select>
  43. </uni-forms-item>
  44. <!-- 是否停机 -->
  45. <uni-forms-item
  46. class="form-item"
  47. :label="$t('equipmentMaintenance.isStop')"
  48. name="ifStop"
  49. :required="true"
  50. >
  51. <uni-data-select
  52. :clear="false"
  53. v-model="maintain.ifStop"
  54. :localdata="ifStopRange"
  55. >
  56. </uni-data-select>
  57. </uni-forms-item>
  58. <!-- 维修开始时间 维修类型是委外时不必填-->
  59. <uni-forms-item
  60. class="form-item"
  61. :label="$t('equipmentMaintenance.maintenanceStartTime')"
  62. name="maintainStartTime"
  63. :required="maintain.type == 'out' ? false : true"
  64. >
  65. <!-- :end="dateMax" -->
  66. <uni-datetime-picker
  67. type="datetime"
  68. :border="false"
  69. :start="maintain.failureTime"
  70. returnType="timestamp"
  71. :placeholder="$t('operation.PleaseSelect')"
  72. :style="{
  73. color: maintain.maintainStartTime ? '#333' : '#999',
  74. 'font-size': maintain.maintainStartTime
  75. ? '14px !important'
  76. : 'inherit !important',
  77. }"
  78. v-model="maintain.maintainStartTime"
  79. >
  80. </uni-datetime-picker>
  81. </uni-forms-item>
  82. <!-- return-type="timestamp" -->
  83. <!-- 维修结束时间 维修类型是委外时不必填-->
  84. <uni-forms-item
  85. class="form-item"
  86. :label="$t('equipmentMaintenance.maintenanceEndTime')"
  87. name="maintainEndTime"
  88. :required="maintain.type == 'out' ? false : true"
  89. >
  90. <!-- :end="dateMax" -->
  91. <uni-datetime-picker
  92. type="datetime"
  93. :border="false"
  94. :start="maintain.failureTime"
  95. returnType="timestamp"
  96. :placeholder="$t('operation.PleaseSelect')"
  97. :style="{
  98. color: maintain.maintainEndTime ? '#333' : '#999',
  99. 'font-size': maintain.maintainEndTime
  100. ? '14px !important'
  101. : 'inherit !important',
  102. }"
  103. v-model="maintain.maintainEndTime"
  104. />
  105. </uni-forms-item>
  106. <!-- 故障时间 维修类型是委外时必填-->
  107. <uni-forms-item
  108. class="form-item"
  109. :label="$t('fault.faultTime')"
  110. name="failureTime"
  111. :required="maintain.type == 'out' ? true : false"
  112. >
  113. <!-- :end="dateMax" -->
  114. <uni-datetime-picker
  115. type="datetime"
  116. :border="false"
  117. returnType="timestamp"
  118. :disabled="true"
  119. :placeholder="$t('operation.PleaseSelect')"
  120. :style="{
  121. color: maintain.failureTime ? '#333' : '#999',
  122. 'font-size': maintain.failureTime
  123. ? '14px !important'
  124. : 'inherit !important',
  125. }"
  126. v-model="maintain.failureTime"
  127. />
  128. </uni-forms-item>
  129. <!-- 故障影响 -->
  130. <uni-forms-item
  131. class="form-item"
  132. :label="$t('fault.faultImpact')"
  133. name="failureInfluence"
  134. :required="false"
  135. >
  136. <uni-easyinput
  137. style="text-align: right"
  138. :inputBorder="false"
  139. :clearable="true"
  140. :styles="{ disableColor: '#fff' }"
  141. v-model="maintain.failureInfluence"
  142. :placeholder="$t('operation.PleaseFillIn')"
  143. />
  144. </uni-forms-item>
  145. <!-- 故障系统 -->
  146. <uni-forms-item
  147. class="form-item"
  148. :label="$t('fault.faultSystem')"
  149. name="failureSystem"
  150. :required="false"
  151. >
  152. <uni-easyinput
  153. style="text-align: right"
  154. :inputBorder="false"
  155. :clearable="true"
  156. :styles="{ disableColor: '#fff' }"
  157. v-model="maintain.failureSystem"
  158. :placeholder="$t('operation.PleaseFillIn')"
  159. />
  160. </uni-forms-item>
  161. <!-- 维修费用 维修类型是委外时可填 -->
  162. <uni-forms-item
  163. class="form-item"
  164. :label="$t('equipmentMaintenance.cost')"
  165. name="maintainFee"
  166. :required="false"
  167. v-if="maintain.type == 'in'"
  168. >
  169. <uni-easyinput
  170. style="text-align: right"
  171. :inputBorder="false"
  172. :clearable="true"
  173. :styles="{ disableColor: '#fff' }"
  174. v-model="maintain.maintainFee"
  175. :disabled="maintain.type == 'out' ? false : true"
  176. />
  177. </uni-forms-item>
  178. <!-- 图片 -->
  179. <uni-forms-item
  180. class="form-item"
  181. :label="$t('general.picture')"
  182. name="picList"
  183. :required="false"
  184. >
  185. <uni-file-picker
  186. file-mediatype="image"
  187. mode="grid"
  188. :auto-upload="false"
  189. :limit="9"
  190. :imageStyles="{ border: false }"
  191. v-model="maintain.picList"
  192. @select="upload"
  193. @delete="deleteImg"
  194. >
  195. <template #default>
  196. <view
  197. class="flex-col align-center justify-center"
  198. style="width: 60px; height: 60px; background-color: #f4f4f4"
  199. >
  200. <uni-icons type="plusempty" color="#ACACAC" size="12" />
  201. </view>
  202. </template>
  203. </uni-file-picker>
  204. </uni-forms-item>
  205. <!-- 类型是out(OA委外)时,触发oa流程 -->
  206. <template v-if="maintain.type == 'out'">
  207. <!-- 申请人 -->
  208. <uni-forms-item
  209. class="form-item"
  210. :label="$t('equipmentMaintenance.applicant')"
  211. :required="true"
  212. name="applyPersonId"
  213. >
  214. <uni-data-select
  215. :clear="false"
  216. :disabled="true"
  217. v-model="maintain.applyPersonId"
  218. :localdata="applyPersonRange"
  219. @click="
  220. openLocalSearch(
  221. applyPersonRange,
  222. 'applyPersonId',
  223. $t('equipmentMaintenance.applicant')
  224. )
  225. "
  226. >
  227. </uni-data-select>
  228. </uni-forms-item>
  229. <!-- 维修类别 -->
  230. <uni-forms-item
  231. class="form-item"
  232. :label="$t('equipmentMaintenance.classify')"
  233. :required="true"
  234. name="maintainClassify"
  235. >
  236. <uni-data-select
  237. :clear="false"
  238. v-model="maintain.maintainClassify"
  239. :localdata="maintainClassifyRange"
  240. >
  241. </uni-data-select>
  242. </uni-forms-item>
  243. <!-- 运行公里/小时 -->
  244. <uni-forms-item
  245. class="form-item"
  246. :label="$t('equipmentMaintenance.runningKilometersPerHour')"
  247. :required="false"
  248. name="kmHour"
  249. >
  250. <uni-easyinput
  251. style="text-align: right"
  252. :inputBorder="false"
  253. :clearable="true"
  254. :styles="{ disableColor: '#fff' }"
  255. v-model="maintain.kmHour"
  256. :placeholder="$t('operation.PleaseFillIn')"
  257. />
  258. </uni-forms-item>
  259. <!-- 规格型号 -->
  260. <uni-forms-item
  261. class="form-item"
  262. :label="$t('equipmentMaintenance.specificationModel')"
  263. :required="true"
  264. name="specificationModel"
  265. >
  266. <uni-easyinput
  267. style="text-align: right"
  268. :inputBorder="false"
  269. :clearable="true"
  270. :styles="{ disableColor: '#fff' }"
  271. v-model="maintain.model"
  272. :placeholder="$t('operation.PleaseFillIn')"
  273. />
  274. </uni-forms-item>
  275. <!-- 启用日期 -->
  276. <uni-forms-item
  277. class="form-item"
  278. :label="$t('equipmentMaintenance.enableDate')"
  279. :required="true"
  280. name="enableDate"
  281. >
  282. <uni-datetime-picker
  283. type="date"
  284. :border="false"
  285. returnType="string"
  286. :placeholder="$t('operation.PleaseSelect')"
  287. :style="{
  288. color: maintain.enableDate ? '#333' : '#999',
  289. 'font-size': maintain.enableDate
  290. ? '14px !important'
  291. : 'inherit !important',
  292. }"
  293. v-model="maintain.enableDate"
  294. >
  295. </uni-datetime-picker>
  296. </uni-forms-item>
  297. <!-- 供应商 -->
  298. <uni-forms-item
  299. class="form-item"
  300. :label="$t('equipmentMaintenance.supplier')"
  301. :required="true"
  302. name="supplier"
  303. >
  304. <uni-easyinput
  305. style="text-align: right"
  306. :inputBorder="false"
  307. :clearable="true"
  308. :styles="{ disableColor: '#fff' }"
  309. v-model="maintain.supplier"
  310. :placeholder="$t('operation.PleaseFillIn')"
  311. >
  312. <template #right>
  313. <button
  314. class="mini-btn"
  315. type="primary"
  316. size="mini"
  317. @click="onManufacturerChoose"
  318. >
  319. {{ $t("operation.PleaseSelect") }}
  320. </button>
  321. </template>
  322. </uni-easyinput>
  323. </uni-forms-item>
  324. <!-- 维修费用 -->
  325. <uni-forms-item
  326. class="form-item"
  327. :label="$t('equipmentMaintenance.cost')"
  328. :required="true"
  329. name="maintainFee"
  330. >
  331. <uni-easyinput
  332. style="text-align: right"
  333. :inputBorder="false"
  334. :clearable="true"
  335. :styles="{ disableColor: '#fff' }"
  336. v-model="maintain.maintainFee"
  337. :placeholder="$t('operation.PleaseFillIn')"
  338. :disabled="maintain.type == 'out' ? false : true"
  339. />
  340. </uni-forms-item>
  341. <!-- 项目经理 -->
  342. <uni-forms-item
  343. class="form-item"
  344. :label="$t('equipmentMaintenance.projectManager')"
  345. :required="true"
  346. name="projectManager"
  347. >
  348. <uni-data-select
  349. :clear="false"
  350. :disabled="true"
  351. v-model="maintain.projectManager"
  352. :localdata="projectManagerRange"
  353. @click="
  354. openLocalSearch(
  355. projectManagerRange,
  356. 'projectManager',
  357. $t('equipmentMaintenance.projectManager')
  358. )
  359. "
  360. >
  361. </uni-data-select>
  362. </uni-forms-item>
  363. <!-- 维修地点 -->
  364. <uni-forms-item
  365. class="form-item"
  366. :label="$t('equipmentMaintenance.maintenanceLocation')"
  367. :required="false"
  368. name="address"
  369. >
  370. <uni-easyinput
  371. style="text-align: right"
  372. :inputBorder="false"
  373. :clearable="true"
  374. :styles="{ disableColor: '#fff' }"
  375. v-model="maintain.address"
  376. :placeholder="$t('operation.PleaseFillIn')"
  377. />
  378. </uni-forms-item>
  379. <!-- 委外相关附件 -->
  380. <uni-forms-item
  381. class="form-item"
  382. :label="$t('equipmentMaintenance.outsourceRelatedAttachments')"
  383. :required="false"
  384. name="outFilesList"
  385. >
  386. <uni-file-picker
  387. :clear="false"
  388. :limit="9"
  389. file-mediatype="all"
  390. v-model="maintain.outFilesList"
  391. @select="uploadOutFiles"
  392. @delete="deleteOutFiles"
  393. >
  394. </uni-file-picker>
  395. </uni-forms-item>
  396. <!-- 维修项目 -->
  397. <uni-forms-item
  398. class="form-item"
  399. :label="$t('equipmentMaintenance.maintenanceItem')"
  400. :required="true"
  401. name="maintainItem"
  402. >
  403. <uni-easyinput
  404. style="text-align: right"
  405. type="textarea"
  406. :autoHeight="true"
  407. :inputBorder="false"
  408. :clearable="true"
  409. :styles="{ disableColor: '#fff' }"
  410. v-model="maintain.maintainItems"
  411. :placeholder="$t('operation.PleaseFillIn')"
  412. />
  413. </uni-forms-item>
  414. </template>
  415. <!-- ----------------------------------- OA委外 end ------------------------ -->
  416. <!-- 故障描述 -->
  417. <uni-forms-item
  418. class="form-item"
  419. :label="$t('fault.description')"
  420. :required="false"
  421. name="description"
  422. >
  423. <uni-easyinput
  424. style="text-align: right"
  425. type="textarea"
  426. :autoHeight="true"
  427. :inputBorder="false"
  428. :clearable="true"
  429. :styles="{ disableColor: '#fff' }"
  430. v-model="maintain.description"
  431. :placeholder="$t('operation.PleaseFillIn')"
  432. />
  433. </uni-forms-item>
  434. <!-- 维修描述 维修类型是委外时不必填-->
  435. <uni-forms-item
  436. class="form-item"
  437. :label="$t('equipmentMaintenance.description')"
  438. :required="maintain.type == 'out' ? false : true"
  439. name="maintainDescription"
  440. >
  441. <uni-easyinput
  442. style="text-align: right"
  443. type="textarea"
  444. :autoHeight="true"
  445. :inputBorder="false"
  446. :clearable="true"
  447. :styles="{ disableColor: '#fff' }"
  448. v-model="maintain.maintainDescription"
  449. :placeholder="$t('operation.PleaseFillIn')"
  450. />
  451. </uni-forms-item>
  452. <!-- 解决办法 -->
  453. <uni-forms-item
  454. class="form-item"
  455. :label="$t('fault.solution')"
  456. :required="false"
  457. name="solution"
  458. >
  459. <uni-easyinput
  460. style="text-align: right"
  461. type="textarea"
  462. :autoHeight="true"
  463. :inputBorder="false"
  464. :clearable="true"
  465. :styles="{ disableColor: '#fff' }"
  466. v-model="maintain.solution"
  467. :placeholder="$t('operation.PleaseFillIn')"
  468. />
  469. </uni-forms-item>
  470. <!-- 备注 -->
  471. <uni-forms-item
  472. class="form-item"
  473. :label="$t('operation.remark')"
  474. :required="false"
  475. name="remark"
  476. >
  477. <uni-easyinput
  478. style="text-align: right"
  479. type="textarea"
  480. :autoHeight="true"
  481. :inputBorder="false"
  482. :clearable="true"
  483. :styles="{ disableColor: '#fff' }"
  484. v-model="maintain.remark"
  485. :placeholder="$t('operation.PleaseFillIn')"
  486. />
  487. </uni-forms-item>
  488. </uni-forms>
  489. <uni-row class="form-item flex-row align-center">
  490. <!-- 选择维修项 -->
  491. <uni-col :span="9">
  492. <button
  493. class="add-btn"
  494. size="mini"
  495. type="primary"
  496. @click="onChooseRepair()"
  497. >
  498. <uni-icons type="paperplane-filled" color="white"></uni-icons>
  499. {{ $t("operation.select")
  500. }}{{ $t("equipmentMaintenance.maintenanceItems") }}
  501. </button>
  502. </uni-col>
  503. <uni-col :span="2"> </uni-col>
  504. <!-- 新增维修项 -->
  505. <uni-col :span="9">
  506. <button
  507. class="add-btn yellow"
  508. size="mini"
  509. type="default"
  510. @click="onAddRepair()"
  511. >
  512. <uni-icons type="plusempty" color="white"></uni-icons>
  513. {{ $t("operation.add")
  514. }}{{ $t("equipmentMaintenance.maintenanceItems") }}
  515. </button>
  516. </uni-col>
  517. </uni-row>
  518. <view class="device-section" v-for="bom in maintainBom">
  519. <!-- 设备编码 -->
  520. <view class="item-module">
  521. <view class="item-content flex-row align-center justify-between">
  522. <view class="item-title">
  523. <span class="item-title-width"
  524. >{{ $t("device.deviceCode") }}:</span
  525. >
  526. </view>
  527. <view class="item-title">
  528. <span>{{ bom.deviceCode }}</span>
  529. </view>
  530. </view>
  531. <view class="module-border"> </view>
  532. </view>
  533. <!-- 设备名称 -->
  534. <view class="item-content flex-row align-center justify-between">
  535. <view class="item-title">
  536. <span class="item-title-width"
  537. >{{ $t("device.deviceName") }}:</span
  538. >
  539. </view>
  540. <view class="item-title">
  541. <span>{{ bom.deviceName }}</span>
  542. </view>
  543. </view>
  544. <!-- 维修项 -->
  545. <view class="item-content flex-row align-center justify-between">
  546. <view class="item-title">
  547. <span class="item-title-width"
  548. >{{ $t("equipmentMaintenance.maintenanceItems") }}:</span
  549. >
  550. </view>
  551. <view class="item-title">
  552. <span>{{ bom.name }}</span>
  553. </view>
  554. </view>
  555. <!-- 物料数量 -->
  556. <view class="item-content flex-row align-center justify-between">
  557. <view class="item-title">
  558. <span class="item-title-width"
  559. >{{ $t("workOrder.materialCount") }}:</span
  560. >
  561. </view>
  562. <view class="item-title">
  563. <span>{{ bom.materialCount }}</span>
  564. </view>
  565. </view>
  566. <!-- 操作按钮 -->
  567. <view class="item-opera flex-row justify-end">
  568. <!-- 删除 -->
  569. <button type="primary" :plain="true" @click="ondeleteBom(bom)">
  570. {{ $t("operation.delete") }}
  571. </button>
  572. <!-- 选择物料 -->
  573. <button type="primary" :plain="true" @click="onMaterialChoose(bom)">
  574. {{ $t("workOrder.selectMaterial") }}
  575. </button>
  576. <button
  577. type="primary"
  578. :plain="false"
  579. @click="onMaterialView(bom)"
  580. v-if="bom.materialSelected"
  581. >
  582. {{ $t("workOrder.materialDetails") }}
  583. </button>
  584. </view>
  585. </view>
  586. </view>
  587. </scroll-view>
  588. <button
  589. class="submit-btn"
  590. type="primary"
  591. @click="formSubmit(repairFormRef)"
  592. >
  593. {{ $t("operation.submit") }}
  594. </button>
  595. </view>
  596. <!-- 选择设备 -->
  597. <device-single ref="deviceSingleRef" @devide-submit="onChooseDevice" />
  598. <!-- 本地搜索 (选择申请人、项目经理) -->
  599. <local-search ref="localSearchRef" @choosed="onChooseLocalSearch" />
  600. <!-- 选择供应商 -->
  601. <supplier-choose
  602. ref="manufacturerPopupRef"
  603. @confirm="onSelectedManufacturer"
  604. />
  605. <!-- 选择维修项 -->
  606. <repair-multiple ref="repairMultipleRef" @repair-submit="onRepairSubmit" />
  607. <!-- 新增维修项 -->
  608. <repair-add ref="addRef" @add-set="onRepairEmit"></repair-add>
  609. <!-- :deptId="addMateriaItem.deptId" -->
  610. <!-- 选择物料 -->
  611. <materialsChoose
  612. ref="materialsChooseRef"
  613. :deviceId="addMateriaItem.id"
  614. :bomNodeId="addMateriaItem.bomNodeId"
  615. :materialItem="addMateriaItem"
  616. @material-submit="materialSubmit"
  617. />
  618. <!-- 查看物料详情 -->
  619. <materials-view ref="materialsViewRef" />
  620. </template>
  621. <script setup>
  622. import { onLoad, onReady, onBackPress } from "@dcloudio/uni-app";
  623. import {
  624. reactive,
  625. ref,
  626. watch,
  627. computed,
  628. watchEffect,
  629. onMounted,
  630. onBeforeUnmount,
  631. nextTick,
  632. getCurrentInstance,
  633. } from "vue";
  634. import {
  635. getRepairDetail,
  636. updateRepair,
  637. getRepairApplicantList,
  638. getRepairProjectManagerList,
  639. } from "@/api/repair.js";
  640. import { getRandomNumber } from "@/utils/methods";
  641. import dayjs from "dayjs";
  642. import { uploadFile } from "@/api";
  643. import deviceSingle from "@/components/device/single.vue";
  644. import supplierChoose from "@/components/supplier/choose.vue";
  645. import repairMultiple from "@/components/repair/multiple.vue";
  646. import repairAdd from "@/components/repair/add.vue";
  647. import materialsChoose from "@/components/materials/choose.vue";
  648. import materialsView from "@/components/materials/view.vue";
  649. import localSearch from "@/components/local-search.vue";
  650. import { useDataDictStore } from "@/store/modules/dataDict";
  651. import { reloginByUserId } from "@/utils/auth";
  652. const { getDataDictList } = useDataDictStore();
  653. // 引用全局变量$t
  654. const { appContext } = getCurrentInstance();
  655. const t = appContext.config.globalProperties.$t;
  656. // 获取维修类型
  657. const typeDict = getDataDictList("pms_main_type");
  658. // 遍历typeDict,新增text字段 值为label
  659. typeDict.forEach((item) => {
  660. item.text = item.label;
  661. });
  662. console.log("typeDict", typeDict);
  663. // 维修类型
  664. const typeRange = ref(typeDict);
  665. // 是否停机
  666. const ifStopRange = ref([
  667. {
  668. value: 1,
  669. text: t("operation.yes"),
  670. },
  671. {
  672. value: 0,
  673. text: t("operation.no"),
  674. },
  675. ]);
  676. // 申请人
  677. const applyPersonRange = ref([]);
  678. // 获取申请人列表
  679. const getApplicantList = async () => {
  680. // id参数创建的时候传undefined,详情的时候需要传入工单的创建人creator
  681. const res = await getRepairApplicantList({
  682. id: "",
  683. });
  684. if (res.code == 0) {
  685. applyPersonRange.value = res.data.map((item) => {
  686. return {
  687. value: item.oaId,
  688. text: item.lastname,
  689. };
  690. });
  691. // console.log(
  692. // "🚀 ~ getApplicantList ~ applyPersonRange.value:",
  693. // applyPersonRange.value
  694. // );
  695. }
  696. };
  697. // 维修类别列表
  698. const maintainClassifyRange = getDataDictList("pms_maintain_classify").map(
  699. (item) => {
  700. return {
  701. value: item.value,
  702. text: item.label,
  703. };
  704. }
  705. );
  706. console.log("🚀 ~ maintainClassifyRange:", maintainClassifyRange);
  707. // 项目经理
  708. const projectManagerRange = ref([]);
  709. // 获取项目经理列表
  710. const getProjectManagerList = async () => {
  711. // id参数创建的时候传undefined,详情的时候需要传入工单的创建人creator
  712. const res = await getRepairProjectManagerList({
  713. id: "",
  714. });
  715. if (res.code !== 0) {
  716. uni.showToast({
  717. title: res.msg,
  718. icon: "error",
  719. });
  720. return;
  721. }
  722. projectManagerRange.value = res.data.map((item) => {
  723. return {
  724. value: item.oaId,
  725. text: item.lastname,
  726. };
  727. });
  728. // console.log(
  729. // "🚀 ~ getProjectManagerList ~ projectManagerRange.value:",
  730. // projectManagerRange.value
  731. // );
  732. };
  733. // 供应商选择
  734. const manufacturerPopupRef = ref(null);
  735. const onManufacturerChoose = () => {
  736. console.log(
  737. "🚀 ~ onManufacturerChoose ~ onManufacturerChoose:",
  738. onManufacturerChoose
  739. );
  740. manufacturerPopupRef.value.open("bottom");
  741. };
  742. // 供应商选择确认
  743. const onSelectedManufacturer = (item) => {
  744. console.log("🚀 ~ onSelectedManufacturer ~ item:", item);
  745. maintain.value.supplier = item.name;
  746. };
  747. // 获取当前时间
  748. const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
  749. const dateMax = ref(now);
  750. const maintainId = ref("");
  751. const getData = () => {
  752. getRepairDetail({
  753. id: maintainId.value,
  754. }).then((res) => {
  755. console.log("getRepairDetail", res);
  756. res.data.ifStop = res.data.ifStop ? 1 : 0;
  757. const { maintainBomDOS, ...rest } = res.data;
  758. maintain.value = rest;
  759. // 判断maintain.value中是否存在pics字段,如果不存在则将pics字段转换为数组
  760. if (!maintain.value.pics) {
  761. maintain.value.pics = [];
  762. }
  763. // 判断maintain.value中是否存在outFiles字段,如果不存在则将outFiles字段转换为数组
  764. if (!maintain.value.outFiles) {
  765. maintain.value.outFiles = [];
  766. }
  767. // 判断维修类型是否为OA委外,如果是则获取申请人列表和项目经理列表
  768. if (maintain.value.type == "out") {
  769. getApplicantList();
  770. getProjectManagerList();
  771. }
  772. if (maintainBomDOS.length) {
  773. // 遍历维修项,将设备名称和设备编码添加到维修项中
  774. maintainBom.value = maintainBomDOS.map((bom) => {
  775. bom.deviceName = res.data.deviceName;
  776. bom.deviceCode = res.data.deviceCode;
  777. bom = {
  778. ...bom,
  779. workOrderBomOnlyKey: `${bom.deviceCode}_${bom.deviceName}_${bom.name}`, //手动拼接唯一标识
  780. };
  781. console.log("maintainBom.value = maintainBomDOS-bom", bom);
  782. // 判断是否存在物料明细
  783. if (bom?.materials?.length) {
  784. // 计算物料数量
  785. bom.materialCount = bom.materials.reduce((total, item) => {
  786. return total + item.materialCount;
  787. }, 0);
  788. bom.materialSelected = true;
  789. // 遍历物料明细,拼接chooseKey
  790. bom.materials.forEach((material) => {
  791. material.chooseKey = `${material.materialCode}_${material.costCenterId}_${material.factoryId}_${material.unitPrice}_${material.storageLocationId}`;
  792. });
  793. } else {
  794. bom = {
  795. ...bom,
  796. materialCount: 0, // 物料数量
  797. materials: [], // 物料明细
  798. materialSelected: false, //手动添加是否选择物料标识
  799. };
  800. console.log("maintainBom.value = maintainBomDOS-bom -else", bom);
  801. }
  802. return bom;
  803. });
  804. }
  805. console.log("maintainBom", maintainBom.value);
  806. });
  807. };
  808. onLoad(async (option) => {
  809. await reloginByUserId(option.reloginUserId);
  810. maintainId.value = option.id;
  811. getData();
  812. });
  813. onReady(() => {});
  814. //维修工单
  815. const maintain = ref({
  816. deviceId: "",
  817. deviceName: "",
  818. type: "", // 类型(是否委外 in 内部 out 外部)
  819. picList: [], //用于上传照片 提交时删除
  820. pics: [], // 用于存放上传后的照片地址 提交时使用
  821. outFilesList: [], // 用于上传委外相关附件 提交时删除
  822. outFiles: [], // 用于存放上传后的委外相关附件地址 提交时使用
  823. });
  824. // 选择设备
  825. const deviceSingleRef = ref(null);
  826. const selectedDevices = ref({});
  827. const onAddDevice = () => {
  828. deviceSingleRef.value.open();
  829. };
  830. const onChooseDevice = (data) => {
  831. console.log("onChooseDevice", data);
  832. maintain.value.deviceId = data.id;
  833. maintain.value.deviceCode = data.deviceCode;
  834. maintain.value.deviceName = data.deviceName;
  835. console.log("onChooseDevice-maintain", maintain.value);
  836. // 将选择的设备赋值给selectedDevices
  837. selectedDevices.value = data;
  838. // 如果维修类型为OA委外,将设备的model值(规格型号)赋值给maintain的model
  839. if (maintain.value.type === "out") {
  840. maintain.value.model = data.model;
  841. // 同时将设备的enableDate值(启用日期)赋值给maintain的enableDate
  842. maintain.value.enableDate = data.enableDate;
  843. } else {
  844. // 否则将model清空
  845. maintain.value.model = "";
  846. // 同时将enableDate清空
  847. maintain.value.enableDate = "";
  848. }
  849. };
  850. // 上传图片
  851. const upload = async (event) => {
  852. console.log("🚀 ~ upload ~ event:", event);
  853. console.log("🚀 ~ upload ~ event.tempFilePaths):", event.tempFilePaths);
  854. for (const path of event.tempFilePaths) {
  855. console.log("🚀 ~ upload ~ maintain.value.pics:", maintain.value);
  856. maintain.value.pics.push((await uploadFile(path)).data);
  857. }
  858. console.log("🚀 ~ upload ~ maintain.value.pics :", maintain.value.pics);
  859. };
  860. // 删除图片
  861. const deleteImg = (event) => {
  862. console.log("🚀 ~ deleteImg ~ event:", event);
  863. maintain.value.pics.splice(event.index, 1);
  864. console.log("🚀 ~ deleteImg ~ maintain.value.pics:", maintain.value.pics);
  865. };
  866. // 上传委外相关附件
  867. const uploadOutFiles = async (event) => {
  868. console.log("🚀 ~ uploadOutFiles ~ event:", event);
  869. console.log(
  870. "🚀 ~ uploadOutFiles ~ event.tempFilePaths):",
  871. event.tempFilePaths
  872. );
  873. for (const path of event.tempFilePaths) {
  874. maintain.value.outFiles.push((await uploadFile(path)).data);
  875. }
  876. console.log(
  877. "🚀 ~ uploadOutFiles ~ maintain.value.outFiles :",
  878. maintain.value.outFiles
  879. );
  880. };
  881. // 删除委外相关附件
  882. const deleteOutFiles = (event) => {
  883. console.log("🚀 ~ deleteOutFiles ~ event:", event);
  884. maintain.value.outFiles.splice(event.index, 1);
  885. console.log(
  886. "🚀 ~ deleteOutFiles ~ maintain.value.outFiles:",
  887. maintain.value.outFiles
  888. );
  889. };
  890. // 本地搜索
  891. const localSearchRef = ref(null);
  892. // 打开本地搜索
  893. const openLocalSearch = (list, propKey, title) => {
  894. localSearchRef.value.open({
  895. list,
  896. propKey,
  897. title,
  898. choosed: maintain.value[propKey],
  899. });
  900. };
  901. // 本地搜索确认选择
  902. const onChooseLocalSearch = (propKey, item) => {
  903. console.log("🚀 ~ onChooseLocalSearch ~ propKey, item:", propKey, item);
  904. // 根据propKey设置maintain的值
  905. maintain.value[propKey] = item.value;
  906. };
  907. // 选择维修项
  908. const repairMultipleRef = ref(null);
  909. const onChooseRepair = () => {
  910. // 判断是否选择设备
  911. if (!maintain.value.deviceId) {
  912. uni.showToast({
  913. title: ` ${t("operation.please")}${t("device.selectDevice")}`,
  914. icon: "none",
  915. });
  916. return;
  917. }
  918. repairMultipleRef.value.open([maintain.value.deviceId]);
  919. };
  920. // 维修项
  921. const maintainBom = ref([]);
  922. // 选择维修项提交
  923. const onRepairSubmit = (data) => {
  924. console.log("onRepairSubmit", data);
  925. // 判断data数组中bomNodeId是否存在maintainBom数组中, 如果不存在, 则添加 并将materialSelected设为false
  926. data.forEach((bom) => {
  927. if (!maintainBom.value.some((item) => item.bomNodeId === bom.bomNodeId)) {
  928. maintainBom.value.push({
  929. ...bom,
  930. materialCount: 0, // 物料数量
  931. materials: [], // 物料明细
  932. workOrderBomOnlyKey: `${bom.deviceCode}_${bom.deviceName}_${bom.name}`, //手动拼接唯一标识
  933. materialSelected: false, //手动添加是否选择物料标识
  934. });
  935. }
  936. });
  937. console.log("onRepairSubmit-maintainBom", maintainBom.value);
  938. };
  939. // 删除维修项
  940. const ondeleteBom = (bom) => {
  941. // 查找maintainBom中是否存在bom
  942. const index = maintainBom.value.findIndex(
  943. (item) => item.workOrderBomOnlyKey === bom.workOrderBomOnlyKey
  944. );
  945. if (index !== -1) {
  946. maintainBom.value.splice(index, 1);
  947. }
  948. };
  949. const addRef = ref(null);
  950. const onAddRepair = () => {
  951. // 判断是否选择设备
  952. if (!maintain.value.deviceId) {
  953. uni.showToast({
  954. title: ` ${t("operation.please")}${t("device.selectDevice")}`,
  955. icon: "none",
  956. });
  957. return;
  958. }
  959. const info = {
  960. id: maintain.value.deviceId,
  961. deviceId: maintain.value.deviceId,
  962. deviceCode: maintain.value.deviceCode,
  963. deviceName: maintain.value.deviceName,
  964. bom: maintainBom.value,
  965. };
  966. addRef.value.open(info);
  967. };
  968. const onRepairEmit = (data) => {
  969. console.log("onRepairEmit", data);
  970. maintainBom.value.push({
  971. ...data,
  972. materialCount: 0, // 物料数量
  973. materials: [], // 物料明细
  974. workOrderBomOnlyKey: `${data.deviceCode}_${data.deviceName}_${data.name}`, //手动拼接唯一标识
  975. materialSelected: false, //手动添加是否选择物料标识
  976. });
  977. };
  978. // 物料选择
  979. const materialsChooseRef = ref(null);
  980. const addMateriaItem = ref({});
  981. const onMaterialChoose = (item) => {
  982. console.log("onMaterialChoose", item);
  983. addMateriaItem.value = item;
  984. materialsChooseRef.value.open(item);
  985. };
  986. // 保养工单 - 物料
  987. const maintainMaterials = ref([]);
  988. const materialSubmit = (material) => {
  989. console.log("material - submit", material);
  990. // 查找maintainBom.value中与addMateriaItem.value中workOrderBomOnlyKey相同的bom
  991. const bom = maintainBom.value.find(
  992. (item) => item.workOrderBomOnlyKey === material.workOrderBomOnlyKey
  993. );
  994. console.log("materialSubmit-bom", bom);
  995. if (bom) {
  996. // 若bom中的materials数组中存在与material中chooseKey相同的物料,则更新数量,否则添加物料并修改bom中的是否选择物料
  997. // 计算materials中所有物料的数量,并赋值给bom.materialCount
  998. // 计算maintainBom中所有materials数组中所有物料的费用并赋值给maintain.value.maintainFee
  999. // maintain.value.maintainFee保留两位小数
  1000. const index = bom.materials.findIndex(
  1001. (item) => item.chooseKey === material.chooseKey
  1002. );
  1003. if (index !== -1) {
  1004. bom.materials[index].quantity =
  1005. parseFloat(bom.materials[index].quantity) +
  1006. parseFloat(material.quantity);
  1007. } else {
  1008. bom.materials.push({
  1009. ...material,
  1010. // bomNodeId: addMateriaItem.value.bomNodeId,
  1011. // name: addMateriaItem.value.name,
  1012. // code: addMateriaItem.value.code
  1013. });
  1014. // 修改是否选择物料
  1015. bom.materialSelected = true;
  1016. }
  1017. // 计算materials中所有物料的数量,并赋值给bom.materialCount
  1018. bom.materialCount = bom.materials.reduce((total, item) => {
  1019. return parseFloat(total) + parseFloat(item.quantity);
  1020. }, 0);
  1021. // 计算maintainBom中所有materials数组中所有物料的费用并赋值给maintain.value.maintainFee
  1022. maintain.value.maintainFee = maintainBom.value.reduce((total, item) => {
  1023. return (
  1024. total +
  1025. item.materials.reduce((subTotal, subItem) => {
  1026. return (
  1027. parseFloat(subTotal) +
  1028. parseFloat(subItem.quantity) * parseFloat(subItem.unitPrice)
  1029. );
  1030. }, 0)
  1031. );
  1032. }, 0);
  1033. // maintain.value.maintainFee保留两位小数
  1034. maintain.value.maintainFee = maintain.value.maintainFee.toFixed(2);
  1035. console.log("maintain.value.maintainFee", maintain.value.maintainFee);
  1036. console.log("materialSubmit-maintainBom", maintainBom.value);
  1037. }
  1038. };
  1039. const materialsViewRef = ref(null);
  1040. const onMaterialView = (item) => {
  1041. console.log("onMaterialView", item);
  1042. uni.navigateTo({
  1043. url: "/pages/material/view",
  1044. success: () => {
  1045. setTimeout(() => {
  1046. uni.$emit("material-view", item.materials);
  1047. }, 300); // 延迟300ms,根据实际情况调整
  1048. },
  1049. });
  1050. };
  1051. const repairFormRef = ref(null);
  1052. const maintainBaseRules = ref({
  1053. // 设备名称
  1054. deviceName: {
  1055. rules: [
  1056. {
  1057. required: true,
  1058. errorMessage: `${t("operation.PleaseSelect")}${t(
  1059. "maintenanceWorkOrder.equipment"
  1060. )}`,
  1061. },
  1062. ],
  1063. },
  1064. // 维修类型
  1065. type: {
  1066. rules: [
  1067. {
  1068. required: true,
  1069. errorMessage: `${t("operation.PleaseSelect")}${t(
  1070. "equipmentMaintenance.maintenanceType"
  1071. )}`,
  1072. },
  1073. ],
  1074. },
  1075. // 是否停机
  1076. ifStop: {
  1077. rules: [
  1078. {
  1079. required: true,
  1080. errorMessage: `${t("operation.PleaseSelect")}${t(
  1081. "equipmentMaintenance.isStop"
  1082. )}`,
  1083. },
  1084. ],
  1085. },
  1086. // 维修开始时间
  1087. maintainStartTime: {
  1088. rules: [
  1089. {
  1090. required: false,
  1091. errorMessage: `${t("operation.PleaseSelect")}${t(
  1092. "equipmentMaintenance.maintenanceStartTime"
  1093. )}`,
  1094. },
  1095. {
  1096. validator: (rule, value, callback, source) => {
  1097. if (source.maintainEndTime && value > source.maintainEndTime) {
  1098. callback(new Error(`${t("general.timeNotBeLater")}`));
  1099. } else {
  1100. callback();
  1101. }
  1102. },
  1103. },
  1104. ],
  1105. },
  1106. // 维修结束时间
  1107. maintainEndTime: {
  1108. rules: [
  1109. {
  1110. required: false,
  1111. errorMessage: `${t("operation.PleaseSelect")}${t(
  1112. "equipmentMaintenance.maintenanceEndTime"
  1113. )}`,
  1114. },
  1115. {
  1116. validator: (rule, value, callback, source) => {
  1117. if (source.maintainStartTime && value < source.maintainStartTime) {
  1118. callback(new Error(`${t("general.timeNotBeEarlier")}`));
  1119. } else {
  1120. callback();
  1121. }
  1122. },
  1123. },
  1124. ],
  1125. },
  1126. // 故障时间
  1127. failureTime: {
  1128. rules: [
  1129. {
  1130. required: false,
  1131. errorMessage: `${t("operation.PleaseSelect")}${t("fault.faultTime")}`,
  1132. },
  1133. ],
  1134. },
  1135. // 维修描述
  1136. maintainDescription: {
  1137. rules: [
  1138. {
  1139. required: false,
  1140. errorMessage: `${t("operation.PleaseFillIn")}${t(
  1141. "equipmentMaintenance.description"
  1142. )}`,
  1143. },
  1144. ],
  1145. },
  1146. // 以下是OA委外的校验规则 type = out
  1147. // 申请人
  1148. applyPersonId: {
  1149. rules: [
  1150. {
  1151. required: false,
  1152. errorMessage: `${t("operation.PleaseSelect")}${t(
  1153. "equipmentMaintenance.applicant"
  1154. )}`,
  1155. },
  1156. ],
  1157. },
  1158. // 维修类别
  1159. maintainClassify: {
  1160. rules: [
  1161. {
  1162. required: false,
  1163. errorMessage: `${t("operation.PleaseSelect")}${t(
  1164. "equipmentMaintenance.classify"
  1165. )}`,
  1166. },
  1167. ],
  1168. },
  1169. // 规格型号
  1170. model: {
  1171. rules: [
  1172. {
  1173. required: false,
  1174. errorMessage: `${t("operation.PleaseFillIn")}${t(
  1175. "equipmentMaintenance.specificationModel"
  1176. )}`,
  1177. },
  1178. ],
  1179. },
  1180. // 启用日期
  1181. enableDate: {
  1182. rules: [
  1183. {
  1184. required: false,
  1185. errorMessage: `${t("operation.PleaseSelect")}${t(
  1186. "equipmentMaintenance.enableDate"
  1187. )}`,
  1188. },
  1189. ],
  1190. },
  1191. // 供应商
  1192. supplier: {
  1193. rules: [
  1194. {
  1195. required: false,
  1196. errorMessage: `${t("operation.PleaseFillIn")}${t(
  1197. "equipmentMaintenance.supplier"
  1198. )}`,
  1199. },
  1200. ],
  1201. },
  1202. // 维修费用
  1203. maintainFee: {
  1204. rules: [
  1205. {
  1206. required: false,
  1207. errorMessage: `${t("operation.PleaseFillIn")}${t(
  1208. "equipmentMaintenance.cost"
  1209. )}`,
  1210. },
  1211. ],
  1212. },
  1213. // 项目经理
  1214. projectManager: {
  1215. rules: [
  1216. {
  1217. required: false,
  1218. errorMessage: `${t("operation.PleaseSelect")}${t(
  1219. "equipmentMaintenance.projectManager"
  1220. )}`,
  1221. },
  1222. ],
  1223. },
  1224. // 维修项目
  1225. maintenanceItem: {
  1226. rules: [
  1227. {
  1228. required: false,
  1229. errorMessage: `${t("operation.PleaseFillIn")}${t(
  1230. "equipmentMaintenance.maintenanceItem"
  1231. )}`,
  1232. },
  1233. ],
  1234. },
  1235. });
  1236. // 动态计算校验规则
  1237. const maintainRules = computed(() => {
  1238. const rules = JSON.parse(JSON.stringify(maintainBaseRules.value));
  1239. // 根据维修类型动态调整规则
  1240. if (maintain.value.type === "out") {
  1241. // 委外维修:维修开始/结束时间可选,故障时间必填
  1242. rules.maintainStartTime.rules[0].required = false;
  1243. rules.maintainEndTime.rules[0].required = false;
  1244. rules.failureTime.rules[0].required = true;
  1245. rules.maintainDescription.rules[0].required = false;
  1246. // oa委外:申请人、维修类别、规格型号、启用日期、供应商、维修费用、项目经理、维修项目必填
  1247. rules.applyPersonId.rules[0].required = true;
  1248. rules.maintainClassify.rules[0].required = true;
  1249. rules.model.rules[0].required = true;
  1250. rules.enableDate.rules[0].required = true;
  1251. rules.supplier.rules[0].required = true;
  1252. rules.maintainFee.rules[0].required = true;
  1253. rules.projectManager.rules[0].required = true;
  1254. rules.maintenanceItem.rules[0].required = true;
  1255. } else {
  1256. // 非委外维修:维修开始/结束时间必填,故障时间可选
  1257. rules.maintainStartTime.rules[0].required = true;
  1258. rules.maintainEndTime.rules[0].required = true;
  1259. rules.failureTime.rules[0].required = false;
  1260. rules.maintainDescription.rules[0].required = true;
  1261. // 非委外:申请人、维修类别、规格型号、启用日期、供应商、维修费用、项目经理、维修项目非必填
  1262. rules.applyPersonId.rules[0].required = false;
  1263. rules.maintainClassify.rules[0].required = false;
  1264. rules.model.rules[0].required = false;
  1265. rules.enableDate.rules[0].required = false;
  1266. rules.supplier.rules[0].required = false;
  1267. rules.maintainFee.rules[0].required = false;
  1268. rules.projectManager.rules[0].required = false;
  1269. rules.maintenanceItem.rules[0].required = false;
  1270. }
  1271. return rules;
  1272. });
  1273. // 监听设备变化
  1274. watch(
  1275. () => maintain.value.deviceId,
  1276. (newDeviceId, oldDeviceId) => {
  1277. if (newDeviceId !== oldDeviceId) {
  1278. // 1. 清空维修项与物料
  1279. maintainBom.value = [];
  1280. // 2. 重置总费用
  1281. maintain.value.maintainFee = "";
  1282. // 3. 委外类型下,重置规格型号(重新关联新设备的model)与启用日期enableDate
  1283. if (maintain.value.type === "out") {
  1284. maintain.value.model = selectedDevices.value.model || "";
  1285. maintain.value.enableDate = selectedDevices.value.enableDate || "";
  1286. }
  1287. // 4. 重置表单校验(设备相关字段)
  1288. nextTick(() => {
  1289. repairFormRef.value?.clearValidate(["maintainBom", "maintainFee"]);
  1290. });
  1291. }
  1292. }
  1293. );
  1294. // 监听维修类型数据变化,触发规则更新和校验重置
  1295. watch(
  1296. () => maintain.value.type,
  1297. (newVal, oldVal) => {
  1298. console.log("维修类型变更:", oldVal, "->", newVal);
  1299. // 维修类型为OA委外时,获取申请人列表和项目经理列表
  1300. if (newVal == "out" && oldVal !== "out") {
  1301. // 获取申请人列表
  1302. getApplicantList();
  1303. // 获取项目经理列表
  1304. getProjectManagerList();
  1305. // 委外类型下,重置规格型号(重新关联新设备的model)与启用日期enableDate
  1306. if (maintain.value.type === "out") {
  1307. maintain.value.model = selectedDevices.value.model || "";
  1308. maintain.value.enableDate = selectedDevices.value.enableDate || "";
  1309. }
  1310. } // 内部类型:清空委外特有字段
  1311. else if (newVal === "in" && oldVal === "out") {
  1312. const outFields = [
  1313. "applyPersonId",
  1314. "maintainClassify",
  1315. "kmHour",
  1316. "model",
  1317. "enableDate",
  1318. "supplier",
  1319. "projectManager",
  1320. "address",
  1321. "outFiles",
  1322. "maintainItems",
  1323. ];
  1324. outFields.forEach((field) => (maintain.value[field] = ""));
  1325. // 重置委外字段校验
  1326. nextTick(() => {
  1327. repairFormRef.value?.clearValidate(outFields);
  1328. });
  1329. }
  1330. // 重置相关字段的值和校验状态
  1331. resetFieldsByTypeChange(newVal, oldVal);
  1332. }
  1333. );
  1334. // 根据类型变更重置字段
  1335. const resetFieldsByTypeChange = (newType, oldType) => {
  1336. // 如果类型没有变化或不是初始化阶段,则不执行重置
  1337. if (newType === oldType && oldType !== undefined) return;
  1338. // 重置时间字段
  1339. if (
  1340. (newType === "out" && oldType !== "out") ||
  1341. (newType !== "out" && oldType === "out")
  1342. ) {
  1343. // // 重置时间字段值
  1344. // if (newType === 'out') {
  1345. // maintain.value.maintainStartTime = ''
  1346. // maintain.value.maintainEndTime = ''
  1347. // maintain.value.maintainDescription = ''
  1348. // } else {
  1349. // maintain.value.failureTime = ''
  1350. // }
  1351. // 重置表单校验状态
  1352. nextTick(() => {
  1353. repairFormRef.value?.clearValidate([
  1354. "maintainStartTime",
  1355. "maintainEndTime",
  1356. "failureTime",
  1357. "maintainDescription",
  1358. ]);
  1359. });
  1360. }
  1361. };
  1362. /**
  1363. * 校验时间规则(maintainRules未覆盖的场景)
  1364. * @returns {boolean} 校验结果
  1365. */
  1366. const checkTimeRules = async () => {
  1367. const { maintainStartTime, maintainEndTime, failureTime } = maintain.value;
  1368. // 判断维修开始时间是否大于维修结束时间
  1369. if (
  1370. maintainStartTime &&
  1371. maintainEndTime &&
  1372. maintainStartTime > maintainEndTime
  1373. ) {
  1374. uni.showToast({ title: t("general.timeNotBeLater"), icon: "none" });
  1375. return false;
  1376. }
  1377. // 维修开始时间不能早于故障时间
  1378. if (failureTime && maintainStartTime && maintainStartTime < failureTime) {
  1379. uni.showToast({ title: t("general.startTimeNotBeEarlier"), icon: "none" });
  1380. return false;
  1381. }
  1382. // 维修结束时间不能早于故障时间
  1383. if (failureTime && maintainEndTime && maintainEndTime < failureTime) {
  1384. uni.showToast({ title: t("general.endTimeNotBeEarlier"), icon: "none" });
  1385. return false;
  1386. }
  1387. return true;
  1388. };
  1389. const formSubmit = async (formEl) => {
  1390. if (!formEl) return;
  1391. try {
  1392. // 1. 清除旧错误状态
  1393. formEl.clearValidate();
  1394. // 2. 同步最新的maintainRules(解决computed延迟)
  1395. const latestRules = maintainRules.value;
  1396. await nextTick(); // 等待DOM与规则同步
  1397. formEl.setRules(latestRules);
  1398. // 3. 执行表单基础校验(maintainRules生效)
  1399. await formEl.validate();
  1400. console.log("基础校验通过(maintainRules已生效)");
  1401. // 4. 校验时间规则
  1402. const isTimeValid = await checkTimeRules();
  1403. if (!isTimeValid) return;
  1404. // 5. 业务逻辑校验
  1405. // 判断维修类型,如果是委外则不判断是否选择物料
  1406. if (maintain.value.type === "in") {
  1407. if (maintainBom.value.length === 0) {
  1408. uni.showToast({
  1409. title: `${t("operation.PleaseSelect")}${t(
  1410. "equipmentMaintenance.maintenanceItems"
  1411. )}`,
  1412. icon: "none",
  1413. });
  1414. return;
  1415. }
  1416. // 判断已选择的维修项是否添加物料
  1417. for (let i = 0; i < maintainBom.value.length; i++) {
  1418. if (maintainBom.value[i].materials.length === 0) {
  1419. uni.showToast({
  1420. title: `${maintainBom.value[i].deviceCode}-${
  1421. maintainBom.value[i].name
  1422. }${t("maintenanceWorkOrder.materialUnselected")}`,
  1423. icon: "none",
  1424. });
  1425. return;
  1426. }
  1427. }
  1428. }
  1429. // 删除maintainBom.value数组中的materialSelected和workOrderBomOnlyKey
  1430. // 并且删除maintainBom.value.material数组中的chooseKey和workOrderBomOnlyKey
  1431. // 形成一个新数组
  1432. const orderBom = maintainBom.value.map((item) => {
  1433. const newItem = {
  1434. ...item,
  1435. ifStop: item.ifStop ? true : false,
  1436. };
  1437. delete newItem.materialSelected;
  1438. delete newItem.workOrderBomOnlyKey;
  1439. newItem.materials = newItem.materials.map((materialItem) => {
  1440. const newMaterialItem = {
  1441. ...materialItem,
  1442. };
  1443. delete newMaterialItem.chooseKey;
  1444. delete newMaterialItem.workOrderBomOnlyKey;
  1445. delete newMaterialItem.picList;
  1446. return newMaterialItem;
  1447. });
  1448. return newItem;
  1449. });
  1450. console.log("orderBom", orderBom);
  1451. // 保留两位小数
  1452. updateRepair({
  1453. maintain: {
  1454. ...maintain.value,
  1455. status: maintain.value.type == "in" ? "finished" : "tx",
  1456. },
  1457. maintainMaterials: orderBom,
  1458. })
  1459. .then((res) => {
  1460. console.log("updateRepair-res", res);
  1461. if (res.code == 0) {
  1462. uni.showToast({
  1463. title: t("operation.success"),
  1464. icon: "success",
  1465. });
  1466. uni.navigateBack();
  1467. } else {
  1468. uni.showToast({
  1469. title: res.msg,
  1470. icon: "none",
  1471. });
  1472. }
  1473. })
  1474. .catch((err) => {
  1475. console.log("updateRepair-err", err);
  1476. });
  1477. } catch (err) {
  1478. // 8. 校验失败处理(明确错误来源)
  1479. console.log("提交失败:", err);
  1480. const errorMsg = err[0]?.errorMessage || t("operation.formValidateFailed");
  1481. uni.showToast({ title: errorMsg, icon: "none" });
  1482. }
  1483. };
  1484. onMounted(() => {
  1485. // 监听子页面提交的事件
  1486. console.log("onMounted");
  1487. // uni.$on('multiple-devide-submit', (data) => {
  1488. // console.log('接收到子页面数据:', data);
  1489. // selectedDevices.value = data
  1490. // onDeviceBomList()
  1491. // });
  1492. });
  1493. onBeforeUnmount(() => {
  1494. // 移除监听
  1495. console.log("onBeforeUnmount");
  1496. // uni.$off('multiple-devide-submit');
  1497. });
  1498. </script>
  1499. <style lang="scss" scoped>
  1500. @import "@/style/work-order-detail.scss";
  1501. </style>