communicate-add-or-update.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. <template>
  2. <div>
  3. <div class="my-title">{{ !id ? "新增" : display ? "详情" : "修改" }}</div>
  4. <el-form
  5. :model="dataForm"
  6. :rules="dataRule"
  7. ref="dataForm"
  8. label-width="auto"
  9. >
  10. <el-row class="my-row">
  11. <el-col :span="6">
  12. <el-form-item label="客户名称" prop="cusId">
  13. <el-select
  14. v-model="dataForm.cusId"
  15. :disabled="display"
  16. remote
  17. placeholder="请选择"
  18. style="width: 100%"
  19. >
  20. <el-option
  21. v-for="item in optionsCus"
  22. :key="item.value"
  23. :label="item.customerName"
  24. :value="item.customerId"
  25. >
  26. </el-option>
  27. </el-select>
  28. </el-form-item>
  29. </el-col>
  30. <el-col :span="6">
  31. <el-form-item label="客户联系人" prop="contact">
  32. <el-input
  33. v-model="dataForm.contact"
  34. disabled
  35. placeholder="联系人"
  36. ></el-input>
  37. </el-form-item>
  38. </el-col>
  39. <el-col :span="6">
  40. <el-form-item label="联系电话" prop="contactTel">
  41. <el-input v-model="dataForm.contactTel" placeholder=""></el-input>
  42. </el-form-item>
  43. </el-col>
  44. <el-col :span="6">
  45. <el-form-item label="沟通方式" prop="way">
  46. <el-input v-model="dataForm.way" placeholder=""></el-input>
  47. </el-form-item>
  48. </el-col>
  49. </el-row>
  50. <el-row class="my-row">
  51. <el-col :span="6">
  52. <el-form-item label="沟通类别" prop="coType">
  53. <el-select
  54. v-model="dataForm.coType"
  55. :disabled="display"
  56. remote
  57. @change="typeChanged"
  58. placeholder="请选择"
  59. style="width: 100%"
  60. >
  61. <el-option
  62. v-for="item in options"
  63. :key="item.code"
  64. :label="item.value"
  65. :value="item.code"
  66. >
  67. </el-option>
  68. </el-select>
  69. </el-form-item>
  70. </el-col>
  71. </el-row>
  72. <el-row class="my-row">
  73. <el-col :span="12">
  74. <el-form-item label="沟通主要内容" prop="content">
  75. <el-input
  76. v-model="dataForm.content"
  77. :disabled="display"
  78. type="textarea"
  79. ></el-input>
  80. </el-form-item>
  81. </el-col>
  82. <el-col :span="12">
  83. <el-form-item label="备注">
  84. <el-input
  85. v-model="dataForm.notes"
  86. :disabled="display"
  87. type="textarea"
  88. ></el-input>
  89. </el-form-item>
  90. </el-col>
  91. </el-row>
  92. <el-row class="my-row">
  93. <el-col :span="8">
  94. <el-form-item label="技术资料" prop="attachListTechnical">
  95. <upload-component
  96. :display="display"
  97. :displayStar="false"
  98. :accept="'*'"
  99. v-model="dataForm.attachListTechnical"
  100. @uploadSuccess="uploadSuccessTechnical"
  101. />
  102. </el-form-item>
  103. </el-col>
  104. <el-col :span="8" :offset="4">
  105. <el-form-item label="数模/图纸" prop="attachListDrawing">
  106. <upload-component
  107. :display="display"
  108. :displayStar="false"
  109. :accept="'*'"
  110. v-model="dataForm.attachListDrawing"
  111. @uploadSuccess="uploadSuccessDrawing"
  112. />
  113. </el-form-item>
  114. </el-col>
  115. </el-row>
  116. <el-row class="my-row">
  117. <el-col :span="8">
  118. <el-form-item label="沟通表原件" prop="attachList">
  119. <upload-component
  120. :display="display"
  121. :displayStar="false"
  122. :accept="'*'"
  123. v-model="dataForm.attachList"
  124. @uploadSuccess="uploadSuccess"
  125. />
  126. </el-form-item>
  127. </el-col>
  128. <el-col :span="8" :offset="4">
  129. <el-form-item label="其他附件" prop="attachListOther">
  130. <upload-component
  131. :display="display"
  132. :displayStar="false"
  133. :accept="'*'"
  134. v-model="dataForm.attachListOther"
  135. @uploadSuccess="uploadSuccessOther"
  136. />
  137. </el-form-item>
  138. </el-col>
  139. </el-row>
  140. <div>
  141. <div class="title">沟通物料明细</div>
  142. <el-row>
  143. <el-table :data="cusRCommProductVOS" border style="width: 100%">
  144. <el-table-column
  145. label="序号"
  146. type="index"
  147. width="50"
  148. align="center"
  149. >
  150. </el-table-column>
  151. <el-table-column
  152. prop="productName"
  153. header-align="center"
  154. align="center"
  155. min-width="120"
  156. :show-tooltip-when-overflow="true"
  157. label="物料名称"
  158. >
  159. </el-table-column>
  160. <el-table-column
  161. prop="productSpecifications"
  162. header-align="center"
  163. align="center"
  164. :show-tooltip-when-overflow="true"
  165. label="规格"
  166. >
  167. </el-table-column>
  168. <el-table-column
  169. prop="cnt"
  170. header-align="center"
  171. align="center"
  172. label="数量"
  173. >
  174. </el-table-column>
  175. <el-table-column
  176. prop="deliveryDate"
  177. header-align="center"
  178. align="center"
  179. min-width="100"
  180. width="150"
  181. label="交付日期"
  182. >
  183. </el-table-column>
  184. <!-- <el-table-column
  185. prop="price"
  186. header-align="center"
  187. align="center"
  188. min-width="100"
  189. label="含税单价"
  190. >
  191. </el-table-column>
  192. <el-table-column
  193. prop="amount"
  194. header-align="center"
  195. align="center"
  196. min-width="100"
  197. label="含税总价"
  198. >
  199. <template slot-scope="scope">
  200. <span>{{ (scope.row.cnt * scope.row.price).toFixed(1) }}</span>
  201. </template>
  202. </el-table-column>
  203. <el-table-column
  204. prop="rate"
  205. header-align="center"
  206. align="center"
  207. min-width="100"
  208. label="税率"
  209. >
  210. <template slot-scope="scope"> {{ scope.row.rate }}% </template>
  211. </el-table-column> -->
  212. <el-table-column
  213. prop="notes"
  214. header-align="center"
  215. align="center"
  216. min-width="180"
  217. :show-tooltip-when-overflow="true"
  218. label="备注"
  219. >
  220. </el-table-column>
  221. <el-table-column
  222. fixed="right"
  223. header-align="center"
  224. align="center"
  225. width="100"
  226. label="操作"
  227. >
  228. <template slot-scope="scope">
  229. <el-button
  230. type="text"
  231. size="small"
  232. @click="updateProductHandle(scope.row)"
  233. >编辑</el-button
  234. >
  235. <el-button
  236. style="color: red"
  237. type="text"
  238. size="small"
  239. @click="deleteProductHandle(scope.row.recordId)"
  240. >删除</el-button
  241. >
  242. </template>
  243. </el-table-column>
  244. </el-table>
  245. </el-row>
  246. <el-row v-if="!display" style="text-align: center; margin-top: 10px">
  247. <el-button
  248. type="primary"
  249. icon="el-icon-plus"
  250. @click="inBound"
  251. ></el-button>
  252. </el-row>
  253. </div>
  254. <div>
  255. <div class="title">任务工单派发</div>
  256. <el-row>
  257. <el-table :data="workInfoList" border style="width: 100%">
  258. <el-table-column
  259. label="序号"
  260. type="index"
  261. width="50"
  262. align="center"
  263. >
  264. </el-table-column>
  265. <el-table-column
  266. prop="taskType"
  267. header-align="center"
  268. align="center"
  269. min-width="100"
  270. width="120"
  271. label="工单类型"
  272. >
  273. <template slot-scope="scope">
  274. <span>{{
  275. taskTypeOption.findIndex((t) => t.value == scope.row.taskType) > -1
  276. ? taskTypeOption.find((t) => t.value == scope.row.taskType).label
  277. : ''
  278. }}</span>
  279. </template>
  280. </el-table-column>
  281. <el-table-column
  282. prop="taskName"
  283. header-align="center"
  284. align="center"
  285. :show-tooltip-when-overflow="true"
  286. label="工单名称"
  287. >
  288. </el-table-column>
  289. <el-table-column
  290. prop="ranks"
  291. header-align="center"
  292. align="center"
  293. width="120"
  294. label="级别"
  295. >
  296. <template slot-scope="scope">
  297. <span>{{
  298. rankTypeOption.findIndex((t) => t.value == scope.row.ranks) > -1
  299. ? rankTypeOption.find((t) => t.value == scope.row.ranks).label
  300. : ''
  301. }}</span>
  302. </template>
  303. </el-table-column>
  304. <el-table-column
  305. prop="content"
  306. header-align="center"
  307. align="center"
  308. min-width="100"
  309. label="工单内容"
  310. :show-tooltip-when-overflow="true"
  311. >
  312. </el-table-column>
  313. <el-table-column
  314. prop="receiver"
  315. header-align="center"
  316. align="center"
  317. width="150"
  318. label="任务接收人"
  319. >
  320. <template slot-scope="scope">
  321. <span>{{ scope.row.receiverName }}</span>
  322. </template>
  323. </el-table-column>
  324. <el-table-column
  325. prop="attachListVo"
  326. header-align="center"
  327. align="center"
  328. width="150"
  329. label="任务附件"
  330. >
  331. <template slot-scope="scope">
  332. <el-button
  333. :disabled="
  334. !scope.row.attachListVo || scope.row.attachListVo.length === 0
  335. "
  336. type="text"
  337. size="small"
  338. @click="attachDetails(scope.row.attachListVo)"
  339. >查看</el-button
  340. >
  341. </template>
  342. </el-table-column>
  343. <el-table-column
  344. prop="notes"
  345. header-align="center"
  346. align="center"
  347. :show-tooltip-when-overflow="true"
  348. label="备注"
  349. >
  350. </el-table-column>
  351. <el-table-column
  352. fixed="right"
  353. header-align="center"
  354. align="center"
  355. width="100"
  356. label="操作"
  357. >
  358. <template slot-scope="scope">
  359. <el-button
  360. type="text"
  361. size="small"
  362. @click="updateWorderHandle(scope.row)"
  363. >编辑</el-button
  364. >
  365. <el-button
  366. style="color: red"
  367. type="text"
  368. size="small"
  369. @click="deleteProductHandle(scope.row.recordId)"
  370. >删除</el-button
  371. >
  372. </template>
  373. </el-table-column>
  374. </el-table>
  375. </el-row>
  376. <el-row v-if="!display" style="text-align: center; margin-top: 10px">
  377. <el-button
  378. type="primary"
  379. icon="el-icon-plus"
  380. @click="worderAdd"
  381. ></el-button>
  382. </el-row>
  383. </div>
  384. </el-form>
  385. <span slot="footer" class="dialog-footer">
  386. <el-button @click="onChose">取消</el-button>
  387. <el-button v-if="!display" type="primary" @click="dataFormSubmit()"
  388. >确定</el-button
  389. >
  390. </span>
  391. <add-or-update v-if="inboundVisible" ref="inbound" @addItem="addItem" />
  392. <worder-add-or-update
  393. v-if="worderVisible"
  394. ref="worder"
  395. @submit="addWorderItem"
  396. />
  397. <attach-detail-dialog ref="attachDetail" @onChose="onChose" />
  398. </div>
  399. </template>
  400. <script>
  401. // import templateChose from '../product/template-chose'
  402. import { getCustomer, getCoDetail } from '@/api/cus'
  403. import { getDictList } from '@/api/dict'
  404. import uploadComponent from '../common/upload-component-v2'
  405. import AddOrUpdate from '../product/template-add-or-update-v2'
  406. import WorderAddOrUpdate from '../worder/add-or-update'
  407. import AttachDetailDialog from '../common/attach-detail-dialog'
  408. import { taskTypeOption, rankTypeOption } from '@/utils/enums'
  409. export default {
  410. name: 'communicate-add-or-update',
  411. components: {
  412. AddOrUpdate,
  413. uploadComponent,
  414. WorderAddOrUpdate,
  415. AttachDetailDialog
  416. },
  417. computed: {
  418. orgId: {
  419. get () {
  420. return this.$store.state.user.orgId
  421. }
  422. }
  423. },
  424. data () {
  425. return {
  426. inboundVisible: false,
  427. detailVisible: false,
  428. worderVisible: false,
  429. attachVisible: false,
  430. visible: false,
  431. display: false,
  432. dictType: 'material_type',
  433. options: [],
  434. optionsCus: [],
  435. dataList: [],
  436. attachListTechnical: [], // 技术资料
  437. attachListDrawing: [], // 数模/图纸
  438. attachList: [], // 沟通表原件
  439. attachListOther: [], // 其他附件
  440. id: 0,
  441. cusRCommProductVOS: [],
  442. workInfoList: [],
  443. dataForm: {},
  444. taskTypeOption: taskTypeOption,
  445. rankTypeOption: rankTypeOption,
  446. dataRule: {
  447. cusId: [
  448. { required: true, message: '客户名称不能为空', trigger: 'blur' }
  449. ],
  450. coType: [
  451. { required: true, message: '沟通类别不能为空', trigger: 'change' }
  452. ],
  453. contact: [
  454. { required: true, message: '联系人不能为空', trigger: 'blur' }
  455. ],
  456. contactTel: [
  457. { required: true, message: '联系电话不能为空', trigger: 'blur' }
  458. ],
  459. way: [{ required: true, message: '沟通方式不能为空', trigger: 'blur' }],
  460. content: [
  461. { required: true, message: '沟通内容不能为空', trigger: 'blur' }
  462. ]
  463. }
  464. }
  465. },
  466. watch: {
  467. 'dataForm.cusId' (value) {
  468. this.optionsCus.forEach((v) => {
  469. if (v.customerId === value) {
  470. this.dataForm.contact = v.contact
  471. }
  472. })
  473. }
  474. },
  475. methods: {
  476. onChose () {
  477. this.$emit('onChose')
  478. this.inboundVisible = false
  479. this.detailVisible = false
  480. this.worderVisible = false
  481. this.attachVisible = false
  482. },
  483. async init (id, display) {
  484. this.dataForm = {}
  485. this.cusRCommProductVOS = []
  486. this.workInfoList = []
  487. this.visible = true
  488. this.id = id || 0
  489. this.display = display
  490. // 获取沟通类别
  491. await getDictList({ type: 'communication_type' }).then(({ data }) => {
  492. if (data) {
  493. this.options = data
  494. }
  495. })
  496. await getCustomer().then(({ data }) => {
  497. if (data && data.code === '200') {
  498. this.optionsCus = data.data
  499. }
  500. })
  501. if (!id) return
  502. this.detailVisible = true
  503. await getCoDetail(this.id).then(({ data }) => {
  504. if (data && data.code === '200') {
  505. this.dataForm = data.data
  506. if (this.dataForm.coType !== '1') {
  507. this.detailVisible = false
  508. }
  509. // 附件显示
  510. if (this.dataForm.attachListTechnical) {
  511. this.dataForm.attachListTechnical.forEach((item) => {
  512. item.name = item.fileName
  513. item.id = item.url
  514. })
  515. }
  516. if (this.dataForm.attachListDrawing) {
  517. this.dataForm.attachListDrawing.forEach((item) => {
  518. item.name = item.fileName
  519. item.id = item.url
  520. })
  521. }
  522. if (this.dataForm.attachList) {
  523. this.dataForm.attachList.forEach((item) => {
  524. item.name = item.fileName
  525. item.id = item.url
  526. })
  527. }
  528. if (this.dataForm.attachListOther) {
  529. this.dataForm.attachListOther.forEach((item) => {
  530. item.name = item.fileName
  531. item.id = item.url
  532. })
  533. }
  534. if (data.data.cusRCommProductVOS) {
  535. data.data.cusRCommProductVOS.forEach((item) => {
  536. this.addItem(item)
  537. })
  538. }
  539. if (data.data.workInfoList) {
  540. data.data.workInfoList.forEach((item) => {
  541. this.addWorderItem(item)
  542. })
  543. }
  544. }
  545. })
  546. },
  547. // 表单提交
  548. dataFormSubmit () {
  549. this.$refs['dataForm'].validate((valid) => {
  550. if (valid) {
  551. // 添加附件
  552. // let fList = this.fileList
  553. // console.log('fileList = ' + fList)
  554. // if (fList.length > 0) {
  555. // this.dataForm.attachList = [];
  556. // for (let i = 0; i < fList.length; i++) {
  557. // this.dataForm.attachList.push({
  558. // fileName: fList[i].name,
  559. // url: fList[i].url,
  560. // });
  561. // }
  562. // } else {
  563. // this.$message.error("请上传文件");
  564. // return;
  565. // }
  566. // if (this.dataForm.coType === "1") {
  567. // if (this.cusRCommProductVOS.length === 0) {
  568. // this.$message.error("请选择订单产品明细");
  569. // return;
  570. // }
  571. // }
  572. this.dataForm.cusRCommProductVOS = this.cusRCommProductVOS
  573. this.dataForm.workInfoList = this.workInfoList
  574. this.$http({
  575. url: !this.id
  576. ? this.$http.adornUrl(`/biz-service/cusCommunication/save`)
  577. : this.$http.adornUrl(`/biz-service/cusCommunication/update`),
  578. method: 'post',
  579. data: this.$http.adornData({ ...this.dataForm, orgId: this.orgId })
  580. }).then(({ data }) => {
  581. if (data && data.code === '200') {
  582. this.$message({
  583. message: '操作成功',
  584. type: 'success',
  585. duration: 1500,
  586. onClose: () => {
  587. this.onChose()
  588. this.$emit('refreshDataList')
  589. }
  590. })
  591. } else {
  592. this.$message.error(data.msg)
  593. }
  594. })
  595. }
  596. })
  597. },
  598. validateField (type) {
  599. this.$refs.dataForm.validateField(type)
  600. },
  601. inBound () {
  602. this.inboundVisible = true
  603. this.$nextTick(() => {
  604. this.$refs.inbound.init(1)
  605. })
  606. },
  607. // 编辑产品项
  608. updateProductHandle (row) {
  609. this.inboundVisible = true
  610. this.$nextTick(() => {
  611. this.$refs.inbound.init(1, row)
  612. })
  613. },
  614. addItem (item) {
  615. if (!item.recordId) {
  616. item.recordId = Math.round(Math.random() * 1000000)
  617. }
  618. if (
  619. this.cusRCommProductVOS.findIndex(
  620. (item1) => item1.recordId === item.recordId
  621. ) === -1
  622. ) {
  623. this.cusRCommProductVOS.push({
  624. ...item
  625. })
  626. }
  627. },
  628. // 添加工单
  629. addWorderItem (item) {
  630. if (!item.recordId) {
  631. item.recordId = Math.round(Math.random() * 1000000)
  632. }
  633. if (
  634. this.workInfoList.findIndex(
  635. (item1) => item1.recordId === item.recordId
  636. ) === -1
  637. ) {
  638. this.workInfoList.push({ ...item })
  639. }
  640. },
  641. uploadSuccessTechnical (fileList) {
  642. this.attachListTechnical = fileList
  643. },
  644. uploadSuccessDrawing (fileList) {
  645. this.attachListDrawing = fileList
  646. },
  647. uploadSuccess (fileList) {
  648. this.attachList = fileList
  649. },
  650. uploadSuccessOther (fileList) {
  651. this.attachListOther = fileList
  652. },
  653. typeChanged (item) {
  654. this.detailVisible = item === '1'
  655. },
  656. // 删除产品项
  657. deleteProductHandle (recordId) {
  658. this.cusRCommProductVOS.splice(
  659. this.cusRCommProductVOS.findIndex((item) => item.recordId === recordId),
  660. 1
  661. )
  662. },
  663. worderAdd () {
  664. this.worderVisible = true
  665. this.$nextTick(() => {
  666. this.$refs.worder.init(0, null)
  667. })
  668. },
  669. updateWorderHandle (row) {
  670. this.worderVisible = true
  671. row.attachList = row.attachListVo
  672. this.$nextTick(() => {
  673. this.$refs.worder.init(1, row)
  674. })
  675. },
  676. attachDetails (attachList) {
  677. // attachList.forEach((item) => {
  678. // item.fileName = item.name
  679. // })
  680. this.$refs.attachDetail.init(attachList)
  681. }
  682. }
  683. }
  684. </script>
  685. <style scoped>
  686. .my-line {
  687. border-bottom: 1px solid #c0c4cc;
  688. margin-bottom: 10px;
  689. }
  690. .title {
  691. padding: 10px 0;
  692. }
  693. </style>