list.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. <template>
  2. <div class="SippliersList">
  3. <Toptitle title="客户列表">
  4. <slot name="titleButton">
  5. <!-- <Button @click="handleSet()"
  6. type="primary"
  7. style="margin-right:10px;">新增分类</Button> -->
  8. <Upload
  9. style="display:inline"
  10. name="your_file"
  11. :show-upload-list="false"
  12. :headers="headers"
  13. :on-error="uploadError"
  14. :on-success="uploadSuccess"
  15. :action="$store.state.ip + '/api/custom_import'"
  16. >
  17. <Button type="success" ghost icon="md-exit" style="margin-right:10px;"
  18. >导入</Button
  19. >
  20. </Upload>
  21. <Button type="success" ghost icon='ios-download-outline' style="margin-right:10px;" @click='exportData()'
  22. >导出</Button
  23. >
  24. <Button
  25. type="primary"
  26. @click="handleGoPage(1, '')"
  27. style="margin-right:10px;"
  28. >新增</Button
  29. >
  30. </slot>
  31. </Toptitle>
  32. <div class="content">
  33. <div class="content_left">
  34. <Tree
  35. :data="treeData"
  36. select-node
  37. children-key="sub"
  38. style="width:100%;"
  39. @on-select-change="handleTreeSelect"
  40. class="demo-tree-render"
  41. ></Tree>
  42. </div>
  43. <div class="content_right">
  44. <div class="content_right_topform">
  45. <Form :label-width="90" :model="searchData">
  46. <FormItem label="客户编码:">
  47. <Input
  48. type="text"
  49. size="small"
  50. clearable
  51. v-model="searchData.code"
  52. style="width: 150px"
  53. placeholder="客户编码"
  54. />
  55. </FormItem>
  56. <FormItem label="客户名称:">
  57. <Input
  58. type="text"
  59. size="small"
  60. clearable
  61. v-model="searchData.title"
  62. style="width: 150px"
  63. placeholder="客户名称"
  64. />
  65. </FormItem>
  66. <FormItem label="专营业务员:">
  67. <Select
  68. v-model="searchData.service_id"
  69. size="small"
  70. clearable
  71. filterable
  72. label-in-value
  73. style="width: 150px"
  74. >
  75. <Option
  76. v-for="sitem in userList"
  77. :key="sitem.id"
  78. :label="sitem.nickname"
  79. :value="sitem.id"
  80. >
  81. </Option>
  82. </Select>
  83. </FormItem>
  84. <FormItem label="超标方案:">
  85. <Select
  86. v-model="searchData.plan_id"
  87. size="small"
  88. clearable
  89. filterable
  90. label-in-value
  91. style="width: 150px"
  92. >
  93. <Option
  94. v-for="sitem in overStandardList"
  95. :key="sitem.id"
  96. :label="sitem.title"
  97. :value="sitem.id"
  98. >
  99. </Option>
  100. </Select>
  101. </FormItem>
  102. <!-- <FormItem label="是否启用:">
  103. <Select v-model="searchData.lock"
  104. size="small"
  105. clearable
  106. style="width: 150px">
  107. <Option label='是'
  108. value="1" />
  109. <Option label='否'
  110. value="2" />
  111. </Select>
  112. </FormItem> -->
  113. <FormItem label="创建时间:">
  114. <DatePicker
  115. type="date"
  116. clearable
  117. size="small"
  118. style="width: 150px"
  119. placeholder="年/月/日"
  120. v-model="searchData.date[0]"
  121. ></DatePicker>
  122. </FormItem>
  123. <FormItem label="~">
  124. <DatePicker
  125. type="date"
  126. size="small"
  127. clearable
  128. style="width: 150px"
  129. placeholder="年/月/日"
  130. v-model="searchData.date[1]"
  131. ></DatePicker>
  132. </FormItem>
  133. <FormItem>
  134. <Button
  135. type="primary"
  136. size="small"
  137. @click="initData(searchData)"
  138. style="margin-right:10px;"
  139. >搜索</Button
  140. >
  141. </FormItem>
  142. </Form>
  143. <div class="content_right_topfrom_btn"></div>
  144. </div>
  145. <div class="content_right_content">
  146. <div class="content_right_content_table">
  147. <Table
  148. :columns="tableColumns"
  149. border
  150. :max-height="400"
  151. :loading="tableLoading"
  152. :data="tableData"
  153. >
  154. <template slot="setSlot" slot-scope="{ row, index }">
  155. <a style="margin:0 5px" @click="handleSet(2, row, index)"
  156. >编辑</a
  157. >
  158. <a style="margin:0 5px" @click="handleSet(3, row, index)"
  159. >查看</a
  160. >
  161. <a style="margin:0 5px" @click="handleSet(4, row, index)"
  162. >删除</a
  163. >
  164. </template>
  165. </Table>
  166. <div class="content_right_content_page">
  167. <Page
  168. :page-size-opts="[10, 20, 30, 40, 100]"
  169. @on-page-size-change="changeSize"
  170. @on-change="changePage"
  171. :current="pageIndex"
  172. show-total
  173. show-elevator
  174. :total="total"
  175. show-sizer
  176. :page-size="pageSize"
  177. />
  178. </div>
  179. </div>
  180. </div>
  181. </div>
  182. </div>
  183. </div>
  184. </template>
  185. <script>
  186. // 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
  187. // 例如:import 《组件名称》 from '《组件路径》';
  188. export default {
  189. name: "SippliersList",
  190. components: {},
  191. props: {},
  192. // import引入的组件需要注入到对象中才能使用
  193. data() {
  194. // 这里存放数据
  195. return {
  196. type: "",
  197. treeData: [
  198. {
  199. title: "客户分类",
  200. expand: true,
  201. sub: [],
  202. render: (h, { root, node, data }) => {
  203. return h(
  204. "span",
  205. {
  206. style: {
  207. display: "inline-block",
  208. width: "100%",
  209. },
  210. },
  211. [
  212. h("span", [
  213. h("Icon", {
  214. props: {
  215. type: "ios-folder-outline",
  216. },
  217. style: {
  218. marginRight: "8px",
  219. },
  220. }),
  221. h("span", data.title),
  222. ]),
  223. ]
  224. );
  225. },
  226. },
  227. ],
  228. buttonProps: {
  229. type: "default",
  230. size: "small",
  231. },
  232. headers: { Authorization: localStorage.getItem("token") },
  233. overStandardList: [],
  234. tableColumns: [
  235. {
  236. title: "客户编码",
  237. key: "code",
  238. align: "center",
  239. tooltip: true,
  240. resizable: true,
  241. width: 240,
  242. },
  243. {
  244. title: "客户名称",
  245. key: "title",
  246. align: "center",
  247. tooltip: true,
  248. resizable: true,
  249. width: 240,
  250. },
  251. {
  252. title: "折扣率(%)",
  253. key: "fax",
  254. align: "center",
  255. tooltip: true,
  256. resizable: true,
  257. width: 200,
  258. },
  259. {
  260. title: "专营业务员",
  261. key: "nickname",
  262. align: "center",
  263. tooltip: true,
  264. resizable: true,
  265. width: 240,
  266. },
  267. // {
  268. // title: '专营业务员', key: 'service_id', align: 'center', tooltip: true, minWidth: 140,
  269. // render: (h, params) => {
  270. // const { row } = params
  271. // let text
  272. // this.userList.forEach(element => {
  273. // (element.id == row.service_id) && (text = element.nickname)
  274. // });
  275. // return h('span', {}, text)
  276. // }
  277. // },
  278. {
  279. title: "超标方案",
  280. key: "plan_title",
  281. align: "center",
  282. tooltip: true,
  283. resizable: true,
  284. width: 240,
  285. // render: (h, params) => {
  286. // const { row } = params
  287. // let text
  288. // this.overStandardList.forEach(element => {
  289. // (element.id == row.overdraft_plan_id) && (text = element.title)
  290. // });
  291. // return h('span', {}, text)
  292. // }
  293. },
  294. {
  295. title: "是否启用",
  296. key: "lock",
  297. align: "center",
  298. resizable: true,
  299. width: 100,
  300. render: (h, params) => {
  301. const { row } = params;
  302. return h("span", {}, row.lock == 1 ? "是" : "否");
  303. },
  304. },
  305. {
  306. title: "创建时间",
  307. key: "crt_time",
  308. align: "center",
  309. tooltip: true,
  310. resizable: true,
  311. width: 240,
  312. render: (h, params) => {
  313. return h("span", {}, this.func.replaceDate(params.row.crt_time));
  314. },
  315. },
  316. // {
  317. // title: '添加时间', key: 'crt_time', align: 'center', minWidth: 120,
  318. // render: (h, params) => {
  319. // const { row } = params
  320. // return h('span', {}, this.func.replaceDate(row.crt_time))
  321. // }
  322. // },
  323. {
  324. title: "操作",
  325. key: "code",
  326. align: "center",
  327. minWidth: 170,
  328. slot: "setSlot",
  329. },
  330. ],
  331. tableData: [],
  332. tableLoading: false,
  333. pageIndex: 1,
  334. pageSize: 10,
  335. total: 0,
  336. searchData: {
  337. title: "",
  338. code: "",
  339. service_id: "",
  340. lock: "",
  341. date: [],
  342. // start_time: '',
  343. // end_time: '',
  344. },
  345. suppliersTypeTitle: "",
  346. suppliersTypeId: "",
  347. userList: [],
  348. };
  349. },
  350. // 生命周期 - 创建完成(可以访问当前this实例)
  351. created() {
  352. // 获取超标方案
  353. this.axios({ method: "get", url: "/api/overdraft_list" }).then((res) => {
  354. this.overStandardList = res.data.data;
  355. });
  356. // 获取用户列表
  357. this.axios({ method: "get", url: "/api/employee_list" }).then((res) => {
  358. this.userList = res.data.data;
  359. });
  360. // 获取客户分类列表
  361. this.axios({
  362. method: "post",
  363. url: "/api/basic_custom_list",
  364. }).then((res) => {
  365. this.treeData[0].sub = res.data;
  366. });
  367. },
  368. // 生命周期 - 挂载完成(可以访问DOM元素)
  369. mounted() {
  370. this.initData(this.searchData);
  371. },
  372. methods: {
  373. initData(row) {
  374. this.searchData.date[0]
  375. ? (this.searchData.start_time = this.func.replaceDateNoHMS(
  376. this.searchData.date[0]
  377. ))
  378. : "";
  379. this.searchData.date[1]
  380. ? (this.searchData.end_time = this.func.replaceDateNoHMS(
  381. this.searchData.date[1]
  382. ))
  383. : "";
  384. const subForm = {
  385. start_time: this.func.replaceDateNoHMS(this.searchData.date[0]) || "",
  386. end_time: this.func.replaceDateNoHMS(this.searchData.date[1]) || "",
  387. title: row.title,
  388. code: row.code,
  389. service_id: row.service_id,
  390. };
  391. this.tableLoading = true;
  392. this.axios({
  393. method: "get",
  394. url: "/api/custom_list",
  395. params: {
  396. ...subForm,
  397. page_index: this.pageIndex,
  398. page_size: this.pageSize,
  399. },
  400. })
  401. .then((res) => {
  402. this.tableLoading = false;
  403. this.total = res.data.total;
  404. this.tableData = res.data.data;
  405. })
  406. .catch((err) => {});
  407. },
  408. handleSet(type, row, index) {
  409. // 2编辑 3查看 4删除
  410. switch (type) {
  411. case 2:
  412. case 3:
  413. this.handleGoPage(type, row.id);
  414. break;
  415. case 4:
  416. this.$Modal.confirm({
  417. title: "确认删除?",
  418. content: "此操作无法恢复,请确认!",
  419. onOk: () => {
  420. this.axios({
  421. method: "post",
  422. url: "/api/custom_del",
  423. data: {
  424. id: row.id,
  425. },
  426. })
  427. .then((res) => {
  428. this.$Message.success(res.msg);
  429. this.initData(this.searchData);
  430. })
  431. .catch((err) => {});
  432. },
  433. onCancel: () => {},
  434. });
  435. break;
  436. }
  437. },
  438. append(data) {
  439. const children = data.children || [];
  440. children.push({
  441. code: this.form.code,
  442. title: this.form.title,
  443. expand: true,
  444. });
  445. this.$set(data, "children", children);
  446. },
  447. remove(root, node, data) {
  448. if (node.children && node.children.length > 0) {
  449. this.$Message.error("有子集时不可删除");
  450. } else {
  451. const parentKey = root.find((el) => el === node).parent;
  452. const parent = root.find((el) => el.nodeKey === parentKey).node;
  453. const index = parent.children.indexOf(data);
  454. parent.children.splice(index, 1);
  455. }
  456. },
  457. handleModalOk() {
  458. this.append(this.treeData[0]);
  459. },
  460. handleTreeSelect(arr, row) {
  461. this.searchData.code = row.code;
  462. this.suppliersTypeTitle = row.title;
  463. this.suppliersTypeId = row.id;
  464. this.initData(this.searchData);
  465. },
  466. uploadSuccess(res) {
  467. if (res.code == 200) {
  468. this.$Message.success(res.msg || "上传成功");
  469. } else {
  470. this.$Message.warning(res.msg || "上传失败");
  471. }
  472. this.getData(this.proxyObj);
  473. },
  474. uploadError(err) {
  475. this.$Message.error(err.msg || "上传失败");
  476. },
  477. changeSize(e) {
  478. this.pageSize = e;
  479. this.initData(this.searchData);
  480. },
  481. changePage(e) {
  482. this.pageIndex = e;
  483. this.initData(this.searchData);
  484. },
  485. handleGoPage(type, id) {
  486. // if (type == 1 && this.suppliersTypeTitle == '') {
  487. // this.$Message.warning('新增请先选择左侧客户分类!')
  488. // } else {
  489. this.$router.push({
  490. path: "/cms/BasicSettings/CustomerFiles/detail",
  491. query: {
  492. type,
  493. id,
  494. },
  495. });
  496. // }
  497. },
  498. async exportData(){
  499. const res = await this.axios('/api/custom_export')
  500. if(res.code == 200){
  501. let url = `${this.$store.state.ip}/api/storage/${res.data.file}`
  502. location.href = url
  503. }
  504. },
  505. },
  506. // 监听属性 类似于data概念
  507. computed: {},
  508. // 监控data中的数据变化
  509. watch: {},
  510. beforeCreate() {}, // 生命周期 - 创建之前
  511. beforeMount() {}, // 生命周期 - 挂载之前
  512. beforeUpdate() {}, // 生命周期 - 更新之前
  513. updated() {}, // 生命周期 - 更新之后
  514. beforeDestroy() {}, // 生命周期 - 销毁之前
  515. destroyed() {}, // 生命周期 - 销毁完成
  516. activated() {}, // 如果页面有keep-alive缓存功能,这个函数会触发
  517. };
  518. </script>
  519. <style lang="scss" scoped>
  520. .content {
  521. width: 100%;
  522. display: flex;
  523. justify-content: space-between;
  524. padding-top: 30px;
  525. .content_left {
  526. width: 15%;
  527. height: 60vh;
  528. border-right: 1px solid #515a6e;
  529. }
  530. .content_right {
  531. width: 83%;
  532. .content_right_topform {
  533. /deep/.ivu-form {
  534. display: flex;
  535. justify-content: flex-start;
  536. flex-wrap: wrap;
  537. }
  538. /deep/.ivu-form-item {
  539. display: inline-block;
  540. width: 250px;
  541. }
  542. .content_right_topfrom_btn {
  543. display: flex;
  544. justify-content: flex-end;
  545. }
  546. }
  547. .content_right_content {
  548. border-top: 1px solid #f4f4f4;
  549. margin-top: 20px;
  550. padding-top: 20px;
  551. .content_right_content_btn {
  552. display: flex;
  553. justify-content: flex-end;
  554. margin-bottom: 20px;
  555. }
  556. .content_right_content_table {
  557. }
  558. .content_right_content_page {
  559. display: flex;
  560. justify-content: center;
  561. padding-top: 20px;
  562. }
  563. }
  564. }
  565. }
  566. .demo-tree-render {
  567. width: 100%;
  568. }
  569. </style>