index.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  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-radio',
  226. options: [
  227. { label: '上架', value: 'ON' },
  228. { label: '下架', value: 'OFF' }
  229. ],
  230. attributes: {},
  231. formItemAttributes: {
  232. label: '状态',
  233. prop: 'status',
  234. rules: [...required]
  235. }
  236. },
  237. {
  238. md: 6,
  239. isShow: true,
  240. name: 'el-cascader',
  241. attributes: {
  242. style: 'width:100%',
  243. placeholder: '请输入',
  244. options: this.materialCategoryTree,
  245. 'show-all-levels': false,
  246. props: { value: 'categoryId', label: 'categoryName', children: 'child', emitPath: false },
  247. clearable: true
  248. },
  249. formItemAttributes: {
  250. label: '选择分类',
  251. prop: 'categoryId',
  252. rules: [...required]
  253. }
  254. },
  255. {
  256. md: 6,
  257. isShow: true,
  258. name: 'el-input',
  259. attributes: { placeholder: '请输入' },
  260. formItemAttributes: {
  261. label: '收费项目名称',
  262. prop: 'normName',
  263. rules: [...required]
  264. }
  265. },
  266. {
  267. md: 6,
  268. isShow: true,
  269. name: 'el-select-add',
  270. labelKey: 'dictValue',
  271. valueKey: 'dictValue',
  272. options: this.partsUnitList,
  273. attributes: { placeholder: '请选择单位', filterable: true, clearable: true },
  274. formItemAttributes: {
  275. label: '单位',
  276. prop: 'unit',
  277. rules: [...required]
  278. }
  279. },
  280. {
  281. md: 6,
  282. isShow: true,
  283. name: 'el-input',
  284. attributes: { placeholder: '请输入' },
  285. formItemAttributes: {
  286. label: '辅材代码',
  287. prop: 'normCode',
  288. rules: []
  289. }
  290. },
  291. {
  292. md: 6,
  293. isShow: true,
  294. name: 'el-input',
  295. attributes: { placeholder: '请输入' },
  296. formItemAttributes: {
  297. label: '规格型号',
  298. prop: 'specification',
  299. rules: []
  300. }
  301. },
  302. {
  303. md: 6,
  304. isShow: true,
  305. name: 'el-radio',
  306. options: [
  307. { label: '物料收费', value: 'M' },
  308. { label: '服务收费', value: 'S' }
  309. ],
  310. attributes: {},
  311. formItemAttributes: {
  312. label: '收费类型',
  313. prop: 'normType',
  314. rules: [...required]
  315. },
  316. events: {
  317. change: () => {
  318. this.formData.items = []
  319. }
  320. }
  321. },
  322. {
  323. md: 6,
  324. isShow: true,
  325. name: 'el-input',
  326. attributes: { placeholder: '请输入', type: 'number' },
  327. formItemAttributes: {
  328. label: '收费标准',
  329. prop: 'normAmount',
  330. rules: [...required]
  331. },
  332. events: {
  333. input: val => {
  334. this.formData.selfWorkerAmount = ''
  335. this.formData.outWorkerAmount = ''
  336. this.$nextTick(() => {
  337. this.formData.selfWebsitAmount = this.setNumber(
  338. this.formData.normAmount - (this.formData.selfWorkerAmount || 0)
  339. )
  340. this.formData.outWebsitAmount = this.setNumber(
  341. this.formData.normAmount - (this.formData.outWorkerAmount || 0)
  342. )
  343. })
  344. }
  345. }
  346. },
  347. {
  348. md: 6,
  349. isShow: true,
  350. name: 'slot-component',
  351. attributes: { placeholder: '请输入' },
  352. formItemAttributes: {
  353. label: '',
  354. prop: '',
  355. 'label-width': '0px'
  356. },
  357. render: (h, { props, onInput }) => {
  358. var { value } = props
  359. return <div style="color:red">注:分账金额需扣除手续费0.6%</div>
  360. }
  361. },
  362. // {
  363. // md: 6,
  364. // isShow: true,
  365. // name: 'el-input',
  366. // attributes: { placeholder: '请输入', type: 'number', disabled: !this.formData.normAmount },
  367. // formItemAttributes: {
  368. // label: '自有库存师傅(分账金额)',
  369. // prop: 'selfWorkerAmount',
  370. // rules: [...required]
  371. // },
  372. // events: {
  373. // input: val => {
  374. // if (Number(val) > this.formData.normAmount) {
  375. // this.formData.selfWorkerAmount = this.setNumber(this.formData.normAmount)
  376. // }
  377. // this.formData.selfWebsitAmount = this.setNumber(this.formData.normAmount - this.formData.selfWorkerAmount)
  378. // }
  379. // },
  380. // slots: {
  381. // append: (h, { props, onInput }) => {
  382. // return <div>元</div>
  383. // }
  384. // }
  385. // },
  386. // {
  387. // md: 6,
  388. // isShow: true,
  389. // name: 'el-input',
  390. // attributes: { placeholder: '请输入', type: 'number', disabled: !this.formData.normAmount },
  391. // formItemAttributes: {
  392. // label: '外购辅材师傅(分账金额)',
  393. // prop: 'outWorkerAmount',
  394. // rules: [...required]
  395. // },
  396. // events: {
  397. // input: val => {
  398. // if (Number(val) > this.formData.normAmount) {
  399. // this.formData.outWorkerAmount = this.setNumber(this.formData.normAmount)
  400. // }
  401. // this.formData.outWebsitAmount = this.setNumber(this.formData.normAmount - this.formData.outWorkerAmount)
  402. // }
  403. // },
  404. // slots: {
  405. // append: (h, { props, onInput }) => {
  406. // return <div>元</div>
  407. // }
  408. // }
  409. // },
  410. // {
  411. // md: 6,
  412. // isShow: true,
  413. // name: 'el-input',
  414. // attributes: { placeholder: '请输入', disabled: true, type: 'number' },
  415. // formItemAttributes: {
  416. // label: '自有库存商户(分账金额)',
  417. // prop: 'selfWebsitAmount',
  418. // rules: [...required]
  419. // },
  420. // slots: {
  421. // append: (h, { props, onInput }) => {
  422. // return <div>元</div>
  423. // }
  424. // }
  425. // },
  426. // {
  427. // md: 6,
  428. // isShow: true,
  429. // name: 'el-input',
  430. // attributes: { placeholder: '请输入', disabled: true, type: "number", },
  431. // formItemAttributes: {
  432. // label: '外购辅材商户(分账金额)',
  433. // prop: 'outWebsitAmount',
  434. // rules: [...required]
  435. // },
  436. // slots: {
  437. // append: (h, { props, onInput }) => {
  438. // return <div>元</div>
  439. // }
  440. // }
  441. // },
  442. // {
  443. // md: 6,
  444. // isShow: true,
  445. // name: 'el-input',
  446. // attributes: { placeholder: '请输入', type: 'number' },
  447. // formItemAttributes: {
  448. // label: '师傅手工费用',
  449. // prop: 'manualAmount',
  450. // rules: [...required]
  451. // }
  452. // },
  453. {
  454. md: 24,
  455. isShow: true,
  456. name: 'el-input',
  457. attributes: { placeholder: '请输入', type: 'textarea', rows: 5 },
  458. formItemAttributes: {
  459. label: '备注',
  460. prop: 'remark',
  461. rules: []
  462. }
  463. }
  464. ]
  465. },
  466. formItems2() {
  467. return [
  468. {
  469. name: 'slot-component',
  470. md: 24,
  471. formItemAttributes: {
  472. 'label-width': '0px',
  473. label: '',
  474. prop: 'items',
  475. rules: []
  476. },
  477. render: (h, { props }) => {
  478. return (
  479. <div>
  480. <div>
  481. <el-button
  482. size="mini"
  483. type="primary"
  484. onClick={() => {
  485. this.formVisible = true
  486. }}
  487. >
  488. 新增
  489. </el-button>
  490. </div>
  491. <zj-table
  492. columns={[
  493. {
  494. columnAttributes: {
  495. label: '大类名称',
  496. prop: 'parentCategoryName'
  497. }
  498. },
  499. {
  500. columnAttributes: {
  501. label: '小类名称',
  502. prop: 'goodsCategoryName'
  503. }
  504. },
  505. {
  506. columnAttributes: {
  507. label: '辅材名称',
  508. prop: 'workerGoodsName'
  509. }
  510. },
  511. {
  512. columnAttributes: {
  513. label: '单位',
  514. prop: 'salesUnit'
  515. }
  516. },
  517. {
  518. columnAttributes: {
  519. label: '辅材代码',
  520. prop: 'goodsCode'
  521. }
  522. },
  523. {
  524. columnAttributes: {
  525. label: '数量',
  526. prop: 'qty',
  527. width: 150
  528. },
  529. render: (h, { row, column, index }) => {
  530. return (
  531. <div style="padding: 0 10px">
  532. <el-input
  533. value={row[column.columnAttributes.prop]}
  534. onInput={val => {
  535. row[column.columnAttributes.prop] = val
  536. }}
  537. placeholder="请输入内容"
  538. ></el-input>
  539. </div>
  540. )
  541. }
  542. },
  543. {
  544. columnAttributes: {
  545. label: '操作',
  546. prop: ''
  547. },
  548. render: (h, { row, column, index }) => {
  549. return (
  550. <div style="padding: 0 10px">
  551. <el-button
  552. size="mini"
  553. type="text"
  554. onClick={() => {
  555. this.formData.items.splice(index, 1)
  556. }}
  557. >
  558. 删除
  559. </el-button>
  560. </div>
  561. )
  562. }
  563. }
  564. ]}
  565. table-data={this.formData.items || []}
  566. />
  567. </div>
  568. )
  569. }
  570. }
  571. ]
  572. }
  573. },
  574. methods: {
  575. // 列表请求函数
  576. getList: materialNormList,
  577. // 列表导出函数
  578. exportList: materialNormListExport,
  579. // 表格列解析渲染数据更改
  580. columnParsing(item, defaultData) {
  581. return defaultData
  582. },
  583. // 监听勾选变化
  584. selectionChange(data) {
  585. this.recordSelected = data
  586. },
  587. operation() {
  588. return this.operationBtn({
  589. edit: {
  590. click: ({ row, index, column }) => {
  591. this.openForm('edit', row.normId)
  592. }
  593. }
  594. })
  595. },
  596. openForm() {},
  597. openForm(type, id) {
  598. this.$refs.tabPage.addTab({
  599. // 对应显示的模块
  600. activeKey: type,
  601. // 唯一标识
  602. key: type,
  603. // 页签名称
  604. label: { edit: '编辑', add: '新增' }[type],
  605. // 打开时事件
  606. triggerEvent: () => {
  607. this.formCancel()
  608. this.$nextTick(() => {
  609. this.formType = type
  610. Promise.all([
  611. getTypeList({
  612. pageNum: 1,
  613. pageSize: -1,
  614. params: [
  615. { param: 'a.dict_type', compare: '=', value: `ASSIST_UNIT` },
  616. { param: 'a.status', compare: '=', value: 'ON' }
  617. ]
  618. }),
  619. materialCategoryTree({ state: 'ON' })
  620. ]).then(([res1, res2]) => {
  621. this.partsUnitList = res1.data.records
  622. this.materialCategoryTree = res2.data.filter(item => item.child && item.child.length > 0)
  623. this.formDialog = true
  624. })
  625. if (type == 'add') {
  626. this.formDialogType = 0
  627. } else if (type == 'edit') {
  628. this.formDialogType = 1
  629. materialNormDetail({ id }).then(res => {
  630. Object.assign(this.formData, res.data)
  631. })
  632. }
  633. })
  634. },
  635. // 关闭时事件
  636. closeEvent: () => {
  637. this.formCancel()
  638. }
  639. })
  640. },
  641. formCancel() {
  642. this.formVisible = false
  643. this.$refs?.formRef?.resetFields()
  644. this.$data.formData = this.$options.data().formData
  645. },
  646. formConfirm(cancel) {
  647. this.$refs.formRef.validate((valid, invalidFields, errLabels) => {
  648. if (valid) {
  649. ;[materialNormAdd, materialNormEdit][this.formDialogType](this.formData).then(res => {
  650. this.$message({ type: 'success', message: `${this.formDialogTitles[this.formDialogType]}成功!` })
  651. cancel('list')
  652. this.$refs.pageRef.refreshList()
  653. })
  654. }
  655. })
  656. },
  657. setRowStatus(type) {
  658. materialNormBatchUpdateStatus({
  659. ids: this.recordSelected.map(item => item.normId).join(','),
  660. stateEnum: type
  661. }).then(res => {
  662. this.$message({ type: 'success', message: `设置成功!` })
  663. this.$refs.pageRef.refreshList()
  664. })
  665. },
  666. setNumber(val) {
  667. return Number(val.toFixed(2))
  668. },
  669. close() {
  670. this.formVisible = false
  671. },
  672. confirm(data) {
  673. data
  674. .filter(val => !~this.formData.items.map(item => item.workerGoodsId).indexOf(val.goodsId))
  675. .map(item => {
  676. this.formData.items.push({
  677. goodsCategoryId: item.categoryId,
  678. goodsCategoryName: item.categoryName,
  679. goodsCode: item.goodsCode,
  680. salesUnit: item.salesUnit,
  681. parentCategoryId: item.parentCategoryId,
  682. parentCategoryName: item.parentCategoryName,
  683. workerGoodsId: item.goodsId,
  684. workerGoodsName: item.goodsName,
  685. qty: ''
  686. })
  687. })
  688. this.close()
  689. }
  690. }
  691. }
  692. </script>
  693. <style lang="scss" scoped></style>