index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. <template>
  2. <template-page
  3. v-if="pageShow"
  4. ref="pageRef"
  5. :get-list="getList"
  6. :table-attributes="tableAttributes"
  7. :table-events="tableEvents"
  8. :options-evens-group="optionsEvensGroup"
  9. :moreParameters="moreParameters"
  10. :column-parsing="columnParsing"
  11. :exportList="exportList"
  12. :operation="operation()"
  13. key="pageType"
  14. >
  15. <div slot="moreSearch">
  16. <el-radio-group v-model="pageType" size="mini" @input="changePageType">
  17. <el-radio-button label="list">列表</el-radio-button>
  18. <el-radio-button label="goodsder">商品明细</el-radio-button>
  19. <el-radio-button label="codeder">条码明细</el-radio-button>
  20. </el-radio-group>
  21. <br /><br />
  22. </div>
  23. <div class="cartographer_big">
  24. <el-dialog
  25. :title="formDialogTitles[formDialogType]"
  26. width="100%"
  27. :modal="false"
  28. :visible.sync="formDialog"
  29. :before-close="handleClose"
  30. >
  31. <zj-page-container>
  32. <zj-page-fill>
  33. <div style="box-sizing: border-box; padding: 20px 20px 0 20px">
  34. <zj-form-container ref="formRef" :form-data="formData" :form-attributes="{ size: 'mini' }">
  35. <zj-form-module title="单据信息" label-width="100px" :form-data="formData" :form-items="formItems">
  36. </zj-form-module>
  37. <zj-form-module title="" label-width="100px" :form-data="formData" :form-items="formItems2">
  38. <el-tabs slot="header" v-model="activeName">
  39. <el-tab-pane label="商品信息" name="goodsInfo"></el-tab-pane>
  40. <el-tab-pane v-if="formDialogType > 0 && joinCode" label="条码信息" name="codeInfo"></el-tab-pane>
  41. </el-tabs>
  42. </zj-form-module>
  43. <zj-form-module
  44. v-if="formData.isPlan && formDialog"
  45. title="计划单明细"
  46. label-width="100px"
  47. :form-data="formData"
  48. :form-items="formItemsFeicTes"
  49. >
  50. </zj-form-module>
  51. </zj-form-container>
  52. </div>
  53. </zj-page-fill>
  54. <div v-if="activeName == 'goodsInfo'" style="text-align: right; box-sizing: border-box; padding: 16px 20px">
  55. <el-button v-if="formDialogType == 0" size="mini" type="primary" @click="save">保存</el-button>
  56. <el-button v-if="formDialogType == 1" size="mini" type="primary" @click="submit">提交</el-button>
  57. <el-button v-if="formDialogType == 3" size="mini" type="primary" @click="examine('OK')">审核通过</el-button>
  58. <el-button v-if="formDialogType == 3" size="mini" type="primary" @click="examine('FAIL')"
  59. >审核驳回</el-button
  60. >
  61. </div>
  62. </zj-page-container>
  63. </el-dialog>
  64. </div>
  65. <el-dialog title="计划单明细" :visible.sync="dialogVisible" width="1000px" :before-close="handleCloseTes">
  66. <div style="width: 960px; height: 680px">
  67. <template-page
  68. v-if="dialogVisible"
  69. ref="pageRefTes"
  70. :get-list="getListTes"
  71. :table-attributes="tableAttributesTes"
  72. :table-events="tableEventsTes"
  73. >
  74. </template-page>
  75. </div>
  76. <span slot="footer" class="dialog-footer">
  77. <el-button @click="dialogVisible = false">取 消</el-button>
  78. <el-button type="primary" @click="quedingtianjia">确 定</el-button>
  79. </span>
  80. </el-dialog>
  81. </template-page>
  82. </template>
  83. <script>
  84. import TemplatePage from '@/components/template/template-page-1.vue'
  85. import import_mixin from '@/components/template/import_mixin.js'
  86. import operation_mixin from '@/components/template/operation_mixin.js'
  87. import {
  88. goodsPurchaseList,
  89. goodsPurchaseListExport,
  90. goodsPurchaseItemList,
  91. goodsPurchaseItemListExport,
  92. goodsPurchaseCodeList,
  93. goodsPurchaseCodeListExport,
  94. goodsPurchaseAdd,
  95. goodsPurchaseDetail,
  96. goodsPurchaseSubmit,
  97. goodsPurchaseConfirm,
  98. goodsPurchaseDel
  99. } from '@/api/goodsPurchasedStored.js'
  100. import { goodsPlanItemList } from '@/api/purchaseSchedule.js'
  101. import form_ty from '../mixins/common_form'
  102. import storage_table from '../mixins/storage_table'
  103. import storage_goods from '../mixins/storage_goods'
  104. import storage_codes from '../mixins/storage_codes'
  105. import common from '../mixins/common_code'
  106. import jihuamingxi from '../mixins/jihuamingxi'
  107. import { delayPerform, firstPerform, intervalPerform, passivePerform, queuePerform } from 'js-perform-lock'
  108. import { required, diyRequired } from '@/components/template/rules_verify.js'
  109. export default {
  110. components: { TemplatePage },
  111. mixins: [import_mixin, operation_mixin, form_ty, storage_table, storage_goods, storage_codes, common, jihuamingxi],
  112. data() {
  113. return {
  114. dialogVisible: false,
  115. pageType: 'list',
  116. pageShow: true,
  117. // 表格属性
  118. tableAttributes: {
  119. // 启用勾选列
  120. selectColumn: false
  121. },
  122. tableAttributesTes: {
  123. // 启用勾选列
  124. selectColumn: true,
  125. reserveSelection: true,
  126. 'row-key': 'goodsPlanItemId'
  127. },
  128. tableEventsTes: {
  129. 'selection-change': this.selectionChangeTes
  130. },
  131. // 表格事件
  132. tableEvents: {
  133. 'selection-change': this.selectionChange
  134. },
  135. // 勾选选中行
  136. recordSelected: [],
  137. /** 表单变量 */
  138. formDialogType: 0,
  139. formDialogTitles: ['新增入库单', '编辑入库单', '入库单详情', '审核入库单'],
  140. formDialog: false,
  141. appraise_status: '',
  142. formData: {
  143. companyWechatId: '',
  144. companyWechatName: '',
  145. examineBy: '',
  146. examineTime: '',
  147. fileUrl: '',
  148. remark: '',
  149. status: '',
  150. submitBy: '',
  151. submitTime: '',
  152. totalAmount: 0,
  153. totalQty: 0,
  154. updateBy: '',
  155. updateTime: '',
  156. venderId: '',
  157. venderName: '',
  158. storageId: '',
  159. storageName: '',
  160. fileUrl: [],
  161. items: [],
  162. planItems: [],
  163. codeInfoList: [],
  164. isPlan: ''
  165. },
  166. activeName: 'goodsInfo',
  167. goods_material_id: '',
  168. joinCode: false,
  169. joinCodeText: JSON.parse(localStorage.getItem('greemall_user')).joinCode,
  170. logs: [],
  171. tesXuanXiang: []
  172. }
  173. },
  174. computed: {
  175. // 事件组合
  176. optionsEvensGroup() {
  177. if (this.pageType == 'list') {
  178. return [
  179. [
  180. [
  181. this.optionsEvensAuth('add', {
  182. click: () => {
  183. this.openForm()
  184. this.formDialog = true
  185. this.joinCode = JSON.parse(localStorage.getItem('greemall_user')).joinCode === 'CODE'
  186. }
  187. })
  188. ]
  189. ]
  190. ]
  191. } else if (this.pageType == 'goodsder') {
  192. return []
  193. } else if (this.pageType == 'codeder') {
  194. return []
  195. }
  196. },
  197. formItemsFeicTes() {
  198. return [
  199. {
  200. md: 24,
  201. isShow: true,
  202. name: 'slot-component',
  203. formItemAttributes: {
  204. label: '',
  205. prop: 'planItems',
  206. 'label-width': '0px',
  207. rules: this.formData.isPlan ? [...required] : []
  208. },
  209. render: (h, { props, onInput }) => {
  210. var { value } = props
  211. return (
  212. <div>
  213. {[
  214. !!~[0, 1].indexOf(this.formDialogType) ? (
  215. <div style="margin-bottom:10px">
  216. <el-button
  217. type="primary"
  218. onClick={() => {
  219. if (this.formData.venderId) {
  220. this.dialogVisible = true
  221. this.tesXuanXiang = []
  222. } else {
  223. this.$message({
  224. dangerouslyUseHTMLString: true,
  225. type: 'warning',
  226. message: '请选择供应商',
  227. duration: 5000
  228. })
  229. }
  230. }}
  231. >
  232. 添加
  233. </el-button>
  234. </div>
  235. ) : null,
  236. <zj-table
  237. columns={this.teshumingxi}
  238. tableData={this.formData.planItems}
  239. tableAttributes={{
  240. size: 'mini',
  241. border: true
  242. }}
  243. />
  244. ]}
  245. </div>
  246. )
  247. }
  248. }
  249. ]
  250. },
  251. // 更多参数
  252. moreParameters() {
  253. if (this.pageType == 'list') {
  254. return [
  255. {
  256. name: '状态',
  257. key: 'status',
  258. value: '',
  259. conditions: [
  260. {
  261. label: '保存',
  262. value: 'SAVE'
  263. },
  264. {
  265. label: '审核通过',
  266. value: 'OK'
  267. },
  268. // {
  269. // label: '驳回',
  270. // value: 'FAIL'
  271. // },
  272. {
  273. label: '全部',
  274. value: ''
  275. }
  276. ]
  277. }
  278. ]
  279. } else if (this.pageType == 'goodsder') {
  280. return []
  281. } else if (this.pageType == 'codeder') {
  282. return []
  283. }
  284. }
  285. },
  286. watch: {
  287. pageType() {
  288. this.handleClose()
  289. this.pageShow = false
  290. this.$nextTick(() => {
  291. this.pageShow = true
  292. })
  293. }
  294. },
  295. methods: {
  296. tishicuowu: new delayPerform(500).refactor(function (/**可接收参数**/) {
  297. if (this.logs) {
  298. var logs = Array.from(
  299. new Set(
  300. JSON.parse(JSON.stringify(this.logs)).map(item => {
  301. return `${item.index !== undefined ? '第' + (item.index + 1) + '行:' : ''}${item.errMsg}`
  302. })
  303. )
  304. )
  305. this.logs = []
  306. this.$message({
  307. dangerouslyUseHTMLString: true,
  308. type: 'warning',
  309. message: logs.join('<div/>'),
  310. duration: 5000
  311. })
  312. }
  313. }),
  314. getListTes(p, cb) {
  315. return goodsPlanItemList({
  316. ...p,
  317. params: [
  318. ...p.params,
  319. { param: 'a.vender_id', compare: '=', value: this.formData.venderId },
  320. { param: 'b.surplus_qty', compare: '>', value: '0' }
  321. ]
  322. })
  323. },
  324. handleCloseTes() {
  325. this.dialogVisible = false
  326. },
  327. selectionChangeTes(data) {
  328. this.tesXuanXiang = data
  329. },
  330. quedingtianjia() {
  331. this.tesXuanXiang.map(item => {
  332. if (!this.formData.planItems.find(v => v.goodsPlanItemId == item.goodsPlanItemId)) {
  333. this.formData.planItems.unshift({
  334. amount: '', //
  335. brandId: item.brandId,
  336. brandName: item.brandName,
  337. enginCode: item.enginCode,
  338. enginName: item.enginName,
  339. factoryNo: item.factoryNo,
  340. goodsMaterialId: item.goodsMaterialId,
  341. goodsMaterialName: item.goodsMaterialName,
  342. goodsPlanId: item.id,
  343. goodsPlanItemId: item.goodsPlanItemId,
  344. goodsPurchaseId: '', //
  345. goodsPurchasePlanItemId: '', //
  346. inStockQty: item.inStockQty,
  347. insideQty: '', //
  348. mainId: item.mainId,
  349. mainName: item.mainName,
  350. orderGoodsType: item.orderGoodsType,
  351. qty: item.qty,
  352. outQty: '', //
  353. partsQty: '', //
  354. price: '', //
  355. recQty: '', //
  356. retQty: '', //
  357. seriesName: item.seriesName,
  358. smallId: item.smallId,
  359. smallName: item.smallName,
  360. specsName: item.specsName,
  361. surplusQty: item.surplusQty,
  362. unit: item.unit
  363. })
  364. }
  365. })
  366. this.dialogVisible = false
  367. },
  368. changePageType() {
  369. this.goods_material_id = ''
  370. },
  371. // 列表请求函数
  372. getList(p, cb) {
  373. if (this.pageType == 'list') {
  374. var pam = JSON.parse(JSON.stringify(p))
  375. if (pam.status) {
  376. pam.params.push({ param: 'a.status', compare: '=', value: pam.status })
  377. }
  378. return goodsPurchaseList(pam)
  379. } else if (this.pageType == 'goodsder') {
  380. return goodsPurchaseItemList(p)
  381. } else if (this.pageType == 'codeder') {
  382. if (this.goods_material_id) {
  383. return goodsPurchaseCodeList({
  384. ...p,
  385. params: [...p.params, { param: 'b.goods_material_id', compare: '=', value: this.goods_material_id }]
  386. })
  387. } else {
  388. return goodsPurchaseCodeList(p)
  389. }
  390. }
  391. },
  392. // 列表导出函数
  393. exportList(...p) {
  394. if (this.pageType == 'list') {
  395. return goodsPurchaseListExport(...p)
  396. } else if (this.pageType == 'goodsder') {
  397. return goodsPurchaseItemListExport(...p)
  398. } else if (this.pageType == 'codeder') {
  399. return goodsPurchaseCodeListExport(...p)
  400. }
  401. },
  402. // 表格列解析渲染数据更改
  403. columnParsing(item, defaultData) {
  404. return defaultData
  405. },
  406. // 监听勾选变化
  407. selectionChange(data) {
  408. this.recordSelected = data
  409. },
  410. // 打开创建弹窗
  411. openForm() {
  412. this.isEditIndex = -1
  413. this.getGysList()
  414. this.getWarehouseList()
  415. this.getBaseList()
  416. },
  417. // 打开详情弹窗
  418. openDetailForm(row, type) {
  419. goodsPurchaseDetail({ id: row.id }).then(res => {
  420. Object.assign(this.formData, res.data, {
  421. fileUrl: res.data.fileUrl ? [{ url: res.data.fileUrl }] : [],
  422. items: res.data.items.map(item => ({ ...item, details: {} }))
  423. })
  424. this.joinCode = res.data.joinCode === 'CODE'
  425. this.formDialogType = type
  426. this.openForm()
  427. this.formDialog = true
  428. })
  429. },
  430. // 关闭弹窗
  431. handleClose() {
  432. // this.$refs?.formRef?.resetFields()
  433. this.formData = this.$options?.data()?.formData
  434. this.formDialog = false
  435. this.formDialogType = 0
  436. this.activeName = 'goodsInfo'
  437. this.joinCode = false
  438. },
  439. // 操作按钮
  440. operation() {
  441. if (this.pageType == 'list') {
  442. return this.operationBtn({
  443. edit: {
  444. conditions: ({ row, index, column }) => {
  445. return row.status == 'SAVE'
  446. },
  447. click: ({ row, index, column }) => {
  448. this.openDetailForm(row, 1)
  449. }
  450. },
  451. del: {
  452. prompt: '是否确定删除',
  453. conditions: ({ row, index, column }) => {
  454. return row.status == 'SAVE'
  455. },
  456. click: ({ row, index, column }) => {
  457. goodsPurchaseDel({
  458. id: row.id
  459. }).then(res => {
  460. this.$message({
  461. type: 'success',
  462. message: '删除成功'
  463. })
  464. this.$refs.pageRef.refreshList()
  465. })
  466. }
  467. },
  468. detail: {
  469. click: ({ row, index, column }) => {
  470. this.openDetailForm(row, 2)
  471. }
  472. },
  473. shenhe: {
  474. conditions: ({ row, index, column }) => {
  475. return row.status == 'WAIT'
  476. },
  477. click: ({ row, index, column }) => {
  478. this.openDetailForm(row, 3)
  479. }
  480. }
  481. })
  482. } else if (this.pageType == 'goodsder') {
  483. return this.operationBtn({
  484. codeDetail: {
  485. click: ({ row, index, column }) => {
  486. this.goods_material_id = row.goodsMaterialId
  487. this.pageType = 'codeder'
  488. }
  489. }
  490. })
  491. } else if (this.pageType == 'codeder') {
  492. return undefined
  493. }
  494. },
  495. // 保存
  496. save() {
  497. this.$refs.formRef.validateField(this.getVfyKey(this.isEditIndex), (valid, invalidFields, errLabels) => {
  498. if (valid && this.eidtItems()) {
  499. if (!this.formData.storageId && JSON.parse(localStorage.getItem('greemall_user')).joinCode != 'NO') {
  500. return this.$message({
  501. type: 'warning',
  502. message: '仓库不能为空'
  503. })
  504. }
  505. if (this.formData.isPlan) {
  506. try {
  507. this.formData.planItems.map((item, index) => {
  508. if (!item.recQty || item.recQty == 0) {
  509. throw new Error('')
  510. }
  511. })
  512. } catch (error) {
  513. this.$message.warning('到货数量必须填写并且大于0')
  514. return false
  515. }
  516. }
  517. goodsPurchaseAdd({
  518. ...this.formData,
  519. items: this.formData.items.map((item, index) => ({ ...item, index: index + 1 })),
  520. fileUrl: this.formData.fileUrl.map(item => item.url).join(','),
  521. codeInfoList: undefined
  522. }).then(res => {
  523. this.$message({
  524. type: 'success',
  525. message: '保存成功'
  526. })
  527. this.$refs.pageRef.refreshList()
  528. this.handleClose()
  529. })
  530. }
  531. })
  532. },
  533. // 提交
  534. submit() {
  535. goodsPurchaseSubmit({
  536. id: this.formData.id
  537. }).then(res => {
  538. this.$message({
  539. type: 'success',
  540. message: '提交成功'
  541. })
  542. this.handleClose()
  543. this.$refs.pageRef.refreshList()
  544. })
  545. },
  546. // 审核
  547. examine(type) {
  548. goodsPurchaseConfirm({
  549. id: this.formData.id,
  550. statusEnum: type
  551. }).then(res => {
  552. this.$message({
  553. type: 'success',
  554. message: '操作成功'
  555. })
  556. this.handleClose()
  557. this.$refs.pageRef.refreshList()
  558. })
  559. }
  560. }
  561. }
  562. </script>
  563. <style lang="scss" scoped>
  564. .tab {
  565. padding: 20px 20px 0 20px;
  566. }
  567. ::v-deep .teshudeshangchuananniu {
  568. color: #409eff !important;
  569. }
  570. </style>