index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. <template>
  2. <div class="user-management-container">
  3. <div class="side-layout">
  4. <div class="tree-side">
  5. <span style="font-size: 25px">招标区域</span>
  6. <el-tree
  7. ref="tree"
  8. :data="regionOptions"
  9. default-expand
  10. :default-expand-all="false"
  11. :expand-on-click-node="true"
  12. :filter-node-method="filterNode"
  13. highlight-current
  14. node-key="id"
  15. :props="defaultProps"
  16. @node-click="handleNodeClick">
  17. <span slot-scope="{ node }" class="custom-tree-node">
  18. <span>{{ node.label }}</span>
  19. <span>
  20. <i class="el-icon-more"></i>
  21. </span>
  22. </span>
  23. </el-tree>
  24. </div>
  25. <div class="tree-table">
  26. <vab-query-form>
  27. <vab-query-form-top-panel>
  28. <el-form :inline="true" :model="queryForm" @submit.native.prevent>
  29. <el-form-item>
  30. <el-input
  31. v-model.trim="queryForm.productName"
  32. clearable
  33. placeholder="产品名称"
  34. @keyup.enter.native="queryData" />
  35. </el-form-item>
  36. <el-form-item>
  37. <el-input
  38. v-model.trim="queryForm.title"
  39. clearable
  40. placeholder="招标信息标题"
  41. @keyup.enter.native="queryData" />
  42. </el-form-item>
  43. <el-form-item>
  44. <el-input
  45. v-model.trim="queryForm.bidder"
  46. clearable
  47. placeholder="中标单位"
  48. @keyup.enter.native="queryData" />
  49. </el-form-item>
  50. <el-form-item>
  51. <el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
  52. <el-button icon="el-icon-refresh-right" @click="reset">重置</el-button>
  53. </el-form-item>
  54. </el-form>
  55. </vab-query-form-top-panel>
  56. <vab-query-form-left-panel :span="12">
  57. <el-button v-permissions="['base:bid:add']" icon="el-icon-plus" type="primary" @click="addBid">
  58. 新建招标记录
  59. </el-button>
  60. <el-button
  61. v-permissions="['base:distributor:add']"
  62. icon="el-icon-plus"
  63. type="primary"
  64. @click="addDistributor">
  65. 新建经销商
  66. </el-button>
  67. </vab-query-form-left-panel>
  68. <vab-query-form-right-panel :span="12">
  69. <table-tool :columns="columns" :show-columns.sync="showColumns" table-type="collectionTable" />
  70. </vab-query-form-right-panel>
  71. </vab-query-form>
  72. <el-table
  73. :key="tableKey"
  74. ref="table"
  75. v-loading="listLoading"
  76. border
  77. :data="list"
  78. :height="$baseTableHeight(2)"
  79. @selection-change="setSelectRows">
  80. <el-table-column
  81. v-for="(item, index) in showColumns"
  82. :key="index"
  83. align="center"
  84. :label="item.label"
  85. :prop="item.prop"
  86. show-overflow-tooltip
  87. :sortable="item.sortable"
  88. :width="item.width">
  89. <template #default="{ row }">
  90. <el-button v-if="item.prop === 'title'" style="font-size: 14px" type="text" @click="handleDetail(row)">
  91. {{ row.title }}
  92. </el-button>
  93. <span v-else-if="item.prop === 'infoType'">
  94. {{ bidInfoTypeOptions[row.infoType] }}
  95. </span>
  96. <span v-else-if="item.prop === 'productLine'">
  97. {{ selectDictLabel(productLineOptions, row.productLine) }}
  98. </span>
  99. <span v-else-if="item.prop === 'status'">
  100. {{ selectDictLabel(bidStatus, row.status) }}
  101. </span>
  102. <span v-else>{{ row[item.prop] }}</span>
  103. </template>
  104. </el-table-column>
  105. <el-table-column align="center" fixed="right" label="操作" width="180px">
  106. <template slot-scope="scope">
  107. <el-button
  108. v-if="scope.row.status == '10' || scope.row.status == '40'"
  109. v-permissions="['base:bid:add']"
  110. type="text"
  111. @click="bidEdit(scope.row)">
  112. 编辑
  113. </el-button>
  114. <el-button
  115. v-if="scope.row.status == '10' || scope.row.status == '40'"
  116. v-permissions="['base:bid:delete']"
  117. type="text"
  118. @click="bidDel(scope.row)">
  119. 删除
  120. </el-button>
  121. <el-button
  122. v-if="scope.row.status == '10' || scope.row.status == '40'"
  123. v-permissions="['proj:business:add']"
  124. type="text"
  125. @click="addProjBusiness(scope.row)">
  126. 新增项目
  127. </el-button>
  128. <el-button
  129. v-if="scope.row.status == '10' || scope.row.status == '40'"
  130. type="text"
  131. @click="closeLoop(scope.row)">
  132. 闭环
  133. </el-button>
  134. </template>
  135. </el-table-column>
  136. <template #empty>
  137. <el-image class="vab-data-empty" :src="require('@/assets/empty_images/data_empty.png')" />
  138. </template>
  139. </el-table>
  140. <el-pagination
  141. background
  142. :current-page="queryForm.pageNum"
  143. :layout="layout"
  144. :page-size="queryForm.pageSize"
  145. :total="total"
  146. @current-change="handleCurrentChange"
  147. @size-change="handleSizeChange" />
  148. </div>
  149. </div>
  150. <!-- 招标信息 -->
  151. <Bid ref="bid" @bidSave="fetchData" />
  152. <!-- 项目 -->
  153. <addBusiness ref="addBusiness" />
  154. <!-- 经销商 -->
  155. <addDistributor ref="addDistributor" />
  156. <!-- 闭环 -->
  157. <closeLoopDialog ref="closeLoopDialog" @doRefesh="fetchData" />
  158. </div>
  159. </template>
  160. <script>
  161. import bidApi from '@/api/customer/bid'
  162. import regionApi from '@/api/base/region'
  163. import regionAuthApi from '@/api/base/regionAuth'
  164. import TableTool from '@/components/table/TableTool'
  165. import to from 'await-to-js'
  166. import Bid from '../components/Bid'
  167. import addBusiness from '@/views/proj/business/components/BusinessAdd'
  168. import addDistributor from '@/views/base/distributor/components/DistrEdit'
  169. import closeLoopDialog from './components/closeLoop'
  170. export default {
  171. name: 'Distributor',
  172. components: { TableTool, Bid, addBusiness, addDistributor, closeLoopDialog },
  173. data() {
  174. return {
  175. tableKey: 0,
  176. list: [],
  177. listLoading: true,
  178. layout: 'total, sizes, prev, pager, next, jumper',
  179. total: 0,
  180. selectRows: '',
  181. queryForm: {
  182. pageNum: 1,
  183. pageSize: 10,
  184. productName: '',
  185. title: '',
  186. bidder: '',
  187. custProvinceId: null,
  188. },
  189. showColumns: [],
  190. columns: [
  191. {
  192. label: '招标信息标题',
  193. width: '320px',
  194. prop: 'title',
  195. sortable: false,
  196. },
  197. {
  198. label: '招标产品名称',
  199. width: '160px',
  200. prop: 'productName',
  201. sortable: false,
  202. },
  203. {
  204. label: '发布日期',
  205. width: '160px',
  206. prop: 'publishedTime',
  207. sortable: false,
  208. },
  209. {
  210. label: '状态',
  211. width: '150px',
  212. prop: 'status',
  213. sortable: false,
  214. },
  215. {
  216. label: '预算',
  217. width: '100px',
  218. prop: 'budget',
  219. sortable: false,
  220. },
  221. {
  222. label: '产品线',
  223. width: '150px',
  224. prop: 'productLine',
  225. sortable: false,
  226. },
  227. {
  228. label: '客户名称',
  229. width: 'auto',
  230. prop: 'cuctName',
  231. sortable: false,
  232. },
  233. {
  234. label: '信息分类',
  235. width: '100px',
  236. prop: 'infoType',
  237. sortable: false,
  238. },
  239. {
  240. label: '中标单位',
  241. width: '100px',
  242. prop: 'bidder',
  243. sortable: false,
  244. },
  245. {
  246. label: '创建招标日期',
  247. width: '160px',
  248. prop: 'biddingTime',
  249. sortable: false,
  250. },
  251. {
  252. label: '闭环信息描述',
  253. width: 'auto',
  254. prop: 'closeLoopMsg',
  255. sortable: false,
  256. },
  257. {
  258. label: '渠道推进工作',
  259. width: 'auto',
  260. prop: 'channelPromotionWork',
  261. sortable: false,
  262. },
  263. {
  264. label: '客户推进工作',
  265. width: 'auto',
  266. prop: 'customerPromotionWork',
  267. sortable: false,
  268. },
  269. {
  270. label: '客户后续销售机会',
  271. width: 'auto',
  272. prop: 'customerSubsequentOpportunity',
  273. sortable: false,
  274. },
  275. {
  276. label: '备注',
  277. width: 'auto',
  278. prop: 'remark',
  279. sortable: false,
  280. disableCheck: false,
  281. },
  282. ],
  283. regionOptions: [],
  284. userSalesProvince: undefined,
  285. defaultProps: {
  286. id: 'id',
  287. children: 'children',
  288. label: 'regionDesc',
  289. },
  290. treeDefaultExpandAll: true,
  291. bidInfoTypeOptions: {},
  292. productLineOptions: [],
  293. bidStatus: [],
  294. }
  295. },
  296. watch: {
  297. showColumns: function () {
  298. this.tableKey++
  299. this.$nextTick(() => this.$refs.table.doLayout())
  300. },
  301. },
  302. activated() {
  303. this.fetchData()
  304. },
  305. created() {
  306. this.getOptions()
  307. this.fetchData()
  308. this.getRegionTree()
  309. },
  310. methods: {
  311. // 闭环
  312. closeLoop(row) {
  313. this.$refs.closeLoopDialog.init(row)
  314. },
  315. // 新建经销商
  316. addDistributor() {
  317. this.$refs['addDistributor'].showEdit()
  318. },
  319. // 新增项目
  320. addProjBusiness(row) {
  321. let bid = JSON.parse(JSON.stringify(row))
  322. this.$refs['addBusiness'].showEdit({}, bid)
  323. },
  324. // 新增
  325. addBid() {
  326. this.$refs.bid.init()
  327. },
  328. // 编辑
  329. bidEdit(row) {
  330. this.$refs.bid.init(row.id)
  331. },
  332. // 删除招标信息
  333. bidDel(row) {
  334. this.$confirm('确认删除?', '提示', {
  335. confirmButtonText: '确定',
  336. cancelButtonText: '取消',
  337. type: 'warning',
  338. })
  339. .then(async () => {
  340. const [err, res] = await to(bidApi.delete({ id: [row.id] }))
  341. if (err) return
  342. if (res.code == 200) {
  343. this.$message({
  344. type: 'success',
  345. message: '删除成功!',
  346. })
  347. this.fetchData()
  348. }
  349. })
  350. .catch((err) => {
  351. console.error(err)
  352. })
  353. },
  354. getOptions() {
  355. this.getDicts('bid_info_type').then((response) => {
  356. this.bidInfoTypeOptions = {}
  357. response.data.values.filter((i) => {
  358. this.bidInfoTypeOptions[i.key] = i.value
  359. })
  360. })
  361. this.getDicts('sys_product_line').then((response) => {
  362. this.productLineOptions = response.data.values || []
  363. })
  364. this.getDicts('bid_status').then((response) => {
  365. this.bidStatus = response.data.values || []
  366. })
  367. },
  368. async getRegionTree() {
  369. const { data: data } = await regionApi.getRegionTree({ isPermission: '1' })
  370. for (let val of data.list) {
  371. if (val.regionDesc === '其他区域') {
  372. val.regionDesc = '负责区域'
  373. this.regionOptions.unshift(val)
  374. } else {
  375. this.regionOptions.push(val)
  376. }
  377. }
  378. },
  379. async getUserSalesProvince() {
  380. const { data: data } = await regionAuthApi.getUserSalesProvince({})
  381. if (data && data.list) {
  382. this.regionOptions.unshift(data.list)
  383. }
  384. },
  385. // 筛选节点
  386. filterNode(value, data) {
  387. if (!value) return true
  388. return data[this.defaultProps.label].indexOf(value) !== -1
  389. },
  390. // 节点单击事件
  391. handleNodeClick(data) {
  392. if (data.children && data.children.length) {
  393. this.queryForm.custProvinceId = data.children.map((item) => item.regionCode)
  394. } else {
  395. this.queryForm.custProvinceId = [data.regionCode]
  396. }
  397. this.fetchData()
  398. },
  399. setSelectRows(val) {
  400. this.selectRows = val
  401. },
  402. handleDelete(row) {
  403. if (row.id) {
  404. this.$baseConfirm('你确定要删除当前项吗', null, async () => {
  405. const { msg } = await bidApi.delete({ ids: [row.id] })
  406. this.$baseMessage(msg, 'success', 'vab-hey-message-success')
  407. await this.fetchData()
  408. })
  409. } else {
  410. if (this.selectRows.length > 0) {
  411. const ids = this.selectRows.map((item) => parseInt(item.id))
  412. console.log(ids)
  413. this.$baseConfirm('你确定要删除选中项吗', null, async () => {
  414. const { msg } = await bidApi.delete({ ids })
  415. this.$baseMessage(msg, 'success', 'vab-hey-message-success')
  416. await this.fetchData()
  417. })
  418. } else {
  419. this.$baseMessage('未选中任何行', 'error', 'vab-hey-message-error')
  420. }
  421. }
  422. },
  423. handleSizeChange(val) {
  424. this.queryForm.pageSize = val
  425. this.fetchData()
  426. },
  427. handleCurrentChange(val) {
  428. this.queryForm.pageNum = val
  429. this.fetchData()
  430. },
  431. queryData() {
  432. this.queryForm.pageNum = 1
  433. this.fetchData()
  434. },
  435. async fetchData() {
  436. this.listLoading = true
  437. const params = this.queryForm
  438. const {
  439. data: { list, total },
  440. } = await bidApi.list(params)
  441. this.list = list
  442. this.total = total
  443. this.listLoading = false
  444. this.tableKey++
  445. this.$nextTick(() => this.$refs.table.doLayout())
  446. },
  447. reset() {
  448. this.queryForm = {
  449. pageNum: 1,
  450. pageSize: 10,
  451. distName: '',
  452. belongSale: '',
  453. }
  454. this.fetchData()
  455. },
  456. //详情
  457. handleDetail(row) {
  458. this.$router.push({
  459. path: '/customer/inviteDetail',
  460. query: {
  461. id: row.id,
  462. },
  463. })
  464. },
  465. },
  466. }
  467. </script>
  468. <style>
  469. .el-tree-node:focus > .el-tree-node__content {
  470. /*设置选中的样式 */
  471. background-color: #dde9ff !important;
  472. }
  473. .el-tree-node__content:hover {
  474. /*设置鼠标飘过的颜色 */
  475. background: #eaf9ff !important;
  476. color: #007bff;
  477. }
  478. .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
  479. /*current选中的样式 */
  480. color: #4d95fd;
  481. font-weight: bold;
  482. background-color: #dde9ff !important;
  483. }
  484. </style>