index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. <!--
  2. * @Author: liuzhenlin 461480418@qq.ocm
  3. * @Date: 2023-01-12 11:57:48
  4. * @LastEditors: liuzhenlin
  5. * @LastEditTime: 2023-03-06 16:46:52
  6. * @Description: file content
  7. * @FilePath: \oms\pages\home\index.vue
  8. -->
  9. <template>
  10. <view class="home">
  11. <!-- <WaterMark></WaterMark> -->
  12. <view class="nav">
  13. <view :style="{ paddingTop }">
  14. <view class="title" :style="[{ height }, { lineHeight: height }]">首页</view>
  15. </view>
  16. </view>
  17. <view class="main">
  18. <view class="header">
  19. <u-swiper :list="bannerList" radius="0" interval="5000" circular></u-swiper>
  20. <!-- <view class="h-left">
  21. <text class="name">大数华创</text>
  22. <text class="txt">提升工作效率,降低管理难度</text>
  23. <view class="line"></view>
  24. </view>
  25. <view class="h-right"></view> -->
  26. </view>
  27. <view class="msg-box">
  28. <view class="tab-date-wrap">
  29. <text class="tab-date-item" @click="getReport('week')" :class="{ dateActive: tabDate == 'week' }">本周</text>
  30. <text class="tab-date-item" @click="getReport('month')" :class="{ dateActive: tabDate == 'month' }">
  31. 本月
  32. </text>
  33. </view>
  34. <view class="date-msg">
  35. <u-row justify="space-between">
  36. <u-col span="4">
  37. <view class="center flex-column" @click="handleHomeLink('/pages/openSeaCustomer/index')">
  38. <view class="num">{{ newCustomer }}</view>
  39. <view class="txt">新增客户</view>
  40. </view>
  41. </u-col>
  42. <u-col span="4">
  43. <view class="center flex-column" @click="handleHomeLink('/pages/project/index')">
  44. <view class="num">{{ newBusiness }}</view>
  45. <view class="txt">新增项目</view>
  46. </view>
  47. </u-col>
  48. <u-col span="4">
  49. <view class="center flex-column" @click="handleHomeLink('/pages/schedule/index?type=1', 2)">
  50. <view class="num">{{ newTask }}</view>
  51. <view class="txt">督办事项</view>
  52. </view>
  53. </u-col>
  54. </u-row>
  55. </view>
  56. </view>
  57. <view class="menu-wrap">
  58. <u-row justify="space-between" gutter="14">
  59. <u-col span="6">
  60. <view class="menu-item flex_l flex-colunm" @click="handleHomeLink('/pages/openSeaCustomer/index')">
  61. <view class="menu-img-box">
  62. <image class="menu-img" src="../../static/images/menu5.png" mode="scaleToFill" />
  63. </view>
  64. <view class="menu-info flex flex-column">
  65. <view class="tit1">公海客户</view>
  66. <view class="tit2">公海客户管理</view>
  67. </view>
  68. </view>
  69. </u-col>
  70. <u-col span="6">
  71. <view class="menu-item flex_l flex-colunm" @click="handleHomeLink('/pages/customer/index')">
  72. <view class="menu-img-box">
  73. <image class="menu-img" src="../../static/images/menu1.png" mode="scaleToFill" />
  74. </view>
  75. <view class="menu-info flex flex-column">
  76. <view class="tit1">客户管理</view>
  77. <view class="tit2">客户信息管理</view>
  78. </view>
  79. </view>
  80. </u-col>
  81. </u-row>
  82. <u-row justify="space-between" gutter="14">
  83. <u-col span="6">
  84. <view class="menu-item flex_l flex-colunm" @click="handleHomeLink('/pages/project/index')">
  85. <view class="menu-img-box">
  86. <image class="menu-img" src="../../static/images/menu2.png" mode="scaleToFill" />
  87. </view>
  88. <view class="menu-info flex flex-column">
  89. <view class="tit1">项目管理</view>
  90. <view class="tit2">项目进展查询</view>
  91. </view>
  92. </view>
  93. </u-col>
  94. <u-col span="6">
  95. <view class="menu-item flex_l flex-colunm" @click="handleHomeLink('/pages/contract/index')">
  96. <view class="menu-img-box">
  97. <image class="menu-img" src="../../static/images/menu3.png" mode="scaleToFill" />
  98. </view>
  99. <view class="menu-info flex flex-column">
  100. <view class="tit1">合同管理</view>
  101. <view class="tit2">合同信息查阅</view>
  102. </view>
  103. </view>
  104. </u-col>
  105. </u-row>
  106. <u-row justify="space-between" gutter="14">
  107. <u-col span="6">
  108. <view class="menu-item flex_l flex-colunm" @click="handleHomeLink('/pages/distributor/index')">
  109. <view class="menu-img-box">
  110. <image class="menu-img" src="../../static/images/menu4.png" mode="scaleToFill" />
  111. </view>
  112. <view class="menu-info flex flex-column">
  113. <view class="tit1">合作伙伴</view>
  114. <view class="tit2">合作伙伴展示</view>
  115. </view>
  116. </view>
  117. </u-col>
  118. <u-col span="6">
  119. <view class="menu-item flex_l flex-colunm" @click="handleHomeLink()">
  120. <view class="menu-img-box">
  121. <image class="menu-img" src="../../static/images/menu6.png" mode="scaleToFill" />
  122. </view>
  123. <view class="menu-info flex flex-column">
  124. <view class="tit1">工单管理</view>
  125. <view class="tit2">工单进度查询</view>
  126. </view>
  127. </view>
  128. </u-col>
  129. </u-row>
  130. </view>
  131. <view class="data-container">
  132. <h4>个人看板</h4>
  133. <view class="flex flex-wrap flex-around">
  134. <view class="board-data" v-for="(v, i) in privateBoard" :key="i">
  135. <view>
  136. <u-text :bold="true" :text="v.report_data"></u-text>
  137. </view>
  138. <view>
  139. <u-text lines="1" :text="v.report_name"></u-text>
  140. </view>
  141. </view>
  142. </view>
  143. </view>
  144. <view class="data-container">
  145. <h4>个人报表</h4>
  146. <view class="echarts" v-for="item in echarts" :key="item.id">
  147. <h4>{{ item.report_name }}</h4>
  148. <view class="chart">
  149. <l-echart :ref="item.id + ''" @finished="init(item.id)"></l-echart>
  150. </view>
  151. </view>
  152. </view>
  153. <!-- <view class="rank-wrap">
  154. <view class="rank-tit flex_l">
  155. <image class="rank-tit-img" src="../../static/images/rank-img.png" mode="scaleToFill" />
  156. <text>回款排名</text>
  157. </view>
  158. <view class="rank-list-wrap">
  159. <view class="rank-th">
  160. <u-row justify="space-between">
  161. <u-col span="2">
  162. <view class="th1 text-center">排名</view>
  163. </u-col>
  164. <u-col span="4">
  165. <view class="th2 text-center">姓名</view>
  166. </u-col>
  167. <u-col span="6">
  168. <view class="th3 text-center">回款额</view>
  169. </u-col>
  170. </u-row>
  171. </view>
  172. <view class="rank-list">
  173. <view class="rank-item" v-for="(v, i) in rankList" :key="i">
  174. <u-row justify="space-between">
  175. <u-col span="2">
  176. <view class="rank-box center">
  177. <image
  178. class="rank-img"
  179. v-if="i < 3"
  180. :src="require(`../../static/images/rank${i + 1}.png`)"
  181. mode=""></image>
  182. <view v-else class="th1 text-center rank">{{ i + 1 }}</view>
  183. </view>
  184. </u-col>
  185. <u-col span="4">
  186. <view class="th2 text-center">{{ v.name }}</view>
  187. </u-col>
  188. <u-col span="6">
  189. <view class="th3 text-center">
  190. <u-text mode="price" :text="v.money"></u-text>
  191. </view>
  192. </u-col>
  193. </u-row>
  194. </view>
  195. </view>
  196. <view class="view-all">查看全部排名 ></view>
  197. </view>
  198. </view> -->
  199. </view>
  200. <view class="check" @click="toCheckIn">卡</view>
  201. </view>
  202. </template>
  203. <script>
  204. import indexApi from '@/api/system/index.js'
  205. import homeApi from '@/api/home'
  206. import to from 'await-to-js'
  207. import LEchart from '@/uni_modules/lime-echart/components/l-echart/l-echart.vue'
  208. import * as echarts from '@/uni_modules/lime-echart/static/echarts.min'
  209. export default {
  210. name: 'omsIndex',
  211. data() {
  212. return {
  213. bannerList: [
  214. require('@/static/images/swiper/banner1.png'),
  215. require('@/static/images/swiper/banner2.png'),
  216. require('@/static/images/swiper/banner3.png'),
  217. ],
  218. privateBoard: [], //个人看板数据
  219. height: '',
  220. paddingTop: '',
  221. tabDate: 'week',
  222. newCustomer: 0,
  223. newBusiness: 0,
  224. newTask: 0,
  225. rankList: [
  226. // {
  227. // name: '邱国辉',
  228. // money: '100000',
  229. // },
  230. // {
  231. // name: '邱国辉',
  232. // money: '100000000',
  233. // },
  234. // {
  235. // name: '邱国辉',
  236. // money: '100000000',
  237. // },
  238. // {
  239. // name: '邱国辉',
  240. // money: '100000000',
  241. // },
  242. // {
  243. // name: '邱国辉',
  244. // money: '100000000',
  245. // },
  246. ],
  247. echarts: [],
  248. }
  249. },
  250. created() {
  251. const navData = uni.getMenuButtonBoundingClientRect()
  252. this.height = navData.height + 'px'
  253. this.paddingTop = navData.top + 'px'
  254. },
  255. mounted() {
  256. this.getHomeConfig()
  257. },
  258. onShow() {
  259. this.getReport('week')
  260. },
  261. components: {
  262. LEchart,
  263. },
  264. methods: {
  265. async getReport(type) {
  266. this.tabDate = type
  267. let params = { viewInterval: this.tabDate }
  268. const [err, res] = await to(homeApi.getReportData(params))
  269. if (err) return
  270. if (res.code == 200) {
  271. this.newCustomer = res.data.newCustomer
  272. this.newBusiness = res.data.newBusiness
  273. this.newTask = res.data.newTask
  274. }
  275. },
  276. handleHomeLink(url, linkType) {
  277. if (!url) {
  278. uni.showToast({
  279. title: '功能开发中~',
  280. icon: 'none',
  281. })
  282. return
  283. }
  284. if (linkType && linkType == '2') {
  285. uni.reLaunch({
  286. url,
  287. })
  288. } else {
  289. uni.navigateTo({
  290. //保留当前页面,跳转到应用内的某个页面
  291. url,
  292. })
  293. }
  294. },
  295. // 获取首页配置
  296. async getHomeConfig() {
  297. const [err, res] = await to(
  298. indexApi.getHomeReport({
  299. module_code: 'HomePage',
  300. })
  301. )
  302. if (err) return
  303. const obj = JSON.parse(res.data.configInfo)
  304. this.privateBoard = obj.num_report_config || []
  305. this.echarts = obj.data_report_config || []
  306. this.getHomeNumReportData()
  307. },
  308. // 获取首页个人看板数据
  309. async getHomeNumReportData() {
  310. let ids = this.privateBoard.map((item) => {
  311. return item.id
  312. })
  313. const {
  314. data: { num_report_response },
  315. } = await indexApi.getHomeNumReportData({ ids: ids })
  316. let privateBoardData = []
  317. this.privateBoard.forEach((item, index) => {
  318. num_report_response.forEach((val) => {
  319. if (item.id === val.id) {
  320. this.privateBoard[index].report_data = val.data
  321. privateBoardData.push(this.privateBoard[index])
  322. }
  323. })
  324. })
  325. this.privateBoard = privateBoardData.splice(0, 6)
  326. console.log(this.privateBoard)
  327. },
  328. async init(id) {
  329. console.log(id, 'id')
  330. const [err, res] = await to(
  331. indexApi.getHomeDataReportData({
  332. id,
  333. })
  334. )
  335. if (err) return
  336. const option = {
  337. grid: {
  338. bottom: 10,
  339. top: 20,
  340. right: 10,
  341. containLabel: true,
  342. },
  343. tooltip: {
  344. trigger: 'axis',
  345. },
  346. xAxis: [
  347. {
  348. type: 'category',
  349. data: res.data.data.xData,
  350. axisTick: {
  351. alignWithLabel: true,
  352. },
  353. },
  354. ],
  355. yAxis: [
  356. {
  357. type: 'value',
  358. name: '(元)',
  359. nameLocation: 'start',
  360. },
  361. ],
  362. series: [
  363. {
  364. name: '销售指标',
  365. type: 'bar',
  366. data: res.data.data.yDataTarget,
  367. },
  368. {
  369. name: '销售额度',
  370. type: 'bar',
  371. data: res.data.data.yDataReal,
  372. },
  373. ],
  374. }
  375. console.log('option', option)
  376. this.$refs[id][0].init(echarts, (chart) => {
  377. chart.setOption(option)
  378. })
  379. },
  380. toCheckIn() {
  381. uni.navigateTo({
  382. //保留当前页面,跳转到应用内的某个页面
  383. url: '/pages/home/checkIn',
  384. })
  385. },
  386. },
  387. }
  388. </script>
  389. <style>
  390. page {
  391. background: #f2f3f5;
  392. }
  393. </style>
  394. <style lang="scss" scoped>
  395. .home {
  396. padding-top: 200rpx;
  397. // position: relative;
  398. .check {
  399. position: fixed;
  400. right: 20rpx;
  401. bottom: 20rpx;
  402. width: 90rpx;
  403. height: 90rpx;
  404. line-height: 90rpx;
  405. text-align: center;
  406. border-radius: 45rpx;
  407. background-color: #3e7ef8;
  408. color: #fff;
  409. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  410. }
  411. .nav {
  412. position: absolute;
  413. left: 0;
  414. top: 0;
  415. width: 100%;
  416. height: 556rpx;
  417. background: #3e7ef8;
  418. border-radius: 0 0 92rpx 92rpx;
  419. z-index: -1;
  420. .title {
  421. text-align: center;
  422. font-size: 32rpx;
  423. font-weight: bold;
  424. color: #ffffff;
  425. }
  426. }
  427. .main {
  428. box-sizing: border-box;
  429. padding: 0 32rpx 46rpx;
  430. position: absolute;
  431. width: 100%;
  432. height: calc(100vh - 200rpx);
  433. // overflow: hidden;
  434. .msg-box {
  435. width: 100%;
  436. height: 185rpx;
  437. background: #ffffff;
  438. box-shadow: 0 6rpx 19rpx 2rpx rgba(0, 45, 132, 0.15);
  439. border-radius: 31rpx 31rpx 31rpx 31rpx;
  440. margin: 0 auto;
  441. .tab-date-wrap {
  442. padding: 8rpx 0 24rpx 38rpx;
  443. .tab-date-item {
  444. font-size: 24rpx;
  445. font-weight: bold;
  446. color: #d8e5fe;
  447. margin-right: 16rpx;
  448. }
  449. .dateActive {
  450. font-size: 28rpx;
  451. color: #3e7ef8;
  452. }
  453. }
  454. .date-msg {
  455. .num {
  456. font-size: 38rpx;
  457. font-weight: bold;
  458. color: #fe6936;
  459. margin-bottom: 4rpx;
  460. }
  461. .txt {
  462. font-size: 24rpx;
  463. color: #646464;
  464. }
  465. }
  466. }
  467. .menu-wrap {
  468. .menu-item {
  469. margin-top: 32rpx;
  470. background: #ffffff;
  471. box-shadow: 0 6rpx 19rpx 2rpx rgba(0, 45, 132, 0.15);
  472. border-radius: 31rpx;
  473. padding: 40rpx 0 40rpx 52rpx;
  474. .menu-img-box {
  475. margin-right: 14rpx;
  476. display: flex;
  477. align-items: center;
  478. justify-content: center;
  479. }
  480. .menu-img {
  481. width: 36px;
  482. height: 36px;
  483. }
  484. .menu-info {
  485. display: flex;
  486. .tit1 {
  487. font-size: 28rpx;
  488. font-weight: bold;
  489. color: #323232;
  490. margin-bottom: 12rpx;
  491. }
  492. .tit2 {
  493. font-size: 24rpx;
  494. color: #646464;
  495. }
  496. }
  497. }
  498. }
  499. .rank-wrap {
  500. margin-top: 34rpx;
  501. .rank-tit {
  502. margin-bottom: 18rpx;
  503. .rank-tit-img {
  504. margin: 0 10rpx 0 28rpx;
  505. width: 31rpx;
  506. height: 31rpx;
  507. }
  508. text {
  509. font-size: 28rpx;
  510. font-weight: bold;
  511. color: #323232;
  512. }
  513. }
  514. .rank-list-wrap {
  515. width: 100%;
  516. background: #ffffff;
  517. border-radius: 31rpx;
  518. .rank-th {
  519. padding: 34rpx 0 20rpx 72rpx;
  520. }
  521. .rank-list {
  522. margin-bottom: 24rpx;
  523. .rank-item {
  524. .rank-box {
  525. .rank-img {
  526. width: 41px;
  527. height: 42px;
  528. }
  529. .rank {
  530. width: 41px;
  531. height: 42px;
  532. line-height: 42px;
  533. font-size: 28rpx;
  534. font-weight: bold;
  535. color: #969696;
  536. }
  537. }
  538. padding: 19rpx 0 19rpx 72rpx;
  539. &:not(:last-child) {
  540. border-bottom: 2rpx solid #f2f3f5;
  541. }
  542. }
  543. }
  544. }
  545. .view-all {
  546. font-size: 24rpx;
  547. color: #3e7ef8;
  548. text-align: center;
  549. height: 60rpx;
  550. }
  551. }
  552. .data-container {
  553. background-color: #fff;
  554. box-shadow: 0 6rpx 19rpx 2rpx rgba(0, 45, 132, 0.15);
  555. border-radius: 31rpx 31rpx 31rpx 31rpx;
  556. margin: 0 auto;
  557. margin-top: 32rpx;
  558. padding: 0 20rpx 20rpx;
  559. h4 {
  560. font-size: 28rpx;
  561. line-height: 80rpx;
  562. font-weight: bold;
  563. color: #323232;
  564. padding-left: 40rpx;
  565. }
  566. .board-data {
  567. width: 46%;
  568. border-radius: 10rpx;
  569. padding: 0 20rpx;
  570. border: 1px solid #eee;
  571. line-height: 50rpx;
  572. margin-bottom: 20rpx;
  573. }
  574. .echarts {
  575. height: 480rpx;
  576. box-shadow: 0 6rpx 19rpx 2rpx rgba(0, 45, 132, 0.15);
  577. border-radius: 31rpx 31rpx 31rpx 31rpx;
  578. + .echarts {
  579. margin-top: 32rpx;
  580. }
  581. .chart {
  582. height: 400rpx;
  583. }
  584. }
  585. }
  586. }
  587. }
  588. </style>