index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. <template>
  2. <zj-tab-page ref="tabPage" :defaultActives="[{ key: 'list', label: $route.meta.title + '-列表', essential: true }]">
  3. <template slot-scope="{ activeKey, data }">
  4. <template-page
  5. v-if="activeKey == 'list'"
  6. ref="pageRef"
  7. :get-list="getList"
  8. :table-attributes="tableAttributes"
  9. :table-events="tableEvents"
  10. :options-evens-group="optionsEvensGroup"
  11. :moreParameters="moreParameters"
  12. :column-parsing="columnParsing"
  13. :operation="operation()"
  14. :exportList="exportList"
  15. :operationColumnWidth="80"
  16. >
  17. </template-page>
  18. <div v-if="~['add', 'edit'].indexOf(activeKey)">
  19. <div style="box-sizing: border-box; padding: 20px">
  20. <zj-form-container ref="formRef" :form-data="formData" :styleSwitch="false">
  21. <zj-form-module title="编辑" label-width="120px" :form-data="formData" :form-items="formItems">
  22. </zj-form-module>
  23. <zj-form-module
  24. v-if="formData.normType === 'M'"
  25. title="添加辅材"
  26. label-width="0px"
  27. :form-data="formData"
  28. :form-items="formItems2"
  29. >
  30. </zj-form-module>
  31. </zj-form-container>
  32. </div>
  33. <div slot="footer" style="box-sizing: border-box; padding-bottom: 20px; padding-right: 20px; text-align: right">
  34. <el-button size="mini" @click="data.removeTab()">取 消</el-button>
  35. <el-button size="mini" @click="formConfirm(data.removeTab)" type="primary">确 定</el-button>
  36. </div>
  37. <selectGoods
  38. v-if="formVisible"
  39. @close="close"
  40. @confirm="confirm"
  41. :guolvList="(formData.items || []).map(item => item.workerGoodsId)"
  42. />
  43. </div>
  44. </template>
  45. </zj-tab-page>
  46. </template>
  47. <script>
  48. import TemplatePage from '@/components/template/template-page-1.vue'
  49. import import_mixin from '@/components/template/import_mixin.js'
  50. import { required, mobileRequired, mobile } from '@/components/template/rules_verify.js'
  51. import {
  52. materialNormList,
  53. materialNormListExport,
  54. materialNormAdd,
  55. materialNormEdit,
  56. materialNormDetail,
  57. materialNormBatchUpdateStatus,
  58. materialNormImport2,
  59. materialNormImport
  60. } from '@/api/auxiliaryChargeManagement'
  61. import { materialCategoryTree } from '@/api/auxiliaryMaterialClass'
  62. import { getTypeList } from '@/api/auxiliaryFittings/attachmentProfile'
  63. import { commonTemplateDownload } from '@/api/common.js'
  64. import operation_mixin from '@/components/template/operation_mixin.js'
  65. import selectGoods from './selectGoods.vue'
  66. export default {
  67. components: { TemplatePage, selectGoods },
  68. mixins: [import_mixin, operation_mixin],
  69. data() {
  70. return {
  71. // 表格属性
  72. tableAttributes: {
  73. // 启用勾选列
  74. selectColumn: true
  75. },
  76. // 表格事件
  77. tableEvents: {
  78. 'selection-change': this.selectionChange
  79. },
  80. // 勾选选中行
  81. recordSelected: [],
  82. /** 表单变量 */
  83. formDialogType: 0,
  84. formDialogTitles: ['新增', '编辑'],
  85. formDialog: false,
  86. formData: {
  87. companyWechatName: JSON.parse(localStorage.getItem('greemall_user')).companyName,
  88. categoryId: '',
  89. companyWechatId: '',
  90. createBy: '',
  91. createTime: '',
  92. normAmount: 0,
  93. normCode: '',
  94. normId: '',
  95. normName: '',
  96. normType: '',
  97. outWebsitAmount: 0,
  98. outWorkerAmount: 0,
  99. parentCategoryId: '',
  100. remark: '',
  101. selfWebsitAmount: 0,
  102. selfWorkerAmount: 0,
  103. specification: '',
  104. status: 'ON',
  105. unit: '',
  106. manualAmount: 0,
  107. items: []
  108. },
  109. partsUnitList: [],
  110. materialCategoryTree: [],
  111. formType: 'add',
  112. formVisible: false
  113. }
  114. },
  115. computed: {
  116. // 事件组合
  117. optionsEvensGroup() {
  118. return [
  119. [
  120. [
  121. this.optionsEvensAuth('add', {
  122. click: () => {
  123. this.openForm('add')
  124. }
  125. })
  126. ],
  127. [
  128. this.optionsEvensAuth(['imp', 'template'], {
  129. name: '导入物料',
  130. click: () => {}
  131. }),
  132. this.optionsEvensAuth('imp', ({ moduleName }) => {
  133. return {
  134. name: moduleName,
  135. render: () => {
  136. return this.importButton(materialNormImport, moduleName)
  137. }
  138. }
  139. }),
  140. this.optionsEvensAuth('template', {
  141. click: () => {
  142. commonTemplateDownload({ name: '辅材收费标准模板(物料收费).xlsx' }, `辅材收费标准模板(物料收费)`)
  143. .then(res => {
  144. this.$message({
  145. message: '下载成功',
  146. type: 'success'
  147. })
  148. })
  149. .catch(err => {
  150. this.$message.error('下载失败')
  151. })
  152. }
  153. })
  154. ],
  155. [
  156. this.optionsEvensAuth(['Import', 'downloadTemplate'], {
  157. name: '导入服务',
  158. click: () => {}
  159. }),
  160. this.optionsEvensAuth('Import', ({ moduleName }) => {
  161. return {
  162. name: moduleName,
  163. render: () => {
  164. return this.importButton(materialNormImport2, moduleName)
  165. }
  166. }
  167. }),
  168. this.optionsEvensAuth('downloadTemplate', {
  169. click: () => {
  170. commonTemplateDownload({ name: '辅材收费标准模板(服务收费).xlsx' }, `辅材收费标准模板(服务收费)`)
  171. .then(res => {
  172. this.$message({
  173. message: '下载成功',
  174. type: 'success'
  175. })
  176. })
  177. .catch(err => {
  178. this.$message.error('下载失败')
  179. })
  180. }
  181. })
  182. ]
  183. ],
  184. [
  185. [
  186. this.optionsEvensAuth('batchLaunch', {
  187. click: () => {
  188. if (this.recordSelected.length) {
  189. this.setRowStatus('ON')
  190. } else {
  191. this.$message({
  192. type: 'warning',
  193. message: `请先勾选需要设置的数据!`
  194. })
  195. }
  196. }
  197. })
  198. ],
  199. [
  200. this.optionsEvensAuth('batchRemoval', {
  201. click: () => {
  202. if (this.recordSelected.length) {
  203. this.setRowStatus('OFF')
  204. } else {
  205. this.$message({
  206. type: 'warning',
  207. message: `请先勾选需要设置的数据!`
  208. })
  209. }
  210. }
  211. })
  212. ]
  213. ]
  214. ]
  215. },
  216. // 更多参数
  217. moreParameters() {
  218. return []
  219. },
  220. formItems() {
  221. return [
  222. {
  223. md: 6,
  224. isShow: true,
  225. name: 'el-input',
  226. attributes: { placeholder: '请输入', disabled: true },
  227. formItemAttributes: {
  228. label: '所属商户',
  229. prop: 'companyWechatName',
  230. rules: [...required]
  231. }
  232. },
  233. {
  234. md: 6,
  235. isShow: true,
  236. name: 'el-radio',
  237. options: [
  238. { label: '上架', value: 'ON' },
  239. { label: '下架', value: 'OFF' }
  240. ],
  241. attributes: {},
  242. formItemAttributes: {
  243. label: '状态',
  244. prop: 'status',
  245. rules: [...required]
  246. }
  247. },
  248. {
  249. md: 6,
  250. isShow: true,
  251. name: 'el-cascader',
  252. attributes: {
  253. style: 'width:100%',
  254. placeholder: '请输入',
  255. options: this.materialCategoryTree,
  256. 'show-all-levels': false,
  257. props: { value: 'categoryId', label: 'categoryName', children: 'child', emitPath: false },
  258. clearable: true
  259. },
  260. formItemAttributes: {
  261. label: '选择分类',
  262. prop: 'categoryId',
  263. rules: [...required]
  264. }
  265. },
  266. {
  267. md: 6,
  268. isShow: true,
  269. name: 'el-input',
  270. attributes: { placeholder: '请输入' },
  271. formItemAttributes: {
  272. label: '辅材名称',
  273. prop: 'normName',
  274. rules: [...required]
  275. }
  276. },
  277. {
  278. md: 6,
  279. isShow: true,
  280. name: 'el-select-add',
  281. labelKey: 'dictValue',
  282. valueKey: 'dictValue',
  283. options: this.partsUnitList,
  284. attributes: { placeholder: '请选择单位', filterable: true, clearable: true },
  285. formItemAttributes: {
  286. label: '单位',
  287. prop: 'unit',
  288. rules: [...required]
  289. }
  290. },
  291. {
  292. md: 6,
  293. isShow: true,
  294. name: 'el-input',
  295. attributes: { placeholder: '请输入' },
  296. formItemAttributes: {
  297. label: '商品代码',
  298. prop: 'normCode',
  299. rules: []
  300. }
  301. },
  302. {
  303. md: 6,
  304. isShow: true,
  305. name: 'el-input',
  306. attributes: { placeholder: '请输入' },
  307. formItemAttributes: {
  308. label: '规格型号',
  309. prop: 'specification',
  310. rules: []
  311. }
  312. },
  313. {
  314. md: 6,
  315. isShow: true,
  316. name: 'el-radio',
  317. options: [
  318. { label: '物料收费', value: 'M' },
  319. { label: '服务收费', value: 'S' }
  320. ],
  321. attributes: {},
  322. formItemAttributes: {
  323. label: '收费类型',
  324. prop: 'normType',
  325. rules: [...required]
  326. },
  327. events: {
  328. change: () => {
  329. this.formData.items = []
  330. }
  331. }
  332. },
  333. {
  334. md: 6,
  335. isShow: true,
  336. name: 'el-input',
  337. attributes: { placeholder: '请输入', type: 'number' },
  338. formItemAttributes: {
  339. label: '收费标准',
  340. prop: 'normAmount',
  341. rules: [...required]
  342. },
  343. events: {
  344. input: val => {
  345. this.formData.selfWorkerAmount = ''
  346. this.formData.outWorkerAmount = ''
  347. this.$nextTick(() => {
  348. this.formData.selfWebsitAmount = this.setNumber(
  349. this.formData.normAmount - (this.formData.selfWorkerAmount || 0)
  350. )
  351. this.formData.outWebsitAmount = this.setNumber(
  352. this.formData.normAmount - (this.formData.outWorkerAmount || 0)
  353. )
  354. })
  355. }
  356. }
  357. },
  358. {
  359. md: 6,
  360. isShow: true,
  361. name: 'slot-component',
  362. attributes: { placeholder: '请输入' },
  363. formItemAttributes: {
  364. label: '',
  365. prop: '',
  366. 'label-width': '0px'
  367. },
  368. render: (h, { props, onInput }) => {
  369. var { value } = props
  370. return <div style="color:red">注:分账金额需扣除手续费0.6%</div>
  371. }
  372. },
  373. // {
  374. // md: 6,
  375. // isShow: true,
  376. // name: 'el-input',
  377. // attributes: { placeholder: '请输入', type: 'number', disabled: !this.formData.normAmount },
  378. // formItemAttributes: {
  379. // label: '自有库存师傅(分账金额)',
  380. // prop: 'selfWorkerAmount',
  381. // rules: [...required]
  382. // },
  383. // events: {
  384. // input: val => {
  385. // if (Number(val) > this.formData.normAmount) {
  386. // this.formData.selfWorkerAmount = this.setNumber(this.formData.normAmount)
  387. // }
  388. // this.formData.selfWebsitAmount = this.setNumber(this.formData.normAmount - this.formData.selfWorkerAmount)
  389. // }
  390. // },
  391. // slots: {
  392. // append: (h, { props, onInput }) => {
  393. // return <div>元</div>
  394. // }
  395. // }
  396. // },
  397. // {
  398. // md: 6,
  399. // isShow: true,
  400. // name: 'el-input',
  401. // attributes: { placeholder: '请输入', type: 'number', disabled: !this.formData.normAmount },
  402. // formItemAttributes: {
  403. // label: '外购辅材师傅(分账金额)',
  404. // prop: 'outWorkerAmount',
  405. // rules: [...required]
  406. // },
  407. // events: {
  408. // input: val => {
  409. // if (Number(val) > this.formData.normAmount) {
  410. // this.formData.outWorkerAmount = this.setNumber(this.formData.normAmount)
  411. // }
  412. // this.formData.outWebsitAmount = this.setNumber(this.formData.normAmount - this.formData.outWorkerAmount)
  413. // }
  414. // },
  415. // slots: {
  416. // append: (h, { props, onInput }) => {
  417. // return <div>元</div>
  418. // }
  419. // }
  420. // },
  421. // {
  422. // md: 6,
  423. // isShow: true,
  424. // name: 'el-input',
  425. // attributes: { placeholder: '请输入', disabled: true, type: 'number' },
  426. // formItemAttributes: {
  427. // label: '自有库存商户(分账金额)',
  428. // prop: 'selfWebsitAmount',
  429. // rules: [...required]
  430. // },
  431. // slots: {
  432. // append: (h, { props, onInput }) => {
  433. // return <div>元</div>
  434. // }
  435. // }
  436. // },
  437. // {
  438. // md: 6,
  439. // isShow: true,
  440. // name: 'el-input',
  441. // attributes: { placeholder: '请输入', disabled: true, type: "number", },
  442. // formItemAttributes: {
  443. // label: '外购辅材商户(分账金额)',
  444. // prop: 'outWebsitAmount',
  445. // rules: [...required]
  446. // },
  447. // slots: {
  448. // append: (h, { props, onInput }) => {
  449. // return <div>元</div>
  450. // }
  451. // }
  452. // },
  453. // {
  454. // md: 6,
  455. // isShow: true,
  456. // name: 'el-input',
  457. // attributes: { placeholder: '请输入', type: 'number' },
  458. // formItemAttributes: {
  459. // label: '师傅手工费用',
  460. // prop: 'manualAmount',
  461. // rules: [...required]
  462. // }
  463. // },
  464. {
  465. md: 24,
  466. isShow: true,
  467. name: 'el-input',
  468. attributes: { placeholder: '请输入', type: 'textarea', rows: 5 },
  469. formItemAttributes: {
  470. label: '备注',
  471. prop: 'remark',
  472. rules: []
  473. }
  474. }
  475. ]
  476. },
  477. formItems2() {
  478. return [
  479. {
  480. name: 'slot-component',
  481. md: 24,
  482. formItemAttributes: {
  483. 'label-width': '0px',
  484. label: '',
  485. prop: 'items',
  486. rules: [...required]
  487. },
  488. render: (h, { props }) => {
  489. return (
  490. <div>
  491. <div>
  492. <el-button
  493. size="mini"
  494. type="primary"
  495. onClick={() => {
  496. this.formVisible = true
  497. }}
  498. >
  499. 新增
  500. </el-button>
  501. </div>
  502. <zj-table
  503. columns={[
  504. {
  505. columnAttributes: {
  506. label: '大类名称',
  507. prop: 'parentCategoryName'
  508. }
  509. },
  510. {
  511. columnAttributes: {
  512. label: '小类名称',
  513. prop: 'goodsCategoryName'
  514. }
  515. },
  516. {
  517. columnAttributes: {
  518. label: '辅材名称',
  519. prop: 'workerGoodsName'
  520. }
  521. },
  522. {
  523. columnAttributes: {
  524. label: '单位',
  525. prop: 'salesUnit'
  526. }
  527. },
  528. {
  529. columnAttributes: {
  530. label: '商品代码',
  531. prop: 'goodsCode'
  532. }
  533. },
  534. {
  535. columnAttributes: {
  536. label: '数量',
  537. prop: 'qty',
  538. width: 150
  539. },
  540. render: (h, { row, column, index }) => {
  541. return (
  542. <div style="padding: 0 10px">
  543. <el-input
  544. value={row[column.columnAttributes.prop]}
  545. onInput={val => {
  546. row[column.columnAttributes.prop] = val
  547. }}
  548. placeholder="请输入内容"
  549. ></el-input>
  550. </div>
  551. )
  552. }
  553. },
  554. {
  555. columnAttributes: {
  556. label: '操作',
  557. prop: ''
  558. },
  559. render: (h, { row, column, index }) => {
  560. return (
  561. <div style="padding: 0 10px">
  562. <el-button
  563. size="mini"
  564. type="text"
  565. onClick={() => {
  566. this.formData.items.splice(index, 1)
  567. }}
  568. >
  569. 删除
  570. </el-button>
  571. </div>
  572. )
  573. }
  574. }
  575. ]}
  576. table-data={this.formData.items || []}
  577. />
  578. </div>
  579. )
  580. }
  581. }
  582. ]
  583. }
  584. },
  585. methods: {
  586. // 列表请求函数
  587. getList: materialNormList,
  588. // 列表导出函数
  589. exportList: materialNormListExport,
  590. // 表格列解析渲染数据更改
  591. columnParsing(item, defaultData) {
  592. return defaultData
  593. },
  594. // 监听勾选变化
  595. selectionChange(data) {
  596. this.recordSelected = data
  597. },
  598. operation() {
  599. return this.operationBtn({
  600. edit: {
  601. click: ({ row, index, column }) => {
  602. this.openForm('edit', row.normId)
  603. }
  604. }
  605. })
  606. },
  607. openForm() {},
  608. openForm(type, id) {
  609. this.$refs.tabPage.addTab({
  610. // 对应显示的模块
  611. activeKey: type,
  612. // 唯一标识
  613. key: type,
  614. // 页签名称
  615. label: { edit: '编辑', add: '新增' }[type],
  616. // 打开时事件
  617. triggerEvent: () => {
  618. this.formCancel()
  619. this.$nextTick(() => {
  620. this.formType = type
  621. Promise.all([
  622. getTypeList({
  623. pageNum: 1,
  624. pageSize: -1,
  625. params: [
  626. { param: 'a.dict_type', compare: '=', value: `ASSIST_UNIT` },
  627. { param: 'a.status', compare: '=', value: 'ON' }
  628. ]
  629. }),
  630. materialCategoryTree({ state: 'ON' })
  631. ]).then(([res1, res2]) => {
  632. this.partsUnitList = res1.data.records
  633. this.materialCategoryTree = res2.data.filter(item => item.child && item.child.length > 0)
  634. this.formDialog = true
  635. })
  636. if (type == 'add') {
  637. this.formDialogType = 0
  638. } else if (type == 'edit') {
  639. this.formDialogType = 1
  640. materialNormDetail({ id }).then(res => {
  641. Object.assign(this.formData, res.data)
  642. })
  643. }
  644. })
  645. },
  646. // 关闭时事件
  647. closeEvent: () => {
  648. this.formCancel()
  649. }
  650. })
  651. },
  652. formCancel() {
  653. this.formVisible = false
  654. this.$refs?.formRef?.resetFields()
  655. this.$data.formData = this.$options.data().formData
  656. },
  657. formConfirm(cancel) {
  658. this.$refs.formRef.validate((valid, invalidFields, errLabels) => {
  659. if (valid) {
  660. ;[materialNormAdd, materialNormEdit][this.formDialogType](this.formData).then(res => {
  661. this.$message({ type: 'success', message: `${this.formDialogTitles[this.formDialogType]}成功!` })
  662. cancel('list')
  663. this.$refs.pageRef.refreshList()
  664. })
  665. }
  666. })
  667. },
  668. setRowStatus(type) {
  669. materialNormBatchUpdateStatus({
  670. ids: this.recordSelected.map(item => item.normId).join(','),
  671. stateEnum: type
  672. }).then(res => {
  673. this.$message({ type: 'success', message: `设置成功!` })
  674. this.$refs.pageRef.refreshList()
  675. })
  676. },
  677. setNumber(val) {
  678. return Number(val.toFixed(2))
  679. },
  680. close() {
  681. this.formVisible = false
  682. },
  683. confirm(data) {
  684. data
  685. .filter(val => !~this.formData.items.map(item => item.workerGoodsId).indexOf(val.goodsId))
  686. .map(item => {
  687. this.formData.items.push({
  688. goodsCategoryId: item.categoryId,
  689. goodsCategoryName: item.categoryName,
  690. goodsCode: item.goodsCode,
  691. salesUnit: item.salesUnit,
  692. parentCategoryId: item.parentCategoryId,
  693. parentCategoryName: item.parentCategoryName,
  694. workerGoodsId: item.goodsId,
  695. workerGoodsName: item.goodsName,
  696. qty: ''
  697. })
  698. })
  699. this.close()
  700. }
  701. }
  702. }
  703. </script>
  704. <style lang="scss" scoped></style>