Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

1348 Zeilen
33 KiB

  1. <template>
  2. <view class="pages">
  3. <!-- 日报内容部分 -->
  4. <view class="container">
  5. <!-- 头部日报卡 -->
  6. <view class="c-head-card">
  7. <view class="c-title-text">
  8. {{ projectName || '' }}数智工牌周报
  9. </view>
  10. <text class="date">{{ weekObj.createTimeName }}</text>
  11. <view class="creative-time">
  12. 生成时间:{{ weekObj.createTime || '--' }}
  13. </view>
  14. </view>
  15. </view>
  16. <view class="nodata-box" v-if="nodata">
  17. <image class="img" src="/static/images/nodata.png" mode="" />
  18. <view class="text">此项目本周还没有接待量哦~</view>
  19. </view>
  20. <view v-if="!nodata">
  21. <!-- 简报 -->
  22. <view class="briefing">
  23. <view class="briefing-title">
  24. 简报
  25. </view>
  26. <!-- 简报表格部分 -->
  27. <view class="briefing-box">
  28. <block v-for="(data, index) in numlist" :key="index">
  29. <view class="briefing-box-item">
  30. <view class="tops" :class="[data.class || '']">
  31. {{ data.name }}
  32. </view>
  33. <view class="middle" :class="[data.class || '']">
  34. {{ data.num || 0 }}
  35. </view>
  36. <view class="bottom">
  37. 对比上周: {{ data.preNum || 0 }}
  38. <text class="b-text"
  39. :class="{up: data.percent > 0, down: data.percent < 0}">{{ data.percent || '0' }}</text>
  40. <template v-if="data.percent != 0">
  41. <text style="margin-left: 8rpx;font-size: 34rpx;font-weight: bold;"
  42. :class="{up: data.percent > 0, down: data.percent < 0}">{{ data.percent > 0 ? '↑' : '↓' }}</text>
  43. </template>
  44. </view>
  45. </view>
  46. </block>
  47. </view>
  48. </view>
  49. <!-- 销讲场景执行排名 -->
  50. <view class="execution-ranking" v-if="!weekObj.orgCode">
  51. <view class="execution-ranking-title">
  52. 销讲场景执行排名
  53. </view>
  54. <template v-if="isShowXJTop1List">
  55. <view class="execution-ranking-desc" v-if="false">
  56. <text>销讲场景平均执行对比上周</text>
  57. <text>{{ rankTop('fractionPKName') }}</text>
  58. <text>{{ rankTop('fractionPK') }}</text>
  59. <text>%</text>
  60. <template v-if="rankTop('fractionBastValue') > 0">
  61. <text>,其中【{{ rankTop('fractionBastName') }}】最强为</text>
  62. <text class="up">{{ rankTop('fractionBastValue') }}</text>
  63. <text>%</text>
  64. </template>
  65. <template v-if="rankTop('fractionLastValue') < 0">
  66. <text>,【{{ rankTop('fractionLastName') }}】执行最弱为</text>
  67. <text class="down">{{ rankTop('fractionLastValue') }}</text>
  68. <text>%;</text>
  69. </template>
  70. </view>
  71. <!-- 排名百分比列表 -->
  72. <view class="ranking-box" @click="toTrendAnalysis('销讲数据')">
  73. <block v-for="(percent, index) in weekObj.XJTop1List" :key="index">
  74. <view class="ranking-item">
  75. <view class="left">{{ percent.title }}</view>
  76. <view class="middle">
  77. <u-line-progress :active-color="$options.filters.setColor(index)"
  78. inactive-color="#F2F2F2" :show-percent="false" :percent="percent.value">
  79. </u-line-progress>
  80. </view>
  81. <view class="right"> {{ percent.value || '0' }} %</view>
  82. </view>
  83. </block>
  84. </view>
  85. </template>
  86. <template v-else>
  87. <view class="empity">
  88. 暂无数据
  89. </view>
  90. </template>
  91. </view>
  92. <!-- 接待统计 -->
  93. <view class="statistics">
  94. <view class="statistics-title">
  95. 接待统计
  96. </view>
  97. <template v-if="isShowStatistics">
  98. <view class="statistics-desc" v-if="false">
  99. <text>
  100. 顾问平均执行率对比上周
  101. </text>
  102. <text>
  103. {{ rankTop('ranktype') || '' }}
  104. </text>
  105. <text :class="[rankTop('class')]">{{ rankTop('people') || '' }}</text>
  106. <text class="">
  107. 人,其中{{ rankTop('topName') || '' }}上升
  108. </text>
  109. <text class="up">{{ rankTop('topPk') || '0' }}</text>
  110. <text class="">
  111. %为最高,{{ rankTop('lastName') || '' }}下降
  112. </text>
  113. <text class="down">{{ rankTop('lastPk') || '0' }}</text>
  114. <text class="">
  115. %降幅最大。
  116. </text>
  117. </view>
  118. <view class="table">
  119. <view class="thead">
  120. <block v-for="(head, headIndex) in tableHead" :key="headIndex">
  121. <view class="thead-item"
  122. :style="[(weekObj.orgCode && head.title2) ? head.style1 : head.style]">
  123. <template v-if="weekObj.orgCode && head.title2">
  124. {{ head.title2 }}
  125. </template>
  126. <template v-else>
  127. {{ head.title }}
  128. </template>
  129. </view>
  130. </block>
  131. </view>
  132. <view class="tbody" @click="toEmployeesstatistics('顾问排名')">
  133. <block v-for="(data, index) in weekObj.customerInfo1" :key="index">
  134. <view class="tbody-item">
  135. <template v-if="!weekObj.orgCode">
  136. <view class="tbody-items name">{{ data.name }}</view>
  137. </template>
  138. <template v-else>
  139. <view class="tbody-items time">{{ data.houseName }}</view>
  140. </template>
  141. <view class="tbody-items nums">{{ data.activeCustomer }}</view>
  142. <template v-if="!weekObj.orgCode">
  143. <view class="tbody-items time">{{ data.avgDuration }}m</view>
  144. </template>
  145. <template v-else>
  146. <view class="tbody-items time">{{ data.avgDuration/60 }}m</view>
  147. </template>
  148. <view class="tbody-items percent">{{ data.fraction }}%</view>
  149. <template v-if="!weekObj.orgCode">
  150. <view class="tbody-items week" :class="{up: data.pk > 0, down: data.pk < 0}">
  151. <template v-if="data.pk">
  152. {{ data.pk > 0 ? `+${data.pk}` : data.pk }}%
  153. </template>
  154. </view>
  155. </template>
  156. <template v-else>
  157. <view class="tbody-items week"
  158. :class="{up: data.fractionContrast > 0, down: data.fractionContrast < 0}">
  159. <template v-if="data.fractionContrast">
  160. {{ data.fractionContrast > 0 ? `+${data.fractionContrast}` : data.fractionContrast }}%
  161. </template>
  162. </view>
  163. </template>
  164. </view>
  165. </block>
  166. </view>
  167. </view>
  168. </template>
  169. <template v-else>
  170. <view class="empity">
  171. 暂无数据
  172. </view>
  173. </template>
  174. </view>
  175. <!-- 顾问销讲执行率排名 -->
  176. <view class="guwen-ranking">
  177. <view class="guwen-ranking-title">
  178. <template v-if="!weekObj.orgCode">
  179. 顾问销讲执行率排名(TOP10)
  180. </template>
  181. <template v-else>
  182. 项目统计排名(TOP10)
  183. </template>
  184. </view>
  185. <template v-if="isShowZXLTopList">
  186. <!-- 排名百分比列表 -->
  187. <view class="ranking-box">
  188. <block v-for="(percent, index) in weekObj.ZXLTopList" :key="index">
  189. <view class="ranking-item" @click="toStaffAnalysis('销讲数据', percent)">
  190. <view class="left">{{ percent.title }}</view>
  191. <view class="middle">
  192. <u-line-progress :active-color="$options.filters.setColor(index)"
  193. inactive-color="#F2F2F2" :show-percent="false" :percent="percent.value">
  194. </u-line-progress>
  195. </view>
  196. <view class="right"> {{ percent.value || '0' }} %</view>
  197. </view>
  198. </block>
  199. </view>
  200. </template>
  201. <template v-else>
  202. <view class="empity">
  203. 暂无数据
  204. </view>
  205. </template>
  206. </view>
  207. <!-- 顾问接待量排名 -->
  208. <view class="guwen-ranking">
  209. <view class="guwen-ranking-title">
  210. <template v-if="!weekObj.orgCode">
  211. 顾问接待量排名(TOP10)
  212. </template>
  213. <template v-else>
  214. 项目有效接待排名(TOP10)
  215. </template>
  216. </view>
  217. <template v-if="isShowJDLTopList">
  218. <!-- 排名百分比列表 -->
  219. <view class="ranking-box">
  220. <block v-for="(percent, index) in weekObj.JDLTopList" :key="index">
  221. <view class="ranking-item" @click="toStaffAnalysis('销讲数据', percent)">
  222. <view class="left">{{ percent.title }}</view>
  223. <view class="middle">
  224. <u-line-progress :active-color="$options.filters.setColor(index)"
  225. inactive-color="#F2F2F2" :show-percent="false" :percent="percent.values">
  226. </u-line-progress>
  227. </view>
  228. <view class="right"> {{ percent.value || '0' }} </view>
  229. </view>
  230. </block>
  231. </view>
  232. </template>
  233. <template v-else>
  234. <view class="empity">
  235. 暂无数据
  236. </view>
  237. </template>
  238. </view>
  239. <!-- 顾问接待量排名 -->
  240. <view class="guwen-ranking" v-if="weekObj.level1List">
  241. <view class="guwen-ranking-title">
  242. 画像一级触达排名(TOP10)
  243. </view>
  244. <template v-if="weekObj.level1List">
  245. <!-- 排名百分比列表 -->
  246. <view class="ranking-box">
  247. <block v-for="(percent, index) in weekObj.level1List" :key="index">
  248. <view class="ranking-item">
  249. <view class="left">{{ percent.name }}</view>
  250. <view class="middle">
  251. <u-line-progress :active-color="$options.filters.setColor(index)"
  252. inactive-color="#F2F2F2" :show-percent="false" :percent="percent.percent">
  253. </u-line-progress>
  254. </view>
  255. <view class="right"> {{ percent.total || '0' }} </view>
  256. </view>
  257. </block>
  258. </view>
  259. </template>
  260. <template v-else>
  261. <view class="empity">
  262. 暂无数据
  263. </view>
  264. </template>
  265. </view>
  266. <view class="guwen-ranking" v-if="weekObj.level2List">
  267. <view class="guwen-ranking-title">
  268. 画像关键词触达排名(TOP10)
  269. </view>
  270. <template v-if="weekObj.level2List">
  271. <!-- 排名百分比列表 -->
  272. <view class="ranking-box">
  273. <block v-for="(percent, index) in weekObj.level2List" :key="index">
  274. <view class="ranking-item">
  275. <view class="left">{{ percent.name }}</view>
  276. <view class="middle">
  277. <u-line-progress :active-color="$options.filters.setColor(index)"
  278. inactive-color="#F2F2F2" :show-percent="false" :percent="percent.percent">
  279. </u-line-progress>
  280. </view>
  281. <view class="right"> {{ percent.total || '0' }} </view>
  282. </view>
  283. </block>
  284. </view>
  285. </template>
  286. <template v-else>
  287. <view class="empity">
  288. 暂无数据
  289. </view>
  290. </template>
  291. </view>
  292. <!-- 使用建议 -->
  293. <view class="proposal" v-if="weekObj.suggest">
  294. <view class="proposal-title">
  295. 使用建议
  296. </view>
  297. <!-- 建议的文字 -->
  298. <view class="proposal-box">
  299. <u-parse class="ql-editor" :content="weekObj.suggest" />
  300. </view>
  301. </view>
  302. <!-- 底部按钮 -->
  303. <view class="nav-footer">
  304. <view class="footer-item" @click="toHome">
  305. 回到管理端
  306. </view>
  307. <view class="footer-item full" style="margin-left: 24rpx;" @tap="forShare">
  308. <button open-type="share" class="fulls">
  309. 一键转发
  310. </button>
  311. </view>
  312. </view>
  313. </view>
  314. </view>
  315. </template>
  316. <script>
  317. import uParse from '@/components/gaoyia-parse/parse.vue'
  318. export default {
  319. components: {
  320. uParse
  321. },
  322. data() {
  323. return {
  324. nodata: false,
  325. tableHead: [{
  326. title: '顾问',
  327. title2: '项目名称',
  328. style: {
  329. flex: 1
  330. },
  331. style1: {
  332. flex: 2
  333. },
  334. },
  335. {
  336. title: '接待量',
  337. style: {
  338. flex: 1
  339. }
  340. },
  341. {
  342. title: '平均接待时长',
  343. style: {
  344. flex: 2
  345. }
  346. },
  347. {
  348. title: '平均执行率',
  349. style: {
  350. flex: 2
  351. }
  352. },
  353. {
  354. title: '对比上周',
  355. style: {
  356. flex: 1.5
  357. }
  358. },
  359. ],
  360. id: '', // id
  361. needList: ['JDLTop', 'ZXLTop', 'XJTop1'], // 需要转换数组的内容
  362. // 简报
  363. numlist: [{
  364. name: '接待量 (次)',
  365. num: '',
  366. setName: 'receptionCount1',
  367. percent: '',
  368. percentName: 'receptionCountPK',
  369. preNum: '', // 上周数量
  370. preNumName: 'receptionCount2', //
  371. path: '/pages/center/records/index',
  372. pathParms: '?activeTotal=4&refresh=refresh', // 参数
  373. auth: '接待记录', //
  374. }, {
  375. name: '有效接待 (次)',
  376. num: '',
  377. setName: 'activeCustomer1',
  378. percent: '',
  379. percentName: 'activeCustomerPK',
  380. preNum: '', // 上周数量
  381. preNumName: 'activeCustomer2', //
  382. path: '/pages/center/records/index',
  383. pathParms: '?activeTotal=4&refresh=refresh&validInvalid=0', // 参数
  384. auth: '接待记录', //
  385. },
  386. {
  387. name: '平均执行率(%)',
  388. num: '',
  389. setName: 'fraction1',
  390. percent: '',
  391. percentName: 'fractionPK',
  392. preNum: '', // 上周数量
  393. preNumName: 'fraction2', //
  394. path: '/pages/center/records/index',
  395. pathParms: '?activeTotal=4&refresh=refresh&validInvalid=0', // 参数
  396. auth: '接待记录', //
  397. },
  398. {
  399. name: '平均接待时长(分)',
  400. num: '',
  401. setName: 'avgDuration1',
  402. percent: '',
  403. percentName: 'avgDurationPK',
  404. preNum: '', // 上周数量
  405. preNumName: 'avgDuration2', //
  406. path: '/pages/center/records/index',
  407. pathParms: '?activeTotal=4&refresh=refresh&validInvalid=0', // 参数
  408. auth: '接待记录', //
  409. },
  410. {
  411. name: '违禁接待 (次)',
  412. num: '',
  413. setName: 'prohibitedNum1',
  414. percent: '',
  415. percentName: 'prohibitedNumPK',
  416. preNum: '', // 上周数量
  417. preNumName: 'prohibitedNum2', //
  418. class: 'down',
  419. path: '/pages/center/prohibited/index',
  420. pathParms: '?activeTotal=4&violatedStatus=1&refresh=refresh', // 参数
  421. auth: '违禁记录',
  422. },
  423. {
  424. name: '客户画像触达 (次)',
  425. num: '',
  426. setName: 'reachSum1',
  427. percent: '',
  428. percentName: 'reachSumPK',
  429. preNum: '', // 上周数量
  430. preNumName: 'reachSum2', //
  431. path: '/pages/center/Piabodata/Userinsightinto',
  432. pathParms: '?activeTotal=3', // 参数
  433. auth: '销讲数据',
  434. },
  435. {
  436. name: '已标记',
  437. num: '',
  438. setName: 'labelledReceptionNum1',
  439. percent: '',
  440. percentName: 'labelledReceptionNumPK',
  441. preNum: '', // 上周数量
  442. preNumName: 'labelledReceptionNum2', //
  443. path: '/pages/center/records/index',
  444. pathParms: '?activeTotal=4&refresh=refresh&markAdvisor=1', // 参数
  445. auth: '接待记录', //
  446. },
  447. {
  448. name: '未标记',
  449. num: '',
  450. setName: 'unlabelledReceptionNum1',
  451. percent: '',
  452. percentName: 'unlabelledReceptionNumPK',
  453. preNum: '', // 上周数量
  454. preNumName: 'unlabelledReceptionNum2', //
  455. class: 'down',
  456. path: '/pages/center/records/index',
  457. pathParms: '?activeTotal=4&refresh=refresh&markAdvisor=0', // 参数
  458. auth: '接待记录', //
  459. },
  460. ],
  461. // 周报详情
  462. weekObj: {},
  463. projectName: '', // 项目名称
  464. }
  465. },
  466. computed: {
  467. // 获取本地存储的权限列表
  468. menuList() {
  469. return uni.getStorageSync('weapp_session_Menu_data')
  470. },
  471. // 排名最高与最低
  472. rankTop() {
  473. return name => {
  474. let obj = {}
  475. try {
  476. if (this.weekObj.customerInfo1.length && this.weekObj.customerInfo2.length) {
  477. obj.ranktype = (this.weekObj.customerInfo1.length - this.weekObj.customerInfo2.length) >
  478. 0 ? '上升' : '下降'
  479. obj.people = Math.abs(this.weekObj.customerInfo1.length - this.weekObj.customerInfo2
  480. .length)
  481. }
  482. if (this.weekObj.customerInfo1 && this.weekObj.customerInfo1.length > 0) {
  483. obj.topName = this.weekObj.customerInfo1[0].name
  484. obj.topPk = Math.abs(this.weekObj.customerInfo1[0].pk)
  485. obj.lastName = this.weekObj.customerInfo1[this.weekObj.customerInfo1.length - 1].name,
  486. obj.lastPk = Math.abs(this.weekObj.customerInfo1[this.weekObj.customerInfo1.length - 1]
  487. .pk)
  488. }
  489. if (this.weekObj.customerInfo1.length && this.weekObj.customerInfo2.length) {
  490. obj.class = (this.weekObj.customerInfo1.length - this.weekObj.customerInfo2.length) > 0 ?
  491. 'up' : 'down'
  492. }
  493. if (this.weekObj.fractionPK) {
  494. obj.fractionPKName = this.weekObj.fractionPK > 0 ? '上涨' : '下跌'
  495. obj.fractionPK = Math.abs(this.weekObj.fractionPK)
  496. }
  497. if (this.weekObj.XJTop1List && this.weekObj.XJTop1List.length > 0) {
  498. obj.fractionBastName = this.weekObj.XJTop1List[0].title
  499. obj.fractionBastValue = this.weekObj.XJTop1List[0].value
  500. }
  501. if (this.weekObj.XJTop1List && this.weekObj.XJTop1List.length > 0) {
  502. obj.fractionLastName = this.weekObj.XJTop1List[this.weekObj.XJTop1List.length - 1].title
  503. obj.fractionLastValue = this.weekObj.XJTop1List[this.weekObj.XJTop1List.length - 1].value
  504. }
  505. return obj[name] || ''
  506. } catch (e) {
  507. console.log(e)
  508. return ''
  509. }
  510. }
  511. },
  512. // 接待统计
  513. isShowStatistics() {
  514. // return this.rankTop('ranktype') && this.rankTop('class') && this.rankTop('people') && this.rankTop('topName') && this.rankTop('topPk') && this.rankTop('lastName') && this.rankTop('lastPk') && this.weekObj.customerInfo1 && this.weekObj.customerInfo1.length > 0
  515. return this.weekObj.customerInfo1 && this.weekObj.customerInfo1.length > 0
  516. },
  517. isShowXJTop1List() {
  518. // return this.weekObj.XJTop1List && this.weekObj.XJTop1List.length > 0 && this.rankTop('fractionPKName') && this.rankTop('fractionPK') && this.rankTop('fractionBastName') && this.rankTop('fractionBastValue') && this.rankTop('fractionLastName') && this.rankTop('fractionLastName') && this.rankTop('fractionLastValue')
  519. return this.weekObj.XJTop1List && this.weekObj.XJTop1List.length > 0
  520. },
  521. isShowZXLTopList() {
  522. return this.weekObj.ZXLTopList && this.weekObj.ZXLTopList.length > 0
  523. },
  524. isShowJDLTopList() {
  525. return this.weekObj.JDLTopList && this.weekObj.JDLTopList.length > 0
  526. },
  527. },
  528. onLoad(option) {
  529. if (option.id) this.id = option.id
  530. this.getMessage()
  531. },
  532. onShareAppMessage() {
  533. return {
  534. title: `${this.projectName}数智工牌周报`,
  535. path: `/pages/reportExcel/weekReport?id=${this.id}`
  536. }
  537. },
  538. methods: {
  539. forShare() {
  540. this.$u.get("/zkMessage/shareMessage", {
  541. id: this.id
  542. })
  543. },
  544. // 趋势分析
  545. toTrendAnalysis(name) {
  546. return
  547. let date = this.weekObj.weekDate.split('~')
  548. let [t1, t2] = [date[0], date[1]]
  549. let time1 = new Date(t1.replace(/-/g, '/'))
  550. let time2 = new Date(t2.replace(/-/g, '/'))
  551. time1.setDate(time1.getDate() - 7)
  552. time2.setDate(time2.getDate() - 7)
  553. let res1 = `${time1.getFullYear()}-${time1.getMonth() + 1}-${time1.getDate()}`
  554. let res2 = `${time2.getFullYear()}-${time2.getMonth() + 1}-${time2.getDate()}`
  555. if (this.isPassWatch(name)) {
  556. uni.navigateTo({
  557. url: `/pages/center/Piabodata/TrendAnalysis?type=1&staTime=${date[0]}&endtime=${date[1]}&staTime1=${res1}&endtime1=${res2}`
  558. })
  559. } else {
  560. uni.showToast({
  561. title: '暂无权限',
  562. icon: "none"
  563. })
  564. }
  565. },
  566. // 顾问排名
  567. toEmployeesstatistics(name) {
  568. let date = this.weekObj.weekDate.split('~')
  569. let [t1, t2] = [date[0], date[1]]
  570. if (this.isPassWatch(name)) {
  571. uni.navigateTo({
  572. url: `/pages/center/Piabodata/Employeesstatistics?type=1&staTime=${date[0]}&endtime=${date[1]}`
  573. })
  574. } else {
  575. uni.showToast({
  576. title: '暂无权限',
  577. icon: "none"
  578. })
  579. }
  580. },
  581. // 员工分析
  582. toStaffAnalysis(name, data) {
  583. let obj = this.weekObj.customerInfo1.find(item => {
  584. return item.name == data.title
  585. })
  586. console.log(obj)
  587. let time = this.weekObj.weekDate.split('~')
  588. if (this.isPassWatch(name)) {
  589. uni.navigateTo({
  590. url: `/pages/center/Piabodata/StaffAnalysis?type=1&id=${obj.id}&startDate=${time[0]}&endDate=${time[1]}`
  591. });
  592. } else {
  593. uni.showToast({
  594. title: '暂无权限',
  595. icon: "none"
  596. })
  597. }
  598. },
  599. // 跳转对应页面
  600. toAuthPage(data) {
  601. if (!uni.getStorageSync('weapp_session_login_data').token) {
  602. this.toHome()
  603. return
  604. }
  605. if (this.isPassWatch(data.auth)) {
  606. let time = this.weekObj.weekDate.split('~')
  607. data.pathParms = `${data.pathParms}&staTime=${time[0]}&endtime=${time[1]}`
  608. uni.navigateTo({
  609. url: `${data.path}${data.pathParms}`
  610. })
  611. } else {
  612. uni.showToast({
  613. title: '暂无权限',
  614. icon: "none"
  615. })
  616. }
  617. },
  618. // 是否有权限观看
  619. isPassWatch(name) {
  620. return this.menuList.findIndex(item => {
  621. return item.name == name
  622. }) == -1 ? false : true
  623. },
  624. // 跳转首页
  625. toHome() {
  626. uni.navigateTo({
  627. url: '/pages/index/guide'
  628. })
  629. },
  630. // 获取周报详情
  631. getMessage() {
  632. this.$u.get('/zkMessage/findByProjectId', {
  633. id: this.id
  634. }).then(res => {
  635. // console.log(res)
  636. let data = {}
  637. if (res.zkMessage.content) {
  638. data = JSON.parse(res.zkMessage.content)
  639. this.bubbleSort(data.customerInfo1 || [], 'pk')
  640. this.bubbleSort(data.customerInfo2 || [], 'pk')
  641. data.customerInfo1 && data.customerInfo1.reverse()
  642. data.customerInfo2 && data.customerInfo2.reverse()
  643. this.weekObj = {
  644. ...res.zkMessage,
  645. ...data
  646. }
  647. } else {
  648. this.nodata = true
  649. this.weekObj = {
  650. ...res.zkMessage,
  651. }
  652. }
  653. if (this.weekObj.level1List[0] && this.weekObj.level1List[0].total) {
  654. let max1 = this.weekObj.level1List[0].total || 1
  655. this.weekObj.level1List.forEach(item => {
  656. item.percent = Math.floor((item.total / max1) * 100)
  657. })
  658. } else {
  659. this.weekObj.level1List.forEach(item => {
  660. item.percent = 0
  661. })
  662. }
  663. if (this.weekObj.level2List[0] && this.weekObj.level2List[0].total) {
  664. let max2 = this.weekObj.level2List[0].total || 1
  665. this.weekObj.level2List.forEach(item => {
  666. item.percent = Math.floor((item.total / max2) * 100)
  667. })
  668. } else {
  669. this.weekObj.level2List.forEach(item => {
  670. item.percent = 0
  671. })
  672. }
  673. this.weekObj.createTimeName = this.getTimeLines(this.weekObj.weekDate, 1)
  674. console.log(this.weekObj, 'this.weekObj')
  675. this.projectName = res.projectName
  676. this.numlist.forEach(item => {
  677. if (data[item.setName]) {
  678. item.num = data[item.setName]
  679. }
  680. if (data[item.percentName]) {
  681. item.percent = data[item.percentName]
  682. }
  683. if (data[item.preNumName]) {
  684. item.preNum = data[item.preNumName]
  685. }
  686. })
  687. this.init()
  688. }).catch(e => {
  689. console.log(e)
  690. })
  691. },
  692. // 把对象转成数组并在后续的步骤方便处理
  693. init() {
  694. console.log(this.weekObj, 'this.weekObj')
  695. this.needList.forEach(item => {
  696. console.log(item)
  697. if (this.weekObj[item] && Object.keys(this.weekObj[item]).length > 0) {
  698. this.weekObj[item + 'List'] = [] // 销讲执行
  699. for (let i in this.weekObj[item]) {
  700. this.weekObj[item + 'List'].push({
  701. title: i,
  702. value: this.weekObj[item][i]
  703. })
  704. }
  705. } else {
  706. this.weekObj[item + 'List'] = []
  707. }
  708. })
  709. this.sortInitArr()
  710. },
  711. // 排序对象转换后的数组
  712. sortInitArr() {
  713. this.needList.forEach(item => {
  714. if (this.weekObj[item + 'List']) {
  715. console.log(item)
  716. this.bubbleSort(this.weekObj[item + 'List'])
  717. this.weekObj[item + 'List'] = this.dealData(this.weekObj[item + 'List'])
  718. }
  719. })
  720. this.reverseList()
  721. },
  722. // 反转数组
  723. reverseList() {
  724. this.needList.forEach(item => {
  725. if (this.weekObj[item + 'List']) {
  726. this.weekObj[item + 'List'].reverse()
  727. }
  728. })
  729. console.log(this.weekObj, '12312312312')
  730. },
  731. // 冒泡排序
  732. bubbleSort(arr, keys = 'value') {
  733. console.log(arr, 'keys', keys)
  734. for (let i = 0; i < arr.length - 1; i += 1) {
  735. //通过 arr.length 次把第一位放到最后,完成排序
  736. //-i是因为最后的位置是会动态改变的,当完成一次后,最后一位会变成倒数第二位
  737. for (let j = 0; j < arr.length - 1 - i; j += 1) {
  738. if (arr[j][keys] > arr[j + 1][keys]) {
  739. const temp = arr[j];
  740. arr[j] = arr[j + 1];
  741. arr[j + 1] = temp;
  742. }
  743. }
  744. }
  745. },
  746. // 定义一个公共方法对数据进行处理
  747. dealData(arr) {
  748. // 获取最大值
  749. let num = Math.max.apply(Math, arr.map((o) => {
  750. return o.value
  751. }))
  752. arr.map(item => {
  753. item.values = Math.floor(item.value / num * 100)
  754. })
  755. return arr
  756. },
  757. // 转换时间
  758. getTimeLine(date, type = 1) {
  759. let resu = '--'
  760. if (!date) return resu
  761. let time = new Date(date.replace(/-/g, '/'))
  762. time.setDate(time.getDate() - 7)
  763. let arr = date.split(' ')
  764. let str = arr[0]
  765. let result = str.split('-')
  766. let m = (time.getMonth() + 1) < 10 ? `0${time.getMonth() + 1}` : (time.getMonth() + 1)
  767. let d = time.getDate() < 10 ? `0${time.getDate()}` : time.getDate()
  768. if (type == 1) {
  769. resu = `${m}.${d}-${result[1]}.${result[2]}`
  770. } else {
  771. resu = `${m}月${d}日~${result[1]}月${result[2]}日`
  772. }
  773. return resu
  774. },
  775. // 转换时间
  776. getTimeLines(date) {
  777. if (!date) return ''
  778. let arr = date.split('~')
  779. let str0 = arr[0].split('-')
  780. let str1 = arr[1].split('-')
  781. return `${str0[1]}月${str0[2]}日~${str1[1]}月${str1[2]}日`
  782. },
  783. },
  784. filters: {
  785. // 时间格式转换
  786. fomatDate(date) {
  787. if (!date) return '--'
  788. let arr = date.split(' ')
  789. let str = arr[0]
  790. let result = str.split('-')
  791. return `${result[1]}-${result[2]}`
  792. },
  793. // 转换时间
  794. getTimeLine(date, type = 1) {
  795. if (!date) return '--'
  796. console.log(date.replace(/-/g, '/'))
  797. let time = new Date(date.replace(/-/g, '/'))
  798. time.setDate(time.getDate() - 7)
  799. let arr = date.split(' ')
  800. let str = arr[0]
  801. let result = str.split('-')
  802. let m = (time.getMonth() + 1) < 10 ? `0${time.getMonth() + 1}` : (time.getMonth() + 1)
  803. let d = time.getDate() < 10 ? `0${time.getDate()}` : time.getDate()
  804. if (type == 1) {
  805. return `${m}.${d}-${result[1]}.${result[2]}`
  806. } else {
  807. return `${m}月${d}日~${result[1]}月${result[2]}日`
  808. }
  809. },
  810. // 设置颜色
  811. setColor(index) {
  812. let color = ''
  813. switch (index) {
  814. case 0:
  815. color = '#E7483C';
  816. break;
  817. case 1:
  818. color = '#FF8C13';
  819. break;
  820. case 2:
  821. color = '#FFCC00';
  822. break;
  823. default:
  824. color = '#4FC78F';
  825. break;
  826. }
  827. return color
  828. },
  829. }
  830. }
  831. </script>
  832. <style lang="scss" scoped>
  833. @import '@/static/css/quill/quill.core.css';
  834. @import '@/static/css/quill/quill.snow.css';
  835. @import '@/static/css/quill/quill.bubble.css';
  836. .pages {
  837. width: 100vw;
  838. min-height: 100vh;
  839. display: flex;
  840. flex-direction: column;
  841. background: #F8F8F8;
  842. .nav-header {
  843. flex-shrink: 0;
  844. }
  845. .container {
  846. padding: 30rpx 30rpx 40rpx;
  847. display: flex;
  848. flex-direction: column;
  849. background: #fff;
  850. .c-head-card {
  851. padding: 30rpx;
  852. width: 100%;
  853. min-height: 252rpx;
  854. border: 2rpx solid #000000;
  855. border-radius: 12rpx;
  856. box-shadow: 10rpx 10rpx #2671E2;
  857. display: flex;
  858. flex-direction: column;
  859. .c-title-text {
  860. // position: relative;
  861. flex-grow: 1;
  862. font-size: 48rpx;
  863. font-weight: bold;
  864. color: #303030;
  865. }
  866. .date {
  867. // position: absolute;
  868. // right: 0;
  869. // bottom: 6rpx;
  870. font-size: 30rpx;
  871. color: #303030;
  872. }
  873. .creative-time {
  874. margin: 20rpx 0 0 0;
  875. flex-shrink: 0;
  876. }
  877. }
  878. }
  879. .nodata-box {
  880. width: 750rpx;
  881. flex: 1;
  882. margin: 0 auto;
  883. display: flex;
  884. justify-content: center;
  885. align-items: center;
  886. flex-direction: column;
  887. background-color: #fff;
  888. .img {
  889. width: 400rpx;
  890. height: 400rpx;
  891. }
  892. .text {
  893. text-align: center;
  894. font-size: 28rpx;
  895. font-family: PingFangSC-Regular, PingFang SC;
  896. font-weight: 400;
  897. color: #666666;
  898. line-height: 40rpx;
  899. }
  900. }
  901. .briefing {
  902. background: #fff;
  903. .briefing-title {
  904. padding: 0 30rpx;
  905. height: 90rpx;
  906. display: flex;
  907. align-items: center;
  908. border: 1rpx solid #E0E0E0;
  909. font-size: 32rpx;
  910. font-weight: bold;
  911. }
  912. .briefing-box {
  913. width: 100%;
  914. display: flex;
  915. flex-wrap: wrap;
  916. .briefing-box-item {
  917. padding: 20rpx 30rpx;
  918. width: 50%;
  919. height: 186rpx;
  920. border: 1px solid #E0E0E0;
  921. border-left: none;
  922. border-top: none;
  923. &:nth-of-type(2n) {
  924. border-right: none;
  925. }
  926. .top {
  927. font-size: 28rpx;
  928. }
  929. .middle {
  930. margin: 14rpx 0 12rpx;
  931. font-size: 32rpx;
  932. font-weight: 600;
  933. color: #333333;
  934. }
  935. .bottom {
  936. font-size: 26rpx;
  937. color: #666666;
  938. .b-text {
  939. margin-left: 20rpx;
  940. &.down {
  941. color: #E7483C;
  942. font-size: 34rpx;
  943. }
  944. &.up {
  945. font-size: 34rpx;
  946. color: #43CD80;
  947. }
  948. }
  949. }
  950. }
  951. }
  952. }
  953. .execution-ranking {
  954. margin: 20rpx 0 0 0;
  955. padding: 30rpx;
  956. background: #fff;
  957. .execution-ranking-title {
  958. font-size: 32rpx;
  959. font-weight: bold;
  960. }
  961. .execution-ranking-desc {
  962. margin-top: 20rpx;
  963. font-size: 30rpx;
  964. }
  965. .ranking-box {
  966. margin: 30rpx 0 0 0;
  967. .ranking-item {
  968. margin-bottom: 18rpx;
  969. display: flex;
  970. &:nth-last-of-type(1) {
  971. margin-bottom: 0;
  972. }
  973. .left {
  974. flex-shrink: 0;
  975. width: 270rpx;
  976. font-size: 30rpx;
  977. overflow: hidden;
  978. text-overflow: ellipsis;
  979. white-space: nowrap;
  980. }
  981. .middle {
  982. flex-grow: 1;
  983. }
  984. .right {
  985. flex-shrink: 0;
  986. width: 118rpx;
  987. font-size: 30rpx;
  988. text-align: center;
  989. }
  990. }
  991. }
  992. }
  993. .statistics {
  994. margin: 20rpx 0 0 0;
  995. background: #fff;
  996. .statistics-title {
  997. padding: 30rpx 30rpx 0;
  998. width: 100%;
  999. font-size: 32rpx;
  1000. font-weight: bold;
  1001. }
  1002. .statistics-desc {
  1003. padding: 0 30rpx;
  1004. margin-top: 20rpx;
  1005. }
  1006. .table {
  1007. margin: 30rpx 0 0 0;
  1008. .thead {
  1009. padding: 0 30rpx;
  1010. width: 100%;
  1011. height: 72rpx;
  1012. display: flex;
  1013. align-items: center;
  1014. border: 1rpx solid #E0E0E0;
  1015. border-left: none;
  1016. border-right: none;
  1017. font-size: 26rpx;
  1018. .thead-item {
  1019. text-align: center;
  1020. }
  1021. }
  1022. .tbody {
  1023. .tbody-item {
  1024. padding: 0 30rpx;
  1025. display: flex;
  1026. align-items: center;
  1027. height: 72rpx;
  1028. background: #FAFCFF;
  1029. &:nth-of-type(2n) {
  1030. background: #FFFFFF;
  1031. }
  1032. .tbody-items {
  1033. flex: 1;
  1034. display: flex;
  1035. justify-content: center;
  1036. }
  1037. .name {
  1038. justify-content: flex-start;
  1039. overflow: hidden;
  1040. text-overflow: ellipsis;
  1041. white-space: nowrap;
  1042. }
  1043. .time {
  1044. flex: 2;
  1045. }
  1046. .percent {
  1047. flex: 2;
  1048. }
  1049. .week {
  1050. flex: 1.5;
  1051. }
  1052. }
  1053. }
  1054. .tbottom {
  1055. width: 100%;
  1056. height: 72rpx;
  1057. display: flex;
  1058. justify-content: center;
  1059. align-items: center;
  1060. font-size: 30rpx;
  1061. color: #2671E2;
  1062. background: #FAFCFF;
  1063. }
  1064. }
  1065. }
  1066. .guwen-ranking {
  1067. margin: 20rpx 0 0 0;
  1068. width: 100%;
  1069. padding: 30rpx;
  1070. background: #fff;
  1071. .guwen-ranking-title {
  1072. font-size: 32rpx;
  1073. font-weight: 500;
  1074. }
  1075. .guwen-ranking-desc {
  1076. margin-top: 20rpx;
  1077. font-size: 30rpx;
  1078. }
  1079. .ranking-box {
  1080. margin: 30rpx 0 0 0;
  1081. .ranking-item {
  1082. margin-bottom: 18rpx;
  1083. display: flex;
  1084. &:nth-last-of-type(1) {
  1085. margin-bottom: 0;
  1086. }
  1087. .left {
  1088. flex-shrink: 0;
  1089. width: 270rpx;
  1090. font-size: 30rpx;
  1091. overflow: hidden;
  1092. text-overflow: ellipsis;
  1093. white-space: nowrap;
  1094. }
  1095. .middle {
  1096. flex-grow: 1;
  1097. }
  1098. .right {
  1099. flex-shrink: 0;
  1100. width: 118rpx;
  1101. font-size: 30rpx;
  1102. text-align: center;
  1103. }
  1104. }
  1105. }
  1106. }
  1107. .proposal {
  1108. margin: 20rpx 0 0 0;
  1109. padding: 30rpx;
  1110. background: #fff;
  1111. .proposal-title {
  1112. font-size: 32rpx;
  1113. font-weight: 500;
  1114. }
  1115. .proposal-box {
  1116. margin: 30rpx 0 0 0;
  1117. .proposal-item {
  1118. margin: 20rpx 0 0 0;
  1119. display: flex;
  1120. .lside {
  1121. flex-shrink: 0;
  1122. margin: 0 12rpx 0 0;
  1123. width: 44rpx;
  1124. height: 44rpx;
  1125. border-radius: 50%;
  1126. background: #2671E2;
  1127. text-align: center;
  1128. line-height: 44rpx;
  1129. color: #fff;
  1130. }
  1131. .rside {
  1132. .rside-title {
  1133. font-size: 32rpx;
  1134. }
  1135. .rside-box {
  1136. margin: 16rpx 0 0 0;
  1137. }
  1138. }
  1139. }
  1140. }
  1141. }
  1142. .nav-footer {
  1143. position: sticky;
  1144. bottom: 0;
  1145. padding: 32rpx;
  1146. width: 100%;
  1147. display: flex;
  1148. justify-content: center;
  1149. background: #fff;
  1150. .footer-item {
  1151. flex: 1;
  1152. height: 88rpx;
  1153. display: flex;
  1154. justify-content: center;
  1155. align-items: center;
  1156. color: #2671E2;
  1157. border: 2rpx solid #2671E2;
  1158. border-radius: 8rpx;
  1159. overflow: hidden;
  1160. font-size: 32rpx;
  1161. &.full {
  1162. background: #2671E2;
  1163. color: #fff;
  1164. .fulls {
  1165. box-sizing: border-box;
  1166. width: 100%;
  1167. height: 100%;
  1168. background: transparent;
  1169. color: #fff;
  1170. font-size: 32rpx;
  1171. font-weight: normal;
  1172. line-height: 88rpx;
  1173. }
  1174. }
  1175. }
  1176. }
  1177. .up {
  1178. color: #43CD80 !important;
  1179. }
  1180. .down {
  1181. color: #E6273A !important;
  1182. }
  1183. .empity {
  1184. width: 100%;
  1185. height: 300rpx;
  1186. display: flex;
  1187. justify-content: center;
  1188. align-items: center;
  1189. font-size: 28rpx;
  1190. color: #666666;
  1191. }
  1192. }
  1193. </style>