index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  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}}</text>
  49. </view>
  50. <view class="">
  51. <text>总资产</text>
  52. <text>{{statistic.totalAccount}}</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}}</text>
  67. </view>
  68. <view class="">
  69. <text>会员总数</text>
  70. <text>{{statistic.memberCount}}</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 == 300) {
  248. _this.handelClose()
  249. }
  250. }, 1000)
  251. },
  252. handelClose() {
  253. this.count = 0
  254. clearTimeout(this.timerSocket)
  255. this.timerSocket = null
  256. if (!this.$isEmpty(this.webSocket)) {
  257. this.webSocket.closeSocket()
  258. }
  259. },
  260. //开启socket end
  261. logout() {
  262. this.$dialog.showModal('确定要退出吗?').then(res => {
  263. uni.clearStorage()
  264. uni.reLaunch({
  265. url: "../login/account-login"
  266. })
  267. })
  268. },
  269. async init() {
  270. let phone = this.$cache.get('phone')
  271. let params = {
  272. personTel: phone,
  273. auditStatus: 1 //审核通过
  274. }
  275. let res = await this.$api.shop.list(params)
  276. this.shopList = res.data.records
  277. let item = this.shopList[0]
  278. this.shopId = item.id
  279. this.shopLable = item.name
  280. this.labelIds = item.labelIds
  281. this.labelNames = item.labelNames
  282. this.mallId = item.mallId
  283. this.cacheSelectedShop(item)
  284. //获取统计数据
  285. this.getStatistic()
  286. },
  287. getStatistic() {
  288. this.$api.shop.statistic(this.shopId).then(res => {
  289. this.statistic = res.data
  290. })
  291. },
  292. cacheSelectedShop(item) {
  293. let selectedShop = {
  294. id: this.shopId,
  295. label: this.shopLable,
  296. labelIds: this.labelIds,
  297. labelNames: this.labelNames
  298. }
  299. this.$cache.put("selectedShop", Object.assign(item, selectedShop))
  300. this.$u.vuex('vuex_shopId', this.shopId)
  301. this.$u.vuex('vuex_mallId', this.mallId)
  302. this.$u.vuex('vuex_isOpenMember',item.isOpenMember==1?true:false)
  303. },
  304. shopConfirm(e) {
  305. this.shopId = e[0].value
  306. this.shopLable = e[0].label
  307. let item = this.shopList.filter((item) => {
  308. if (this.shopId == item.id) {
  309. return true
  310. }
  311. })
  312. this.labelIds = item.labelIds
  313. this.labelNames = item.labelNames
  314. this.cacheSelectedShop(item[0])
  315. //获取统计数据
  316. this.getStatistic()
  317. },
  318. operate(index) {
  319. if (!this.vuex_isOpenMember && (index== 0 || index==1)) {
  320. this.isOpenMemberShow=true
  321. return
  322. }
  323. if (index == 0) {
  324. this.$jump('/pages/pay/pay')
  325. } else if (index == 1) {
  326. this.$jump('/pages/checkstand/pay-qrcode')
  327. } else if (index == 2) {
  328. this.$jump('/pages/card/card')
  329. }
  330. },
  331. }
  332. }
  333. </script>
  334. <style lang="scss" scoped>
  335. .cu-list.grid>.cu-item .cu-tag {
  336. right: auto;
  337. left: 54%;
  338. margin-left: 20rpx;
  339. }
  340. .title {
  341. display: flex;
  342. .icon {
  343. background-color: #FFFFFF;
  344. border-radius: 50%;
  345. display: flex;
  346. justify-content: center;
  347. align-items: center;
  348. width: 50rpx;
  349. height: 50rpx;
  350. image {
  351. width: 36rpx;
  352. height: 36rpx;
  353. }
  354. }
  355. text {
  356. font-weight: 800;
  357. font-size: 32rpx;
  358. color: #303030;
  359. }
  360. }
  361. .top-menu {
  362. border-radius: 20rpx;
  363. margin-top: 20rpx;
  364. background-image: linear-gradient(to right, #FBA33D, #FF8D32);
  365. }
  366. .menu-list {
  367. display: flex;
  368. justify-content: space-between;
  369. padding-top: 20rpx;
  370. .menu {
  371. width: 48.8%;
  372. color: #FFFFFF;
  373. display: flex;
  374. flex-direction: column;
  375. align-items: center;
  376. border-radius: 14rpx;
  377. padding: 30rpx 20rpx;
  378. .menu-top {
  379. display: flex;
  380. image {
  381. width: 70rpx;
  382. height: 70rpx;
  383. }
  384. }
  385. .menu-bottom {
  386. padding-top: 20rpx;
  387. font-size: 30rpx;
  388. display: flex;
  389. justify-content: space-around;
  390. width: 100%;
  391. view {
  392. display: flex;
  393. flex-direction: column;
  394. text-align: center;
  395. text:first-child {
  396. margin-bottom: 10rpx;
  397. font-size: 26rpx;
  398. color: #E0E2F6;
  399. }
  400. }
  401. }
  402. }
  403. .menu1 {
  404. background-color: #5C6186;
  405. }
  406. .menu2 {
  407. background-color: #E19D5B;
  408. }
  409. }
  410. .market {
  411. margin-top: 20rpx;
  412. border-radius: 20rpx;
  413. background-color: #FFFFFF;
  414. padding: 30rpx 50rpx 20rpx;
  415. .title {
  416. font-weight: 800;
  417. }
  418. }
  419. .system {
  420. margin-top: 20rpx;
  421. border-radius: 20rpx;
  422. background-color: #FFFFFF;
  423. padding: 30rpx 50rpx 20rpx;
  424. .title {
  425. font-weight: 800;
  426. }
  427. }
  428. .btn {
  429. margin-right: -30rpx;
  430. display: flex;
  431. .image {
  432. display: flex;
  433. justify-content: center;
  434. align-items: center;
  435. border-radius: 50%;
  436. background-color: #FFFFFF;
  437. padding: 8rpx;
  438. image {
  439. width: 20rpx;
  440. height: 20rpx;
  441. }
  442. }
  443. color: #FFFFFF;
  444. border-radius: 50rpx 0 0 50rpx;
  445. padding:8rpx 10rpx 8rpx 35rpx;
  446. background-image: linear-gradient(to right, #FFD67B, #F99200);
  447. }
  448. .money {
  449. font-size: 80rpx;
  450. color: $u-type-warning;
  451. position: relative;
  452. .close {
  453. position: absolute;
  454. top: 20rpx;
  455. right: 20rpx;
  456. line-height: 28rpx;
  457. font-size: 28rpx;
  458. }
  459. }
  460. </style>