bucketSelect.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. <template>
  2. <view class="mainBox">
  3. <uni-nav-bar
  4. fixed="true"
  5. statusBar="true"
  6. left-icon="back"
  7. title="选择出库明细"
  8. @clickLeft="backAdd"
  9. >
  10. <template slot="right">
  11. <uni-icons
  12. type="search"
  13. size="30"
  14. @click.native="openSearch"
  15. ></uni-icons>
  16. </template>
  17. </uni-nav-bar>
  18. <u-collapse>
  19. <u-collapse-item title="基本信息" name="Docs guide">
  20. <CellInfo label="物品编码" :value="infoData.assetCode"></CellInfo>
  21. <CellInfo label="物品名称" :value="infoData.assetName"></CellInfo>
  22. <CellInfo
  23. v-for="(item, index) in tableHeader"
  24. :key="index"
  25. :label="item.label"
  26. :value="infoData[item.prop]"
  27. ></CellInfo>
  28. <CellInfo
  29. label="总库存量"
  30. :value="infoData.realInventoryNum"
  31. ></CellInfo>
  32. <!-- <CellInfo
  33. label="总包装数量"
  34. :value="infoData.realPacketNum"
  35. ></CellInfo> -->
  36. </u-collapse-item>
  37. </u-collapse>
  38. <view class="self-table-header">
  39. <view class="table-code">编码</view>
  40. <view class="table-batch">批次号</view>
  41. </view>
  42. <view class="listContent">
  43. <checkbox-group @change="handleChange">
  44. <view class="listBox" v-for="(item, index) in listData" :key="index">
  45. <label>
  46. <view class="self-table-tr">
  47. <view class="table-code">{{ item.onlyCode }}</view>
  48. <view class="table-batch">{{ item.batchNum }}</view>
  49. <view class="table-date"></view>
  50. <view class="other-info">
  51. <view>包装编码:{{ item.num }}</view>
  52. <view v-if="!infoData.isUnpack"
  53. >最小包装单元:{{ item.measurementUnit }}{{ item.unit }}/{{
  54. item.minPackUnit
  55. }}</view
  56. >
  57. <view v-if="item.manufactureTime || item.procurementTime"
  58. >{{ item.procurementTime ? '采购日期' : '生产日期' }}:{{
  59. item.manufactureTime || item.procurementTime
  60. }}</view
  61. >
  62. <view style="width: 100%"
  63. >货位:{{ item.warehouseName }}-{{ item.areaName }}-{{
  64. item.shelfCode
  65. }}-{{ item.cargoSpaceCode }}</view
  66. >
  67. <view style="width: 100%">入库时间:{{ item.createTime }}</view>
  68. </view>
  69. <view class="checked">
  70. <checkbox
  71. :value="item.onlyCode"
  72. :checked="selectList.includes(item.onlyCode)"
  73. ></checkbox>
  74. </view>
  75. </view>
  76. </label>
  77. </view>
  78. </checkbox-group>
  79. <u-empty style="margin-top: 20vh" v-if="!listData.length" />
  80. </view>
  81. <view class="content-footer">
  82. <view class="op-tool">
  83. {{ selectList.length }}/{{ listData.length }}已选<text
  84. class="select-all text-primary"
  85. @click="selectAll = !selectAll"
  86. >全选</text
  87. >
  88. <template v-if="infoData.takeStockPattern == 1">
  89. <text class="text-primary" @click="openBatch">批量出库</text>
  90. </template>
  91. </view>
  92. <div v-if="infoData.sparePartsNum || infoData.sparePartsNum === 0">
  93. 申领数量:{{ infoData.sparePartsNum }}
  94. </div>
  95. <u-button
  96. type="success"
  97. size="small"
  98. class="u-reset-button"
  99. :disabled="!selectList.length"
  100. @click="jumpAdd"
  101. >
  102. <view class="selBtn"> 提交 </view>
  103. </u-button>
  104. </view>
  105. <!-- 搜索组件 -->
  106. <u-popup :show="searchVisible" mode="right" @close="searchVisible = false">
  107. <view class="search-container">
  108. <view class="title">筛选</view>
  109. <uni-forms
  110. label-width="400rpx"
  111. ref="customForm"
  112. :modelValue="popupInfo"
  113. label-position="top"
  114. >
  115. <uni-forms-item label="货位" name="cargoSpaceCode">
  116. <uni-easyinput
  117. v-model="popupInfo.cargoSpaceCode"
  118. :inputBorder="false"
  119. placeholder="请输入"
  120. />
  121. </uni-forms-item>
  122. <uni-forms-item
  123. :label="`${getDictValue('物品类型', +assetType)}编码`"
  124. name="onlyCode"
  125. >
  126. <uni-easyinput
  127. v-model="popupInfo.onlyCode"
  128. :inputBorder="false"
  129. placeholder="请输入"
  130. />
  131. </uni-forms-item>
  132. <uni-forms-item label="批次号" name="batchNum">
  133. <uni-easyinput
  134. v-model="popupInfo.batchNum"
  135. :inputBorder="false"
  136. placeholder="请输入"
  137. />
  138. </uni-forms-item>
  139. <uni-forms-item label="包装编码" name="num">
  140. <uni-easyinput
  141. v-model="popupInfo.num"
  142. :inputBorder="false"
  143. placeholder="请输入"
  144. />
  145. </uni-forms-item>
  146. <uni-forms-item label="生产日期" name="range">
  147. <view class="time-wrapper">
  148. <uni-datetime-picker
  149. v-model="popupInfo.range"
  150. :border="false"
  151. :icon="false"
  152. type="daterange"
  153. />
  154. </view>
  155. </uni-forms-item>
  156. <uni-forms-item label="采购日期" name="productTime">
  157. <view class="time-wrapper">
  158. <uni-datetime-picker
  159. v-model="popupInfo.productTime"
  160. :border="false"
  161. :icon="false"
  162. type="daterange"
  163. />
  164. </view>
  165. </uni-forms-item>
  166. </uni-forms>
  167. <view class="footer">
  168. <view class="btn reset" @click="handleReset"> 重置 </view>
  169. <view class="btn search" @click="handleSearch"> 搜索 </view>
  170. </view>
  171. </view>
  172. </u-popup>
  173. <u-popup :show="batchVisible" mode="center" @close="batchVisible = false">
  174. <view class="search-container">
  175. <view class="title">批量选择</view>
  176. <view class="batch-box">
  177. <uni-number-box
  178. :key="forceUpdate"
  179. :min="0"
  180. v-model="multipleNum"
  181. :max="listData.length"
  182. ></uni-number-box>
  183. </view>
  184. <view class="footer">
  185. <view class="btn reset" @click="batchVisible = false"> 取消 </view>
  186. <view class="btn search" @click="batchConfirm"> 确定 </view>
  187. </view>
  188. </view>
  189. </u-popup>
  190. </view>
  191. </template>
  192. <script>
  193. import CellInfo from '@/components/CellInfo.vue'
  194. import { post, postJ, get } from '@/utils/api.js'
  195. import { tableHeader } from '../common'
  196. import dictMixins from '@/mixins/dictMixins'
  197. // let [page, size, isEnd] = [1, 20, true]
  198. export default {
  199. components: { CellInfo },
  200. mixins: [dictMixins],
  201. data () {
  202. return {
  203. selectList: [],
  204. listData: [],
  205. forceUpdate: false,
  206. multipleNumUpdate: false,
  207. searchVisible: false,
  208. batchVisible: false,
  209. assetType: '',
  210. assetCode: '',
  211. total: 0,
  212. infoData: {},
  213. popupInfo: {
  214. cargoSpaceCode: '',
  215. range: [],
  216. productTime: [],
  217. batchNum: '',
  218. num: '',
  219. onlyCode: ''
  220. },
  221. multipleNum: 0
  222. }
  223. },
  224. //选择的列表长度
  225. computed: {
  226. tableHeader () {
  227. return tableHeader(this.assetType)
  228. },
  229. selectAll: {
  230. set (val) {
  231. if (val) {
  232. this.selectList = this.listData.map(i => i.onlyCode)
  233. } else {
  234. this.selectList = []
  235. }
  236. },
  237. get () {
  238. return (
  239. this.selectList.length &&
  240. this.selectList.length == this.listData.length
  241. )
  242. }
  243. }
  244. },
  245. onLoad ({ assetCode, assetType }) {
  246. this.requestDict('物品类型')
  247. this.assetType = assetType
  248. this.assetCode = assetCode
  249. this.handleList(assetCode, assetType)
  250. this.infoData = uni.getStorageSync('outputInfoData') || {}
  251. this.selectList = (this.infoData.warehouseLedgerDetails || []).map(
  252. i => i.onlyCode
  253. )
  254. this.multipleNum = 0
  255. },
  256. onShow () {},
  257. //触底刷新
  258. // onReachBottom: function () {
  259. // if (isEnd) {
  260. // return
  261. // }
  262. // // 显示加载图标
  263. // uni.showLoading({
  264. // title: '数据加载中'
  265. // })
  266. // //获取更多数据
  267. // page++
  268. // this.getList()
  269. // },
  270. mounted () {},
  271. methods: {
  272. // 表格数据
  273. async handleList () {
  274. // this.selectList = []
  275. this.multipleNum = 0
  276. const params = {
  277. assetCode: this.assetCode,
  278. assetType: this.assetType,
  279. ...this.popupInfo
  280. }
  281. if (params.range?.length) {
  282. params.startTime = params.range[0]
  283. params.endTime = params.range[1]
  284. }
  285. if (params.productTime?.length) {
  286. params.startProductTime = params.productTime[0]
  287. params.endProductTime = params.productTime[1]
  288. }
  289. delete params.range
  290. delete params.productTime
  291. console.log('params--------', params)
  292. const res = await get(
  293. this.apiUrl + `/outInWarehouse/getWarehouseActualDetail`,
  294. params
  295. )
  296. if (res?.success) {
  297. this.listData = res.data
  298. }
  299. },
  300. openBatch () {
  301. this.multipleNum = 0
  302. this.batchVisible = true
  303. },
  304. batchConfirm () {
  305. if (!this.multipleNum) {
  306. uni.showToast({
  307. title: '请输入大于0的数量',
  308. icon: 'none'
  309. })
  310. return
  311. }
  312. this.batchVisible = false
  313. if (this.selectList.length === this.multipleNum) return
  314. if (this.selectList.length >= this.multipleNum) {
  315. this.selectList.splice(this.multipleNum, this.selectList.length)
  316. } else {
  317. let rest = this.multipleNum - this.selectList.length
  318. for (const p of this.listData) {
  319. if (!this.selectList.includes(p.onlyCode)) {
  320. this.selectList.push(p.onlyCode)
  321. rest--
  322. }
  323. if (!rest) break
  324. }
  325. }
  326. // this.selectList = this.listData
  327. // .slice(0, this.multipleNum)
  328. // .map(i => i.onlyCode)
  329. },
  330. handleReset () {
  331. this.popupInfo = {}
  332. this.handleList()
  333. this.searchVisible = false
  334. },
  335. handleSearch () {
  336. this.handleList()
  337. this.searchVisible = false
  338. },
  339. handleChange ({ detail }) {
  340. this.selectList = detail.value
  341. console.log(detail.value)
  342. },
  343. openSearch () {
  344. this.searchVisible = true
  345. },
  346. //跳转回添加页面
  347. jumpAdd () {
  348. uni.$emit(
  349. 'bucketSelect',
  350. this.listData.filter(item => this.selectList.includes(item.onlyCode))
  351. )
  352. uni.navigateBack()
  353. },
  354. //返回添加页
  355. backAdd () {
  356. uni.navigateBack()
  357. }
  358. }
  359. }
  360. </script>
  361. <style lang="scss" scoped>
  362. .mainBox {
  363. height: 100vh;
  364. position: relative;
  365. display: flex;
  366. flex-direction: column;
  367. .u-popup {
  368. flex: 0;
  369. }
  370. .listContent {
  371. flex: 1;
  372. overflow: auto;
  373. padding-bottom: 125rpx;
  374. }
  375. .self-table-tr,
  376. .self-table-header {
  377. font-size: 28rpx;
  378. display: flex;
  379. justify-content: space-between;
  380. flex-wrap: wrap;
  381. .table-date,
  382. .table-batch,
  383. .table-code {
  384. box-sizing: border-box;
  385. width: 27%;
  386. padding: 0 5rpx;
  387. word-break: break-all;
  388. }
  389. .table-code {
  390. width: 50%;
  391. }
  392. .table-date {
  393. width: 37%;
  394. }
  395. .other-info {
  396. color: #aaa;
  397. width: 100%;
  398. display: flex;
  399. justify-content: space-between;
  400. font-size: 28rpx;
  401. flex-wrap: wrap;
  402. > view {
  403. margin-bottom: 10rpx;
  404. }
  405. }
  406. .checked {
  407. width: 100%;
  408. display: flex;
  409. justify-content: flex-end;
  410. }
  411. }
  412. .self-table-tr {
  413. border-bottom: 1rpx dashed #ccc;
  414. padding: 20rpx 10rpx;
  415. }
  416. .self-table-header {
  417. padding: 10rpx;
  418. border-bottom: 1rpx solid #ccc;
  419. }
  420. //底部按钮
  421. .content-footer {
  422. position: fixed;
  423. bottom: 0;
  424. width: 100%;
  425. height: 120rpx;
  426. border-top: 1rpx solid #eeecec;
  427. background-color: #ffffff;
  428. z-index: 999;
  429. display: flex;
  430. justify-content: space-between;
  431. align-items: center;
  432. padding: 0 20rpx;
  433. box-sizing: border-box;
  434. .select-all {
  435. margin-left: 20rpx;
  436. margin-right: 30rpx;
  437. }
  438. .op-tool {
  439. display: flex;
  440. justify-content: flex-start;
  441. align-items: center;
  442. // /deep/.u-number-box {
  443. // align-items: stretch;
  444. // height: 60rpx;
  445. // margin: 0 15rpx;
  446. // .u-number-box__input {
  447. // width: 80rpx !important;
  448. // height: auto !important;
  449. // }
  450. // .u-number-box__minus,
  451. // .u-number-box__plus {
  452. // height: auto !important;
  453. // }
  454. // }
  455. }
  456. /deep/.u-button {
  457. height: 80rpx;
  458. font-size: 30rpx;
  459. width: 100rpx;
  460. margin: 0;
  461. }
  462. }
  463. }
  464. .search-container {
  465. width: 70vw;
  466. padding: 30rpx 36rpx;
  467. .batch-box {
  468. height: 100rpx;
  469. display: flex;
  470. justify-content: center;
  471. align-items: center;
  472. padding-bottom: 80rpx;
  473. }
  474. .footer {
  475. position: absolute;
  476. bottom: 0;
  477. left: 0;
  478. width: 100%;
  479. display: flex;
  480. box-shadow: 0 10rpx 30rpx 0 #000;
  481. .btn {
  482. width: 50%;
  483. height: 80rpx;
  484. border-radius: 0 !important;
  485. flex: 1;
  486. display: flex;
  487. justify-content: center;
  488. align-items: center;
  489. &.reset {
  490. color: $j-primary-border-green;
  491. }
  492. &.search {
  493. color: #fff;
  494. background-color: $j-primary-border-green;
  495. }
  496. }
  497. }
  498. .title {
  499. font-weight: bold;
  500. font-size: 30rpx;
  501. }
  502. .status-wrapper {
  503. display: flex;
  504. align-items: center;
  505. justify-content: space-between;
  506. view {
  507. background-color: rgba(242, 242, 242, 1);
  508. height: 60rpx;
  509. border-radius: 30rpx;
  510. line-height: 60rpx;
  511. text-align: center;
  512. width: 160rpx;
  513. border: 1rpx solid rgba(242, 242, 242, 1);
  514. &.active {
  515. color: #157a2c;
  516. border-color: rgba(21, 122, 44, 1);
  517. }
  518. }
  519. }
  520. /deep/.uni-date {
  521. .uni-icons {
  522. display: none;
  523. }
  524. .uni-date-x {
  525. padding: 0;
  526. view {
  527. margin: 0 20rpx;
  528. }
  529. }
  530. }
  531. /deep/.uni-date__x-input,
  532. /deep/.uni-easyinput__content-input {
  533. height: 60rpx;
  534. border-radius: 30rpx;
  535. overflow: hidden;
  536. background-color: rgba(242, 242, 242, 1);
  537. }
  538. }
  539. </style>