index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. <!--
  2. * @Author: liuzhenlin 461480418@qq.ocm
  3. * @Date: 2023-01-10 13:40:41
  4. * @LastEditors: wanglj
  5. * @LastEditTime: 2023-03-22 11:26:48
  6. * @Description: file content
  7. * @FilePath: \opms_frontend\src\views\collection\index.vue
  8. -->
  9. <template>
  10. <div class="collection-manage">
  11. <vab-query-form>
  12. <vab-query-form-top-panel>
  13. <el-form :inline="true" label-width="0px" :model="queryForm" @submit.native.prevent>
  14. <el-form-item prop="contractCode">
  15. <el-input
  16. v-model="queryForm.contractCode"
  17. clearable
  18. placeholder="合同编号"
  19. @keyup.enter.native="queryData" />
  20. </el-form-item>
  21. <el-form-item prop="custId">
  22. <el-input
  23. v-model="queryForm.custName"
  24. class="customer-input"
  25. clearable
  26. placeholder="客户名称"
  27. @keyup.enter.native="queryData" />
  28. </el-form-item>
  29. <el-form-item prop="custId">
  30. <el-select v-model="queryForm.approStatus" class="status-select" clearable placeholder="审核状态">
  31. <el-option v-for="item in approStatusOption" :key="item.id" :label="item.label" :value="item.id" />
  32. </el-select>
  33. </el-form-item>
  34. <el-form-item prop="inchargeName">
  35. <el-input
  36. v-model="queryForm.inchargeName"
  37. clearable
  38. placeholder="销售工程师"
  39. @keyup.enter.native="queryData" />
  40. </el-form-item>
  41. <el-form-item prop="custProvince">
  42. <el-select
  43. v-model="queryForm.custProvince"
  44. class="compact-select"
  45. clearable
  46. placeholder="所在省"
  47. value-key="id">
  48. <el-option v-for="item in provinceOptions" :key="item.id" :label="item.distName" :value="item" />
  49. </el-select>
  50. </el-form-item>
  51. <el-form-item prop="custCity">
  52. <el-select
  53. v-model="queryForm.custCity"
  54. class="compact-select"
  55. clearable
  56. placeholder="所在市"
  57. value-key="id">
  58. <el-option
  59. v-for="item in queryForm.custProvince ? queryForm.custProvince.children : []"
  60. :key="item.id"
  61. clearable
  62. :label="item.distName"
  63. :value="item" />
  64. </el-select>
  65. </el-form-item>
  66. <el-form-item prop="filterDate">
  67. <el-date-picker
  68. v-model="queryForm.filterDate"
  69. end-placeholder="回款结束时间"
  70. range-separator="至"
  71. start-placeholder="回款开始时间"
  72. style="width: 100%"
  73. type="daterange"
  74. value-format="yyyy-MM-dd" />
  75. </el-form-item>
  76. <el-form-item>
  77. <el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
  78. </el-form-item>
  79. </el-form>
  80. </vab-query-form-top-panel>
  81. <vab-query-form-left-panel :span="12">
  82. <!-- <el-button icon="el-icon-plus" size="mini" type="primary" @click="handleEdit()">新建</el-button>
  83. <el-button icon="el-icon-delete" type="danger" @click="handleDelete()">删除</el-button> -->
  84. </vab-query-form-left-panel>
  85. <vab-query-form-right-panel :span="12">
  86. <table-tool :columns="columns" :show-columns.sync="showColumns" table-type="collectionTable" />
  87. </vab-query-form-right-panel>
  88. </vab-query-form>
  89. <el-table
  90. ref="table"
  91. v-loading="listLoading"
  92. border
  93. :data="list"
  94. :height="height"
  95. @selection-change="setSelectRows">
  96. <el-table-column align="center" show-overflow-tooltip type="selection" />
  97. <el-table-column
  98. v-for="(item, index) in showColumns"
  99. :key="index"
  100. align="center"
  101. :label="item.label"
  102. :min-width="item.width"
  103. :prop="item.prop"
  104. show-overflow-tooltip
  105. :sortable="item.sortable">
  106. <template #default="{ row }">
  107. <el-button v-if="item.prop === 'custName'" class="link-button" type="text" @click="handleCustDetail(row)">
  108. {{ row.custName }}
  109. </el-button>
  110. <el-button
  111. v-else-if="item.prop === 'contractCode'"
  112. class="link-button"
  113. type="text"
  114. @click="handleContractDetail(row)">
  115. {{ row.contractCode }}
  116. </el-button>
  117. <span v-else-if="item.prop == 'collectionType'">
  118. {{ selectDictLabel(collectionTypeOption, row.collectionType) }}
  119. </span>
  120. <span v-else-if="item.prop == 'approStatus'">{{ row.approStatus == '10' ? '未回款' : '已回款' }}</span>
  121. <span v-else-if="item.prop == 'updatedTime'">{{ parseTime(row.updatedTime, '{y}-{m}-{d}') }}</span>
  122. <span v-else-if="item.prop == 'createdTime'">{{ parseTime(row.createdTime, '{y}-{m}-{d}') }}</span>
  123. <span v-else-if="item.prop == 'contractAmount'">{{ formatPrice(row.contractAmount) }}</span>
  124. <span v-else-if="item.prop == 'collectionAmount'">{{ formatPrice(row.collectionAmount) }}</span>
  125. <span v-else>{{ row[item.prop] }}</span>
  126. </template>
  127. </el-table-column>
  128. <!-- <el-table-column align="center" label="操作">
  129. <template slot-scope="scope">
  130. <el-button type="text" @click="handleDelete(scope.row)">删除</el-button>
  131. </template>
  132. </el-table-column> -->
  133. </el-table>
  134. <el-pagination
  135. background
  136. :current-page="queryForm.pageNum"
  137. :layout="layout"
  138. :page-size="queryForm.pageSize"
  139. :total="total"
  140. @current-change="handleCurrentChange"
  141. @size-change="handleSizeChange" />
  142. </div>
  143. </template>
  144. <script>
  145. import to from 'await-to-js'
  146. import collectionApi from '@/api/contract/collection'
  147. import TableTool from '@/components/table/TableTool'
  148. import api from '@/api/customer'
  149. export default {
  150. name: 'Collection',
  151. components: {
  152. TableTool,
  153. },
  154. data() {
  155. return {
  156. height: this.$baseTableHeight(2),
  157. approStatusOption: [
  158. { id: '10', label: '未回款' },
  159. { id: '20', label: '已回款' },
  160. ],
  161. listLoading: false,
  162. layout: 'total, sizes, prev, pager, next, jumper',
  163. list: [],
  164. total: 0,
  165. queryForm: {
  166. pageNum: 1,
  167. pageSize: 10,
  168. contractCode: '', // 合同编号
  169. contractName: '', //合同名称
  170. custName: '', // 客户名称 ()
  171. inchargeName: '', // 负责人(销售工程师)
  172. custProvinceId: 0,
  173. custProvince: null,
  174. custCityId: 0,
  175. custCity: null,
  176. filterDate: [],
  177. nboName: '', //项目名称
  178. approStatus: '', //审批状态
  179. },
  180. provinceOptions: [],
  181. collectionTypeOption: [], //回款方式
  182. selectRows: [], //选择的表格数据
  183. industryOptions: [], //客户行业
  184. // 自定义列表
  185. showColumns: [],
  186. columns: [
  187. {
  188. label: '合同编号',
  189. width: '160px',
  190. prop: 'contractCode',
  191. sortable: false,
  192. disableCheck: false,
  193. },
  194. {
  195. label: '客户名称',
  196. width: '280px',
  197. prop: 'custName',
  198. sortable: false,
  199. disableCheck: false,
  200. },
  201. {
  202. label: '合同金额',
  203. width: '120px',
  204. prop: 'contractAmount',
  205. sortable: false,
  206. disableCheck: false,
  207. },
  208. {
  209. label: '回款方式',
  210. width: '100px',
  211. prop: 'collectionType',
  212. sortable: false,
  213. disableCheck: false,
  214. },
  215. {
  216. label: '回款金额',
  217. width: '120px',
  218. prop: 'collectionAmount',
  219. sortable: false,
  220. disableCheck: false,
  221. },
  222. {
  223. label: '审核状态',
  224. width: '100px',
  225. prop: 'approStatus',
  226. sortable: false,
  227. disableCheck: false,
  228. },
  229. {
  230. label: '备注',
  231. width: 'auto',
  232. prop: 'remark',
  233. sortable: false,
  234. disableCheck: false,
  235. },
  236. {
  237. label: '回款时间',
  238. width: '100px',
  239. prop: 'collectionDatetime',
  240. sortable: false,
  241. disableCheck: false,
  242. },
  243. {
  244. label: '销售工程师',
  245. width: '100px',
  246. prop: 'inchargeName',
  247. sortable: false,
  248. disableCheck: false,
  249. },
  250. {
  251. label: '所在省',
  252. width: '200px',
  253. prop: 'custProvince',
  254. sortable: false,
  255. disableCheck: false,
  256. },
  257. {
  258. label: '所在市',
  259. width: '100px',
  260. prop: 'custCity',
  261. sortable: false,
  262. disableCheck: false,
  263. },
  264. {
  265. label: '更新时间',
  266. width: '100px',
  267. prop: 'updatedTime',
  268. sortable: false,
  269. disableCheck: false,
  270. },
  271. {
  272. label: '创建时间',
  273. width: '100px',
  274. prop: 'createdTime',
  275. sortable: false,
  276. disableCheck: false,
  277. },
  278. {
  279. label: '创建人',
  280. width: '100px',
  281. prop: 'createdName',
  282. sortable: false,
  283. disableCheck: false,
  284. },
  285. ],
  286. }
  287. },
  288. watch: {
  289. showColumns: function () {
  290. this.$nextTick(() => this.$refs.table.doLayout())
  291. },
  292. },
  293. activated() {
  294. this.queryData()
  295. },
  296. async mounted() {
  297. await this.getOptions()
  298. let date1 = new Date()
  299. let date2 = new Date()
  300. date1 = date1.setDate(date1.getDate() - 30)
  301. date2 = date2.setDate(date2.getDate() + 30)
  302. this.queryForm.filterDate = [this.parseTime(date1, '{y}-{m}-{d}'), this.parseTime(date2, '{y}-{m}-{d}')]
  303. console.info(this.queryForm.filterDate)
  304. this.queryData()
  305. },
  306. methods: {
  307. async getOptions() {
  308. await Promise.all([api.getProvinceDetail(), this.getDicts('collection_type')])
  309. .then(([province, collectionType]) => {
  310. this.provinceOptions = province.data.list || []
  311. this.collectionTypeOption = collectionType.data.values || []
  312. })
  313. .catch((err) => console.log(err))
  314. },
  315. async queryData() {
  316. this.listLoading = true
  317. const params = { ...this.queryForm }
  318. params.custProvinceId = params.custProvince ? params.custProvince.id : 0
  319. params.custCityId = params.custCity ? params.custCity.id : 0
  320. if (this.queryForm.filterDate && this.queryForm.filterDate.length === 2) {
  321. params.collectionDatetimeStart = this.queryForm.filterDate[0]
  322. params.collectionDatetimeEnd = this.queryForm.filterDate[1]
  323. }
  324. const [err, res] = await to(collectionApi.getList(params))
  325. if (err) return (this.listLoading = false)
  326. this.list = res.data.list || []
  327. this.total = res.data.total
  328. this.listLoading = false
  329. this.$nextTick(() => this.$refs.table.doLayout())
  330. },
  331. reset() {
  332. this.queryForm = {
  333. pageNum: 1,
  334. pageSize: 10,
  335. custCode: '', // 客户编码
  336. custName: '', //客户名称
  337. inchargeName: '', // 负责人(销售工程师)
  338. custIndustry: '', // 客户行业 ()
  339. custLevel: '', //客户级别
  340. }
  341. this.queryData()
  342. },
  343. handleSizeChange(val) {
  344. this.queryForm.pageSize = val
  345. this.queryData()
  346. },
  347. handleCurrentChange(val) {
  348. this.queryForm.pageNum = val
  349. this.queryData()
  350. },
  351. setSelectRows(val) {
  352. this.selectRows = val.map((item) => item.id)
  353. },
  354. // 客户详情
  355. handleCustDetail(row) {
  356. this.$router.push({
  357. path: '/customer/detail',
  358. query: {
  359. id: row.custId,
  360. },
  361. })
  362. },
  363. // 合同详情
  364. handleContractDetail(row) {
  365. this.$router.push({
  366. path: '/contract/detail',
  367. query: {
  368. id: row.contractId,
  369. },
  370. })
  371. },
  372. // 合同删除
  373. handleDelete(row = null) {
  374. let ids = row ? [row.id] : this.selectRows
  375. if (!ids[0]) {
  376. return
  377. }
  378. this.$confirm('确认删除?', '提示', {
  379. confirmButtonText: '确定',
  380. cancelButtonText: '取消',
  381. type: 'warning',
  382. })
  383. .then(async () => {
  384. const [err, res] = await to(collectionApi.delCollection({ id: ids }))
  385. if (err) return
  386. if (res.code == 200) {
  387. this.$message({
  388. type: 'success',
  389. message: '删除成功!',
  390. })
  391. this.queryData()
  392. }
  393. })
  394. .catch(() => {})
  395. },
  396. },
  397. }
  398. </script>
  399. <style lang="scss" scoped>
  400. $base: '.collection-manage';
  401. #{$base} {
  402. height: calc(100vh - 60px - 12px * 2 - 40px);
  403. padding: 12px;
  404. background: #fff;
  405. transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1), border 0s, color 0.1s, font-size 0s;
  406. }
  407. .customer-input {
  408. width: 240px;
  409. }
  410. .status-select {
  411. width: 110px;
  412. }
  413. .compact-select {
  414. width: 90px;
  415. }
  416. </style>