detail.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. <template>
  2. <div>
  3. <Toptitle
  4. :title="type == 1 ? '新增客户' : type == 2 ? '编辑客户' : '查看客户'"
  5. >
  6. <slot name="titleButton">
  7. <Button @click="goBack" type="primary" ghost style="margin-right:10px;"
  8. >返回</Button
  9. >
  10. <Button
  11. @click="postData"
  12. :disabled="isChecked"
  13. type="primary"
  14. style="margin-right:10px;"
  15. >保存</Button
  16. >
  17. </slot>
  18. </Toptitle>
  19. <div class="top_search">
  20. <Form :model="formData" :label-width="100" class="top_search_form">
  21. <FormItem label="客户编码:">
  22. <Input
  23. type="text"
  24. size="small"
  25. v-model="formData.code"
  26. :disabled="isChecked"
  27. placeholder="请输入客户编码"
  28. style="width: 200px"
  29. />
  30. </FormItem>
  31. <FormItem label="客户分类:">
  32. <el-cascader
  33. v-model="formData.basics_custom_id"
  34. size="small"
  35. :show-all-levels="false"
  36. :disabled="isChecked"
  37. :options="cascader_list"
  38. :props="{
  39. expandTrigger: 'hover',
  40. children: 'sub',
  41. value: 'id',
  42. label: 'title',
  43. checkStrictly: true,
  44. emitPath: false,
  45. }"
  46. @change="handleCascaderChange"
  47. ></el-cascader>
  48. </FormItem>
  49. <FormItem label="客户名称:">
  50. <Input
  51. type="text"
  52. size="small"
  53. v-model="formData.title"
  54. :disabled="isChecked"
  55. placeholder="请输入客户名称"
  56. style="width: 200px"
  57. />
  58. </FormItem>
  59. <FormItem label="折扣率(%):">
  60. <Input
  61. type="text"
  62. size="small"
  63. :disabled="isChecked"
  64. v-model="formData.fax"
  65. placeholder="请输入折扣率"
  66. style="width: 200px"
  67. >
  68. </Input>
  69. </FormItem>
  70. <FormItem label="专营业务员:">
  71. <Select
  72. v-model="formData.service_id"
  73. filterable
  74. clearable
  75. transfer
  76. :disabled="isChecked"
  77. >
  78. <Option
  79. v-for="item of userList"
  80. :key="item.id"
  81. :value="item.id"
  82. :label="item.nickname"
  83. ></Option>
  84. </Select>
  85. </FormItem>
  86. <FormItem label="超标方案:">
  87. <Select
  88. v-model="formData.overdraft_plan_id"
  89. filterable
  90. clearable
  91. transfer
  92. :disabled="isChecked"
  93. >
  94. <Option
  95. v-for="item of overStandardList"
  96. :key="item.id"
  97. :value="item.id"
  98. :label="item.title"
  99. ></Option>
  100. </Select>
  101. </FormItem>
  102. <FormItem label="是否启用:">
  103. <i-switch v-model="formData.lockState" :disabled="isChecked" />
  104. </FormItem>
  105. </Form>
  106. </div>
  107. <div class="addBtn">
  108. <Button @click="handleRuleAdd()" :disabled="isChecked" type="primary"
  109. >新增</Button
  110. >
  111. </div>
  112. <Table :columns="tableColumns" max-height="550" :data="tableData" border>
  113. <template slot="priceSet" slot-scope="{ index }">
  114. <Input
  115. :disabled="type == 3"
  116. @on-focus="openKey(index)"
  117. clearable
  118. placeholder="请输入公式"
  119. v-model="tableData[index].formula"
  120. />
  121. </template>
  122. <template slot="set" slot-scope="{ index }">
  123. <a
  124. style="margin:0 5px"
  125. :disabled="isChecked"
  126. @click="handleSet(tableData[index], index, 6)"
  127. >复制</a
  128. >
  129. <a
  130. style="margin:0 5px"
  131. :disabled="isChecked"
  132. @click="handleSet(tableData[index], index, 4)"
  133. >删除</a
  134. >
  135. <a
  136. style="margin:0 5px"
  137. :disabled="isChecked"
  138. @click="handleSet(tableData[index], index, 5)"
  139. >设为默认</a
  140. >
  141. </template>
  142. </Table>
  143. <Modal
  144. v-model="showModal"
  145. title="选择地区"
  146. @on-ok="handleModalOk"
  147. @on-cancel="showModal = false"
  148. >
  149. <div class="modal_content">
  150. <Tree
  151. :data="treeData"
  152. @on-select-change="handleSelectChange"
  153. @on-toggle-expand="handleToggleExpand"
  154. children-key="sub"
  155. style="width:100%;"
  156. class="demo-tree-render"
  157. ></Tree>
  158. </div>
  159. </Modal>
  160. </div>
  161. </template>
  162. <script>
  163. // 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
  164. // 例如:import 《组件名称》 from '《组件路径》';
  165. import KeyBoard from "../../../components/keyboard/index";
  166. export default {
  167. name: "",
  168. components: { KeyBoard },
  169. props: {},
  170. // import引入的组件需要注入到对象中才能使用
  171. data() {
  172. // 这里存放数据
  173. return {
  174. type: this.$route.query.type || null,
  175. id: this.$route.query.id || null,
  176. isChecked: this.$route.query.type == 3 ? true : false,
  177. loading: false,
  178. tableData: [],
  179. page_index: 1,
  180. total: 0,
  181. page_size: 10,
  182. formData: {
  183. lockState: true,
  184. },
  185. keyModal: false,
  186. tableColumns: [
  187. {
  188. title: "负责人",
  189. key: "service_name",
  190. align: "center",
  191. resizable: true,
  192. width: 300,
  193. render: (h, params) => {
  194. const { row, index } = params;
  195. const currencyRow = this.tableData[index];
  196. return this.type != 3
  197. ? h(
  198. "Input",
  199. {
  200. props: {
  201. value: currencyRow.service_name,
  202. placeholder: "请输入负责人",
  203. },
  204. on: {
  205. "on-change": (e) => {
  206. currencyRow.service_name = e.target.value;
  207. },
  208. },
  209. },
  210. currencyRow.service_name
  211. )
  212. : h("span", {}, currencyRow.service_name);
  213. },
  214. },
  215. {
  216. title: "手机号",
  217. key: "mobile",
  218. align: "center",
  219. resizable: true,
  220. width: 300,
  221. render: (h, params) => {
  222. const { row, index } = params;
  223. const currencyRow = this.tableData[index];
  224. return this.type != 3
  225. ? h(
  226. "Input",
  227. {
  228. props: {
  229. value: currencyRow.mobile,
  230. placeholder: "请输入手机号",
  231. },
  232. on: {
  233. "on-change": (e) => {
  234. currencyRow.mobile = e.target.value;
  235. },
  236. },
  237. },
  238. currencyRow.mobile
  239. )
  240. : h("span", {}, currencyRow.mobile);
  241. },
  242. },
  243. {
  244. title: "地区",
  245. key: "area_title",
  246. align: "center",
  247. resizable: true,
  248. width: 300,
  249. render: (h, params) => {
  250. const { row, index } = params;
  251. const currencyRow = this.tableData[index];
  252. return this.isChecked
  253. ? h("span", {}, currencyRow.area_title)
  254. : h(
  255. "a",
  256. {
  257. on: {
  258. click: () => {
  259. this.handleAreaSet(currencyRow, index);
  260. },
  261. },
  262. },
  263. currencyRow.area_title ? currencyRow.area_title : "选择地区"
  264. );
  265. },
  266. },
  267. {
  268. title: "详细地址",
  269. key: "part_id",
  270. align: "center",
  271. resizable: true,
  272. width: 400,
  273. render: (h, params) => {
  274. const { row, index } = params;
  275. const currencyRow = this.tableData[index];
  276. return this.type != 3
  277. ? h(
  278. "Input",
  279. {
  280. props: {
  281. value: currencyRow.address,
  282. placeholder: "请输入详细地址",
  283. },
  284. on: {
  285. "on-change": (e) => {
  286. currencyRow.address = e.target.value;
  287. },
  288. },
  289. },
  290. currencyRow.address
  291. )
  292. : h("span", {}, currencyRow.address);
  293. },
  294. },
  295. { title: "操作", key: "", align: "center", slot: "set", minWidth: 200 },
  296. ],
  297. treeData: [
  298. {
  299. title: "地区分类",
  300. expand: 1,
  301. contextmenu: 1,
  302. id: 0,
  303. sub: [],
  304. render: (h, { root, node, data }) => {
  305. return h(
  306. "span",
  307. {
  308. style: {
  309. display: "inline-block",
  310. width: "100%",
  311. },
  312. },
  313. [
  314. h("span", [
  315. h("Icon", {
  316. props: {
  317. type: "ios-folder-outline",
  318. },
  319. style: {
  320. marginRight: "8px",
  321. },
  322. }),
  323. h("span", data.title),
  324. ]),
  325. h(
  326. "span",
  327. {
  328. style: {
  329. display: "inline-block",
  330. float: "right",
  331. marginRight: "32px",
  332. },
  333. },
  334. []
  335. ),
  336. ]
  337. );
  338. },
  339. },
  340. ],
  341. productTypeList: [],
  342. partsList: [],
  343. attrindex: null,
  344. userList: [],
  345. overStandardList: [],
  346. showModal: false,
  347. selected: null,
  348. currencyIndex: null,
  349. cascader_list: [],
  350. };
  351. },
  352. // 生命周期 - 创建完成(可以访问当前this实例)
  353. created() {
  354. this.axios
  355. .get("/api/basics_product_index")
  356. .then((res) => {
  357. this.productTypeList = res.data.data;
  358. })
  359. .catch((err) => {
  360. console.error(err);
  361. });
  362. // 获取用户列表
  363. this.axios({ method: "get", url: "/api/employee_list" })
  364. .then((res) => {
  365. this.userList = res.data;
  366. })
  367. .catch((err) => {});
  368. // 获取超标方案
  369. this.axios({ method: "get", url: "/api/overdraft_list" })
  370. .then((res) => {
  371. this.overStandardList = res.data.data;
  372. })
  373. .catch((err) => {});
  374. // 获取地区分类列表
  375. this.axios({
  376. method: "get",
  377. url: "/api/basic_area_list",
  378. })
  379. .then((res) => {
  380. this.treeData[0].sub = res.data;
  381. })
  382. .catch((err) => {});
  383. // 获取客户分类列表
  384. this.axios({
  385. method: "post",
  386. url: "/api/basic_custom_list",
  387. })
  388. .then((res) => {
  389. this.cascader_list = res.data;
  390. })
  391. .catch((err) => {});
  392. },
  393. // 生命周期 - 挂载完成(可以访问DOM元素)
  394. mounted() {
  395. this.init();
  396. },
  397. methods: {
  398. init() {
  399. this.id &&
  400. this.axios
  401. .get("/api/custom_detail", { params: { id: this.id } })
  402. .then((res) => {
  403. this.tableData = res.data.list;
  404. this.formData = res.data.detail;
  405. this.formData.lockState = this.formData.lock == 1 ? true : false;
  406. })
  407. .catch((err) => {
  408. console.error(err);
  409. });
  410. },
  411. goBack() {
  412. this.$router.go(-1);
  413. },
  414. handleSet(row, index, type) {
  415. let temp;
  416. switch (type) {
  417. case 4:
  418. this.tableData.splice(index, 1);
  419. break;
  420. //设为默认 todo
  421. case 5:
  422. break;
  423. // 复制
  424. case 6:
  425. temp = JSON.parse(JSON.stringify(row));
  426. this.tableData.splice(index, 0, temp);
  427. break;
  428. }
  429. },
  430. handleAreaSet(row, index) {
  431. this.showModal = true;
  432. this.currencyIndex = index;
  433. },
  434. postData() {
  435. this.axios({
  436. method: "post",
  437. url: "/api/custom_edit",
  438. data: {
  439. ...this.formData,
  440. lock: this.formData.lockState ? 1 : 0,
  441. detail: this.tableData,
  442. },
  443. }).then((res) => {
  444. if (res.code == 200) {
  445. this.$Message.success(res.msg);
  446. this.goBack();
  447. }
  448. });
  449. },
  450. handleRuleAdd() {
  451. const obj = { min: null, max: null, formula: null };
  452. this.tableData.push({});
  453. },
  454. changeProduct(row, index) {
  455. this.axios
  456. .get("/api/get_part_by_basic_product", {
  457. params: { basic_product_id: row.basic_product_id },
  458. })
  459. .then((res) => {
  460. this.partsList = res.data;
  461. })
  462. .catch((err) => {
  463. console.error(err);
  464. });
  465. },
  466. handleToggleExpand(row) {},
  467. handleModalOk() {
  468. this.tableData[this.currencyIndex].area_title = this.selected.title || "";
  469. this.tableData[this.currencyIndex].basic_area_id = this.selected.id || "";
  470. this.tableData.splice(
  471. this.currencyIndex,
  472. 1,
  473. this.tableData[this.currencyIndex]
  474. );
  475. },
  476. handleSelectChange(arr, row) {
  477. if (row.sub.length > 0) {
  478. this.selected = [];
  479. } else {
  480. this.selected = row;
  481. }
  482. },
  483. handleCascaderChange(value) {},
  484. },
  485. // 监听属性 类似于data概念
  486. computed: {},
  487. // 监控data中的数据变化
  488. watch: {},
  489. beforeCreate() {}, // 生命周期 - 创建之前
  490. beforeMount() {}, // 生命周期 - 挂载之前
  491. beforeUpdate() {}, // 生命周期 - 更新之前
  492. updated() {}, // 生命周期 - 更新之后
  493. beforeDestroy() {}, // 生命周期 - 销毁之前
  494. destroyed() {}, // 生命周期 - 销毁完成
  495. activated() {}, // 如果页面有keep-alive缓存功能,这个函数会触发
  496. };
  497. </script>
  498. <style lang="scss" scoped>
  499. .top_search {
  500. padding: 20px 0;
  501. width: 100%;
  502. max-height: 150px;
  503. overflow: hidden;
  504. overflow-y: auto;
  505. .top_search_form {
  506. // width: 800px;
  507. // display: flex;
  508. // justify-content: space-around;
  509. /deep/ .ivu-form-item {
  510. display: inline-block;
  511. width: 300px;
  512. }
  513. }
  514. }
  515. .addBtn {
  516. display: flex;
  517. justify-content: flex-end;
  518. padding: 10px 0;
  519. }
  520. /deep/ .ivu-table-wrapper {
  521. overflow: visible;
  522. }
  523. /deep/.el-input {
  524. width: 200px;
  525. height: 26px;
  526. }
  527. /deep/.el-input__inner {
  528. height: 26px;
  529. line-height: 26px;
  530. }
  531. // /deep/.is-disabled {
  532. // background-color: #f3f3f3;
  533. // color: #ccc;
  534. // cursor: not-allowed;
  535. // }
  536. </style>