report_analysis.js 72 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179
  1. function dateFormatter (date, pattern) {
  2. return new Date(date).pattern(pattern)
  3. }
  4. function subscribeRequestSuccess (res) {
  5. vm.subscribeInfo = res
  6. }
  7. var vm = new Vue({
  8. delimiters: ['${', '}'],
  9. el: '#analysis',
  10. components: {
  11. keywordComponent: keywordComponent,
  12. areaCityMobile: areaCityMobileComponent,
  13. areaComponent: areaComponent,
  14. industryComponent: industryComponent,
  15. cateComponent: cateComponent,
  16. dateComponent: dateComponent,
  17. chartExample: chartExample,
  18. projectHeader: projectHeaderComponent,
  19. // 图表
  20. projectScatter: projectScatter,
  21. marketTimeScatter: marketTimeScatter,
  22. marketAreaScatter: marketAreaScatter,
  23. marketTop3Table: marketTop3Table,
  24. marketUserScatter: marketUserScatter,
  25. marketSegment: marketSegment,
  26. lineChartScatter: lineChartScatter,
  27. },
  28. data: {
  29. sessStorageKey: '$data-report_analysis',
  30. tabActiveName: 'analysis', // analysis/history
  31. subscribeInfo: {},
  32. tabList: [
  33. {
  34. label: '市场分析报告',
  35. name: 'analysis'
  36. },
  37. {
  38. label: '历史报告',
  39. name: 'history'
  40. }
  41. ],
  42. matchWayList: [
  43. {
  44. name: '按标题匹配',
  45. label: 'title'
  46. },
  47. {
  48. name: '按全文匹配',
  49. label: 'content'
  50. }
  51. ],
  52. tabConf: {
  53. titleActiveColor: '#2ABED1',
  54. titleInactiveColor: '#5F5E64',
  55. lineWidth: '24',
  56. color: '#2ABED1'
  57. },
  58. timeOptions: [
  59. {
  60. name: '近3个月',
  61. value: 'lately90',
  62. selected: false
  63. },
  64. {
  65. name: '近半年',
  66. value: 'lately180',
  67. selected: false
  68. },
  69. {
  70. name: '今年全年',
  71. value: 'thisYear',
  72. selected: false
  73. },
  74. {
  75. name: '去年至今',
  76. value: 'sinceLastYear',
  77. selected: false
  78. },
  79. {
  80. name: '前年至今',
  81. value: 'sinceYearBeforeLast',
  82. selected: false
  83. }
  84. ],
  85. scrollTop: 0,
  86. filtersPageShow: true,
  87. filtersCache: {
  88. matchway: 'title'
  89. },
  90. filters: {
  91. selectKeysArr: [], // 关键词简单数组,用于恢复选择状态
  92. matchway: 'title',
  93. keys: [], // 关键词详细数组,用于提交数据
  94. area: {},
  95. industry: [],
  96. industryDetail: {},
  97. buyerclass: [],
  98. rangeTime: {
  99. start: '',
  100. end: '',
  101. exact: 'sinceYearBeforeLast',
  102. },
  103. },
  104. filterDialogShow: {
  105. keys: false,
  106. matchway: false,
  107. area: false,
  108. industry: false,
  109. buyerclass: false,
  110. rangeTime: false
  111. },
  112. // 分析结果页面数据
  113. activeDimension: 'market',
  114. dimensionList: [
  115. {
  116. id: 'market',
  117. name: '市场规模',
  118. top: 0,
  119. anchor: 'market-overview'
  120. },
  121. {
  122. id: 'buyer',
  123. name: '采购单位',
  124. top: 0,
  125. anchor: 'buyerclass-scatter'
  126. },
  127. {
  128. id: 'bidder',
  129. name: '中标单位',
  130. top: 0,
  131. anchor: 'winner-scatter'
  132. },
  133. ],
  134. analysis: { // 开始分析请求的loaed和loading
  135. loaded: false,
  136. loading: false
  137. },
  138. rid: '', // reportId
  139. reportFilters: {
  140. keys: [],
  141. selectTime: '',
  142. selectTimeExtra: '',
  143. area: {},
  144. industry: {},
  145. buyerclass: []
  146. },
  147. sections: {
  148. market: {
  149. overview: [],
  150. refine: {
  151. dataAlready: false,
  152. projectCountData: null,
  153. projectAmountData: null,
  154. // 项目数量Top3
  155. projectCountTop3: null,
  156. // 项目金额Top3
  157. projectAmountTop3: null
  158. }
  159. },
  160. projectScatter: {
  161. dataAlready: false,
  162. chartData: null,
  163. tableData: [
  164. // {
  165. // projectname: 'xxxx',
  166. // area: 'xx',
  167. // city: 'xxx',
  168. // sortprice: 'zzz',
  169. // jgtime: 'zzzz',
  170. // winner_s: [
  171. // {
  172. // name: 'w1',
  173. // id: '33'
  174. // },
  175. // {
  176. // name: 'w2',
  177. // id: '33'
  178. // }
  179. // ]
  180. // },
  181. // {
  182. // projectname: 'xxxx',
  183. // area: 'xx',
  184. // city: 'xxx',
  185. // sortprice: 'zzz',
  186. // jgtime: 'zzzz',
  187. // winner_s: [
  188. // {
  189. // name: 'w1',
  190. // id: '33'
  191. // },
  192. // {
  193. // name: 'w2',
  194. // id: '33'
  195. // }
  196. // ]
  197. // }
  198. ]
  199. },
  200. timeScatter: {
  201. dataAlready: false, // 数据准备好之后才能开始渲染
  202. activeAction: 'month',
  203. actionList: [
  204. {
  205. label: '月度数据',
  206. value: 'month'
  207. },
  208. {
  209. label: '年度数据',
  210. value: 'year'
  211. }
  212. ],
  213. month: {
  214. count: {},
  215. amount: {}
  216. },
  217. year: {
  218. count: {},
  219. amount: {}
  220. }
  221. },
  222. areaScatter: {
  223. dataAlready: false,
  224. chartData: null,
  225. // 地区信息接口返回的原始数据
  226. originAreaData: [],
  227. showAreaPopup: false,
  228. setCityList: [],
  229. selectArea: {},
  230. sortType: 0,
  231. showAreaCityListBtn: false,
  232. // 项目数量Top3
  233. projectCountTop3: null,
  234. // 项目金额Top3
  235. projectAmountTop3: null
  236. },
  237. userScatter: {
  238. list: [],
  239. // 项目数量Top3
  240. projectCountTop3: null,
  241. // 项目金额Top3
  242. projectAmountTop3: null
  243. },
  244. buyerclass: {
  245. dataAlready: false,
  246. chartData: null,
  247. // 项目数量Top3
  248. projectCountTop3: null,
  249. showCountAllBtn: false,
  250. // 项目金额Top3
  251. projectAmountTop3: null,
  252. showAmoutAllBtn: false
  253. },
  254. winner: {
  255. dataAlready: false,
  256. chartData: null,
  257. // 项目数量Top3
  258. projectCountTop3: null,
  259. showCountAllBtn: false,
  260. // 项目金额Top3
  261. projectAmountTop3: null,
  262. showAmoutAllBtn: false
  263. }
  264. },
  265. empty: {
  266. defaultMsg: '对不起,没有匹配到相关信息<br />请修改您的分析条件',
  267. msg: ''
  268. },
  269. stickyOffset: 0,
  270. notSetKey: false, // 未设置关键词
  271. isSubCount: false, // 是否子账号
  272. powerInfo: {},
  273. isWeixin: false,
  274. sortOptionTitle: '项目数量由大到小排序',
  275. sortOptionContent: [
  276. { text: '项目数量由大到小排序', value: 0, active: true },
  277. { text: '项目金额由大到小排序', value: 1, active: false }
  278. ]
  279. },
  280. computed: {
  281. showBuyerBtn: function () {
  282. return this.sections.buyerclass.showCountAllBtn ? this.sections.buyerclass.projectCountTop3.slice(0, 3) : this.sections.buyerclass.projectCountTop3
  283. },
  284. showAmoutBtn: function () {
  285. return this.sections.buyerclass.showAmoutAllBtn ? this.sections.buyerclass.projectAmountTop3.slice(0, 3) : this.sections.buyerclass.projectAmountTop3
  286. },
  287. showWinnerCountBtn: function () {
  288. return this.sections.winner.showCountAllBtn ? this.sections.winner.projectCountTop3.slice(0, 3) : this.sections.winner.projectCountTop3
  289. },
  290. showWinnerAmoutBtn: function () {
  291. return this.sections.winner.showAmoutAllBtn ? this.sections.winner.projectAmountTop3.slice(0, 3) : this.sections.winner.projectAmountTop3
  292. },
  293. showAreaCityBtn: function () {
  294. return this.sections.areaScatter.showAreaCityListBtn ? this.sections.areaScatter.setCityList.slice(0, 5) : this.sections.areaScatter.setCityList
  295. },
  296. getStatus: function () {
  297. if (JSON.stringify(this.powerInfo) !== '{}') {
  298. return this.powerInfo.power.indexOf(26) !== -1
  299. }
  300. },
  301. anchorTopList: function () {
  302. var arr = []
  303. this.dimensionList.forEach(function (item) {
  304. arr.push(item.top)
  305. })
  306. return arr
  307. },
  308. // 报告详情筛选条件只有一个省份
  309. // 此时不显示地区分布chart
  310. notOneAreaFilter () {
  311. var area = this.reportFilters.area
  312. var showArea = area && (Object.keys(area).length > 1 || Object.keys(area).length === 0)
  313. return showArea
  314. },
  315. notOneAreaCityFilter () {
  316. var area = this.reportFilters.area
  317. if (!this.notOneAreaFilter) {
  318. var showCity = area && (area[Object.keys(area)].length >=2 || area[Object.keys(area)].length === 0)
  319. return showCity
  320. } else {
  321. return this.notOneAreaFilter
  322. }
  323. },
  324. emptyShow () {
  325. return !this.rid && this.analysis.loaded
  326. },
  327. tabActive: function () {
  328. var _this = this
  329. var active = {}
  330. this.tabList.some(function (item) {
  331. var findThis = item.name === _this.tabActiveName
  332. if (findThis) {
  333. active = item
  334. return findThis
  335. }
  336. })
  337. return active
  338. },
  339. buyerclassSectionShow () {
  340. const winnerState = this.sections.buyerclass
  341. // return winnerState.dataAlready && winnerState.projectCountTop3 && winnerState.projectAmountTop3
  342. return winnerState.dataAlready && winnerState.chartData
  343. },
  344. winnerSectionShow () {
  345. const winnerState = this.sections.winner
  346. // return winnerState.dataAlready && winnerState.projectCountTop3 && winnerState.projectAmountTop3
  347. return winnerState.dataAlready && winnerState.chartData
  348. },
  349. overviewRateTotal: function () {
  350. var total = 0
  351. this.sections.market.overview.forEach(function (item) {
  352. if (item.ringRatio !== undefined && item.ringRatio !== null) {
  353. total += item.ringRatio
  354. }
  355. })
  356. return total
  357. }
  358. },
  359. watch: {
  360. filtersPageShow (newVal) {
  361. if (!newVal) {
  362. this.isWeixin = utils.isWeiXinBrowser
  363. if (!this.isWeixin) {
  364. this.calcStickyOffset()
  365. }
  366. }
  367. },
  368. subscribeInfo (n) {
  369. if (!this.rid && n && n.member_jy && n.member_jy.i_matchway) {
  370. this.setDefaultMatchWay(n.member_jy.i_matchway)
  371. }
  372. },
  373. },
  374. created () {
  375. this.calcLastTimeText()
  376. this.getPower()
  377. var id = utils.getParam('id')
  378. if (id) {
  379. this.rid = decodeURIComponent(id)
  380. this.filtersPageShow = false
  381. }
  382. },
  383. mounted: function () {
  384. setTimeout(() => {
  385. var restored = this.reStoreState()
  386. if (!restored) {
  387. if (this.rid) {
  388. this.getReportResult()
  389. }
  390. } else {
  391. this.$nextTick(this.calcOffsetTop)
  392. if (utils.isIos) {
  393. setTimeout(this.calcOffsetTop, 1000)
  394. }
  395. }
  396. }, 0)
  397. this.addEventListeners()
  398. utils.iosBackRefresh()
  399. },
  400. methods: {
  401. setDefaultMatchWay: function (matchWay) {
  402. // matchWay 1按标题匹配title 2按全文匹配content
  403. var map = {
  404. 1: 'title',
  405. 2: 'content'
  406. }
  407. var defaultMatchWay = map[matchWay]
  408. if (defaultMatchWay) {
  409. this.filters.matchway = defaultMatchWay
  410. }
  411. },
  412. // 设置排序方式
  413. setsortType (data) {
  414. this.sections.areaScatter.sortType = data
  415. const type = data===0 ? 'total' : 'amount'
  416. // const list = this.setCitySort(this.sections.areaScatter.setCityList, type)
  417. let newArr = []
  418. if(data === 0) {
  419. newArr = this.sections.areaScatter.setCityList.sort((a, b) => b.total - a.total)
  420. } else {
  421. newArr = this.sections.areaScatter.setCityList.sort((a, b) => b.amount - a.amount)
  422. }
  423. this.sections.areaScatter.setCityList = this.formatterWinData(newArr, type)
  424. this.sortOptionTitle = this.sortOptionContent[data].text
  425. this.sections.areaScatter.setCityList = newArr
  426. },
  427. cancelSelectArea () {
  428. this.sections.areaScatter.showAreaPopup = false
  429. },
  430. // 城市排序
  431. setCitySort (list, type) {
  432. return list.sort((a, b) => {
  433. a[type] - b[type]
  434. })
  435. },
  436. // 选择省份展示城市分布(单选)
  437. confirmSelectArea (data) {
  438. console.log(data)
  439. if(this.sections.areaScatter.originAreaData.length > 0) {
  440. this.sections.areaScatter.originAreaData.forEach(item => {
  441. if(item.area == data.data[0]) {
  442. this.sections.areaScatter.selectArea = item
  443. const areaSort = this.sections.areaScatter.sortType === 0 ? 'total' : 'amount'
  444. let newArr = []
  445. if(this.sections.areaScatter.sortType === 0) {
  446. newArr = item.areaDetails.sort((a, b) => b.total - a.total)
  447. } else {
  448. newArr = item.areaDetails.sort((a, b) => b.amount - a.amount)
  449. }
  450. this.sections.areaScatter.setCityList = this.formatterWinData(newArr, areaSort)
  451. this.sections.areaScatter.setCityList = this.sections.areaScatter.setCityList.sort((a, b) => b[areaSort] - a[areaSort])
  452. if(this.sections.areaScatter.setCityList.length > 5) {
  453. this.sections.areaScatter.showAreaCityListBtn = true
  454. } else {
  455. this.sections.areaScatter.showAreaCityListBtn = false
  456. }
  457. }
  458. })
  459. }
  460. this.sections.areaScatter.showAreaPopup = false
  461. },
  462. showCountAmount (data) {
  463. return (data.amount / 10000).toFixed(2)
  464. },
  465. inProList () {
  466. this.saveState()
  467. if(utils.$envs.inWX){
  468. if(!this.getStatus) {
  469. location.href = '/weixin/frontPage/bigmember/free/perfect_info?source=wx_analysis_ProjectDetails'
  470. } else {
  471. window.location.href='/big/wx/page/report_analysis_pro_list?id=' + this.rid
  472. }
  473. } else {
  474. if(!this.getStatus) {
  475. location.href = '/jyapp/frontPage/bigmember/free/perfect_info?source=app_analysis_ProjectDetails'
  476. } else {
  477. window.location.href='/jyapp/big/page/report_analysis_pro_list?id=' + this.rid
  478. }
  479. }
  480. },
  481. gotable () {
  482. this.saveState()
  483. if(utils.$envs.inWX){
  484. window.location.href='/big/wx/page/report_table?source=analysis'+'&flag=3'+'&rid='+this.rid+'&header=客户类型分布详情'
  485. } else {
  486. window.location.href='/jyapp/big/page/report_table?source=analysis'+'&flag=3'+'&rid='+this.rid+'&header=客户类型分布详情'
  487. }
  488. },
  489. isWeiXinBrower() {
  490. var ua = navigator.userAgent.toLowerCase();
  491. if(ua.match(/MicroMessenger/i) == 'micromessenger') {
  492. return true;
  493. } else {
  494. return false;
  495. }
  496. },
  497. showLoading: function () {
  498. return this.$toast.loading({
  499. duration: 0,
  500. forbidClick: true,
  501. message: 'loading...',
  502. })
  503. },
  504. showToast: function (message) {
  505. return this.$toast({
  506. duration: 1500,
  507. forbidClick: true,
  508. message: message,
  509. })
  510. },
  511. showDialog: function (conf) {
  512. var defaultConf = {
  513. title: '提示',
  514. message: 'message',
  515. className: 'j-confirm-dialog',
  516. showConfirmButton: true,
  517. showCancelButton: true,
  518. confirmButtonText: '确定',
  519. confirmButtonColor: '#2abed1'
  520. }
  521. if (conf) {
  522. Object.assign(defaultConf, conf)
  523. }
  524. return this.$dialog.confirm(defaultConf)
  525. },
  526. calcOffsetTop: function () {
  527. var sticky = $('.van-sticky')
  528. var stickyHeight = 0
  529. if (sticky.length) {
  530. stickyHeight = sticky[0].clientHeight
  531. }
  532. this.dimensionList.forEach(function (item) {
  533. var anchor = $('.' + item.anchor)
  534. var offsetTop = 0
  535. if (anchor.length) {
  536. offsetTop = parseInt(anchor[0].offsetTop - stickyHeight)
  537. }
  538. item.top = offsetTop
  539. })
  540. },
  541. addEventListeners: function () {
  542. this.scrollToTop()
  543. },
  544. scrollToTop: function () {
  545. var $scrollDOM = $('.j-container.search-result > .j-main')
  546. // 1. 检查当前高度是否满足显示快速滚动到顶部
  547. this.checkScrollTopButtonShow()
  548. // 2. 具体逻辑
  549. $scrollDOM.on('scroll', this.checkScrollTopButtonShow)
  550. setTimeout(function () {
  551. // 2s后绑定(尽可能保证top能够被计算完)
  552. $scrollDOM.on('scroll', this.checkAnchorItemActive)
  553. }.bind(this), 2500)
  554. $('.scroll-to-top').on('click', function () {
  555. $scrollDOM.animate({ scrollTop: 0 })
  556. })
  557. },
  558. checkAnchorItemActive: function () {
  559. var $scrollDOM = $('.j-container.search-result > .j-main')
  560. var anchorTopList = this.anchorTopList
  561. var scrollTop = parseInt($scrollDOM.scrollTop()) + 3 // (误差校正)
  562. var i = 0
  563. if (scrollTop >= anchorTopList[1] && scrollTop < anchorTopList[2]) {
  564. i = 1
  565. } else if (scrollTop > anchorTopList[2] && scrollTop > anchorTopList[1] && scrollTop > anchorTopList[0]) { //逻辑上多余判断条件 ,为了处理高度还没有计算出起始的 anchorTopList[2]为0 tab回显错误问题
  566. i = 2
  567. } else if (scrollTop < anchorTopList[1]) {
  568. i = 0
  569. }
  570. this.activeDimension = this.dimensionList[i].id
  571. },
  572. checkScrollTopButtonShow: function () {
  573. var showButtonHeight = 300
  574. var $scrollDOM = $('.j-container.search-result > .j-main')
  575. var button = $('.scroll-to-top')
  576. var scrollTop = $scrollDOM.scrollTop()
  577. if (scrollTop > showButtonHeight) {
  578. button.show()
  579. } else {
  580. button.hide()
  581. }
  582. },
  583. calcStickyOffset: function () {
  584. setTimeout(function () {
  585. var headerHeight = $('.jy-app-header')[0].clientHeight
  586. var tabHeight = $('.analysis-tab')[0].clientHeight
  587. this.stickyOffset = headerHeight + tabHeight - 5
  588. }.bind(this), 1000)
  589. },
  590. setScrollTop: function (scrollTop) {
  591. this.$nextTick(function () {
  592. var wrapper = document.querySelector('.j-container.search-result > .j-main')
  593. wrapper.scrollTop = scrollTop
  594. })
  595. },
  596. saveScrollTop: function () {
  597. var wrapper = document.querySelector('.j-container.search-result > .j-main')
  598. if (wrapper.scrollTop) {
  599. this.scrollTop = parseInt(wrapper.scrollTop)
  600. }
  601. },
  602. beforeTabChange: function (name) {
  603. if (name !== this.tabActiveName) {
  604. this.goToAnalysisHistory()
  605. }
  606. return false
  607. },
  608. goToAnalysisHistory: function () {
  609. location.href = './report_analysis_history'
  610. },
  611. formatSelectTime (value) {
  612. if (!value) return '-'
  613. const timeArr = value.split('-')
  614. return `${dateFormatter(timeArr[0] * 1000, 'yyyy/MM/dd')}-${dateFormatter(timeArr[1] * 1000, 'yyyy/MM/dd')}`
  615. },
  616. getPower:function () {
  617. var _this = this
  618. $.ajax({
  619. type:'POST',
  620. url:'/bigmember/use/isAdd',
  621. success:function(res) {
  622. _this.powerInfo = res.data
  623. if (res.data && res.data.isSubCount){
  624. _this.isSubCount = true
  625. }
  626. }
  627. })
  628. },
  629. init: function () {
  630. // 初始化页面数据
  631. this.initDateTimeSelector('sinceYearBeforeLast')
  632. },
  633. // 时间选择器选中状态
  634. initDateTimeSelector: function (exact) {
  635. if (exact === 'exact') {
  636. this.$refs.dateSelector.setState(this.filters.rangeTime)
  637. } else {
  638. this.$refs.dateSelector.setTimeSelectListState(exact)
  639. this.$refs.dateSelector.dateStyle = false
  640. }
  641. },
  642. resolveSelected: function (type) {
  643. var filters = this.filters
  644. var prefix = '已选:'
  645. var text = ''
  646. if (type === 'keys') {
  647. if (this.notSetKey) return '请设置'
  648. text = this.resolveSelectKeysText(filters.keys)
  649. } else if (type === 'area') {
  650. text = this.resolveSelectAreaText(filters.area)
  651. } else if (type === 'industry') {
  652. text = this.resolveSelectIndustryText(filters.industryDetail)
  653. } else if (type === 'buyerclass') {
  654. text = this.resolveSelectBuyerclassText(filters.buyerclass)
  655. } else if (type === 'matchway') {
  656. text = this.resolveSelectMatchWayText(filters.matchway)
  657. }
  658. return prefix + text
  659. },
  660. resolveSelectMatchWayText: function (m) {
  661. var map = {
  662. title: '按标题匹配',
  663. content: '按全文匹配'
  664. }
  665. return map[m]
  666. },
  667. resolveSelectKeysText: function (keys) {
  668. if (Array.isArray(keys)) {
  669. if (keys.length === 0) {
  670. return '全部'
  671. } else {
  672. var count = 0
  673. var arr = []
  674. keys.forEach(function (classify) {
  675. if (Array.isArray(classify.a_key) && classify.a_key.length) {
  676. count += classify.a_key.length
  677. classify.a_key.forEach(function (item) {
  678. arr.push(item.key.join(' '))
  679. })
  680. }
  681. })
  682. if (count <= 0) {
  683. return '全部'
  684. } else {
  685. return arr.join(',')
  686. }
  687. }
  688. } else {
  689. return '全部'
  690. }
  691. },
  692. resolveSelectAreaText: function (area) {
  693. if (!area || Object.keys(area).length === 0) return '全国'
  694. var areaArr = []
  695. var cityArr = []
  696. for (var key in area) {
  697. if (area[key].length === 0) {
  698. areaArr.push(key)
  699. } else {
  700. cityArr = cityArr.concat(area[key])
  701. }
  702. }
  703. return areaArr.concat(cityArr).join(',')
  704. },
  705. resolveSelectIndustryText: function (industry) {
  706. if (!industry || Object.keys(industry).length === 0) return '全部'
  707. var keyArr = []
  708. var valueArr = []
  709. for (var key in industry) {
  710. if (industry[key].length === 0) {
  711. keyArr.push(key)
  712. } else {
  713. valueArr = valueArr.concat(industry[key])
  714. }
  715. }
  716. return keyArr.concat(valueArr).join(',')
  717. },
  718. resolveSelectBuyerclassText: function (buyerclass) {
  719. if (!Array.isArray(buyerclass)) return '全部'
  720. if (buyerclass.length === 0) return '全部'
  721. return buyerclass.join(',')
  722. },
  723. calcLastTimeText: function () {
  724. const renameList = [
  725. 'thisYear', // 今年全年
  726. 'sinceLastYear', // 去年至今
  727. 'sinceYearBeforeLast' // 前年至今
  728. ]
  729. const thisYear = new Date().getFullYear()
  730. this.timeOptions.forEach(item => {
  731. if (renameList.indexOf(item.value) !== -1) {
  732. if (item.value === renameList[0]) {
  733. item.name = `${thisYear}年全年`
  734. } else if (item.value === renameList[1]) {
  735. item.name = `${thisYear - 1}年至今`
  736. } else if (item.value === renameList[2]) {
  737. item.name = `${thisYear - 2}年至今`
  738. }
  739. }
  740. })
  741. },
  742. // 重置
  743. resetFilter: function (type) {
  744. var filters = this.filters
  745. if (type === 'keys') {
  746. filters.keys = []
  747. filters.selectKeysArr = []
  748. try {
  749. this.$refs.keywordSelector.resetAllNoSelect()
  750. } catch (error) {}
  751. } else if (type === 'area') {
  752. filters.area = {}
  753. } else if (type === 'industry') {
  754. filters.industry = []
  755. filters.industryDetail = {}
  756. } else if (type === 'buyerclass') {
  757. filters.buyerclass = []
  758. } else if (type === 'date') {
  759. this.filters.rangeTime.start = ''
  760. this.filters.rangeTime.edd = ''
  761. this.filters.rangeTime.exact = 'sinceYearBeforeLast'
  762. this.initDateTimeSelector(this.filters.rangeTime.exact)
  763. } else {
  764. this.resetFilter('keys')
  765. this.resetFilter('area')
  766. this.resetFilter('industry')
  767. this.resetFilter('buyerclass')
  768. this.resetFilter('date')
  769. }
  770. },
  771. clickCell: function (key) {
  772. var _this = this
  773. var dialog = this.filterDialogShow
  774. if (key === 'keys') {
  775. if (this.notSetKey) {
  776. return this.setKeyTip()
  777. }
  778. } else if (key === 'area') {
  779. setTimeout(function () {
  780. _this.$refs.areaCitySelector.setState(_this.filters.area)
  781. }, 0)
  782. } else if (key === 'buyerclass') {
  783. setTimeout(function () {
  784. _this.$refs.buyerclassSelector.setState()
  785. }, 0)
  786. } else if (key === 'industry') {
  787. setTimeout(function () {
  788. _this.$refs.industrySelector.setState()
  789. }, 0)
  790. } else if (key = 'matchway') {
  791. this.filtersCache[key] = this.filters[key]
  792. }
  793. dialog[key] = true
  794. },
  795. cancel: function (e, key) {
  796. var dialog = this.filterDialogShow
  797. this.resetFilter(key)
  798. dialog[key] = false
  799. },
  800. confirm: function (e, key) {
  801. var dialog = this.filterDialogShow
  802. var filters = this.filters
  803. if (key === 'keys') {
  804. filters.keys = e.detail
  805. filters.selectKeysArr = e.data
  806. } else if (key === 'area') {
  807. filters.area = e.data
  808. } else if (key === 'industry') {
  809. filters.industry = e.data
  810. filters.industryDetail = e.detail
  811. } else if (key === 'buyerclass') {
  812. filters.buyerclass = e.data
  813. console.log(e.data)
  814. }
  815. dialog[key] = false
  816. },
  817. dateTimeSelectorConfirm () {
  818. var result = this.$refs.dateSelector.getState()
  819. this.filters.rangeTime.start = result.start
  820. this.filters.rangeTime.end = result.end
  821. this.filters.rangeTime.exact = result.exact
  822. },
  823. resetAllFilters: function () {
  824. this.analysis.loaded = false
  825. this.resetFilter('all')
  826. },
  827. getReportResult () {
  828. this.sendRequest()
  829. },
  830. getSelectedKeys () {
  831. const keys = this.filters.keys
  832. if (Array.isArray(keys) && keys.length) {
  833. return JSON.stringify(keys)
  834. } else {
  835. var allKeys = this.$refs.keywordSelector.keywordGroupList
  836. return JSON.stringify(allKeys)
  837. }
  838. },
  839. startAnalysis: function () {
  840. this.dateTimeSelectorConfirm()
  841. const query = {
  842. keysItems: this.getSelectedKeys(),
  843. matchingMode: this.filters.matchway,
  844. rangeTime: `${parseInt(this.filters.rangeTime.start / 1000)}-${parseInt(this.filters.rangeTime.end / 1000)}`,
  845. rangeTimeExtra: this.filters.rangeTime.exact,
  846. area: JSON.stringify(this.filters.area),
  847. industry: JSON.stringify(this.filters.industryDetail),
  848. buyerclass: this.filters.buyerclass.join(',')
  849. }
  850. this.analysis.loaded = false
  851. this.analysis.loading = true
  852. var loading = this.showLoading()
  853. /*
  854. 1.如该用户当前身份下存在“生成中”的报告 则弹框提示报告生成中等等。。。
  855. 2.该用户不存在“生成中”的报告,且该报告需要离线生成
  856. 2-1:【消息-服务通知】APP、微信提醒均未开启 则弹框提示去开启
  857. 2-2:【消息-服务通知】APP或微信提醒已开启 则弹框提示我知道了
  858. */
  859. $.ajax({
  860. type: 'POST',
  861. url: '/bigmember/marketAnalysis/doAnalysis',
  862. data: query,
  863. success: function (res) {
  864. loading.clear()
  865. if (res && res.error_code === 0 && res.data) {
  866. // id:报告id
  867. // msgOpen:微信或APP提醒是否打开(离线生成时会返回该字段)
  868. // status:0-在线生成 走原逻辑 1-离线生成 (判断msgOpen出提示文案) 2-存在正在生成的报告(需要出弹出提示,由用户确认,id为需要取消的报告id,如果用户确认,则传该id调用取消接口后再次调用分析接口)
  869. if (res.data.status === 0) {
  870. this.rid = res.data.id
  871. this.analysis.loaded = true
  872. // location.replace('./report_analysis?id=' + res.data)
  873. this.rid = res.data.id
  874. history.replaceState({}, null, '?id=' + this.rid)
  875. this.getReportResult()
  876. } else if (res.data.status === 1) {
  877. return this.showDialog({
  878. allowHtml: true,
  879. title: '报告生成中',
  880. message: res.data.msgOpen ? '由于您的分析内容较多,报告正在努力生成中,生成成功后将会通过微信、APP给您发送1消息通知,届时您再前往查看此报告。' : '由于您的分析内容较多,报告正在努力生成中。建议您前往开启“<span class="highlight-text">消息-服务通知</span>”提醒,报告生成成功后可通过微信或APP给您发送1消息通知,届时您可前往查看此报告。',
  881. className: 'j-confirm-dialog text-justify',
  882. showCancelButton: !res.data.msgOpen,
  883. confirmButtonText: res.data.msgOpen ? '我知道了' : '去开启',
  884. cancelButtonText: res.data.msgOpen ? '' : '暂不开启',
  885. beforeClose: (action, done) => {
  886. if (action === 'confirm') {
  887. if (!res.data.msgOpen) {
  888. // 去开启 进到推送设置页面
  889. location.href = '/jy_mobile/push/pushsetting?active=1'
  890. } else {
  891. // 我知道了 回到历史报告页面
  892. this.goToAnalysisHistory()
  893. }
  894. } else {
  895. // 暂不开启 回到历史报告页面
  896. this.goToAnalysisHistory()
  897. }
  898. done()
  899. }
  900. })
  901. } else if (res.data.status === 2) {
  902. return this.showDialog({
  903. title: '报告生成确认',
  904. message: '您有1份报告正在“生成中”,请确定是否按照此条件重新生成,注:如确定则原状态为“生成中”的报告将被自动取消。',
  905. className: 'j-confirm-dialog text-justify',
  906. beforeClose: (action, done) => {
  907. if (action === 'confirm') {
  908. this.reportCancel(res.data.id)
  909. done()
  910. } else {
  911. done()
  912. }
  913. }
  914. })
  915. }
  916. } else {
  917. loading.clear()
  918. this.$toast(res.error_msg)
  919. }
  920. }.bind(this),
  921. complete: function () {
  922. loading.clear()
  923. this.analysis.loading = false
  924. }.bind(this)
  925. })
  926. },
  927. // 保存页面状态
  928. saveState: function () {
  929. this.saveScrollTop()
  930. this.dateTimeSelectorConfirm()
  931. var $data = {
  932. analysis: this.analysis,
  933. filters: this.filters,
  934. scrollTop: this.scrollTop,
  935. filtersPageShow: this.filtersPageShow,
  936. reportFilters: this.reportFilters,
  937. sections: this.sections,
  938. isSubCount: this.isSubCount
  939. }
  940. sessionStorage.setItem(this.sessStorageKey, JSON.stringify($data))
  941. },
  942. reStoreState: function () {
  943. var $data = sessionStorage.getItem(this.sessStorageKey)
  944. if ($data) {
  945. $data = JSON.parse($data)
  946. this.isSubCount = $data.isSubCount
  947. this.scrollTop = $data.scrollTop
  948. this.filtersPageShow = $data.filtersPageShow
  949. Object.assign(this.analysis, $data.analysis)
  950. this.$set(this, 'filters', $data.filters)
  951. this.$set(this, 'reportFilters', $data.reportFilters)
  952. this.$set(this, 'sections', $data.sections)
  953. setTimeout(function () {
  954. // 恢复滚动高度
  955. this.setScrollTop(this.scrollTop)
  956. this.initDateTimeSelector(this.filters.rangeTime.exact)
  957. }.bind(this), 0)
  958. sessionStorage.removeItem(this.sessStorageKey)
  959. } else {
  960. this.init()
  961. }
  962. return $data
  963. },
  964. onEmpty (info) {
  965. if (this.loading) {
  966. this.loading.clear()
  967. }
  968. this.filtersPageShow = true
  969. this.analysis.loaded = true
  970. this.rid = ''
  971. if (info && info.msg) {
  972. this.empty.msg = info.msg
  973. } else {
  974. this.empty.msg = this.empty.defaultMsg
  975. }
  976. },
  977. sendRequest () {
  978. let _this = this
  979. // 先请求概况(1),判断报告是否为空
  980. const query = {
  981. rid: this.rid,
  982. flag: 1
  983. }
  984. if (!query.rid) {
  985. return
  986. }
  987. this.loading = this.showLoading()
  988. $.ajax({
  989. type: 'POST',
  990. async: false,
  991. url: '/bigmember/marketAnalysis/getAnalysisResult',
  992. data: query,
  993. success: function(res) {
  994. if (res && res.error_code === 0 && res.data) {
  995. var empty = _this.formatterData(query.flag, res.data)
  996. if (empty) {
  997. return _this.onEmpty()
  998. }
  999. } else {
  1000. if (res.error_msg.indexOf('项目数量超出上限') === -1) {
  1001. return _this.onEmpty()
  1002. } else {
  1003. return _this.onEmpty({ msg: '当前分析条件涉及项目数量已超过最大限制,请修改分析条件进行精确分析' })
  1004. }
  1005. }
  1006. }
  1007. }).responseJSON
  1008. this.filtersPageShow = false
  1009. const flagArr = [
  1010. 0, // 筛选条件
  1011. // 1, // 市场概括与时间分布
  1012. 2, // 项目规模Top10
  1013. 3, // 项目规模分布/地区规模分布/客户分布/地区分布及客户分布&Top3(table+chart)
  1014. 4, // 细分市场
  1015. 5 // 采购单位/中标单位&Top3(table+chart)
  1016. ]
  1017. flagArr.forEach(this.getReport)
  1018. if (this.loading) {
  1019. this.loading.clear()
  1020. }
  1021. },
  1022. getReport (flag) {
  1023. const query = {
  1024. rid: this.rid,
  1025. flag
  1026. }
  1027. if (!query.rid) {
  1028. return
  1029. }
  1030. $.ajax({
  1031. type: 'POST',
  1032. url: '/bigmember/marketAnalysis/getAnalysisResult',
  1033. data: query,
  1034. success: function (res) {
  1035. if (res && res.error_code === 0 && res.data) {
  1036. if(flag==3){
  1037. sessionStorage.setItem('getAnalysisResult_',JSON.stringify(res))
  1038. }
  1039. this.formatterData(flag, res.data)
  1040. } else {
  1041. // this.$toast('请求失败')
  1042. }
  1043. }.bind(this)
  1044. })
  1045. },
  1046. formatterData (flag, data) {
  1047. if (flag === 0) {
  1048. this.sortReportFilters(data)
  1049. } else if (flag === 1) {
  1050. // 市场概况
  1051. const totalCount = this.sortMarketOverview(data.market_profile)
  1052. if (!totalCount) {
  1053. return true
  1054. }
  1055. // 时间分布
  1056. this.sortTimeScatter(data)
  1057. } else if (flag === 2) {
  1058. // 项目规模Top10
  1059. this.sortProjectTop10(data.ProjectTop10)
  1060. } else if (flag === 3) {
  1061. // 项目规模分布/地区规模分布/客户分布/地区分布及客户分布&Top3(table+chart)
  1062. // 项目规模分布
  1063. this.sortProjectScatter(data.projectScale)
  1064. // 地区规模分布
  1065. this.sections.areaScatter.originAreaData = data.area_infos
  1066. this.sortAreaScatter(data.area_infos)
  1067. // 城市分布
  1068. this.sortAreaCityScatter(data.area_infos)
  1069. // 客户分布
  1070. if(data.customer_scale){
  1071. if(data.customer_scale.length!=0){
  1072. let data_=data.customer_scale.slice(0,10)
  1073. this.sortUserScatter(data_)
  1074. }
  1075. }
  1076. // 地区分布及客户分布Top3
  1077. this.sortAreaUserTop3(data)
  1078. } else if (flag === 4) {
  1079. // 细分市场
  1080. this.sortMarketRefineData(data)
  1081. } else if (flag === 5) {
  1082. // 采购单位/中标单位&Top3(table+chart)
  1083. this.sortBuyerclassData(data)
  1084. // 中标单位分析
  1085. this.sortWinnerData(data)
  1086. }
  1087. this.$nextTick(this.calcOffsetTop)
  1088. },
  1089. formatSelectTime (value) {
  1090. if (!value) return '-'
  1091. const timeArr = value.split('-')
  1092. return `${dateFormatter(timeArr[0] * 1000, 'yyyy/MM/dd')}-${dateFormatter(timeArr[1] * 1000, 'yyyy/MM/dd')}`
  1093. },
  1094. // 整理数据,并赋值给filters
  1095. sortReportFilters (data) {
  1096. if (data.keysItems && data.keysItems !== '[]') {
  1097. this.reportFilters.keys = JSON.parse(data.keysItems)
  1098. this.filters.keys = this.reportFilters.keys
  1099. var keyArr = []
  1100. this.filters.keys.forEach(function (classify) {
  1101. if(Array.isArray(classify.a_key)) {
  1102. classify.a_key.forEach(function (item) {
  1103. keyArr.push(item.key.join(' '))
  1104. })
  1105. }
  1106. })
  1107. this.filters.selectKeysArr = keyArr
  1108. }
  1109. // if (data.s_rangeTimeExtra) {
  1110. // this.reportFilters.selectTimeExtra = data.s_rangeTimeExtra
  1111. // this.filters.rangeTime.exact = this.reportFilters.selectTimeExtra
  1112. // } else {
  1113. // this.filters.rangeTime.exact = 'exact'
  1114. // }
  1115. this.filters.rangeTime.exact = 'exact'
  1116. if (data.rangeTime) {
  1117. this.reportFilters.selectTime = data.rangeTime
  1118. var arr = data.rangeTime.split('-')
  1119. this.filters.rangeTime.start = arr[0] * 1000
  1120. this.filters.rangeTime.end = arr[1] * 1000
  1121. if (this.filters.rangeTime.exact === 'exact') {
  1122. var date = new Date(this.filters.rangeTime.end)
  1123. var timeString = date.pattern('yyyy/MM/dd')
  1124. this.filters.rangeTime.end = new Date(timeString).getTime()
  1125. }
  1126. }
  1127. this.$refs.dateSelector.setState(this.filters.rangeTime)
  1128. if (data.area && data.area !== '{}') {
  1129. this.reportFilters.area = JSON.parse(data.area)
  1130. this.filters.area = this.reportFilters.area
  1131. }
  1132. if (data.industry && data.industry !== '{}') {
  1133. this.reportFilters.industry = JSON.parse(data.industry)
  1134. this.$set(this.filters, 'industryDetail', this.reportFilters.industry)
  1135. var industry = []
  1136. for (var key in this.reportFilters.industry) {
  1137. this.reportFilters.industry[key].forEach(function (item) {
  1138. industry.push(key + '_' + item)
  1139. })
  1140. }
  1141. this.filters.industry = industry
  1142. }
  1143. if (data.buyerclass) {
  1144. this.reportFilters.buyerclass = data.buyerclass.split(',')
  1145. this.filters.buyerclass = this.reportFilters.buyerclass
  1146. }
  1147. console.log(data)
  1148. this.filters.matchway = data.matchingMode || 'content'
  1149. },
  1150. // 市场概况
  1151. sortMarketOverview (profile) {
  1152. if (!profile) return
  1153. const list = [
  1154. {
  1155. label: '项目总数',
  1156. unit: '个',
  1157. count: 0,
  1158. ringRatio: 0
  1159. },
  1160. {
  1161. label: '项目总金额',
  1162. unit: '万元',
  1163. count: 0,
  1164. ringRatio: 0
  1165. },
  1166. {
  1167. label: '项目平均金额',
  1168. unit: '万元',
  1169. count: 10.04,
  1170. ringRatio: 0
  1171. },
  1172. {
  1173. label: '中标单位数',
  1174. unit: '家',
  1175. count: 10628,
  1176. ringRatio: 0
  1177. },
  1178. {
  1179. label: '采购单位数',
  1180. unit: '家',
  1181. count: 16215,
  1182. ringRatio: 0
  1183. }
  1184. ]
  1185. // 项目总数
  1186. list[0].count = profile.project_count ? profile.project_count : 0
  1187. list[0].ringRatio = profile.project_count_ratio ? (profile.project_count_ratio * 100).toFixed(2) : 0
  1188. // 项目总金额
  1189. const projectTotalMoney = this.moneyUnit(profile.projctamout ? profile.projctamout : 0)
  1190. list[1].count = projectTotalMoney.count || 0
  1191. list[1].unit = projectTotalMoney.unit || '万元'
  1192. list[1].ringRatio = profile.projctamount_ratio ? (profile.projctamount_ratio * 100).toFixed(2) : 0
  1193. // 项目平均金额
  1194. const projectAvgMoney = this.moneyUnit(profile.projectavgmoney ? profile.projectavgmoney : 0)
  1195. list[2].count = projectAvgMoney.count || 0
  1196. list[2].unit = projectAvgMoney.unit || '万元'
  1197. list[2].ringRatio = profile.projectavgmoney_ratio ? (profile.projectavgmoney_ratio * 100).toFixed(2) : 0
  1198. // 中标单位数
  1199. list[3].count = profile.winnercount ? profile.winnercount : 0
  1200. list[3].ringRatio = profile.winnercount_ratio ? (profile.winnercount_ratio * 100).toFixed(2) : 0
  1201. // 采购单位数
  1202. list[4].count = profile.buyercount ? profile.buyercount : 0
  1203. list[4].ringRatio = profile.winnercount_ratio ? (profile.winnercount_ratio * 100).toFixed(2) : 0
  1204. var totalCount = list.reduce((total, item) => item.count + total, 0)
  1205. if (totalCount) {
  1206. this.sections.market.overview = list
  1207. }
  1208. return totalCount
  1209. },
  1210. // 时间分布
  1211. sortTimeScatter (data) {
  1212. const hasDataM = this.sortTimeScatterData('month', data.month_distribution)
  1213. const hasDataY = this.sortTimeScatterData('year', data.year_distribution)
  1214. const hasData = hasDataM && hasDataY
  1215. this.sections.timeScatter.dataAlready = hasData
  1216. },
  1217. sortTimeScatterData (type, data) {
  1218. // columns: ['日期', '项目规模', '环比增长率(%)'],
  1219. // rows: [
  1220. // {
  1221. // 日期: '6月',
  1222. // 项目规模: 0,
  1223. // '环比增长率(%)': -99
  1224. // },
  1225. // {
  1226. // 日期: '7月',
  1227. // 项目规模: 736325,
  1228. // '环比增长率(%)': 0
  1229. // },
  1230. // ]
  1231. if (!data) return
  1232. // 项目数量
  1233. const mDCount = {
  1234. columns: ['日期', '项目数量(个)', '项目数量环比'],
  1235. rows: []
  1236. }
  1237. let mDCountTotal = 0
  1238. if (Array.isArray(data.project_count)) {
  1239. const field = {
  1240. [mDCount.columns[0]]: 'minth',
  1241. [mDCount.columns[1]]: 'value',
  1242. [mDCount.columns[2]]: 'ratio'
  1243. }
  1244. data.project_count.forEach(item => {
  1245. const row = {}
  1246. mDCount.columns.forEach(column => {
  1247. var value = item[field[column]]
  1248. if (value) {
  1249. if (field[column] === 'ratio') {
  1250. row[column] = utils.formatMoney(value * 100, undefined, true) - 0
  1251. } else {
  1252. row[column] = value
  1253. }
  1254. } else {
  1255. row[column] = null
  1256. }
  1257. if (typeof value === 'number') {
  1258. mDCountTotal += value
  1259. }
  1260. })
  1261. mDCount.rows.push(row)
  1262. })
  1263. }
  1264. if (mDCountTotal || isNaN(mDCountTotal)) {
  1265. this.$set(this.sections.timeScatter[type], 'count', mDCount)
  1266. }
  1267. // 项目规模
  1268. const mDAmount = {
  1269. columns: ['日期', '项目金额(万元)', '项目金额环比'],
  1270. rows: []
  1271. }
  1272. let mDAmuntTotal = 0
  1273. if (Array.isArray(data.project_amount)) {
  1274. const field = {
  1275. [mDAmount.columns[0]]: 'minth',
  1276. [mDAmount.columns[1]]: 'value',
  1277. [mDAmount.columns[2]]: 'ratio'
  1278. }
  1279. data.project_amount.forEach(item => {
  1280. const row = {}
  1281. mDAmount.columns.forEach(column => {
  1282. const value = item[field[column]]
  1283. if (value) {
  1284. if (field[column] === 'value') {
  1285. row[column] = utils.formatMoney(value / 10000, undefined, true) - 0
  1286. } else if (field[column] === 'ratio') {
  1287. row[column] = utils.formatMoney(value * 100, undefined, true)
  1288. } else {
  1289. row[column] = value
  1290. }
  1291. } else {
  1292. row[column] = null
  1293. }
  1294. if (typeof value === 'number') {
  1295. mDAmuntTotal += value
  1296. }
  1297. })
  1298. mDAmount.rows.push(row)
  1299. })
  1300. }
  1301. if (mDAmuntTotal || !isNaN(mDAmuntTotal)) {
  1302. this.$set(this.sections.timeScatter[type], 'amount', mDAmount)
  1303. }
  1304. const r = !!(mDCountTotal + mDAmuntTotal)
  1305. const hasOneNaN = isNaN(mDCountTotal) || isNaN(mDAmuntTotal)
  1306. return hasOneNaN || r
  1307. },
  1308. // 项目规模分布
  1309. sortProjectScatter (data) {
  1310. // const chartData = {
  1311. // columns: ['项目规模', '项目总金额占比', '项目总数占比'],
  1312. // rows: [
  1313. // {
  1314. // 项目规模: '≥1亿',
  1315. // 项目总金额占比: 20,
  1316. // 项目总数占比: 10
  1317. // },
  1318. // {
  1319. // 项目规模: '1000万-1亿',
  1320. // 项目总金额占比: 50,
  1321. // 项目总数占比: 40
  1322. // },
  1323. // {
  1324. // 项目规模: '500万-1000万',
  1325. // 项目总金额占比: 20,
  1326. // 项目总数占比: 30
  1327. // },
  1328. // {
  1329. // 项目规模: '100万-500万',
  1330. // 项目总金额占比: 20,
  1331. // 项目总数占比: 30
  1332. // }
  1333. // ]
  1334. // }
  1335. const scaleList = data
  1336. const scaleData = {
  1337. columns: ['项目规模', '项目总金额占比', '项目总数占比'],
  1338. rows: []
  1339. }
  1340. let total = 0
  1341. if (scaleList && Array.isArray(scaleList)) {
  1342. const field = {
  1343. [scaleData.columns[0]]: 'Name',
  1344. [scaleData.columns[1]]: 'Persent_c',
  1345. [scaleData.columns[2]]: 'Persent_a'
  1346. }
  1347. scaleList.forEach(item => {
  1348. const row = {}
  1349. scaleData.columns.forEach(column => {
  1350. if (field[column] === 'Persent_c' || field[column] === 'Persent_a') {
  1351. row[column] = (item[field[column]] * 100).toFixed(2)
  1352. total += (item[field[column]] - 0)
  1353. } else {
  1354. row[column] = item[field[column]]
  1355. }
  1356. })
  1357. scaleData.rows.push(row)
  1358. })
  1359. }
  1360. if (total) {
  1361. scaleData.rows.reverse()
  1362. this.$set(this.sections.projectScatter, 'chartData', scaleData)
  1363. if (this.sections.projectScatter.tableData.length) {
  1364. this.sections.projectScatter.dataAlready = true
  1365. }
  1366. }
  1367. },
  1368. // 项目规模Top10
  1369. sortProjectTop10 (top10List) {
  1370. if (!Array.isArray(top10List)) return
  1371. this.sections.projectScatter.tableData = top10List.map(top => {
  1372. let winners = top.winner_s ? top.winner_s.join(',') : ''
  1373. if (!winners) {
  1374. winners = []
  1375. } else {
  1376. winners = top.winner_s
  1377. }
  1378. winners = winners.map((item, index) => {
  1379. return {
  1380. name: item,
  1381. id: Array.isArray(top.eidlist) ? top.eidlist[index] : null
  1382. }
  1383. })
  1384. top.area = top.area ? top.area : ''
  1385. top.city = top.city ? top.city : ''
  1386. top.sortprice = top.sortprice ? utils.formatMoney(top.sortprice / 10000, undefined, true) : ''
  1387. top.jgtime = top.jgtime ? dateFormatter(top.jgtime * 1000, 'yyyy-MM-dd') : ''
  1388. top.winner_s = winners
  1389. return top
  1390. })
  1391. if (this.sections.projectScatter.chartData) {
  1392. this.sections.projectScatter.dataAlready = true
  1393. }
  1394. },
  1395. // 地区规模分布
  1396. sortAreaScatter (areaList) {
  1397. // const chartData = {
  1398. // columns: ['项目所在地', '项目数量', '项目金额'],
  1399. // rows: [
  1400. // {
  1401. // 项目所在地: '河南',
  1402. // 项目数量: 2,
  1403. // 项目金额: 2222
  1404. // },
  1405. // {
  1406. // 项目所在地: '北京',
  1407. // 项目数量: 22,
  1408. // 项目金额: 565666
  1409. // },
  1410. // {
  1411. // 项目所在地: '浙江',
  1412. // 项目数量: 22,
  1413. // 项目金额: 765666
  1414. // }
  1415. // ]
  1416. // }
  1417. const areaChartData = {
  1418. columns: ['项目所在地', '项目数量'],
  1419. sColumns: ['项目金额'],
  1420. rows: []
  1421. }
  1422. let total = 0
  1423. if (areaList && Array.isArray(areaList)) {
  1424. const field = {
  1425. [areaChartData.columns[0]]: 'area',
  1426. [areaChartData.columns[1]]: 'total',
  1427. [areaChartData.sColumns[0]]: 'amount'
  1428. }
  1429. areaList.forEach(item => {
  1430. const row = {}
  1431. areaChartData.columns.concat(areaChartData.sColumns).forEach(column => {
  1432. if (field[column] === 'amount') {
  1433. row[column] = utils.formatMoney(item[field[column]] / 10000, undefined, true) - 0
  1434. } else {
  1435. row[column] = item[field[column]]
  1436. }
  1437. if (field[column] === 'amount' || field[column] === 'total') {
  1438. total += (item[field[column]] - 0)
  1439. }
  1440. })
  1441. areaChartData.rows.push(row)
  1442. })
  1443. }
  1444. if (total) {
  1445. this.$set(this.sections.areaScatter, 'chartData', areaChartData)
  1446. this.sections.areaScatter.dataAlready = true
  1447. }
  1448. },
  1449. setAreaCity () {
  1450. this.sections.areaScatter.showAreaPopup = true
  1451. const selectAreaArr = [this.sections.areaScatter.selectArea.area]
  1452. this.$refs.areaSelector.setState(selectAreaArr)
  1453. },
  1454. // 城市分布
  1455. sortAreaCityScatter (areacitylist) {
  1456. if(!areacitylist) return
  1457. const list = areacitylist
  1458. const ZXS = ['北京', '天津', '上海', '重庆', '台湾', '澳门', '香港']
  1459. const result = list.reduce((max, item) => {
  1460. const isMaxZXS = ZXS.includes(max.area)
  1461. const isZXS = ZXS.includes(item.area);
  1462. const isMaxTotal = item.total > max.total;
  1463. const isNotZXSMaxTotal = (isMaxTotal && !isZXS) || isMaxZXS;
  1464. return isNotZXSMaxTotal ? item : max
  1465. })
  1466. if (result.areaDetails.length > 5) {
  1467. this.sections.areaScatter.showAreaCityListBtn = true
  1468. } else {
  1469. this.sections.areaScatter.showAreaCityListBtn = false
  1470. }
  1471. this.sections.areaScatter.setCityList = this.formatterWinData(result.areaDetails, 'total')
  1472. this.sections.areaScatter.selectArea = result
  1473. },
  1474. // 格式化进度条图表数据
  1475. formatterWinData: function(data,type) {
  1476. data.forEach(function(v,i){
  1477. // v.bidamount = (v.bidamount / 10000).fixed(2);
  1478. // v.average = (v.average / 10000).fixed(2);
  1479. switch (type) {
  1480. case 'total':
  1481. v.parent = v.total / data[0].total*100 + "%";
  1482. break;
  1483. case 'amount':
  1484. v.parent = v.amount / data[0].amount*100 + "%";
  1485. break;
  1486. }
  1487. })
  1488. return data;
  1489. },
  1490. // 客户分布
  1491. sortUserScatter (userList) {
  1492. if (Array.isArray(userList)) {
  1493. this.sections.userScatter.list = userList.map(item => {
  1494. item.name = item.buyclass
  1495. item.value = item.total
  1496. item.amount = utils.formatMoney(item.amount / 10000, undefined, true)
  1497. return item
  1498. })
  1499. }
  1500. },
  1501. // 地区分布及客户分布Top3
  1502. sortAreaUserTop3 (data) {
  1503. if (data.scaleAreaCountTop || data.scaleAreaAmountTop) {
  1504. this.sorAreaTop3(data)
  1505. } else {
  1506. this.sections.areaScatter.projectCountTop3 = null
  1507. this.sections.areaScatter.projectAmountTop3 = null
  1508. }
  1509. if (data.scaleBuyclassCountTop || data.scaleBuyclassAmountTop) {
  1510. this.sorUserTop3(data)
  1511. }
  1512. },
  1513. sorAreaTop3 (data) {
  1514. const tableDataCount = {
  1515. columns: ['序号', '地区:项目数量(个),占比', '前3中标单位:中标数量(个)'], // ,该地区占比
  1516. rows: []
  1517. }
  1518. const tableDataAmount = {
  1519. columns: ['序号', '地区:项目金额(万元),占比', '前3中标单位:中标金额(万元)'], // ,该地区占比
  1520. rows: []
  1521. }
  1522. const scaleAreaCountTop3 = data.scaleAreaCountTop
  1523. if (Array.isArray(scaleAreaCountTop3)) {
  1524. scaleAreaCountTop3.forEach((item, index) => {
  1525. item.name = item.name
  1526. item.subInfo1 = item.area_count ? `项目数量:${item.area_count}个` : ''
  1527. item.subInfo2 = item.area_scale ? `全国占比:${utils.formatMoney(item.area_scale * 100, undefined, true)}%` : ''
  1528. item.actionText = `中标单位 TOP3`
  1529. item.childrenShow = true
  1530. item.children = []
  1531. if (Array.isArray(item.winner)) {
  1532. item.winner.forEach((w, i) => {
  1533. const row = {
  1534. name: w.winner,
  1535. id: w.id,
  1536. type: 'winner',
  1537. subInfo1: w.winner_total ? `中标个数:${w.winner_total}个` : '',
  1538. // subInfo2: w.total_scale ? `地区占比:${utils.formatMoney(w.total_scale * 100, undefined, true)}%` : 0
  1539. }
  1540. item.children.push(row)
  1541. })
  1542. }
  1543. })
  1544. tableDataCount.rows = scaleAreaCountTop3
  1545. }
  1546. const scaleAreaAmountTop3 = data.scaleAreaAmountTop
  1547. if (Array.isArray(scaleAreaAmountTop3)) {
  1548. scaleAreaAmountTop3.forEach((item, index) => {
  1549. item.name = item.name
  1550. item.subInfo1 = item.area_amount ? `中标金额:${utils.formatMoney(item.area_amount / 10000, undefined, true)}万元` : ''
  1551. item.subInfo2 = item.area_scale ? `全国占比:${utils.formatMoney(item.area_scale * 100, undefined, true)}%` : ''
  1552. item.actionText = `中标单位 TOP3`
  1553. item.childrenShow = true
  1554. item.children = []
  1555. if (Array.isArray(item.winner)) {
  1556. item.winner.forEach((w, i) => {
  1557. const row = {
  1558. name: w.winner,
  1559. id: w.id,
  1560. type: 'winner',
  1561. subInfo1: w.winner_amount ? `中标金额:${utils.formatMoney(w.winner_amount / 10000, undefined, true)}万元` : '',
  1562. // subInfo2: w.amount_scale ? `地区占比:${utils.formatMoney(w.amount_scale * 100, undefined, true)}%` : ''
  1563. }
  1564. item.children.push(row)
  1565. })
  1566. }
  1567. })
  1568. tableDataAmount.rows = scaleAreaAmountTop3
  1569. }
  1570. if (tableDataCount.rows.length) {
  1571. this.$set(this.sections.areaScatter, 'projectCountTop3', tableDataCount.rows)
  1572. }
  1573. if (tableDataAmount.rows.length) {
  1574. this.$set(this.sections.areaScatter, 'projectAmountTop3', tableDataAmount.rows)
  1575. }
  1576. },
  1577. sorUserTop3 (data) {
  1578. const tableDataCount = {
  1579. columns: ['序号', '客户类型:项目数量(个),占比', '前3中标单位:中标数量(个)'], // ,该客户类型占比
  1580. rows: []
  1581. }
  1582. const tableDataAmount = {
  1583. columns: ['序号', '客户类型:项目金额(万元),占比', '前3中标单位:中标金额(万元)'], // ,该客户类型占比
  1584. rows: []
  1585. }
  1586. const countTop3 = data.scaleBuyclassCountTop
  1587. if (Array.isArray(countTop3)) {
  1588. countTop3.forEach((item, index) => {
  1589. item.name = item.name
  1590. item.subInfo1 = item.buyclass_count ? `项目数量:${item.buyclass_count}个` : ''
  1591. item.subInfo2 = item.buyclass_scale ? `全部占比:${utils.formatMoney(item.buyclass_scale * 100, undefined, true)}%` : ''
  1592. item.actionText = `中标单位 TOP3`
  1593. item.childrenShow = true
  1594. item.children = []
  1595. if (Array.isArray(item.winner)) {
  1596. item.winner.forEach((w, i) => {
  1597. const row = {
  1598. name: w.winner,
  1599. id: w.id,
  1600. type: 'winner',
  1601. subInfo1: w.winner_total ? `中标个数:${w.winner_total}个` : '',
  1602. // subInfo2: w.total_scale ? `该行业占比:${utils.formatMoney(w.total_scale * 100, undefined, true)}%` : ''
  1603. }
  1604. item.children.push(row)
  1605. })
  1606. }
  1607. })
  1608. tableDataCount.rows = countTop3
  1609. }
  1610. const amountTop3 = data.scaleBuyclassAmountTop
  1611. if (Array.isArray(amountTop3)) {
  1612. amountTop3.forEach((item, index) => {
  1613. item.name = item.name
  1614. item.subInfo1 = item.buyclass_amount ? `项目金额:${utils.formatMoney(item.buyclass_amount / 10000, undefined, true)}万元` : ''
  1615. item.subInfo2 = item.buyclass_scale ? `全部占比:${utils.formatMoney(item.buyclass_scale * 100, undefined, true)}%` : 0
  1616. item.actionText = `中标单位 TOP3`
  1617. item.childrenShow = true
  1618. item.children = []
  1619. if (Array.isArray(item.winner)) {
  1620. item.winner.forEach((w, i) => {
  1621. const row = {
  1622. name: w.winner,
  1623. id: w.id,
  1624. type: 'winner',
  1625. subInfo1: w.winner_amount ? `中标金额:${utils.formatMoney(w.winner_amount / 10000, undefined, true)}万元` : '',
  1626. // subInfo2: w.amount_scale ? `该行业占比:${utils.formatMoney(w.amount_scale * 100, undefined, true)}%` : ''
  1627. }
  1628. item.children.push(row)
  1629. })
  1630. }
  1631. })
  1632. tableDataAmount.rows = amountTop3
  1633. }
  1634. if (tableDataCount.rows.length) {
  1635. this.$set(this.sections.userScatter, 'projectCountTop3', tableDataCount.rows)
  1636. }
  1637. if (tableDataAmount.rows.length) {
  1638. this.$set(this.sections.userScatter, 'projectAmountTop3', tableDataAmount.rows)
  1639. }
  1640. },
  1641. // 细分市场
  1642. sortMarketRefineData (data) {
  1643. const refineCount = {
  1644. columns: ['行业', '项目数量'],
  1645. rows: []
  1646. }
  1647. const refineAmount = {
  1648. columns: ['行业', '项目金额'],
  1649. rows: []
  1650. }
  1651. let total = 0
  1652. const refineAll = data.scaleRefineAll
  1653. if (Array.isArray(refineAll)) {
  1654. const field = {
  1655. 行业: 'name',
  1656. 项目数量: 'total',
  1657. 项目金额: 'amount'
  1658. }
  1659. refineAll.forEach(item => {
  1660. const row = {}
  1661. for (const key in field) {
  1662. if (field[key] === 'amount') {
  1663. row[key] = utils.formatMoney(item[field[key]] / 10000, undefined, true)
  1664. } else {
  1665. row[key] = item[field[key]]
  1666. }
  1667. if (field[key] === 'total' || field[key] === 'amount') {
  1668. total += (item[field[key]] - 0)
  1669. }
  1670. }
  1671. refineCount.rows.push(row)
  1672. refineAmount.rows.push(row)
  1673. })
  1674. }
  1675. if (total) {
  1676. this.$set(this.sections.market.refine, 'projectCountData', refineCount)
  1677. this.$set(this.sections.market.refine, 'projectAmountData', refineAmount)
  1678. this.sections.market.refine.dataAlready = true
  1679. }
  1680. this.sortRefineTop3(data)
  1681. },
  1682. sortRefineTop3 (data) {
  1683. const tableDataCount = {
  1684. columns: ['序号', '细分市场:项目数量(个)', '前3中标单位:中标数量(个)'], // ,占比,该细分市场占比
  1685. rows: []
  1686. }
  1687. const tableDataAmount = {
  1688. columns: ['序号', '细分市场:项目金额(万元)', '前3中标单位:中标金额(万元)'], // ,占比,该细分市场占比
  1689. rows: []
  1690. }
  1691. const countTop3 = data.scaleRefineTotalTop
  1692. if (Array.isArray(countTop3)) {
  1693. countTop3.forEach((item, index) => {
  1694. item.name = item.name
  1695. item.subInfo1 = item.value ? `项目数量:${item.value}个` : ''
  1696. // item.subInfo2 = item.prop ? `全部占比:${utils.formatMoney(item.prop * 100, undefined, true)}%` : 0
  1697. item.actionText = `中标单位 TOP3`
  1698. item.childrenShow = true
  1699. item.children = []
  1700. if (Array.isArray(item.topList)) {
  1701. item.topList.forEach((w, i) => {
  1702. const row = {
  1703. name: w.name,
  1704. id: w.id,
  1705. type: 'winner',
  1706. subInfo1: w.value ? `中标个数:${w.value}个` : '',
  1707. // subInfo2: w.prop ? `该细分市场占比:${utils.formatMoney(w.prop * 100, undefined, true)}%` : ''
  1708. }
  1709. item.children.push(row)
  1710. })
  1711. }
  1712. })
  1713. tableDataCount.rows = countTop3
  1714. }
  1715. const amountTop3 = data.scaleRefineAmountTop
  1716. if (Array.isArray(amountTop3)) {
  1717. amountTop3.forEach((item, index) => {
  1718. item.name = item.name
  1719. item.subInfo1 = item.value ? `项目金额:${utils.formatMoney(item.value / 10000, undefined, true)}万元` : ''
  1720. // item.subInfo2 = item.prop ? `全部占比:${utils.formatMoney(item.prop * 100, undefined, true)}%` : 0
  1721. item.actionText = `中标单位 TOP3`
  1722. item.childrenShow = true
  1723. item.children = []
  1724. if (Array.isArray(item.topList)) {
  1725. item.topList.forEach((w, i) => {
  1726. const row = {
  1727. name: w.name,
  1728. id: w.id,
  1729. type: 'winner',
  1730. subInfo1: w.value ? `中标金额:${utils.formatMoney(w.value / 10000, undefined, true)}万元` : '',
  1731. // subInfo2: w.prop ? `该细分市场占比:${utils.formatMoney(w.prop * 100, undefined, true)}%`: ''
  1732. }
  1733. item.children.push(row)
  1734. })
  1735. }
  1736. })
  1737. tableDataAmount.rows = amountTop3
  1738. }
  1739. if (tableDataCount.rows.length) {
  1740. this.$set(this.sections.market.refine, 'projectCountTop3', tableDataCount.rows)
  1741. }
  1742. if (tableDataAmount.rows.length) {
  1743. this.$set(this.sections.market.refine, 'projectAmountTop3', tableDataAmount.rows)
  1744. }
  1745. },
  1746. // 采购单位
  1747. sortBuyerclassData (data) {
  1748. const buyerclassChartData = {
  1749. columns: ['金额区间', '采购总金额占比', '采购单位数量占比'],
  1750. rows: []
  1751. }
  1752. let total = 0
  1753. const buyerclassList = data.buyer_time_distribution
  1754. if (Array.isArray(buyerclassList)) {
  1755. const field = {
  1756. [buyerclassChartData.columns[0]]: 'key',
  1757. [buyerclassChartData.columns[1]]: 'total_amount',
  1758. [buyerclassChartData.columns[2]]: 'total_number'
  1759. }
  1760. buyerclassList.forEach(item => {
  1761. const row = {}
  1762. buyerclassChartData.columns.forEach(column => {
  1763. if (field[column] === 'total_amount' || field[column] === 'total_number') {
  1764. row[column] = (item[field[column]] * 100).toFixed(2)
  1765. total += (item[field[column]] - 0)
  1766. } else {
  1767. row[column] = item[field[column]]
  1768. }
  1769. })
  1770. buyerclassChartData.rows.push(row)
  1771. })
  1772. }
  1773. if (total) {
  1774. buyerclassChartData.rows.reverse()
  1775. this.$set(this.sections.buyerclass, 'chartData', buyerclassChartData)
  1776. this.sections.buyerclass.dataAlready = true
  1777. }
  1778. this.sortBuyerclassTableData(data)
  1779. },
  1780. sortBuyerclassTableData (data) {
  1781. const dataCount = {
  1782. columns: ['序号', '采购单位:采购数量(个)', '前3中标单位:中标数量(个)'], //,占比 | ,占该采购单位
  1783. rows: []
  1784. }
  1785. const dataAmount = {
  1786. columns: ['序号', '采购单位:采购金额(万元)', '前3中标单位:中标金额(万元)'], //,占比 | ,占该采购单位
  1787. rows: []
  1788. }
  1789. const countTop3 = data.buyer_count_top3
  1790. if (Array.isArray(countTop3)) {
  1791. countTop3.forEach((item, index) => {
  1792. item.name = item.name
  1793. item.type = 'buyer'
  1794. item.id = item.name
  1795. item.subInfo1 = item.number ? `项目数量:${item.number}个` : ''
  1796. // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
  1797. item.actionText = `中标单位 TOP3`
  1798. item.childrenShow = true
  1799. item.children = []
  1800. if (Array.isArray(item.winnertop3)) {
  1801. item.winnertop3.forEach((w, i) => {
  1802. const row = {
  1803. name: w.name,
  1804. id: w.id,
  1805. type: 'winner',
  1806. subInfo1: w.number ? `中标个数:${w.number}个` : '',
  1807. // subInfo2: w.accounted ? `占该采购单位:${utils.formatMoney(w.accounted * 100, undefined, true)}%` : ''
  1808. }
  1809. item.children.push(row)
  1810. })
  1811. }
  1812. })
  1813. dataCount.rows = countTop3
  1814. }
  1815. const amountTop3 = data.buyer_amount_top3
  1816. if (Array.isArray(amountTop3)) {
  1817. amountTop3.forEach((item, index) => {
  1818. item.name = item.name
  1819. item.type = 'buyer'
  1820. item.id = item.name
  1821. item.subInfo1 = item.amount ? `采购金额:${utils.formatMoney(item.amount / 10000, undefined, true)}万元` : ''
  1822. // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
  1823. item.actionText = `中标单位 TOP3`
  1824. item.childrenShow = true
  1825. item.children = []
  1826. if (Array.isArray(item.winnertop3)) {
  1827. item.winnertop3.forEach((w, i) => {
  1828. const row = {
  1829. name: w.name,
  1830. id: w.id,
  1831. type: 'winner',
  1832. subInfo1: w.amount ? `中标金额:${utils.formatMoney(w.amount / 10000, undefined, true)}万元` : '',
  1833. // subInfo2: w.accounted ? `该行业占比:${utils.formatMoney(w.accounted * 100, undefined, true)}%` : ''
  1834. }
  1835. item.children.push(row)
  1836. })
  1837. }
  1838. })
  1839. dataAmount.rows = amountTop3
  1840. }
  1841. if (dataCount.rows.length) {
  1842. if (dataCount.rows.length > 3) {
  1843. this.sections.buyerclass.showCountAllBtn = true
  1844. } else {
  1845. this.sections.buyerclass.showCountAllBtn = false
  1846. }
  1847. this.$set(this.sections.buyerclass, 'projectCountTop3', dataCount.rows)
  1848. }
  1849. if (dataAmount.rows.length) {
  1850. if (dataAmount.rows.length > 3) {
  1851. this.sections.buyerclass.showAmoutAllBtn = true
  1852. } else {
  1853. this.sections.buyerclass.showAmoutAllBtn = false
  1854. }
  1855. this.$set(this.sections.buyerclass, 'projectAmountTop3', dataAmount.rows)
  1856. }
  1857. },
  1858. // 中标单位
  1859. sortWinnerData (data) {
  1860. const chartData = {
  1861. columns: ['金额区间', '中标总金额占比', '中标单位数量占比'],
  1862. rows: []
  1863. }
  1864. let total = 0
  1865. const chartLIst = data.winner_time_distribution
  1866. if (Array.isArray(chartLIst)) {
  1867. const field = {
  1868. [chartData.columns[0]]: 'key',
  1869. [chartData.columns[1]]: 'total_amount',
  1870. [chartData.columns[2]]: 'total_number'
  1871. }
  1872. chartLIst.forEach(item => {
  1873. const row = {}
  1874. chartData.columns.forEach(column => {
  1875. if (field[column] === 'total_amount' || field[column] === 'total_number') {
  1876. row[column] = (item[field[column]] * 100).toFixed(2)
  1877. total += (item[field[column]] - 0)
  1878. } else {
  1879. row[column] = item[field[column]]
  1880. }
  1881. })
  1882. chartData.rows.push(row)
  1883. })
  1884. }
  1885. if (total) {
  1886. chartData.rows.reverse()
  1887. this.$set(this.sections.winner, 'chartData', chartData)
  1888. this.sections.winner.dataAlready = true
  1889. }
  1890. this.sortWinnerTableData(data)
  1891. },
  1892. sortWinnerTableData (data) {
  1893. const dataCount = {
  1894. columns: ['序号', '中标单位:中标数量(个)', '前3采购单位:采购数量(个)'], // ,占比 | ,占该中标单位
  1895. rows: []
  1896. }
  1897. const dataAmount = {
  1898. columns: ['序号', '中标单位:中标金额(万元),占比', '前3采购单位:采购金额(万元),占该中标单位'], // ,占比 | ,占该中标单位
  1899. rows: []
  1900. }
  1901. const countTop3 = data.winner_count_top3
  1902. if (Array.isArray(countTop3)) {
  1903. countTop3.forEach((item, index) => {
  1904. item.name = item.name
  1905. item.type = 'winner'
  1906. item.id = item.id
  1907. item.subInfo1 = item.number ? `中标数量:${item.number}个` : ''
  1908. // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
  1909. item.actionText = `采购单位 TOP3`
  1910. item.childrenShow = true
  1911. item.children = []
  1912. if (Array.isArray(item.buyertop3)) {
  1913. item.buyertop3.forEach((w, i) => {
  1914. const row = {
  1915. name: w.name,
  1916. id: w.name,
  1917. type: 'buyer',
  1918. subInfo1: w.number ? `采购数量:${w.number}个` : '',
  1919. // subInfo2: w.accounted ? `占该中标单位:${utils.formatMoney(w.accounted * 100, undefined, true)}%` : ''
  1920. }
  1921. item.children.push(row)
  1922. })
  1923. }
  1924. })
  1925. dataCount.rows = countTop3
  1926. }
  1927. const amountTop3 = data.winner_amount_top3
  1928. if (Array.isArray(amountTop3)) {
  1929. amountTop3.forEach((item, index) => {
  1930. item.name = item.name
  1931. item.type = 'winner'
  1932. item.id = item.id
  1933. item.subInfo1 = item.amount ? `中标金额:${utils.formatMoney(item.amount / 10000, undefined, true)}万元` : ''
  1934. // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
  1935. item.actionText = `采购单位 TOP3`
  1936. item.childrenShow = true
  1937. item.children = []
  1938. if (Array.isArray(item.buyertop3)) {
  1939. item.buyertop3.forEach((w, i) => {
  1940. const row = {
  1941. name: w.name,
  1942. id: w.name,
  1943. type: 'buyer',
  1944. subInfo1: w.amount ? `采购金额:${utils.formatMoney(w.amount / 10000, undefined, true)}万元` : '',
  1945. // subInfo2: w.accounted ? `占该中标单位:${utils.formatMoney(w.accounted * 100, undefined, true)}%` : ''
  1946. }
  1947. item.children.push(row)
  1948. })
  1949. }
  1950. })
  1951. dataAmount.rows = amountTop3
  1952. }
  1953. if (dataCount.rows.length) {
  1954. if (dataCount.rows.length > 3) {
  1955. this.sections.winner.showCountAllBtn = true
  1956. } else {
  1957. this.sections.winner.showCountAllBtn = false
  1958. }
  1959. this.$set(this.sections.winner, 'projectCountTop3', dataCount.rows)
  1960. }
  1961. if (dataAmount.rows.length) {
  1962. if (dataAmount.rows.length > 3) {
  1963. this.sections.winner.showAmoutAllBtn = true
  1964. } else {
  1965. this.sections.winner.showAmoutAllBtn = false
  1966. }
  1967. this.$set(this.sections.winner, 'projectAmountTop3', dataAmount.rows)
  1968. }
  1969. },
  1970. toAnalysisPage: function () {
  1971. this.rid = ''
  1972. this.analysis.loaded = false
  1973. this.filtersPageShow = true
  1974. },
  1975. moneyUnit (num, type, lv) {
  1976. const m = utils.moneyUnit(num, type, lv)
  1977. let unit = String(m).match(/[\u4e00-\u9fa5]/g)
  1978. if (unit && Array.isArray(unit)) {
  1979. unit = unit.join('')
  1980. } else {
  1981. unit = ''
  1982. }
  1983. let count = ''
  1984. if (unit) {
  1985. count = m.replace(unit, '') - 0
  1986. }
  1987. return {
  1988. unit,
  1989. count
  1990. }
  1991. },
  1992. anchorTo (item) {
  1993. // if (!item.top) return
  1994. var offsetTop = item.top || 0
  1995. this.activeDimension = item.id
  1996. this.$nextTick(function () {
  1997. $('.search-result > .j-main')[0].scrollTop = offsetTop
  1998. })
  1999. },
  2000. showSetKeyTip: function () {
  2001. this.notSetKey = true
  2002. },
  2003. setKeyTip: function () {
  2004. this.showDialog({
  2005. title: '',
  2006. message: '分析内容为您订阅的关键词组,您<br />当前尚未订阅,请前往完善',
  2007. className: 'j-confirm-dialog text-center',
  2008. showConfirmButton: true,
  2009. showCancelButton: true,
  2010. confirmButtonText: '订阅管理',
  2011. confirmButtonColor: '#2abed1'
  2012. }).then(() => {
  2013. if (this.isSubCount) {
  2014. // 提示联系管理员
  2015. this.showToast('请联系管理员完善订阅的关键词')
  2016. // this.showDialog({
  2017. // title: '',
  2018. // message: '请联系管理员完善订阅的关键词',
  2019. // className: 'j-confirm-dialog text-center',
  2020. // showConfirmButton: true,
  2021. // showCancelButton: false,
  2022. // confirmButtonText: '我知道了',
  2023. // confirmButtonColor: '#2abed1'
  2024. // })
  2025. } else {
  2026. this.toSubManage()
  2027. }
  2028. })
  2029. },
  2030. toSubManageButtonClick: function () {
  2031. if (this.isSubCount) {
  2032. this.showToast('请联系管理员完善订阅的关键词')
  2033. } else {
  2034. this.toSubManage()
  2035. }
  2036. },
  2037. toSubManage: function () {
  2038. this.isWeixin = utils.isWeiXinBrowser
  2039. let rootlink = 'f'
  2040. if (this.powerInfo.memberStatus > 0) {
  2041. rootlink = 'm'
  2042. } else if (this.powerInfo.vipStatus > 0) {
  2043. rootlink = 'v'
  2044. } else {
  2045. rootlink = 'f'
  2046. }
  2047. if(utils.$envs.inWX) {
  2048. location.href = '/front/vipsubscribe/toSetKeyWordPage?vSwitch=' + rootlink
  2049. } else {
  2050. location.href = '/jyapp/vipsubscribe/toSetKeyWordPage?vSwitch=' + rootlink
  2051. }
  2052. },
  2053. toArticleContent (item) {
  2054. this.saveState()
  2055. if (utils.$envs.inWX) {
  2056. location.href = `/article/content/${item._id}.html`
  2057. } else {
  2058. location.href = `/jyapp/article/content/${item._id}.html`
  2059. }
  2060. },
  2061. toPortrait (id, type) {
  2062. if (!type || !id) return
  2063. this.saveState()
  2064. if (type === 'winner') {
  2065. if (utils.$envs.inWX) {
  2066. location.href = `/weixin/frontPage/collection/sess/ent_portrait?eId=${id}`
  2067. } else {
  2068. location.href = `./ent_portrait?eId=${id}`
  2069. }
  2070. } else if (type === 'buyer') {
  2071. if (utils.$envs.inWX) {
  2072. location.href = `/big/wx/page/unit_portrayal?entName=${id}`
  2073. } else {
  2074. location.href = `./unit_portrayal?entName=${id}`
  2075. }
  2076. }
  2077. },
  2078. // 报告取消
  2079. reportCancel: function (id) {
  2080. var _this = this
  2081. $.ajax({
  2082. type: 'POST',
  2083. url: '/bigmember/marketAnalysis/cancel',
  2084. data: {
  2085. rid: id
  2086. },
  2087. success: function (res) {
  2088. if (res.data) {
  2089. _this.startAnalysis()
  2090. } else {
  2091. _this.showToast(res.error_msg)
  2092. }
  2093. },
  2094. error: function (error) {
  2095. console.error(error)
  2096. }
  2097. })
  2098. }
  2099. }
  2100. })