index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. <template>
  2. <view class="">
  3. <u-navbar :is-back="false" title="联兑通商户版"></u-navbar>
  4. <u-notice-bar mode="horizontal" :show="noticeShow" :list="noticeList"></u-notice-bar>
  5. <view class="margin-30">
  6. <view class="flex justify-between">
  7. <view class="title ">
  8. <view class="icon">
  9. <image src="@/static/icon/dianpu.png" mode=""></image>
  10. </view>
  11. <view class="center margin-left-10">
  12. <view @click="shopShow=true">
  13. <text class="name">{{shopLable}}</text>
  14. <u-icon v-if="shopShow" name="arrow-up-fill" style="margin-left: 10rpx;"></u-icon>
  15. <u-icon v-else name="arrow-down-fill" style="margin-left: 10rpx;"></u-icon>
  16. </view>
  17. </view>
  18. </view>
  19. <view class="btn">
  20. <view class="image">
  21. <image src="@/static/icon/logout.png" mode=""></image>
  22. </view>
  23. <view @click="logout" class="center padding-left-10">
  24. <text>退出</text>
  25. <text class="cuIcon-right"></text>
  26. </view>
  27. </view>
  28. </view>
  29. <view class="cu-list grid col-3 no-border top-menu">
  30. <view class="cu-item" @click="operate(index)" v-for="(item,index) in menuList" :key="index">
  31. <view class="grid-icon margin-top-20">
  32. <image style="width: 66rpx;height: 66rpx;" :src="item.icon" />
  33. </view>
  34. <text style="color: #fff;font-size: 26rpx;">{{item.name}}</text>
  35. </view>
  36. </view>
  37. <view class="menu-list">
  38. <view @click="$jump('/pages/bill/bill')" class="menu menu1">
  39. <view class="menu-top">
  40. <image src="@/static/icon/bill.png"></image>
  41. <view class="center padding-left-20">
  42. <text class="text-lg">我的账单</text>
  43. </view>
  44. </view>
  45. <view class="menu-bottom">
  46. <view class="">
  47. <text>今日营收</text>
  48. <text>{{statistic.todayIncome || 0}}</text>
  49. </view>
  50. <view class="">
  51. <text>总资产</text>
  52. <text>{{statistic.totalAccount || 0}}</text>
  53. </view>
  54. </view>
  55. </view>
  56. <view class="menu menu2" @click="$jump('/pages/member/member')">
  57. <view class="menu-top">
  58. <image src="@/static/icon/center.png"></image>
  59. <view class="center padding-left-20">
  60. <text class="text-lg">会员中心</text>
  61. </view>
  62. </view>
  63. <view class="menu-bottom" style="color: #FFFFFF;">
  64. <view class="">
  65. <text>新增会员</text>
  66. <text>{{statistic.todayMemberIn || 0}}</text>
  67. </view>
  68. <view class="">
  69. <text>会员总数</text>
  70. <text>{{statistic.memberCount || 0}}</text>
  71. </view>
  72. </view>
  73. </view>
  74. </view>
  75. <view class="market">
  76. <text class="title">营销管理</text>
  77. <view class="cu-list grid col-2 no-border margin-top-30">
  78. <view class="cu-item" @click="$jump(item.path)" v-for="(item,index) in marketList" :key="index">
  79. <view class="grid-icon">
  80. <image style="width: 120rpx;height: 120rpx;" :src="item.icon" />
  81. </view>
  82. <text style="color: #222222;font-size: 26rpx;margin-top: 20rpx;">{{item.name}}</text>
  83. <view class="cu-tag bg-red badge" v-if="item.count>0">{{item.count}}</view>
  84. </view>
  85. </view>
  86. </view>
  87. <view class="system">
  88. <text class="title">数字化系统</text>
  89. <view class="cu-list grid col-4 no-border margin-top-30" style="border-radius:20rpx ;">
  90. <view class="cu-item" @click="$u.toast('即将推出')" v-for="(item,index) in systemList" :key="index">
  91. <view class="grid-icon">
  92. <image mode="heightFix" style="height: 56rpx;" :src="item.icon" />
  93. </view>
  94. <text style="color: #222222;font-size: 26rpx;">{{item.name}}</text>
  95. <view class="cu-tag bg-red badge" v-if="item.count>0">{{item.count}}</view>
  96. </view>
  97. </view>
  98. </view>
  99. </view>
  100. <u-modal @confirm="$jump('/pages/member/member')" :show-cancel-button="true" confirm-color="#ff9447" confirm-text="立即开启" cancel-text="暂不开启" v-model="isOpenMemberShow" content="请先创建会员中心"></u-modal>
  101. <u-select @confirm="shopConfirm" v-model="shopShow" value-name="id" label-name="name" :list="shopList">
  102. </u-select>
  103. </view>
  104. </template>
  105. <script>
  106. import socket from "@/utils/socket.js"
  107. export default {
  108. data() {
  109. return {
  110. noticeShow:true,
  111. noticeList: [],
  112. //状态栏高度
  113. statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
  114. //下拉选择商铺
  115. shopShow: false,
  116. //我的商铺列表
  117. shopList: [],
  118. //选中的商铺id
  119. shopId: '',
  120. //选中的商铺labe
  121. shopLable: '',
  122. labelIds: '',
  123. labelNames: '',
  124. //选中的商铺所属的商场
  125. mallId: '',
  126. //统计数据
  127. statistic: {},
  128. //webSocket
  129. webSocket:{},
  130. count: 0,
  131. //菜单
  132. menuList: [{
  133. icon: '/static/icon/scan.png',
  134. name: '扫一扫',
  135. },
  136. {
  137. icon: '/static/icon/pay.png',
  138. name: '收款码',
  139. },
  140. {
  141. icon: '/static/icon/card.png',
  142. name: '卡包',
  143. }
  144. ],
  145. marketList: [{
  146. icon: '/static/icon/faqi.png',
  147. name: '发起活动',
  148. background: "background-image:linear-gradient(#FF9549,#FCB07B)",
  149. path: '/pages/publish/publish',
  150. count: 0
  151. },
  152. {
  153. icon: '/static/icon/qingdan.png',
  154. name: '活动清单',
  155. background: "background-image:linear-gradient(#5892F7,#67BBF9)",
  156. path: '/pages/activity/activity',
  157. count: 0
  158. },
  159. ],
  160. systemList: [{
  161. icon: '/static/icon/system1.png',
  162. name: '外卖平台',
  163. path: '/pages/mine/card/card'
  164. },
  165. {
  166. icon: '/static/icon/system2.png',
  167. name: '预约系统',
  168. path: '/pages/mine/card/card'
  169. },
  170. {
  171. icon: '/static/icon/system3.png',
  172. name: 'ERP系统',
  173. path: '/pages/mine/card/card'
  174. },
  175. {
  176. icon: '/static/icon/system4.png',
  177. name: '线上商城',
  178. path: '/pages/mine/card/card'
  179. },
  180. {
  181. icon: '/static/icon/system5.png',
  182. name: '门店管理',
  183. path: '/pages/mine/card/card'
  184. },
  185. {
  186. icon: '/static/icon/add.png',
  187. name: '添加服务',
  188. path: '/pages/mine/card/card'
  189. },
  190. ],
  191. //是否开启会员中心
  192. isOpenMember:false,
  193. isOpenMemberShow:false,
  194. }
  195. },
  196. onLoad() {
  197. this.init()
  198. },
  199. beforeDestroy() {
  200. this.handelClose()
  201. },
  202. onUnload() {
  203. this.handelClose()
  204. },
  205. onHide() {
  206. this.handelClose()
  207. },
  208. onShow() {
  209. if (this.canReset) {
  210. this.getStatistic()
  211. this.openSocket()
  212. }
  213. this.canReset = true
  214. },
  215. methods: {
  216. //开启socket begin
  217. openSocket() {
  218. let page = this.$util.getPageCtx()
  219. if (page.data.isOpenSocket) {
  220. this.onSocketOpen()
  221. page.data.isOpenSocket = false
  222. }
  223. },
  224. // 启动webSocket
  225. onSocketOpen() {
  226. this.webSocket=new socket({
  227. sid:this.vuex_shopId
  228. })
  229. this.webSocket.init(() => {
  230. console.log("启动成功");
  231. //启动成功,60s后关闭
  232. this.timeToClose()
  233. });
  234. this.webSocket.acceptMessage = (res) => {
  235. ///用户已支付
  236. if (!this.$isEmpty(res.content) && res.content != '连接成功' && res.content != '心跳') {
  237. this.noticeShow=true
  238. this.noticeList.push(res.content)
  239. }
  240. }
  241. },
  242. //定时关闭连接
  243. timeToClose() {
  244. let _this = this
  245. this.timerSocket = setInterval(() => {
  246. _this.count++
  247. if (_this.count == 120) {
  248. _this.noticeShow=false
  249. _this.handelClose()
  250. }
  251. }, 1000)
  252. },
  253. handelClose() {
  254. this.count = 0
  255. clearTimeout(this.timerSocket)
  256. this.timerSocket = null
  257. if (!this.$isEmpty(this.webSocket)) {
  258. this.webSocket.closeSocket()
  259. }
  260. },
  261. //开启socket end
  262. logout() {
  263. this.$dialog.showModal('确定要退出吗?').then(res => {
  264. uni.clearStorage()
  265. uni.reLaunch({
  266. url: "../login/account-login"
  267. })
  268. })
  269. },
  270. async init() {
  271. let phone = this.$cache.get('phone')
  272. let params = {
  273. personTel: phone,
  274. auditStatus: this.$global.SHOP_AUDIT.PASS //审核通过
  275. }
  276. let res = await this.$api.shop.list(params)
  277. this.shopList = res.data.records
  278. let item = this.shopList[0]
  279. this.shopId = item.id
  280. this.shopLable = item.name
  281. this.labelIds = item.labelIds
  282. this.labelNames = item.labelNames
  283. this.mallId = item.mallId
  284. this.cacheSelectedShop(item)
  285. //获取统计数据
  286. this.getStatistic()
  287. },
  288. getStatistic() {
  289. this.$api.shop.statistic(this.shopId).then(res => {
  290. this.statistic = res.data
  291. })
  292. },
  293. cacheSelectedShop(item) {
  294. let selectedShop = {
  295. id: this.shopId,
  296. label: this.shopLable,
  297. labelIds: this.labelIds,
  298. labelNames: this.labelNames
  299. }
  300. this.$cache.put("selectedShop", Object.assign(item, selectedShop))
  301. this.$u.vuex('vuex_shopId', this.shopId)
  302. this.$u.vuex('vuex_mallId', this.mallId)
  303. this.$u.vuex('vuex_isOpenMember',item.isOpenMember==1?true:false)
  304. },
  305. shopConfirm(e) {
  306. this.shopId = e[0].value
  307. this.shopLable = e[0].label
  308. let item = this.shopList.filter((item) => {
  309. if (this.shopId == item.id) {
  310. return true
  311. }
  312. })
  313. this.labelIds = item.labelIds
  314. this.labelNames = item.labelNames
  315. this.cacheSelectedShop(item[0])
  316. //获取统计数据
  317. this.getStatistic()
  318. },
  319. operate(index) {
  320. if (!this.vuex_isOpenMember && (index== 0 || index==1)) {
  321. this.isOpenMemberShow=true
  322. return
  323. }
  324. if (index == 0) {
  325. this.$jump('/pages/pay/pay')
  326. } else if (index == 1) {
  327. this.$jump('/pages/checkstand/pay-qrcode')
  328. } else if (index == 2) {
  329. this.$jump('/pages/card/card')
  330. }
  331. },
  332. }
  333. }
  334. </script>
  335. <style lang="scss" scoped>
  336. .cu-list.grid>.cu-item .cu-tag {
  337. right: auto;
  338. left: 54%;
  339. margin-left: 20rpx;
  340. }
  341. .title {
  342. display: flex;
  343. .icon {
  344. background-color: #FFFFFF;
  345. border-radius: 50%;
  346. display: flex;
  347. justify-content: center;
  348. align-items: center;
  349. width: 50rpx;
  350. height: 50rpx;
  351. image {
  352. width: 36rpx;
  353. height: 36rpx;
  354. }
  355. }
  356. text {
  357. font-weight: 800;
  358. font-size: 32rpx;
  359. color: #303030;
  360. }
  361. }
  362. .top-menu {
  363. border-radius: 20rpx;
  364. margin-top: 20rpx;
  365. background-image: linear-gradient(to right, #FBA33D, #FF8D32);
  366. }
  367. .menu-list {
  368. display: flex;
  369. justify-content: space-between;
  370. padding-top: 20rpx;
  371. .menu {
  372. width: 48.8%;
  373. color: #FFFFFF;
  374. display: flex;
  375. flex-direction: column;
  376. align-items: center;
  377. border-radius: 14rpx;
  378. padding: 30rpx 20rpx;
  379. .menu-top {
  380. display: flex;
  381. image {
  382. width: 70rpx;
  383. height: 70rpx;
  384. }
  385. }
  386. .menu-bottom {
  387. padding-top: 20rpx;
  388. font-size: 30rpx;
  389. display: flex;
  390. justify-content: space-around;
  391. width: 100%;
  392. view {
  393. display: flex;
  394. flex-direction: column;
  395. text-align: center;
  396. text:first-child {
  397. margin-bottom: 10rpx;
  398. font-size: 26rpx;
  399. color: #E0E2F6;
  400. }
  401. }
  402. }
  403. }
  404. .menu1 {
  405. background-color: #5C6186;
  406. }
  407. .menu2 {
  408. background-color: #E19D5B;
  409. }
  410. }
  411. .market {
  412. margin-top: 20rpx;
  413. border-radius: 20rpx;
  414. background-color: #FFFFFF;
  415. padding: 30rpx 50rpx 20rpx;
  416. .title {
  417. font-weight: 800;
  418. }
  419. }
  420. .system {
  421. margin-top: 20rpx;
  422. border-radius: 20rpx;
  423. background-color: #FFFFFF;
  424. padding: 30rpx 50rpx 20rpx;
  425. .title {
  426. font-weight: 800;
  427. }
  428. }
  429. .btn {
  430. margin-right: -30rpx;
  431. display: flex;
  432. .image {
  433. display: flex;
  434. justify-content: center;
  435. align-items: center;
  436. border-radius: 50%;
  437. background-color: #FFFFFF;
  438. padding: 8rpx;
  439. image {
  440. width: 20rpx;
  441. height: 20rpx;
  442. }
  443. }
  444. color: #FFFFFF;
  445. border-radius: 50rpx 0 0 50rpx;
  446. padding:8rpx 10rpx 8rpx 35rpx;
  447. background-image: linear-gradient(to right, #FFD67B, #F99200);
  448. }
  449. .money {
  450. font-size: 80rpx;
  451. color: $u-type-warning;
  452. position: relative;
  453. .close {
  454. position: absolute;
  455. top: 20rpx;
  456. right: 20rpx;
  457. line-height: 28rpx;
  458. font-size: 28rpx;
  459. }
  460. }
  461. </style>