ContainerEquipmentInfo.vue 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204
  1. <template>
  2. <view class="equipment-info-container">
  3. <!-- 容器设计制造安装信息 -->
  4. <view class="section">
  5. <view class="section-header">
  6. <text class="section-title">容器设计制造安装信息</text>
  7. <!-- 编辑按钮栏 -->
  8. <view v-if="canEdit" class="edit-bar">
  9. <button v-if="useOnline === '1'" class="ocr-btn" @click="handleOcr">
  10. <text class="operate-btn-text">拍照录入</text>
  11. </button>
  12. <button class="edit-btn" @click="handleEdit">
  13. <text class="operate-btn-text">
  14. {{ isEdit ? (useOnline === '1' ? '保存' : '暂存') : '编辑' }}
  15. </text>
  16. </button>
  17. <button v-if="isEdit && useOnline !== '1'" class="upload-btn" @click="handleUpload">
  18. <text class="operate-btn-text">上传</text>
  19. </button>
  20. </view>
  21. </view>
  22. <view class="table">
  23. <!-- 设备名称 -->
  24. <view class="table-row">
  25. <view class="table-cell title">
  26. <text class="cell-title">设备名称</text>
  27. <text v-if="isEdit" class="must">*</text>
  28. </view>
  29. <view class="table-cell content">
  30. <input
  31. v-if="isEdit"
  32. v-model="tempData.equipName"
  33. class="edit-input-text"
  34. placeholder="请输入设备名称"
  35. />
  36. <text v-else class="cell-text">{{ equipment.equipName || '--' }}</text>
  37. </view>
  38. </view>
  39. <!-- 设备种类 + 设备类别 -->
  40. <view class="table-row-split">
  41. <view class="table-cell title">
  42. <text class="cell-title">设备种类</text>
  43. <text v-if="isEdit" class="must">*</text>
  44. </view>
  45. <view class="table-cell content">
  46. <view v-if="isEdit" class="edit-input" @click="handlePicker('equipmentType')">
  47. <text>
  48. {{ getDictLabel('equipmentType', tempData.equipmentType) || '请选择' }}
  49. </text>
  50. <image class="arrow-icon" src="/static/images/arrow-right.png" />
  51. </view>
  52. <text v-else class="cell-text">{{ equipment.equipmentType || '--' }}</text>
  53. </view>
  54. <view class="table-cell title">
  55. <text class="cell-title">设备类别</text>
  56. <text v-if="isEdit" class="must">*</text>
  57. </view>
  58. <view class="table-cell content">
  59. <view v-if="isEdit" class="edit-input" @click="handlePicker('type')">
  60. <text>{{ getDictLabel('type', tempData.type) || '请选择' }}</text>
  61. <image class="arrow-icon" src="/static/images/arrow-right.png" />
  62. </view>
  63. <text v-else class="cell-text">{{ equipment.type || '--' }}</text>
  64. </view>
  65. </view>
  66. <!-- 设备品种 + 容器归类 -->
  67. <view class="table-row-split">
  68. <view class="table-cell title">
  69. <text class="cell-title">设备品种</text>
  70. </view>
  71. <view class="table-cell content">
  72. <input
  73. v-if="isEdit"
  74. v-model="tempData.equipCategory"
  75. class="edit-input-text"
  76. placeholder="请输入设备品种"
  77. />
  78. <text v-else class="cell-text">{{ equipment.equipCategory || '--' }}</text>
  79. </view>
  80. <view class="table-cell title">
  81. <text class="cell-title">容器归类</text>
  82. <text v-if="isEdit" class="must">*</text>
  83. </view>
  84. <view class="table-cell content">
  85. <view v-if="isEdit" class="edit-input" @click="handlePicker('equipType')">
  86. <text>{{ getDictLabel('equipType', tempData.equipType) || '请选择' }}</text>
  87. <image class="arrow-icon" src="/static/images/arrow-right.png" />
  88. </view>
  89. <text v-else class="cell-text">{{ equipment.equipTypeName || '--' }}</text>
  90. </view>
  91. </view>
  92. <!-- 设备注册代码 -->
  93. <view class="table-row">
  94. <view class="table-cell title">
  95. <text class="cell-title">设备注册代码</text>
  96. <text v-if="isEdit" class="must">*</text>
  97. </view>
  98. <view class="table-cell content">
  99. <input
  100. v-if="isEdit"
  101. v-model="tempData.equipCode"
  102. class="edit-input-text"
  103. placeholder="请输入设备注册代码"
  104. />
  105. <text v-else class="cell-text">{{ equipment.equipCode || '--' }}</text>
  106. </view>
  107. </view>
  108. <!-- 产品编号 + 使用登记证编号 -->
  109. <view class="table-row-split">
  110. <view class="table-cell title">
  111. <text class="cell-title">产品编号</text>
  112. </view>
  113. <view class="table-cell content">
  114. <input
  115. v-if="isEdit"
  116. v-model="tempData.productNo"
  117. class="edit-input-text"
  118. placeholder="请输入产品编号"
  119. />
  120. <text v-else class="cell-text">{{ equipment.productNo || '--' }}</text>
  121. </view>
  122. <view class="table-cell title">
  123. <text class="cell-title">使用登记证编号</text>
  124. </view>
  125. <view class="table-cell content">
  126. <input
  127. v-if="isEdit"
  128. v-model="tempData.useRegisterNo"
  129. class="edit-input-text"
  130. placeholder="请输入使用登记证编号"
  131. />
  132. <text v-else class="cell-text">{{ equipment.useRegisterNo || '--' }}</text>
  133. </view>
  134. </view>
  135. <!-- 单位内编号 -->
  136. <view class="table-row">
  137. <view class="table-cell title">
  138. <text class="cell-title">单位内编号</text>
  139. </view>
  140. <view class="table-cell content">
  141. <input
  142. v-if="isEdit"
  143. v-model="tempData.unitInnerNo"
  144. class="edit-input-text"
  145. placeholder="请输入单位内编号"
  146. />
  147. <text v-else class="cell-text">{{ equipment.unitInnerNo || '--' }}</text>
  148. </view>
  149. </view>
  150. <!-- 设计单位 -->
  151. <view class="table-row">
  152. <view class="table-cell title">
  153. <text class="cell-title">设计单位</text>
  154. </view>
  155. <view class="table-cell content">
  156. <input
  157. v-if="isEdit"
  158. v-model="tempData.designUnit"
  159. class="edit-input-text"
  160. placeholder="请输入设计单位"
  161. />
  162. <text v-else class="cell-text">{{ equipment.designUnit || '--' }}</text>
  163. </view>
  164. </view>
  165. <!-- 设计日期 + 产品标准 -->
  166. <view class="table-row-split">
  167. <view class="table-cell title">
  168. <text class="cell-title">设计日期</text>
  169. </view>
  170. <view class="table-cell content">
  171. <picker
  172. v-if="isEdit"
  173. mode="date"
  174. :value="tempData.designDate"
  175. @change="onDesignDateChange"
  176. >
  177. <view class="edit-input">
  178. <text>{{ tempData.designDate || '请选择' }}</text>
  179. <image class="arrow-icon" src="/static/images/arrow-right.png" />
  180. </view>
  181. </picker>
  182. <text v-else class="cell-text">{{ equipment.designDate || '--' }}</text>
  183. </view>
  184. <view class="table-cell title">
  185. <text class="cell-title">产品标准</text>
  186. </view>
  187. <view class="table-cell content">
  188. <input
  189. v-if="isEdit"
  190. v-model="tempData.productStandard"
  191. class="edit-input-text"
  192. placeholder="请输入产品标准"
  193. />
  194. <text v-else class="cell-text">{{ equipment.productStandard || '--' }}</text>
  195. </view>
  196. </view>
  197. <!-- 容器图号 + 设计使用年限 -->
  198. <view class="table-row-split">
  199. <view class="table-cell title">
  200. <text class="cell-title">容器图号</text>
  201. </view>
  202. <view class="table-cell content">
  203. <input
  204. v-if="isEdit"
  205. v-model="tempData.equipMapNo"
  206. class="edit-input-text"
  207. placeholder="请输入容器图号"
  208. />
  209. <text v-else class="cell-text">{{ equipment.equipMapNo || '--' }}</text>
  210. </view>
  211. <view class="table-cell title">
  212. <text class="cell-title">设计使用年限</text>
  213. </view>
  214. <view class="table-cell content">
  215. <input
  216. v-if="isEdit"
  217. v-model="tempData.designUseYears"
  218. class="edit-input-text"
  219. placeholder="请输入设计使用年限"
  220. />
  221. <text v-else class="cell-text">{{ equipment.designUseYears || '--' }}</text>
  222. </view>
  223. </view>
  224. <!-- 制造单位 -->
  225. <view class="table-row">
  226. <view class="table-cell title">
  227. <text class="cell-title">制造单位</text>
  228. </view>
  229. <view class="table-cell content">
  230. <input
  231. v-if="isEdit"
  232. v-model="tempData.makeUnit"
  233. class="edit-input-text"
  234. placeholder="请输入制造单位"
  235. />
  236. <text v-else class="cell-text">{{ equipment.makeUnit || '--' }}</text>
  237. </view>
  238. </view>
  239. <!-- 制造日期 -->
  240. <view class="table-row">
  241. <view class="table-cell title">
  242. <text class="cell-title">制造日期</text>
  243. </view>
  244. <view class="table-cell content">
  245. <picker v-if="isEdit" mode="date" :value="tempData.makeDate" @change="onMakeDateChange">
  246. <view class="edit-input">
  247. <text>{{ tempData.makeDate || '请选择' }}</text>
  248. <image class="arrow-icon" src="/static/images/arrow-right.png" />
  249. </view>
  250. </picker>
  251. <text v-else class="cell-text">{{ equipment.makeDate || '--' }}</text>
  252. </view>
  253. </view>
  254. <!-- 安装单位 -->
  255. <view class="table-row">
  256. <view class="table-cell title">
  257. <text class="cell-title">安装单位</text>
  258. </view>
  259. <view class="table-cell content">
  260. <input
  261. v-if="isEdit"
  262. v-model="tempData.installUnit"
  263. class="edit-input-text"
  264. placeholder="请输入安装单位"
  265. />
  266. <text v-else class="cell-text">{{ equipment.installUnit || '--' }}</text>
  267. </view>
  268. </view>
  269. <!-- 投入使用日期 + 主体结构型式 -->
  270. <view class="table-row-split">
  271. <view class="table-cell title">
  272. <text class="cell-title">投入使用日期</text>
  273. </view>
  274. <view class="table-cell content">
  275. <picker
  276. v-if="isEdit"
  277. mode="date"
  278. :value="tempData.useDate"
  279. @change="onUseDateChange"
  280. >
  281. <view class="edit-input">
  282. <text>{{ tempData.useDate || '请选择' }}</text>
  283. <image class="arrow-icon" src="/static/images/arrow-right.png" />
  284. </view>
  285. </picker>
  286. <text v-else class="cell-text">{{ equipment.useDate || '--' }}</text>
  287. </view>
  288. <view class="table-cell title">
  289. <text class="cell-title">主体结构型式</text>
  290. </view>
  291. <view class="table-cell content">
  292. <input
  293. v-if="isEdit"
  294. v-model="tempData.mainStructure"
  295. class="edit-input-text"
  296. placeholder="请输入主体结构型式"
  297. />
  298. <text v-else class="cell-text">{{ equipment.mainStructure || '--' }}</text>
  299. </view>
  300. </view>
  301. <!-- 安装型式 + 支座型式 -->
  302. <view class="table-row-split">
  303. <view class="table-cell title">
  304. <text class="cell-title">安装型式</text>
  305. </view>
  306. <view class="table-cell content">
  307. <input
  308. v-if="isEdit"
  309. v-model="tempData.installType"
  310. class="edit-input-text"
  311. placeholder="请输入安装型式"
  312. />
  313. <text v-else class="cell-text">{{ equipment.installType || '--' }}</text>
  314. </view>
  315. <view class="table-cell title">
  316. <text class="cell-title">支座型式</text>
  317. </view>
  318. <view class="table-cell content">
  319. <input
  320. v-if="isEdit"
  321. v-model="tempData.supportType"
  322. class="edit-input-text"
  323. placeholder="请输入支座型式"
  324. />
  325. <text v-else class="cell-text">{{ equipment.supportType || '--' }}</text>
  326. </view>
  327. </view>
  328. <!-- 保温绝热方式 + 容积 -->
  329. <view class="table-row-split">
  330. <view class="table-cell title">
  331. <text class="cell-title">保温绝热方式</text>
  332. </view>
  333. <view class="table-cell content">
  334. <input
  335. v-if="isEdit"
  336. v-model="tempData.insulationType"
  337. class="edit-input-text"
  338. placeholder="请输入保温绝热方式"
  339. />
  340. <text v-else class="cell-text">{{ equipment.insulationType || '--' }}</text>
  341. </view>
  342. <view class="table-cell title">
  343. <text class="cell-title">容积</text>
  344. </view>
  345. <view class="table-cell content">
  346. <input
  347. v-if="isEdit"
  348. v-model="tempData.equipVolume"
  349. class="edit-input-text"
  350. placeholder="请输入容积"
  351. />
  352. <text v-else class="cell-text">{{ equipment.equipVolume || '--' }}</text>
  353. </view>
  354. </view>
  355. <!-- 容器内径 + 容器高(长) -->
  356. <view class="table-row-split">
  357. <view class="table-cell title">
  358. <text class="cell-title">容器内径</text>
  359. </view>
  360. <view class="table-cell content">
  361. <input
  362. v-if="isEdit"
  363. v-model="tempData.equipInnerDiameter"
  364. class="edit-input-text"
  365. placeholder="请输入容器内径"
  366. />
  367. <text v-else class="cell-text">{{ equipment.equipInnerDiameter || '--' }}</text>
  368. </view>
  369. <view class="table-cell title">
  370. <text class="cell-title">容器高(长)</text>
  371. </view>
  372. <view class="table-cell content">
  373. <input
  374. v-if="isEdit"
  375. v-model="tempData.equipHeight"
  376. class="edit-input-text"
  377. placeholder="请输入容器高(长)"
  378. />
  379. <text v-else class="cell-text">{{ equipment.equipHeight || '--' }}</text>
  380. </view>
  381. </view>
  382. <!-- 最大允许充装量 + 腔体结构 -->
  383. <view class="table-row-split">
  384. <view class="table-cell title">
  385. <text class="cell-title">最大允许充装量</text>
  386. </view>
  387. <view class="table-cell content">
  388. <input
  389. v-if="isEdit"
  390. v-model="tempData.maxAllowFill"
  391. class="edit-input-text"
  392. placeholder="请输入最大允许充装量"
  393. />
  394. <text v-else class="cell-text">{{ equipment.maxAllowFill || '--' }}</text>
  395. </view>
  396. <view class="table-cell title">
  397. <text class="cell-title">腔体结构</text>
  398. </view>
  399. <view class="table-cell content">
  400. <input
  401. v-if="isEdit"
  402. v-model="tempData.cavityStructure"
  403. class="edit-input-text"
  404. placeholder="请输入腔体结构"
  405. />
  406. <text v-else class="cell-text">{{ equipment.cavityStructure || '--' }}</text>
  407. </view>
  408. </view>
  409. <!-- 设计压力 + 工作压力 -->
  410. <view class="table-row-split">
  411. <view class="table-cell title">
  412. <text class="cell-title">设计压力</text>
  413. </view>
  414. <view class="table-cell content">
  415. <input
  416. v-if="isEdit"
  417. v-model="tempData.designPressure"
  418. class="edit-input-text"
  419. placeholder="请输入设计压力"
  420. />
  421. <text v-else class="cell-text">{{ equipment.designPressure || '--' }}</text>
  422. </view>
  423. <view class="table-cell title">
  424. <text class="cell-title">工作压力</text>
  425. </view>
  426. <view class="table-cell content">
  427. <input
  428. v-if="isEdit"
  429. v-model="tempData.workPressure"
  430. class="edit-input-text"
  431. placeholder="请输入工作压力"
  432. />
  433. <text v-else class="cell-text">{{ equipment.workPressure || '--' }}</text>
  434. </view>
  435. </view>
  436. <!-- 设计温度 + 工作介质 -->
  437. <view class="table-row-split">
  438. <view class="table-cell title">
  439. <text class="cell-title">设计温度</text>
  440. </view>
  441. <view class="table-cell content">
  442. <input
  443. v-if="isEdit"
  444. v-model="tempData.designTemperature"
  445. class="edit-input-text"
  446. placeholder="请输入设计温度"
  447. />
  448. <text v-else class="cell-text">{{ equipment.designTemperature || '--' }}</text>
  449. </view>
  450. <view class="table-cell title">
  451. <text class="cell-title">工作介质</text>
  452. </view>
  453. <view class="table-cell content">
  454. <input
  455. v-if="isEdit"
  456. v-model="tempData.workMedium"
  457. class="edit-input-text"
  458. placeholder="请输入工作介质"
  459. />
  460. <text v-else class="cell-text">{{ equipment.workMedium || '--' }}</text>
  461. </view>
  462. </view>
  463. <!-- 筒体腐蚀裕度 + 封头腐蚀裕度 -->
  464. <view class="table-row-split">
  465. <view class="table-cell title">
  466. <text class="cell-title">筒体腐蚀裕度</text>
  467. </view>
  468. <view class="table-cell content">
  469. <input
  470. v-if="isEdit"
  471. v-model="tempData.corrosionAllowance"
  472. class="edit-input-text"
  473. placeholder="请输入筒体腐蚀裕度"
  474. />
  475. <text v-else class="cell-text">{{ equipment.corrosionAllowance || '--' }}</text>
  476. </view>
  477. <view class="table-cell title">
  478. <text class="cell-title">封头腐蚀裕度</text>
  479. </view>
  480. <view class="table-cell content">
  481. <input
  482. v-if="isEdit"
  483. v-model="tempData.headCorrosionAllowance"
  484. class="edit-input-text"
  485. placeholder="请输入封头腐蚀裕度"
  486. />
  487. <text v-else class="cell-text">{{ equipment.headCorrosionAllowance || '--' }}</text>
  488. </view>
  489. </view>
  490. <!-- 筒体材质 + 封头材质 -->
  491. <view class="table-row-split">
  492. <view class="table-cell title">
  493. <text class="cell-title">筒体材质</text>
  494. </view>
  495. <view class="table-cell content">
  496. <input
  497. v-if="isEdit"
  498. v-model="tempData.canisterMaterial"
  499. class="edit-input-text"
  500. placeholder="请输入筒体材质"
  501. />
  502. <text v-else class="cell-text">{{ equipment.canisterMaterial || '--' }}</text>
  503. </view>
  504. <view class="table-cell title">
  505. <text class="cell-title">封头材质</text>
  506. </view>
  507. <view class="table-cell content">
  508. <input
  509. v-if="isEdit"
  510. v-model="tempData.headMaterial"
  511. class="edit-input-text"
  512. placeholder="请输入封头材质"
  513. />
  514. <text v-else class="cell-text">{{ equipment.headMaterial || '--' }}</text>
  515. </view>
  516. </view>
  517. <!-- 夹套材质 + 衬里材料 -->
  518. <view class="table-row-split">
  519. <view class="table-cell title">
  520. <text class="cell-title">夹套材质</text>
  521. </view>
  522. <view class="table-cell content">
  523. <input
  524. v-if="isEdit"
  525. v-model="tempData.sleeveMaterial"
  526. class="edit-input-text"
  527. placeholder="请输入夹套材质"
  528. />
  529. <text v-else class="cell-text">{{ equipment.sleeveMaterial || '--' }}</text>
  530. </view>
  531. <view class="table-cell title">
  532. <text class="cell-title">衬里材料</text>
  533. </view>
  534. <view class="table-cell content">
  535. <input
  536. v-if="isEdit"
  537. v-model="tempData.linerMaterial"
  538. class="edit-input-text"
  539. placeholder="请输入衬里材料"
  540. />
  541. <text v-else class="cell-text">{{ equipment.linerMaterial || '--' }}</text>
  542. </view>
  543. </view>
  544. <!-- 筒体厚度 + 封头厚度 -->
  545. <view class="table-row-split">
  546. <view class="table-cell title">
  547. <text class="cell-title">筒体厚度</text>
  548. </view>
  549. <view class="table-cell content">
  550. <input
  551. v-if="isEdit"
  552. v-model="tempData.canisterPly"
  553. class="edit-input-text"
  554. placeholder="请输入筒体厚度"
  555. />
  556. <text v-else class="cell-text">{{ equipment.canisterPly || '--' }}</text>
  557. </view>
  558. <view class="table-cell title">
  559. <text class="cell-title">封头厚度</text>
  560. </view>
  561. <view class="table-cell content">
  562. <input
  563. v-if="isEdit"
  564. v-model="tempData.headPly"
  565. class="edit-input-text"
  566. placeholder="请输入封头厚度"
  567. />
  568. <text v-else class="cell-text">{{ equipment.headPly || '--' }}</text>
  569. </view>
  570. </view>
  571. <!-- 夹套厚度 + 衬里厚度 -->
  572. <view class="table-row-split">
  573. <view class="table-cell title">
  574. <text class="cell-title">夹套厚度</text>
  575. </view>
  576. <view class="table-cell content">
  577. <input
  578. v-if="isEdit"
  579. v-model="tempData.sleevePly"
  580. class="edit-input-text"
  581. placeholder="请输入夹套厚度"
  582. />
  583. <text v-else class="cell-text">{{ equipment.sleevePly || '--' }}</text>
  584. </view>
  585. <view class="table-cell title">
  586. <text class="cell-title">衬里厚度</text>
  587. </view>
  588. <view class="table-cell content">
  589. <input
  590. v-if="isEdit"
  591. v-model="tempData.linerPly"
  592. class="edit-input-text"
  593. placeholder="请输入衬里厚度"
  594. />
  595. <text v-else class="cell-text">{{ equipment.linerPly || '--' }}</text>
  596. </view>
  597. </view>
  598. <!-- 工作温度 + 设计介质 -->
  599. <view class="table-row-split">
  600. <view class="table-cell title">
  601. <text class="cell-title">工作温度</text>
  602. </view>
  603. <view class="table-cell content">
  604. <input
  605. v-if="isEdit"
  606. v-model="tempData.workTemperature"
  607. class="edit-input-text"
  608. placeholder="请输入工作温度"
  609. />
  610. <text v-else class="cell-text">{{ equipment.workTemperature || '--' }}</text>
  611. </view>
  612. <view class="table-cell title">
  613. <text class="cell-title">设计介质</text>
  614. </view>
  615. <view class="table-cell content">
  616. <input
  617. v-if="isEdit"
  618. v-model="tempData.designMedium"
  619. class="edit-input-text"
  620. placeholder="请输入设计介质"
  621. />
  622. <text v-else class="cell-text">{{ equipment.designMedium || '--' }}</text>
  623. </view>
  624. </view>
  625. <!-- 主体材质 -->
  626. <view class="table-row">
  627. <view class="table-cell title">
  628. <text class="cell-title">主体材质</text>
  629. </view>
  630. <view class="table-cell content">
  631. <input
  632. v-if="isEdit && tempData"
  633. v-model="tempData.mainMaterial"
  634. class="edit-input-text"
  635. placeholder="请输入主体材质"
  636. />
  637. <text v-else class="cell-text">{{ equipment.mainMaterial || '--' }}</text>
  638. </view>
  639. </view>
  640. </view>
  641. </view>
  642. <!-- 选择器弹窗 -->
  643. <view v-if="showPicker" class="popup-overlay" @click="closePicker">
  644. <view class="picker-popup" @click.stop>
  645. <view class="picker-header">
  646. <text class="picker-cancel" @click="closePicker">取消</text>
  647. <text class="picker-title">{{ pickerTitle }}</text>
  648. <text class="picker-confirm" @click="confirmPicker">确定</text>
  649. </view>
  650. <picker-view class="picker-view" :value="pickerIndex" @change="onPickerChange">
  651. <picker-view-column>
  652. <view v-for="item in pickerList" :key="item.value" class="picker-item">
  653. <text>{{ item.label }}</text>
  654. </view>
  655. </picker-view-column>
  656. </picker-view>
  657. </view>
  658. </view>
  659. </view>
  660. </template>
  661. <script lang="ts" setup>
  662. import { ref, reactive, onMounted, watch, computed } from 'vue'
  663. import { updateEquipApi } from '@/api/task'
  664. import { useUserStore } from '@/store/user'
  665. interface Props {
  666. equipmentData: any
  667. useOnline?: string
  668. canEdit?: boolean
  669. orderId?: string
  670. orderItemId?: string
  671. equipId?: string
  672. uploadVerify?: () => Promise<{ code: number; msg: string } | undefined>
  673. }
  674. const props = defineProps<Props>()
  675. const emit = defineEmits<{
  676. update: [data: any]
  677. }>()
  678. const userStore = useUserStore()
  679. const userInfo = computed(() => userStore.userInfo)
  680. defineExpose({
  681. equipment,
  682. equipmentParams: cacheData,
  683. })
  684. const isEdit = ref(false)
  685. const equipment = ref<any>({})
  686. const tempData = ref<any>({})
  687. const cacheData = ref<any>({})
  688. const safeTempData = computed(() => tempData.value || {})
  689. const STORAGE_KEY = `equipment-info-cache-${userInfo.value?.id}-${props.orderId}-${props.equipId}`
  690. const showPicker = ref(false)
  691. const pickerType = ref('')
  692. const pickerTitle = ref('')
  693. const pickerList = ref<any[]>([])
  694. const pickerIndex = ref([0])
  695. const dictType: Record<string, any[]> = {
  696. equipmentType: [
  697. { label: '固定式压力容器', value: '固定式压力容器' },
  698. { label: '移动式压力容器', value: '移动式压力容器' },
  699. { label: '气瓶', value: '气瓶' },
  700. { label: '锅炉', value: '锅炉' },
  701. ],
  702. type: [
  703. { label: '第一类压力容器', value: '第一类压力容器' },
  704. { label: '第二类压力容器', value: '第二类压力容器' },
  705. { label: '第三类压力容器', value: '第三类压力容器' },
  706. ],
  707. equipType: [
  708. { label: '反应压力容器', value: '反应压力容器' },
  709. { label: '分离压力容器', value: '分离压力容器' },
  710. { label: '储存压力容器', value: '储存压力容器' },
  711. { label: '换热压力容器', value: '换热压力容器' },
  712. { label: '移动式压力容器', value: '移动式压力容器' },
  713. { label: '气瓶', value: '气瓶' },
  714. ],
  715. }
  716. const getDictLabel = (type: string, value: string): string => {
  717. if (!dictType[type]) return value
  718. const item = dictType[type].find((i) => i.value === value)
  719. return item?.label || value || ''
  720. }
  721. const hasChanges = (): boolean => {
  722. const keys = Object.keys(tempData.value)
  723. return keys.some((key) => {
  724. const original = equipment.value[key]
  725. const current = tempData.value[key]
  726. return current !== original && current !== '' && current !== undefined
  727. })
  728. }
  729. const handleEdit = async () => {
  730. if (isEdit.value) {
  731. if (!hasChanges()) {
  732. uni.showToast({ title: '没有修改任何信息', icon: 'error' })
  733. return
  734. }
  735. await handleSave()
  736. } else {
  737. tempData.value = { ...equipment.value }
  738. isEdit.value = true
  739. }
  740. }
  741. const handleSave = async () => {
  742. try {
  743. uni.showLoading({ title: props.useOnline === '1' ? '保存中...' : '暂存中...' })
  744. const params = {
  745. id: props.equipId,
  746. orderId: props.orderId,
  747. ...tempData.value,
  748. }
  749. const result: any = await updateEquipApi(params)
  750. if (result?.code === 0) {
  751. uni.showToast({ title: props.useOnline === '1' ? '保存成功' : '暂存成功', icon: 'success' })
  752. equipment.value = { ...equipment.value, ...tempData.value }
  753. cacheData.value = {}
  754. uni.setStorageSync(STORAGE_KEY, {})
  755. if (props.useOnline === '1') {
  756. emit('update', tempData.value)
  757. }
  758. isEdit.value = false
  759. } else {
  760. uni.showToast({ title: result?.msg || '保存失败', icon: 'error' })
  761. }
  762. } catch (error: any) {
  763. console.error('保存失败:', error)
  764. uni.showToast({ title: error?.msg || '保存失败', icon: 'error' })
  765. } finally {
  766. uni.hideLoading()
  767. }
  768. }
  769. const handleUpload = async () => {
  770. const result = await props.uploadVerify?.()
  771. if (!result) return
  772. if (result?.code === 0) {
  773. if (props.useOnline === '1') {
  774. equipment.value = { ...equipment.value, ...cacheData.value }
  775. } else {
  776. await handleEdit()
  777. await new Promise((resolve) => setTimeout(resolve, 100))
  778. await handleSave()
  779. }
  780. uni.showToast({ title: '上传成功', icon: 'success' })
  781. } else {
  782. uni.showToast({ title: result?.msg || '上传失败', icon: 'error' })
  783. }
  784. }
  785. const handleOcr = () => {
  786. uni.chooseImage({
  787. count: 1,
  788. success: (res) => {
  789. const tempFilePath = res.tempFilePaths[0]
  790. uni.navigateTo({
  791. url: `/pages/equipment/detail/ocrInput?equipId=${props.equipId}&imagePath=${tempFilePath}&source=equipmentInfo`,
  792. })
  793. },
  794. })
  795. }
  796. const handlePicker = (type: string) => {
  797. pickerType.value = type
  798. pickerList.value = dictType[type] || []
  799. const currentValue = tempData.value[type]
  800. const index = pickerList.value.findIndex((item) => item.value === currentValue)
  801. pickerIndex.value = [index >= 0 ? index : 0]
  802. const titles: Record<string, string> = {
  803. equipmentType: '设备种类',
  804. type: '设备类别',
  805. equipType: '容器归类',
  806. }
  807. pickerTitle.value = titles[type] || '请选择'
  808. showPicker.value = true
  809. }
  810. const closePicker = () => {
  811. showPicker.value = false
  812. }
  813. const confirmPicker = () => {
  814. const selected = pickerList.value[pickerIndex.value[0]]
  815. if (selected) {
  816. tempData.value[pickerType.value] = selected.value
  817. }
  818. closePicker()
  819. }
  820. const onPickerChange = (e: any) => {
  821. pickerIndex.value = e.detail.value
  822. }
  823. const onDesignDateChange = (e: any) => {
  824. tempData.value.designDate = e.detail.value
  825. }
  826. const onMakeDateChange = (e: any) => {
  827. tempData.value.makeDate = e.detail.value
  828. }
  829. const onUseDateChange = (e: any) => {
  830. tempData.value.useDate = e.detail.value
  831. }
  832. const loadCacheData = () => {
  833. if (!props.canEdit || props.useOnline === '1') return
  834. try {
  835. const cached = uni.getStorageSync(STORAGE_KEY)
  836. if (cached && Object.keys(cached).length > 0) {
  837. cacheData.value = cached
  838. tempData.value = { ...equipment.value, ...cached }
  839. }
  840. } catch (error) {
  841. console.log('加载缓存失败:', error)
  842. }
  843. }
  844. const saveCacheData = () => {
  845. if (!props.canEdit || props.useOnline === '1' || !hasChanges()) return
  846. const changes: Record<string, any> = {}
  847. Object.keys(tempData.value).forEach((key) => {
  848. const original = equipment.value[key]
  849. const current = tempData.value[key]
  850. if (current !== original && current !== '' && current !== undefined) {
  851. changes[key] = current
  852. }
  853. })
  854. if (Object.keys(changes).length > 0) {
  855. cacheData.value = { ...cacheData.value, ...changes }
  856. uni.setStorageSync(STORAGE_KEY, cacheData.value)
  857. }
  858. }
  859. watch(isEdit, (newVal) => {
  860. if (!newVal && hasChanges()) {
  861. saveCacheData()
  862. }
  863. })
  864. watch(
  865. () => props.equipmentData,
  866. (newData) => {
  867. if (newData) {
  868. equipment.value = newData
  869. loadCacheData()
  870. }
  871. },
  872. { immediate: true, deep: true },
  873. )
  874. watch(isEdit, (newIsEdit) => {
  875. if (newIsEdit && !tempData.value) {
  876. tempData.value = {}
  877. }
  878. })
  879. onMounted(() => {
  880. if (props.equipmentData) {
  881. equipment.value = props.equipmentData
  882. loadCacheData()
  883. }
  884. })
  885. </script>
  886. <style lang="scss" scoped>
  887. .equipment-info-container {
  888. padding: 10px;
  889. }
  890. .edit-bar {
  891. display: flex;
  892. flex-direction: row;
  893. justify-content: flex-end;
  894. padding: 0 0;
  895. }
  896. .edit-btn {
  897. display: flex;
  898. align-items: center;
  899. justify-content: center;
  900. min-width: 60px;
  901. height: 28px;
  902. padding: 0 12px;
  903. margin-left: 10px;
  904. font-size: 13px;
  905. color: #fff;
  906. background-color: #2f8eff;
  907. border: none;
  908. border-radius: 3px;
  909. }
  910. .operate-btn-text {
  911. font-size: 14px;
  912. color: #fff;
  913. }
  914. .ocr-btn {
  915. display: flex;
  916. align-items: center;
  917. justify-content: center;
  918. min-width: 70px;
  919. height: 28px;
  920. padding: 0 12px;
  921. font-size: 13px;
  922. color: #fff;
  923. background-color: #2f8eff;
  924. border: none;
  925. border-radius: 3px;
  926. }
  927. .upload-btn {
  928. display: flex;
  929. align-items: center;
  930. justify-content: center;
  931. min-width: 60px;
  932. height: 28px;
  933. padding: 0 12px;
  934. margin-left: 10px;
  935. font-size: 13px;
  936. color: #fff;
  937. background-color: #e6a23c;
  938. border: none;
  939. border-radius: 3px;
  940. }
  941. .section {
  942. margin-bottom: 10px;
  943. overflow: hidden;
  944. background-color: #fff;
  945. border-radius: 5px;
  946. }
  947. .section-header {
  948. display: flex;
  949. flex-flow: row nowrap;
  950. align-items: center;
  951. justify-content: space-between;
  952. padding: 10px 0;
  953. background-color: #f9f9f9;
  954. border-bottom: 1px solid #eee;
  955. }
  956. .section-title {
  957. font-size: 18px;
  958. font-weight: 600;
  959. color: #333;
  960. }
  961. .table {
  962. width: 100%;
  963. border: 1px solid rgb(225, 228, 233);
  964. }
  965. .table-row {
  966. display: flex;
  967. flex-direction: row;
  968. width: 100%;
  969. border-right: 1px solid rgb(225, 228, 233);
  970. border-bottom: 1px solid rgb(225, 228, 233);
  971. .table-cell {
  972. &.title {
  973. width: 25%;
  974. }
  975. &.content {
  976. width: 75%;
  977. }
  978. }
  979. }
  980. .table-row-split {
  981. display: flex;
  982. flex-direction: row;
  983. width: 100%;
  984. border-right: 1px solid rgb(235, 238, 245);
  985. border-bottom: 1px solid rgb(235, 238, 245);
  986. .table-cell {
  987. &.title {
  988. width: 50%;
  989. }
  990. &.content {
  991. width: 50%;
  992. }
  993. }
  994. }
  995. .table-cell {
  996. padding: 10px;
  997. &.title {
  998. display: flex;
  999. flex-direction: row;
  1000. align-items: center;
  1001. background-color: rgb(245, 247, 250);
  1002. border-right: 1px solid rgb(235, 238, 245);
  1003. .cell-title {
  1004. font-size: 14px;
  1005. color: rgb(51, 51, 51);
  1006. }
  1007. .must {
  1008. margin-left: 2px;
  1009. color: #f84a23;
  1010. }
  1011. }
  1012. &.content {
  1013. display: flex;
  1014. align-items: center;
  1015. min-height: 40px;
  1016. .cell-text {
  1017. font-size: 14px;
  1018. color: rgb(106, 106, 106);
  1019. }
  1020. .edit-input {
  1021. display: flex;
  1022. flex: 1;
  1023. flex-direction: row;
  1024. align-items: center;
  1025. justify-content: space-between;
  1026. padding: 5px 10px;
  1027. border: 1px solid #ddd;
  1028. border-radius: 5px;
  1029. text {
  1030. font-size: 14px;
  1031. color: rgb(51, 51, 51);
  1032. }
  1033. .arrow-icon {
  1034. width: 15px;
  1035. height: 15px;
  1036. margin-left: 5px;
  1037. }
  1038. }
  1039. .edit-input-text {
  1040. flex: 1;
  1041. height: 30px;
  1042. padding: 0 10px;
  1043. font-size: 14px;
  1044. border: 1px solid #ddd;
  1045. border-radius: 5px;
  1046. }
  1047. .edit-textarea {
  1048. flex: 1;
  1049. min-height: 60px;
  1050. padding: 5px 10px;
  1051. font-size: 14px;
  1052. border: 1px solid #ddd;
  1053. border-radius: 5px;
  1054. }
  1055. }
  1056. }
  1057. .popup-overlay {
  1058. position: fixed;
  1059. top: 0;
  1060. right: 0;
  1061. bottom: 0;
  1062. left: 0;
  1063. z-index: 999;
  1064. display: flex;
  1065. align-items: flex-end;
  1066. background-color: rgba(0, 0, 0, 0.5);
  1067. }
  1068. .picker-popup {
  1069. width: 100%;
  1070. background-color: #fff;
  1071. border-radius: 10px 10px 0 0;
  1072. }
  1073. .picker-header {
  1074. display: flex;
  1075. flex-direction: row;
  1076. align-items: center;
  1077. justify-content: space-between;
  1078. padding: 15px;
  1079. border-bottom: 1px solid #eee;
  1080. }
  1081. .picker-cancel {
  1082. font-size: 14px;
  1083. color: #999;
  1084. }
  1085. .picker-title {
  1086. font-size: 16px;
  1087. font-weight: 500;
  1088. color: #333;
  1089. }
  1090. .picker-confirm {
  1091. font-size: 14px;
  1092. color: #2f8eff;
  1093. }
  1094. .picker-view {
  1095. height: 200px;
  1096. }
  1097. .picker-item {
  1098. display: flex;
  1099. align-items: center;
  1100. justify-content: center;
  1101. font-size: 16px;
  1102. color: #333;
  1103. }
  1104. </style>