distributionCenter.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. <template>
  2. <view class="page">
  3. <!-- 佣金总计 -->
  4. <view class="commissionTotal">
  5. <view class="user-info dis a-c j-s ">
  6. <view class="dis a-c">
  7. <image src="/static/image/avatar.png" mode=""></image>
  8. <text class="name">某某某</text>
  9. </view>
  10. <text class="time">2025年12月1日加入</text>
  11. </view>
  12. <view class="totals dis j-s">
  13. <view class="item dis f-c a-c">
  14. <text>¥<text class="sum">{{distributionInfo.totalAmount || 0 }}</text> </text>
  15. <text>累计佣金</text>
  16. </view>
  17. <view class="item dis f-c a-c ">
  18. <text>¥<text class="sum">{{distributionInfo.pendingAmount || 0 }}</text> </text>
  19. <text>待结算</text>
  20. </view>
  21. <view class="item dis f-c a-c">
  22. <text>¥<text class="sum">{{distributionInfo.returnAmount || 0 }}</text> </text>
  23. <text>退回佣金</text>
  24. </view>
  25. </view>
  26. </view>
  27. <!-- 分类统计 -->
  28. <view class="categoryStatistics mt-2 dis a-c j-s">
  29. <view class="item" @click="toPage('distributeTeam')">
  30. <view class="title dis a-c j-c ">
  31. 团队管理
  32. </view>
  33. <view class="content dis a-c f-c">
  34. <view class=" totalCount dis a-c ">
  35. <text class="sum">{{distributionInfo.teamNum || 0}}</text>
  36. <text class="unit">人</text>
  37. </view>
  38. <view class="today dis a-c mt-1 ">
  39. <text>今日新增</text>
  40. <image src="/static/image/income.png" mode=""></image>
  41. <text class="sum">{{distributionInfo.todayNewNum || 0}}</text>
  42. <text class="unit">人</text>
  43. </view>
  44. </view>
  45. </view>
  46. <view class="item" @click="toPage('distributionOrders')">
  47. <view class="title dis a-c j-c " style="background: #F6FBE5;">
  48. 分销订单
  49. </view>
  50. <view class="content dis a-c f-c">
  51. <view class=" totalCount dis a-c ">
  52. <text class="sum">{{distributionInfo.distributionOrderNum || 0}}</text>
  53. <text class="unit">笔 </text>
  54. </view>
  55. <view class="today dis a-c mt-1 ">
  56. <text>今日新增</text>
  57. <image src="/static/image/income.png" mode=""></image>
  58. <text class="sum">{{distributionInfo.todayDistributionOrderNum || 0}}</text>
  59. <text class="unit">笔</text>
  60. </view>
  61. </view>
  62. </view>
  63. <view class="item" @click="toPage('distributionOrders')">
  64. <view class="title dis a-c j-c ">
  65. 保费
  66. </view>
  67. <view class="content dis a-c f-c">
  68. <view class=" totalCount dis a-c ">
  69. <text class="sum">{{formatPremium(distributionInfo.totalPremium)}}</text>
  70. <text class="unit">万</text>
  71. </view>
  72. <view class="today dis a-c mt-1 ">
  73. <text>今日新增</text>
  74. <image src="/static/image/income.png" mode=""></image>
  75. <text class="sum">{{formatPremium(distributionInfo.todayPremium)}}</text>
  76. <text class="unit">万</text>
  77. </view>
  78. </view>
  79. </view>
  80. </view>
  81. <!-- 佣金收益 等级划分 -->
  82. <view class="commissionEarnings mt-2 dis j-s a-c " @click="orderDetails(1)">
  83. <!-- 今日收益 -->
  84. <view class="today-earnings dis f-c ">
  85. <view class="dis a-c">
  86. <image src="/static/image/tool/level1.png" mode=""></image>
  87. <text class="title">一级佣金收益</text>
  88. </view>
  89. <view class="dis a-c mt-1">
  90. <text class="today">今日</text>
  91. <text class="sum">+{{distributionInfo.todayFirstLevelCommission || 0}}</text>
  92. </view>
  93. </view>
  94. <!-- 总收益 -->
  95. <view class="total-earnings dis a-c ">
  96. <text class="mr-2">¥{{distributionInfo.firstLevelCommission || 0}}</text>
  97. <u-icon name="arrow-right" color="#666666" size="16" bold></u-icon>
  98. </view>
  99. </view>
  100. <view class="commissionEarnings mt-2 dis j-s a-c " @click="orderDetails(2)">
  101. <!-- 今日收益 -->
  102. <view class="today-earnings dis f-c ">
  103. <view class="dis a-c">
  104. <image src="/static/image/tool/level2.png" mode=""></image>
  105. <text class="title">二级佣金收益</text>
  106. </view>
  107. <view class="dis a-c mt-1">
  108. <text class="today">今日</text>
  109. <text class="sum">+{{distributionInfo.todaySecondLevelCommission || 0}}</text>
  110. </view>
  111. </view>
  112. <!-- 总收益 -->
  113. <view class="total-earnings dis a-c ">
  114. <text class="mr-2">¥{{distributionInfo.secondLevelCommission || 0}}</text>
  115. <u-icon name="arrow-right" color="#666666" size="16" bold></u-icon>
  116. </view>
  117. </view>
  118. <view class="commissionEarnings mt-2 dis j-s a-c " @click="orderDetails(3)">
  119. <!-- 今日收益 -->
  120. <view class="today-earnings dis f-c ">
  121. <view class="dis a-c">
  122. <image src="/static/image/tool/level3.png" mode=""></image>
  123. <text class="title">三级佣金收益</text>
  124. </view>
  125. <view class="dis a-c mt-1">
  126. <text class="today">今日</text>
  127. <text class="sum">+{{distributionInfo.todayThirdLevelCommission || 0}}</text>
  128. </view>
  129. </view>
  130. <!-- 总收益 -->
  131. <view class="total-earnings dis a-c ">
  132. <text class="mr-2">¥{{distributionInfo.thirdLevelCommission || 0 }}</text>
  133. <u-icon name="arrow-right" color="#666666" size="16" bold></u-icon>
  134. </view>
  135. </view>
  136. <!-- 邀请入口 -->
  137. <view class="inviteEntrance mt-2">
  138. <image src="/static/image/my/inviteEntrance.png" mode=""
  139. @click="showLargeImage('/static/image/my/inviteDistribution.png')"></image>
  140. </view>
  141. <!-- 大图预览弹窗 -->
  142. <u-overlay :show="showLargeImageShow" @click="showLargeImageShow = false" :opacity="0.6" class="u-overlay">
  143. <view class="close-btn dis a-c j-c" @click="showLargeImageShow = false">×</view>
  144. <view class="panelcanvas " id="panelcanvas">
  145. <view class="posterview dis f-c" @tap.stop>
  146. <image class="promoImage" :src="sctiveimg" mode=""></image>
  147. <view class="userinfo dis a-c j-s">
  148. <view class="dis a-c">
  149. <image class="avatar" src="/static/image/avatar.png" mode=""></image>
  150. <text class="ml-3">扫码成为分销员</text>
  151. </view>
  152. <image :src="qrcodeImg" class="qrcodeImg" mode="widthFix" lazy-load></image>
  153. </view>
  154. </view>
  155. </view>
  156. <!-- 分享操作栏 -->
  157. <view class="share-prop" @tap.stop>
  158. <view class="header-title dis a-c j-c">分享到</view>
  159. <view class="foo-btn dis a-c j-s">
  160. <view class="interact-item dis f-c a-c" @click="saveImage">
  161. <image src="/static/icon/tool/saveImg.png" mode=""></image>
  162. <text>保存到相册</text>
  163. </view>
  164. <view class="interact-item dis f-c a-c" @click="sendPayCode">
  165. <image src="/static/icon/tool/wx.png" mode=""></image>
  166. <text>微信</text>
  167. </view>
  168. <view class="interact-item dis f-c a-c" @click="shareMoments">
  169. <image src="/static/icon/tool/friendsCircleLogo.png" mode=""></image>
  170. <text>朋友圈</text>
  171. </view>
  172. </view>
  173. </view>
  174. </u-overlay>
  175. <global-loading :show="loadingShow" :text="loadingText"></global-loading>
  176. </view>
  177. </template>
  178. <script>
  179. import Decimal from 'decimal.js';
  180. import QR from "@/common/wxqrcode.js"
  181. import {
  182. pathToBase64,
  183. base64ToPath
  184. } from '@/common/pdf.js'
  185. import {
  186. turnBase64Image
  187. } from '@/plugins/utils.js';
  188. import {
  189. mapState,
  190. mapMutations
  191. } from "vuex"
  192. export default {
  193. data() {
  194. return {
  195. loadingShow: false, //加载
  196. loadingText: '加载中', //加载提示文字
  197. showLargeImageShow: false, //大图预览弹窗
  198. sctiveimg: "", // 放大显示的图片
  199. shareImage: "", //分享图片
  200. qrcodeImg: "", //二维码图片
  201. imageCache: {}, // 缓存已转换的Base64图片
  202. distributionInfo: {},
  203. Info: {}
  204. }
  205. },
  206. onShow() {
  207. },
  208. async onLoad() {
  209. this.loadingShow = true;
  210. try {
  211. await this.getUserInfo() //获取用户信息
  212. await this.getDistribution();
  213. this.qrcodeImg = QR.createQrCodeImg(this.$base.h5BaseUrl + `/#/pages/registr/h5Registr?systemCode=${this
  214. .system_code}&page=分销员注册&info=${JSON.stringify({
  215. name: this.Info.name,
  216. infoId: this.Info.infoId,
  217. id: this.Info.id,
  218. headSculpture: this.Info.headSculpture,
  219. deptName: this.Info.deptName,
  220. })}`, {
  221. size: parseInt(300), //二维码大小
  222. })
  223. this.loadingShow = false;
  224. } catch (error) {
  225. this.loadingShow = false;
  226. }
  227. },
  228. computed: {
  229. ...mapState(['userInfo', 'system_code'])
  230. },
  231. methods: {
  232. async getUserInfo() {
  233. let res = await this.$http.get('/appUser/userInfoGet'); //获取人员信息
  234. if (res.code == '200') {
  235. this.Info = res.data
  236. }
  237. },
  238. aaaa() {
  239. uni.navigateTo({
  240. url: `/pages/registr/h5Registr?systemCode=${this.system_code}&page=分销员注册`
  241. })
  242. },
  243. async orderDetails(value) {
  244. uni.navigateTo({
  245. url: `/pages/tool/distributionOrders?level=` + value,
  246. })
  247. },
  248. //数据格式化
  249. numberFormat(value) {
  250. return (value).toLocaleString('en-US');
  251. },
  252. //保费(元)转万元,Decimal 高精度计算
  253. formatPremium(value) {
  254. if (value === undefined || value === null || value === '') {
  255. return '0';
  256. }
  257. return new Decimal(value).dividedBy(10000).toString();
  258. },
  259. async getDistribution() {
  260. let res = await this.$http.post('/sysDistributionSetting/distributionCenter');
  261. if (res.code == 200) {
  262. this.distributionInfo = res.data;
  263. }
  264. },
  265. // 显示大图(带缓存优化)
  266. async showLargeImage(item) {
  267. try {
  268. if (!this.imageCache[item]) {
  269. this.imageCache[item] = await turnBase64Image(item);
  270. }
  271. this.sctiveimg = this.imageCache[item];
  272. this.showLargeImageShow = true;
  273. setTimeout(() => {
  274. this.canvasImage.generateImage()
  275. }, 1000);
  276. } catch (error) {
  277. console.error("图片转换失败:", error);
  278. uni.showToast({
  279. title: "图片加载失败",
  280. icon: "none"
  281. });
  282. }
  283. },
  284. //分销页面跳转
  285. toPage(pageName) {
  286. uni.navigateTo({
  287. url: `/pages/tool/${pageName}`
  288. })
  289. },
  290. //发送到微信
  291. sendPayCode() {
  292. if (this.shareImage) {
  293. uni.share({
  294. provider: "weixin",
  295. scene: "WXSceneSession",
  296. type: 2,
  297. imageUrl: this.shareImage
  298. })
  299. }
  300. },
  301. //发送到朋友圈
  302. shareMoments() {
  303. if (this.shareImage) {
  304. uni.share({
  305. provider: "weixin",
  306. scene: "WXSceneTimeline",
  307. type: 2,
  308. imageUrl: this.shareImage
  309. })
  310. }
  311. },
  312. //保存图片
  313. saveImage() {
  314. base64ToPath(this.shareImage)
  315. .then(path => {
  316. uni.saveImageToPhotosAlbum({ //保存图片到系统相册。
  317. filePath: path, //图片文件路径
  318. success: function() {
  319. uni.showToast({
  320. title: '已保存到相册',
  321. icon: 'none',
  322. });
  323. },
  324. fail: function(e) {
  325. uni.showToast({
  326. title: '图片保存失败',
  327. icon: 'none',
  328. });
  329. }
  330. });
  331. })
  332. },
  333. //页面截图转路径
  334. receiveRenderData(val) {
  335. this.shareImage = val.replace(/[\r\n]/g, ''); // 去除base64位中的空格
  336. },
  337. showLoading() {
  338. uni.showLoading({
  339. title: '正在生成图片'
  340. });
  341. },
  342. hideLoading() {
  343. uni.hideLoading();
  344. },
  345. }
  346. }
  347. </script>
  348. <script module="canvasImage" lang="renderjs">
  349. import html2canvas from 'html2canvas'
  350. export default {
  351. data() {
  352. return {
  353. }
  354. },
  355. mounted() {
  356. },
  357. methods: {
  358. generateImage() {
  359. setTimeout(() => {
  360. this.$ownerInstance.callMethod('showLoading')
  361. const dom = document.getElementById('panelcanvas') // 需要生成图片内容的 dom 节点
  362. html2canvas(dom, {
  363. width: dom.clientWidth, //dom 原始宽度
  364. height: dom.clientHeight,
  365. scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0
  366. scrollX: 0,
  367. useCORS: true, //支持跨域
  368. // allowTaint: false,
  369. scale: 2, // 设置生成图片的像素比例,默认是1,如果生成的图片模糊的话可以开启该配置项
  370. }).then((canvas) => {
  371. console.log(canvas);
  372. // 生成成功
  373. this.$ownerInstance.callMethod('hideLoading')
  374. this.$ownerInstance.callMethod('receiveRenderData', canvas.toDataURL('image/png'))
  375. }).catch(err => {
  376. // 生成失败 弹出提示弹窗
  377. this.$ownerInstance.callMethod('_errAlert', `【生成图片失败,请重试】${err}`)
  378. })
  379. }, 300)
  380. }
  381. },
  382. }
  383. </script>
  384. <style lang="scss" scoped>
  385. .page {
  386. background-color: #f8f8f8;
  387. padding: 20rpx 30rpx;
  388. box-sizing: border-box;
  389. height: calc(100vh - 88rpx);
  390. }
  391. .commissionTotal {
  392. padding: 10rpx 6rpx 6rpx;
  393. box-sizing: border-box;
  394. background: #FDEA48;
  395. border-radius: 20rpx 20rpx 20rpx 20rpx;
  396. .user-info {
  397. padding: 0 14rpx;
  398. box-sizing: border-box;
  399. image {
  400. width: 54rpx;
  401. height: 54rpx;
  402. }
  403. .name {
  404. font-size: 32rpx;
  405. color: #1f1f1f;
  406. font-weight: bold;
  407. margin-left: 16rpx;
  408. }
  409. .time {
  410. font-size: 22rpx;
  411. color: #999;
  412. }
  413. }
  414. .totals {
  415. margin-top: 8rpx;
  416. padding: 20rpx 24rpx;
  417. box-sizing: border-box;
  418. background: linear-gradient(88deg, #FFFFFF 0%, rgba(255, 255, 255, 0.9) 100%);
  419. border-radius: 16rpx 16rpx 16rpx 16rpx;
  420. display: grid;
  421. grid-template-columns: repeat(3, 1fr);
  422. grid-template-rows: auto;
  423. column-gap: 70rpx;
  424. .item {
  425. >:first-child {
  426. font-size: 24rpx;
  427. color: #333;
  428. font-weight: bold;
  429. .sum {
  430. font-size: 36rpx;
  431. }
  432. }
  433. >:last-child {
  434. font-size: 24rpx;
  435. color: #999;
  436. }
  437. }
  438. }
  439. }
  440. .categoryStatistics {
  441. width: 100%;
  442. .item {
  443. width: 29%;
  444. padding: 2rpx;
  445. box-sizing: border-box;
  446. background: #fff;
  447. border-radius: 20rpx 20rpx 20rpx 20rpx;
  448. .title {
  449. height: 50rpx;
  450. background: #FFF6EB;
  451. border-radius: 20rpx 20rpx 0rpx 0rpx;
  452. border: 2rpx solid #FFFFFF;
  453. font-size: 24rpx;
  454. color: #834A11;
  455. }
  456. .content {
  457. padding: 10rpx 0 20rpx;
  458. box-sizing: border-box;
  459. .totalCount {
  460. .sum {
  461. font-size: 36rpx;
  462. color: #333;
  463. font-weight: bold;
  464. line-height: 1;
  465. }
  466. .unit {
  467. font-size: 24rpx;
  468. color: #999;
  469. margin-left: 4rpx;
  470. }
  471. }
  472. .today {
  473. font-size: 22rpx;
  474. color: #999;
  475. .sum {
  476. color: #333;
  477. }
  478. image {
  479. width: 24rpx;
  480. height: 24rpx;
  481. margin: 0 2rpx;
  482. }
  483. }
  484. }
  485. }
  486. .item:last-child {
  487. width: 36%;
  488. .title {
  489. background: #EBFBF7;
  490. }
  491. }
  492. }
  493. //佣金收益
  494. .commissionEarnings {
  495. background: #FFFFFF;
  496. border-radius: 20rpx 20rpx 20rpx 20rpx;
  497. padding: 30rpx;
  498. box-sizing: border-box;
  499. .today-earnings {
  500. image {
  501. width: 40rpx;
  502. height: 36rpx;
  503. }
  504. .title {
  505. font-size: 30rpx;
  506. color: #333;
  507. font-weight: bold;
  508. margin-left: 4rpx;
  509. }
  510. .today {
  511. font-size: 26rpx;
  512. color: #999;
  513. }
  514. .sum {
  515. font-size: 26rpx;
  516. color: #FF4545;
  517. }
  518. }
  519. .total-earnings {
  520. text {
  521. font-size: 36rpx;
  522. color: #333;
  523. font-weight: bold;
  524. }
  525. }
  526. }
  527. //分销入口
  528. .inviteEntrance {
  529. image {
  530. width: 100%;
  531. height: 146rpx;
  532. border-radius: 20rpx;
  533. }
  534. }
  535. //海报弹窗样式
  536. /* 分享操作栏 */
  537. .share-prop {
  538. position: absolute;
  539. bottom: 0;
  540. left: 0;
  541. width: 100%;
  542. background-color: #fff;
  543. border-radius: 20rpx 20rpx 0 0;
  544. .header-title {
  545. padding: 24rpx;
  546. font-size: 36rpx;
  547. color: #333;
  548. font-weight: bold;
  549. border-bottom: 1rpx solid #eee;
  550. }
  551. .foo-btn {
  552. padding: 30rpx 128rpx;
  553. .interact-item {
  554. image {
  555. width: 88rpx;
  556. height: 88rpx;
  557. margin-bottom: 10rpx;
  558. }
  559. text {
  560. font-size: 24rpx;
  561. color: #333;
  562. }
  563. }
  564. }
  565. }
  566. // 右上角关闭按钮
  567. .close-btn {
  568. position: absolute;
  569. width: 50rpx;
  570. height: 50rpx;
  571. right: 20rpx;
  572. top: 20rpx;
  573. font-size: 36rpx;
  574. line-height: 0.8;
  575. font-weight: bold;
  576. z-index: 10;
  577. background-color: #fff;
  578. border-radius: 50%;
  579. }
  580. /* 大图预览弹窗 */
  581. .posterview {
  582. margin: 20% 80rpx 0;
  583. background-color: #fff;
  584. border-radius: 10rpx;
  585. position: relative;
  586. .promoImage {
  587. width: 100%;
  588. height: 860rpx;
  589. border-radius: 10rpx 10rpx 0 0;
  590. }
  591. .userinfo {
  592. padding: 25rpx 40rpx;
  593. .avatar {
  594. width: 76rpx;
  595. height: 76rpx;
  596. }
  597. .qrcodeImg {
  598. width: 100rpx;
  599. height: 100rpx;
  600. }
  601. text {
  602. font-size: 28rpx;
  603. color: #333;
  604. }
  605. .panelcanvas {
  606. position: relative;
  607. }
  608. }
  609. }
  610. </style>