detail.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. <template>
  2. <div class="borderless" v-loading="pageLoading">
  3. <div class="customer-head">
  4. <div class="customer-back">
  5. <el-button type="danger" style="border: none;background: none;color: red" icon="el-icon-arrow-left"
  6. @click="backToList" :loading="btnLoading">返回列表</el-button>
  7. </div>
  8. <div class="add-customer-btn">
  9. <el-button type="primary" size="small" class="el-button--small-yh" @click.stop="openEdit"
  10. v-if="disabled && !approvalStatus">编 辑
  11. </el-button>
  12. <el-button type="primary" size="small" class="el-button--small-yh" @click.stop="submit" v-if="form.status == 1">
  13. 提交
  14. </el-button>
  15. <el-dropdown style="margin-right: 8px;margin-left: 8px;">
  16. <el-button type="primary" size="small">
  17. 审核处理<i class="el-icon-arrow-down el-icon--right"></i>
  18. </el-button>
  19. <el-dropdown-menu slot="dropdown">
  20. <el-dropdown-item :disabled="form.status > 0 || approvalStatus" @click.native="pleaseCheck">请核数据
  21. </el-dropdown-item>
  22. <el-dropdown-item :disabled="!form.approvalStatus"
  23. @click.native="checkScheduleDialog = true, checkId = form.id">审核进度</el-dropdown-item>
  24. <el-dropdown-item disabled>撤销请核</el-dropdown-item>
  25. <el-dropdown-item v-if="checkDisabled && form.approvalStatus == 'S'" @click.native="openCheckDialog">审批
  26. </el-dropdown-item>
  27. </el-dropdown-menu>
  28. </el-dropdown>
  29. <el-button type="success" :disabled="!form.id" size="small" @click="copyDoc" :loading="btnLoading" v-if="false">
  30. 复制单据</el-button>
  31. <el-button type="primary" @click="editCustomer" size="small" :loading="btnLoading">保存数据</el-button>
  32. </div>
  33. </div>
  34. <div class="customer-main">
  35. <trade-card title="基础信息">
  36. <avue-form ref="form" class="trading-form" v-model="form" :option="option">
  37. <template slot-scope="{}" slot="corpNameLabel">
  38. <span style="color: #409EFF;cursor: pointer" @click.stop="khEdit">客户名称:</span>
  39. </template>
  40. <template slot-scope="{row,index}" slot="corpName">
  41. <warehous-Kh v-model="form.corpName" :zhKey="true" :disabled="disabled || approvalStatus"
  42. @getCropId="getCropId"></warehous-Kh>
  43. </template>
  44. <template slot="fromUser">
  45. <el-select v-model="form.fromUser" filterable clearable size="small" :disabled="disabled || approvalStatus">
  46. <el-option v-for="(item, index) in userList" :key="index" :label="item.realName" :value="item.id">
  47. </el-option>
  48. </el-select>
  49. </template>
  50. <template slot="toUser">
  51. <el-select v-model="form.toUser" filterable clearable size="small" :disabled="disabled || approvalStatus">
  52. <el-option v-for="(item, index) in userList" :key="index" :label="item.realName" :value="item.id">
  53. </el-option>
  54. </el-select>
  55. </template>
  56. </avue-form>
  57. </trade-card>
  58. <trade-card title="沟通记录">
  59. <avue-crud ref="crud" :data="dataList" :option="tableOption" :cell-style="cellStyle" @saveColumn="saveColumn"
  60. @resetColumn="resetColumn">
  61. <template slot="menuLeft">
  62. <el-button type="primary" icon="el-icon-plus" size="small" @click.stop="newDetails"
  63. :disabled="disabled || approvalStatus">
  64. 录入明细</el-button>
  65. <el-button type="info" icon="el-icon-printer" size="small" v-if="false">报表打印</el-button>
  66. </template>
  67. <template slot="menu" slot-scope="{ row, index }">
  68. <el-button size="small" icon="el-icon-edit" type="text" @click="rowCell(row, index)"
  69. :disabled="disabled || approvalStatus">{{
  70. row.$cellEdit ? "保存" : "修改"
  71. }}</el-button>
  72. <el-button size="small" icon="el-icon-delete" type="text" @click="rowDel(row, index)"
  73. :disabled="disabled || approvalStatus">
  74. 删除</el-button>
  75. </template>
  76. <template slot="bizDate" slot-scope="{ row, index }">
  77. <el-date-picker v-if="row.$cellEdit" v-model="row.bizDate" type="date" placeholder="选择日期" size="small"
  78. style="width: 100%" format="yyyy-MM-dd" valueFormat="yyyy-MM-dd"></el-date-picker>
  79. <span v-else>{{ row.bizDate }}</span>
  80. </template>
  81. <template slot="spId" slot-scope="{ row, index }">
  82. <el-select v-if="row.$cellEdit" v-model="row.spId" filterable clearable size="small" :disabled="disabled"
  83. @change="spIdChange(row)">
  84. <el-option v-for="(item, index) in goodsDescList" :key="index" :label="item.cname" :value="item.id">
  85. </el-option>
  86. </el-select>
  87. <span v-else>{{ row.serviceProjectName }}</span>
  88. </template>
  89. <template slot="bizContent" slot-scope="{ row, index }">
  90. <el-input v-if="row.$cellEdit" v-model="row.bizContent" size="small" placeholder="输入内容" />
  91. <span v-else>{{ row.bizContent }}</span>
  92. </template>
  93. <template slot="contacts" slot-scope="{ row, index }">
  94. <el-input v-if="row.$cellEdit" v-model="row.contacts" size="small" placeholder="输入客户联系人" />
  95. <span v-else>{{ row.contacts }}</span>
  96. </template>
  97. <template slot="tel" slot-scope="{ row, index }">
  98. <el-input v-if="row.$cellEdit" v-model="row.tel" size="small" placeholder="输入联系方式" />
  99. <span v-else>{{ row.tel }}</span>
  100. </template>
  101. <template slot="approval" slot-scope="{ row, index }">
  102. <el-switch v-model="row.approval" :disabled="!row.$cellEdit" :inactive-value="0" :active-value="1">
  103. </el-switch>
  104. </template>
  105. </avue-crud>
  106. </trade-card>
  107. <el-dialog append-to-body title="审批" class="el-dialogDeep" :visible.sync="checkDialog" width="50%"
  108. :close-on-click-modal="false" :destroy-on-close="true" :close-on-press-escape="false" v-dialog-drag>
  109. <check :checkData="checkData" :checkDetail="false" :idList="[]" @choceCheckFun="choceCheckFun">
  110. </check>
  111. </el-dialog>
  112. <el-dialog append-to-body title="审批进度" class="el-dialogDeep" :visible.sync="checkScheduleDialog" width="40%"
  113. :close-on-click-modal="false" :destroy-on-close="true" :close-on-press-escape="false" v-dialog-drag>
  114. <check-schedule :checkId="checkId" :batchNo="batchNo" @choceScheduleFun="choceScheduleFun">
  115. </check-schedule>
  116. </el-dialog>
  117. </div>
  118. </div>
  119. </template>
  120. <script>
  121. import tableOption from "./config/customerContact.json";
  122. import {
  123. isDiscount,
  124. isPercentage,
  125. micrometerFormat,
  126. IntegerFormat
  127. } from "@/util/validate";
  128. import { gainUser } from "@/api/basicData/customerInquiry";
  129. import { getUserInfo } from "@/api/system/user";
  130. import { getDeptTree } from "@/api/system/dept";
  131. import { getCurrentDate } from "@/util/date";
  132. import { dataDetail, typeSave, removeGoods, pleaseCheck, getGoodsDescList, leadsSubmit } from "@/api/standAlone/saleLeads";
  133. import { contrastObj, contrastList } from "@/util/contrastData";
  134. import check from "@/components/check/check";
  135. import checkSchedule from "@/components/check/checkSchedule";
  136. export default {
  137. name: "detail",
  138. props: {
  139. detailData: {
  140. type: Object
  141. }
  142. },
  143. components: {
  144. check,
  145. checkSchedule,
  146. },
  147. data() {
  148. const validateRemark = (rule, value, callback) => {
  149. if (this.form.status == 2 && !this.form.remarks) {
  150. callback(new Error('备注不能为空'))
  151. } else {
  152. callback()
  153. }
  154. }
  155. return {
  156. checkData: {},
  157. checkDialog: false,
  158. batchNo: '',
  159. checkId: '',
  160. checkScheduleDialog: false,
  161. approvalStatus: false,
  162. disabled: false,
  163. checkDisabled: false,
  164. pageLoading: false,
  165. btnLoading: false,
  166. form: {},
  167. option: {
  168. menuBtn: false,
  169. labelWidth: 100,
  170. column: [
  171. {
  172. label: "客户名称",
  173. prop: "corpName",
  174. rules: [
  175. {
  176. required: true,
  177. message: " ",
  178. trigger: "blur"
  179. }
  180. ],
  181. span: 8,
  182. slot: true,
  183. },
  184. {
  185. label: "客户联系人",
  186. prop: "contacts",
  187. rules: [
  188. {
  189. required: true,
  190. message: " ",
  191. trigger: "blur"
  192. }
  193. ],
  194. span: 8,
  195. slot: true,
  196. },
  197. {
  198. label: "客户电话",
  199. prop: "tel",
  200. rules: [
  201. {
  202. required: true,
  203. message: " ",
  204. trigger: "blur"
  205. }
  206. ],
  207. span: 8,
  208. slot: true,
  209. type: 'number',
  210. controls: false,
  211. mock: {
  212. type: 'number',
  213. precision: 0,
  214. },
  215. },
  216. {
  217. label: "业务内容",
  218. prop: "bizContent",
  219. rules: [
  220. {
  221. required: true,
  222. message: " ",
  223. trigger: "blur"
  224. }
  225. ],
  226. span: 8,
  227. slot: true,
  228. },
  229. {
  230. label: "业务日期",
  231. prop: "bizDate",
  232. span: 8,
  233. type: "date",
  234. format: "yyyy-MM-dd",
  235. valueFormat: "yyyy-MM-dd HH:mm:ss",
  236. rules: [
  237. {
  238. required: true,
  239. message: " ",
  240. trigger: "blur"
  241. }
  242. ]
  243. },
  244. {
  245. label: "承揽人",
  246. prop: "fromUser",
  247. rules: [
  248. {
  249. required: true,
  250. message: " ",
  251. trigger: "change"
  252. }
  253. ],
  254. span: 8,
  255. slot: true,
  256. },
  257. {
  258. label: "对接人",
  259. prop: "toUser",
  260. rules: [
  261. {
  262. required: true,
  263. message: " ",
  264. trigger: "change"
  265. }
  266. ],
  267. span: 8,
  268. slot: true,
  269. },
  270. {
  271. label: "状态",
  272. prop: "status",
  273. span: 8,
  274. type: 'select',
  275. dicData: [
  276. { label: '沟通中', value: 0 },
  277. { label: '成交', value: 1, disabled: true },
  278. { label: '未成交', value: 2 },
  279. ],
  280. rules: [
  281. {
  282. required: true,
  283. message: " ",
  284. trigger: "change"
  285. }
  286. ],
  287. },
  288. {
  289. label: "备注",
  290. prop: "remarks",
  291. type: "textarea",
  292. minRows: 2,
  293. span: 24,
  294. rules: [
  295. { validator: validateRemark, trigger: 'blur' }
  296. ]
  297. },
  298. ],
  299. },
  300. dataList: [],
  301. tableOption: {},
  302. goodsoptions: [],
  303. unitOption: [],
  304. selectionList: [],
  305. search: {},
  306. treeStyle: "height:" + (window.innerHeight - 315) + "px",
  307. goodsOption: {},
  308. loading: false,
  309. switchDialog: false, // 报表弹窗控制
  310. userList: [],
  311. dic: [],
  312. loginUser: '', // 登录人
  313. loginUserId: null,
  314. oldForm: {},
  315. oldDataList: [],
  316. goodsDescList: []
  317. }
  318. },
  319. async created() {
  320. this.$set(this.form, 'bizDate', getCurrentDate()); // 默认当前日期
  321. this.tableOption = await this.getColumnData(
  322. this.getColumnName(102),
  323. tableOption
  324. );
  325. gainUser().then(res => {
  326. this.userList = res.data.data;
  327. });
  328. getUserInfo().then(res => {
  329. this.$set(this.form, 'fromUser', res.data.data.id);
  330. this.$set(this.form, 'toUser', res.data.data.id);
  331. this.loginUser = res.data.data.realName;
  332. this.loginUserId = res.data.data.id;
  333. })
  334. getDeptTree().then(res => {
  335. this.dic = res.data.data
  336. })
  337. getGoodsDescList().then(res => {
  338. this.goodsDescList = res.data.data
  339. })
  340. this.getWorkDicts('unit').then(res => {
  341. this.unitOption = res.data.data;
  342. })
  343. if (this.detailData.query) {
  344. this.disabled = true;
  345. this.option.column.map(e => {
  346. this.$set(e, 'disabled', true)
  347. })
  348. this.queryData(this.detailData.id);
  349. } else if (this.detailData.auditId) {
  350. this.checker = true;
  351. this.batchNo = this.detailData.check.batchNo
  352. this.queryData(this.detailData.id);
  353. } else if (this.detailData.check) {
  354. this.disabled = true;
  355. this.checkDisabled = true;
  356. this.batchNo = this.detailData.check.batchNo
  357. this.option.column.map(e => {
  358. this.$set(e, 'disabled', true)
  359. })
  360. this.queryData(this.detailData.check.billId);
  361. }
  362. },
  363. filters: {
  364. IntegerFormat(num) {
  365. return IntegerFormat(num);
  366. },
  367. decimalFormat(num) {
  368. return num ? Number(num).toFixed(2) : "0.00";
  369. }
  370. },
  371. methods: {
  372. openCheckDialog() {
  373. this.checkData = this.detailData.check
  374. this.checkDialog = true;
  375. },
  376. choceCheckFun() {
  377. this.checkDialog = false;
  378. },
  379. choceScheduleFun() {
  380. this.checkScheduleDialog = false
  381. },
  382. khEdit() {
  383. this.$router.push('/basicData/customerInformation/index')
  384. },
  385. // 查询
  386. queryData(id) {
  387. this.pageLoading = true;
  388. dataDetail({ id: id }).then(res => {
  389. this.form = res.data.data;
  390. this.dataList = this.form.itemList ? this.form.itemList : [];
  391. delete this.form.itemList;
  392. this.oldForm = { ...this.form };
  393. this.oldDataList = [...this.dataList];
  394. this.approvalStatus = this.form.approvalStatus == "S" || this.form.approvalStatus == "A" ? true : false;
  395. if (this.form.status > 0) {
  396. this.option.column.map(e => {
  397. this.$set(e, 'disabled', true)
  398. })
  399. }
  400. }).finally(() => {
  401. this.pageLoading = false;
  402. })
  403. },
  404. pleaseCheck() {
  405. if (this.dataList.length == 0) {
  406. return this.$message.error('沟通记录为空不能提交')
  407. }
  408. for (let i = 0; i < this.dataList.length; i++) {
  409. if (!this.dataList[i].id) {
  410. return this.$message.error('沟通记录未保存不能提交')
  411. }
  412. }
  413. this.$confirm("您确定提交此次申请吗?", {
  414. confirmButtonText: "确定",
  415. cancelButtonText: "取消",
  416. type: "warning"
  417. }).then(() => {
  418. this.btnLoading = true;
  419. this.$set(this.form, 'itemList', this.dataList)
  420. const data = {
  421. ...this.form,
  422. checkType: "xsjh",
  423. url: "/saleLeads/index",
  424. pageStatus: "this.$store.getters.xsjhStatus",
  425. pageLabel: "销售机会"
  426. };
  427. pleaseCheck(data).then(res => {
  428. this.$message({ type: "success", message: '请核成功' });
  429. this.disabled = true;
  430. this.option.column.map(e => {
  431. this.$set(e, 'disabled', true)
  432. })
  433. this.queryData(this.form.id);
  434. }).finally(() => {
  435. this.btnLoading = false;
  436. })
  437. });
  438. },
  439. //返回列表
  440. backToList() {
  441. this.$emit("goBack");
  442. },
  443. // 编辑按钮触发
  444. openEdit() {
  445. this.disabled = false;
  446. },
  447. // 复制
  448. copyDoc() {
  449. this.$emit("copyOrder", this.form.id);
  450. },
  451. submit() {
  452. let data = {
  453. ...this.form,
  454. itemList: this.dataList
  455. }
  456. this.btnLoading = true;
  457. leadsSubmit(data).then(res => {
  458. this.$message.success('提交成功')
  459. // this.$message({ type: "success", message: this.form.id ? "修改成功!" : "新增成功!" });
  460. // this.queryData(res.data.data);
  461. data.corpId=res.data.data
  462. this.$router.push({
  463. path: '/workManagement/main-items/list',
  464. query: { data: data }
  465. });
  466. }).finally(() => {
  467. this.btnLoading = false;
  468. })
  469. },
  470. getCropId(row) {
  471. this.form.corpId = row
  472. },
  473. //修改提交触发
  474. editCustomer(status) {
  475. this.$refs["form"].validate((valid, done) => {
  476. done();
  477. if (valid) {
  478. this.btnLoading = true;
  479. this.$set(this.form, 'itemList', this.dataList)
  480. typeSave(this.form).then(res => {
  481. this.$message({ type: "success", message: this.form.id ? "修改成功!" : "新增成功!" });
  482. this.queryData(res.data.data);
  483. }).finally(() => {
  484. this.btnLoading = false;
  485. })
  486. } else {
  487. return false
  488. }
  489. })
  490. },
  491. cellStyle() {
  492. return "padding:0;height:40px;";
  493. },
  494. async saveColumn() {
  495. const inSave = await this.saveColumnData(
  496. this.getColumnName(102),
  497. this.tableOption
  498. );
  499. if (inSave) {
  500. this.$message.success("保存成功");
  501. //关闭窗口
  502. this.$refs.crud.$refs.dialogColumn.columnBox = false;
  503. this.$nextTick(() => {
  504. this.$refs.crud.doLayout()
  505. })
  506. }
  507. },
  508. async resetColumn() {
  509. this.tableOption = tableOption;
  510. const inSave = await this.delColumnData(
  511. this.getColumnName(102),
  512. tableOption
  513. );
  514. if (inSave) {
  515. this.$nextTick(() => {
  516. this.$refs.crud.doLayout()
  517. })
  518. this.$message.success("重置成功");
  519. //关闭窗口
  520. setTimeout(() => {
  521. this.$refs.crud.$refs.dialogColumn.columnBox = false;
  522. }, 1000);
  523. }
  524. },
  525. //录入明细
  526. newDetails() {
  527. this.$refs["form"].validate((valid, done) => {
  528. done()
  529. if (valid) {
  530. this.dataList.push({
  531. bizDate: getCurrentDate(),
  532. bizTime: getCurrentDate(),
  533. bizUserName: this.loginUser,
  534. bizUser: this.loginUserId,
  535. $cellEdit: true,
  536. })
  537. }
  538. })
  539. },
  540. rowCell(row, index) {
  541. if (row.$cellEdit == true) {
  542. this.$set(row, "$cellEdit", false);
  543. } else {
  544. this.$set(row, "$cellEdit", true);
  545. }
  546. },
  547. rowDel(row, index) {
  548. this.$confirm("确定删除数据?", {
  549. confirmButtonText: "确定",
  550. cancelButtonText: "取消",
  551. type: "warning"
  552. }).then(() => {
  553. if (row.id) {
  554. removeGoods(row.id).then(res => {
  555. this.$message({
  556. type: 'success',
  557. message: '删除成功!'
  558. })
  559. this.dataList.splice(row.$index, 1);
  560. })
  561. } else {
  562. this.$message({
  563. type: "success",
  564. message: "删除成功!"
  565. });
  566. this.dataList.splice(row.$index, 1);
  567. }
  568. });
  569. },
  570. spIdChange(row) {
  571. console.log(row)
  572. this.goodsDescList.forEach(e => {
  573. row.serviceProjectName = e.cname
  574. row.chargeProposal = e.remarks
  575. });
  576. },
  577. // 验证新旧值对比
  578. verification() {
  579. if (contrastObj(this.form, this.oldForm) ||
  580. contrastList(this.dataList, this.oldDataList)) {
  581. this.$confirm("数据发生变化未有提交记录, 是否提交?", "提示", {
  582. confirmButtonText: "确定",
  583. cancelButtonText: "取消",
  584. type: "warning"
  585. }).then(() => {
  586. this.editCustomer();
  587. }).catch(() => {
  588. return false; //取消改动数据
  589. })
  590. } else {
  591. return true;
  592. }
  593. },
  594. },
  595. }
  596. </script>
  597. <style scoped>
  598. </style>