register.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. <template>
  2. <view>
  3. <uni-nav-bar
  4. fixed="true"
  5. statusBar="true"
  6. left-icon="back"
  7. title="备品备件登记"
  8. @clickLeft="back"
  9. right-icon="scan"
  10. @clickRight="handlscanCheck"
  11. >
  12. </uni-nav-bar>
  13. <view class="check-content">
  14. <uni-easyinput type="text" v-model="searchKey" placeholder="搜索关键字" />
  15. <view class="content-number">
  16. <span class="number-box">共 {{ allNumber }}</span>
  17. <span class="number-box">已选 {{ chooseNumber }}</span>
  18. </view>
  19. <checkbox-group
  20. v-for="(item, index) in showList"
  21. :key="index"
  22. @change="e => selectVal(e, item, index)"
  23. >
  24. <view class="groupbox">
  25. <view class="listBox">
  26. <view class="listBox-con">
  27. <view class="con-line">
  28. <view class="line-name">备件编码</view>
  29. <view class="line-value">{{ item.assetCode }}</view>
  30. </view>
  31. <view class="con-line">
  32. <view class="line-name">备件名称</view>
  33. <view class="line-value">{{ item.informationName }}</view>
  34. </view>
  35. <view class="con-line">
  36. <view class="line-name">单位</view>
  37. <view class="line-value">{{
  38. item.isUnpack ? item.unit : item.minPackUnit
  39. }}</view>
  40. </view>
  41. <view class="con-line" v-if="!item.isUnpack">
  42. <view class="line-name">包装单元</view>
  43. <view class="line-value">
  44. <uni-easyinput
  45. type="number"
  46. v-model.number="item.num"
  47. ></uni-easyinput
  48. >{{ item.unit }}/{{ item.minPackUnit }}</view
  49. >
  50. </view>
  51. <view class="con-line" v-if="!item.isUnpack">
  52. <view class="line-name">剩余</view>
  53. <view class="line-value">
  54. {{ item.unusedNum }}
  55. {{ item.unit }}</view
  56. >
  57. </view>
  58. <view class="con-line">
  59. <view class="line-name">规格/型号</view>
  60. <view class="line-value"
  61. >{{ item.specification }}/{{ item.modelType }}</view
  62. >
  63. </view>
  64. <view class="con-line" v-if="item.selfDefinedParameter">
  65. <view
  66. class="con-line"
  67. v-for="(ite, ind) in JSON.parse(item.selfDefinedParameter)"
  68. :key="ind"
  69. >
  70. <view class="line-name">{{ ite.key }}</view>
  71. <view class="line-value">{{ ite.value }}</view>
  72. </view>
  73. </view>
  74. </view>
  75. <view class="listBox-sel">
  76. <checkbox
  77. class="sel-checbox"
  78. :checked="item.status"
  79. color="#fff"
  80. />
  81. </view>
  82. </view>
  83. </view>
  84. </checkbox-group>
  85. </view>
  86. <view class="footer">
  87. <view class="btn" @click="back"> 取消 </view>
  88. <view class="btn primary" @click="handleSave"> 保存 </view>
  89. </view>
  90. <!-- <ScanCode @scancodedate="cbScancodedate" :model="'uni'"></ScanCode> -->
  91. </view>
  92. </template>
  93. <script>
  94. import { get, post, postJ } from '@/utils/api.js'
  95. import ScanCode from '@/components/ScanCode.vue'
  96. export default {
  97. components: {
  98. ScanCode
  99. },
  100. data () {
  101. return {
  102. searchKey: '',
  103. listData: [],
  104. workOrderCode: '',
  105. workOrderId: '',
  106. equipmentCode: '',
  107. allNumber: 0,
  108. memoList: [],
  109. requestStatus: false,
  110. timer: null,
  111. originList: [],
  112. from: ''
  113. }
  114. },
  115. computed: {
  116. chooseNumber () {
  117. return this.memoList.length || 0
  118. },
  119. showList () {
  120. return this.listData.filter(
  121. ({ specification, modelType, assetCode, informationName }) => {
  122. if (this.searchKey) {
  123. return (
  124. (specification && specification.indexOf(this.searchKey) > -1) ||
  125. (modelType && modelType.indexOf(this.searchKey) > -1) ||
  126. (assetCode && assetCode.indexOf(this.searchKey) > -1) ||
  127. (informationName && informationName.indexOf(this.searchKey) > -1)
  128. )
  129. }
  130. return true
  131. }
  132. )
  133. }
  134. },
  135. onLoad (options) {
  136. this.from = options.from
  137. this.workOrderCode = options.workOrderCode
  138. this.workOrderId = options.workOrderId
  139. this.equipmentCode = options.equipmentCode
  140. },
  141. async onShow () {
  142. let _this = this
  143. if (this.from === 'maintain_service') {
  144. // 维修跳转
  145. await this.getUsedList()
  146. } else {
  147. this.originList = JSON.parse(
  148. this.$store.state.maintenance.sparePartsJson || '[]'
  149. ).map(item => {
  150. item.status = true
  151. return item
  152. })
  153. console.log(this.originList)
  154. this.memoList = uni.$u.deepClone(this.originList)
  155. }
  156. _this.getList()
  157. uni.$off('scancodedate') // 每次进来先 移除全局自定义事件监听器
  158. uni.$on('scancodedate', function (data) {
  159. _this.cbScancodedate(data)
  160. })
  161. // 如果有定时器,清除定时器
  162. if (this.timer) {
  163. clearTimeout(this.timer)
  164. this.timer = null
  165. }
  166. },
  167. onHide () {
  168. uni.$off('scancodedate')
  169. },
  170. onUnload () {
  171. uni.$off('scancodedate')
  172. },
  173. methods: {
  174. // 获取备品备件
  175. getUsedList () {
  176. let par = {
  177. sourceCode: this.workOrderCode
  178. }
  179. if (this.equipmentCode) {
  180. par.equipmentCode = this.equipmentCode
  181. }
  182. return postJ(
  183. this.apiUrl + `/sparePartsApply/getSparePartsExpendList`,
  184. par
  185. ).then(res => {
  186. if (res?.success) {
  187. this.originList = res.data.map(item => {
  188. item.status = true
  189. if (!item.isUnpack) {
  190. item.num = item.measurementUnit - item.unusedNum
  191. }
  192. return item
  193. })
  194. console.log(this.originList)
  195. this.memoList = uni.$u.deepClone(this.originList)
  196. }
  197. })
  198. },
  199. //勾选
  200. selectVal (e, val, index) {
  201. this.showList[index].status = !this.showList[index].status
  202. const idx = this.memoList.findIndex(
  203. item => item.assetCode === this.showList[index].assetCode
  204. )
  205. if (this.showList[index].status) {
  206. if (idx === -1) {
  207. this.memoList.push(this.showList[index])
  208. }
  209. } else {
  210. if (idx > -1) {
  211. this.memoList.splice(idx, 1)
  212. }
  213. }
  214. },
  215. handleSave () {
  216. let flag = false
  217. // 计算剩余
  218. const sparePartsExpendList = uni.$u
  219. .deepClone(this.listData)
  220. .map((item, index) => {
  221. item.status = !!this.memoList.find(i => i.id === item.id)
  222. if (!item.isUnpack) {
  223. if (item.status) {
  224. if (!item.num) {
  225. // 拆包输入
  226. uni.showToast({
  227. title: `请输入${item.assetCode}登记数量`,
  228. icon: 'none'
  229. })
  230. flag = true
  231. return false
  232. }
  233. item.unusedNum = item.unusedNum - item.num
  234. if (item.unusedNum < 0) {
  235. // 拆包输入
  236. uni.showToast({
  237. title: `${item.assetCode}登记数量不能大院剩余数量`,
  238. icon: 'none'
  239. })
  240. flag = true
  241. return false
  242. }
  243. item.status = item.unusedNum === 0
  244. } else {
  245. item.num = 0
  246. const obj = this.originList.find(i => i.id === item.id)
  247. if (obj) {
  248. // 保存过数据 退回
  249. item.unusedNum += obj.num
  250. }
  251. }
  252. }
  253. return item
  254. })
  255. if (flag) {
  256. return
  257. }
  258. this.memoList = sparePartsExpendList
  259. .filter(item => item.status || item.num)
  260. .map(item => {
  261. item.equipmentCode = this.equipmentCode
  262. return item
  263. })
  264. const params = {
  265. sparePartsExpendEquiList: [
  266. {
  267. equipmentCode: this.equipmentCode,
  268. sparePartsJson: JSON.stringify(this.memoList),
  269. workOrderId: +this.workOrderId
  270. }
  271. ],
  272. sparePartsExpendList
  273. }
  274. if (flag) {
  275. return
  276. }
  277. postJ(
  278. this.apiUrl + `/sparePartsApply/updateSparePartsExpend`,
  279. params
  280. ).then(res => {
  281. if (res?.success) {
  282. this.$store.commit(
  283. 'maintenance/SET_SPAREPARTSJSON',
  284. params.sparePartsExpendEquiList[0].sparePartsJson
  285. )
  286. this.back()
  287. }
  288. })
  289. },
  290. back () {
  291. uni.navigateBack({
  292. delta: 1
  293. })
  294. },
  295. // 扫码
  296. /* HandlScanCode() {
  297. uni.navigateTo({
  298. url: '/pages/ScanCode/ScanCode'
  299. })
  300. //uni.$emit('scancode',{code:'null/w05000000130012/锤锤专用05-不拆-逐个/规格01/null/成型/null@_@0'})
  301. }, */
  302. // 扫码枪扫码
  303. cbScancodedate (data) {
  304. this.Scancodedate(data.code)
  305. },
  306. // 相机扫码
  307. handlscanCheck () {
  308. let _this = this
  309. uni.scanCode({
  310. success: function (res) {
  311. _this.Scancodedate(res.result)
  312. }
  313. })
  314. },
  315. Scancodedate (code) {
  316. this.qrContent = code.trim()
  317. //this.qrContent = 'null/w05000000130014/锤锤专用05-不拆-逐个/规格01/null/成型/null@_@0'
  318. this.barType = this.setBarType(this.qrContent)
  319. this.getData()
  320. //let res = await this.getScanCheckMate()
  321. },
  322. // 设置barType
  323. setBarType (val) {
  324. let arr = val.split('@_@')
  325. return (arr && arr[1]) || 0
  326. },
  327. // 根据条码请求设备数据
  328. getData () {
  329. let par = {
  330. barType: this.barType,
  331. qrContent: this.qrContent
  332. }
  333. console.log(par, 'par------------------')
  334. if (this.requestStatus) return
  335. postJ(this.apiUrl + '/scan/getAssetInfo', par).then(res => {
  336. let data = res.data
  337. let result = this.showList.find(item => {
  338. return item.assetCode == data.assetCode
  339. })
  340. console.log('匹配result', result)
  341. if (result) {
  342. if (result.status) {
  343. uni.showToast({
  344. title: '已选定,不可重复扫码!',
  345. icon: 'none',
  346. duration: 2000
  347. })
  348. } else {
  349. uni.showToast({
  350. title: '选定成功',
  351. icon: 'none',
  352. duration: 2000
  353. })
  354. result.status = true
  355. this.memoList.push(result)
  356. }
  357. } else {
  358. uni.showToast({
  359. title: '列表中无此备件!',
  360. icon: 'none',
  361. duration: 2000
  362. })
  363. }
  364. this.requestStatus = true
  365. this.timer = setTimeout(() => {
  366. this.requestStatus = false
  367. }, 500)
  368. })
  369. },
  370. getList (key) {
  371. let par = {
  372. sourceCode: this.workOrderCode
  373. // status: false ,
  374. // searchKey: key
  375. // equipmentCode: this.equipmentCode
  376. }
  377. postJ(this.apiUrl + `/sparePartsApply/getSparePartsExpend`, par).then(
  378. res => {
  379. if (res?.success) {
  380. this.listData = res.data
  381. .filter(i => !i.status)
  382. .map(i => {
  383. const obj = this.memoList.find(itm => itm.id == i.id)
  384. if (!i.isUnpack) {
  385. return {
  386. ...i,
  387. num: obj?.num || '',
  388. unusedNum: obj?.num ? i.unusedNum + obj?.num : i.unusedNum,
  389. status: !!obj
  390. }
  391. }
  392. return i
  393. })
  394. this.memoList.forEach(ele => {
  395. if (!this.listData.find(i => i.id === ele.id)) {
  396. this.listData.push({
  397. ...ele,
  398. unusedNum: ele.num,
  399. num: ele.num
  400. })
  401. }
  402. })
  403. this.allNumber = res.data.length
  404. // this.listData.map(item => {
  405. // if (item.status) {
  406. // //this.chooseNumber = this.chooseNumber + 1
  407. // this.memoList.push(item)
  408. // }
  409. // })
  410. }
  411. }
  412. )
  413. }
  414. }
  415. }
  416. </script>
  417. <style lang="scss" scoped>
  418. .check-content {
  419. box-sizing: border-box;
  420. // height: calc(100vh - 88rpx);
  421. display: flex;
  422. flex-direction: column;
  423. padding: 20rpx 20rpx 120rpx;
  424. .content-number {
  425. width: 96%;
  426. text-align: right;
  427. margin: 16rpx auto;
  428. font-size: 28rpx;
  429. .number-box {
  430. display: inline-block;
  431. margin-left: 30rpx;
  432. }
  433. }
  434. .groupbox {
  435. border: 1rpx solid #ccc;
  436. display: block;
  437. padding: 20rpx 10rpx 20rpx 30rpx;
  438. margin-bottom: 20rpx;
  439. }
  440. .listBox {
  441. display: flex;
  442. justify-content: flex-start;
  443. position: relative;
  444. .listBox-sel {
  445. position: absolute;
  446. top: 0;
  447. right: 0;
  448. }
  449. .sel-checbox {
  450. zoom: 200%;
  451. }
  452. .listBox-con {
  453. width: 100%;
  454. .con-line {
  455. display: flex;
  456. align-items: center;
  457. justify-content: flex-start;
  458. width: 100%;
  459. font-size: 28rpx;
  460. color: #666;
  461. .line-name {
  462. width: 180rpx;
  463. text-align: right;
  464. margin-right: 30rpx;
  465. }
  466. .uni-easyinput {
  467. display: inline-block;
  468. width: 200rpx;
  469. margin: 0 10rpx;
  470. }
  471. }
  472. .con-line:first-child {
  473. color: #000;
  474. }
  475. }
  476. }
  477. }
  478. .footer {
  479. height: 100rpx;
  480. display: flex;
  481. position: fixed;
  482. bottom: 0;
  483. width: 100vw;
  484. border: 1rpx solid $j-primary-border-green;
  485. background: #fff;
  486. .btn {
  487. display: flex;
  488. flex: 1;
  489. justify-content: center;
  490. align-items: center;
  491. border-radius: 0;
  492. &.primary {
  493. background-color: $j-primary-border-green;
  494. color: #fff;
  495. }
  496. }
  497. }
  498. </style>