C端小程序
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

294 linhas
8.6 KiB

  1. let config = require("./config/config.js");
  2. const Http = require("./utils/HttpBasics");
  3. const extConfig = wx.getExtConfigSync ? wx.getExtConfigSync() : {}
  4. App({
  5. data: {},
  6. onLaunch: function (options) {
  7. var that = this;
  8. that.globalData.sceneAddress = options.scene;
  9. /**
  10. * 用户登录
  11. */
  12. that.userLogin(options.scene);
  13. /**
  14. * 小程序版本更新
  15. */
  16. that.updateManager();
  17. },
  18. /**
  19. * 用户登录
  20. */
  21. userLogin: function (sceneAddress) {
  22. let that = this;
  23. // 登录
  24. wx.login({
  25. success: ({
  26. code
  27. }) => {
  28. let usrdata = {
  29. appId: config.weapp.AppId,
  30. code: code,
  31. sceneAddress: sceneAddress
  32. }
  33. Http.post({
  34. url: config.api.login,
  35. data: usrdata
  36. })
  37. .then(res => {
  38. if (res.data && res.data.score) {
  39. if (res.data.score != 0) {
  40. that.globalData.score = res.data.score;
  41. }
  42. }
  43. Http.setToken(res.data.token);
  44. that.globalData.token = res.data.token;
  45. console.log(that.globalData.token)
  46. if (that.tokenCallback) {
  47. that.tokenCallback(res.data.token);
  48. }
  49. })
  50. .catch(err => {
  51. console.log(err)
  52. wx.showModal({
  53. title: '提示',
  54. showCancel: false,
  55. content: '登录失败,请重新尝试',
  56. success: function (res) {
  57. if (res.cancel) {
  58. //点击取消,默认隐藏弹框
  59. } else {
  60. //点击确定
  61. wx.reLaunch({
  62. url: '/pages/index/index',
  63. })
  64. }
  65. }
  66. })
  67. })
  68. }
  69. })
  70. },
  71. updateManager: function () {
  72. /**
  73. * 小程序版本更新
  74. */
  75. if (wx.canIUse('getUpdateManager')) {
  76. const updateManager = wx.getUpdateManager()
  77. updateManager.onCheckForUpdate(function (res) {
  78. // 请求完新版本信息的回调
  79. if (res.hasUpdate) {
  80. console.log('res.hasUpdate====')
  81. updateManager.onUpdateReady(function () {
  82. wx.showModal({
  83. title: '更新提示',
  84. content: '新版本已经准备好,是否重启应用?',
  85. success: function (res) {
  86. console.log('success====', res)
  87. // res: {errMsg: "showModal: ok", cancel: false, confirm: true}
  88. if (res.confirm) {
  89. // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
  90. updateManager.applyUpdate()
  91. } else if (res.cancel) {
  92. //如果需要强制更新,则给出二次弹窗,如果不需要,则这里的代码都可以删掉了
  93. wx.showModal({
  94. title: '温馨提示~',
  95. content: '本次版本更新涉及到新的功能添加,旧版本无法正常访问的哦~',
  96. success: function (res) {
  97. self.autoUpdate()
  98. return;
  99. //第二次提示后,强制更新
  100. if (res.confirm) {
  101. // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
  102. updateManager.applyUpdate()
  103. } else if (res.cancel) {
  104. //重新回到版本更新提示
  105. self.autoUpdate()
  106. }
  107. }
  108. })
  109. }
  110. }
  111. })
  112. })
  113. updateManager.onUpdateFailed(function () {
  114. // 新的版本下载失败
  115. wx.showModal({
  116. title: '已经有新版本了哟~',
  117. content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~'
  118. })
  119. })
  120. }
  121. })
  122. } else {
  123. // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
  124. wx.showModal({
  125. title: '提示',
  126. content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
  127. })
  128. }
  129. },
  130. globalData: {
  131. scene: "",
  132. // token
  133. token: null,
  134. // user openId
  135. openId: null,
  136. // 渠道
  137. sceneAddress: null,
  138. // location info
  139. locationInfo: null,
  140. // 二维码参数
  141. scene: null,
  142. // 支持智慧停车, 用户名下有车
  143. phone: null,
  144. supportCar: false,
  145. parkVendor: 1, // 1: ETCP, 2: TJD
  146. // ETCP token
  147. etcpToken: null,
  148. carLogin: false,
  149. // 当前商场信息
  150. market: {
  151. name: ""
  152. },
  153. // websocket
  154. socketClient: null,
  155. socketReceiver: function (e) { }, //收到消息回调
  156. },
  157. // 初始化websocket
  158. initSocket: function () {
  159. let that = this;
  160. // socket是否连接
  161. let socketConnected = false;
  162. // 待发送的消息队列
  163. let messageQueue = [];
  164. // 是否断线重连
  165. let reconnect = true;
  166. // 发送消息
  167. function sendSocketMessage(msg) {
  168. // console.log(msg);
  169. // 如果socket已连接则发送消息
  170. if (socketConnected) {
  171. wx.sendSocketMessage({
  172. data: msg
  173. })
  174. } else {
  175. // socket没有连接将消息放入队列中
  176. messageQueue.push(msg);
  177. }
  178. }
  179. // 关闭连接
  180. function close() {
  181. if (socketConnected) {
  182. wx.closeSocket()
  183. socketConnected = false;
  184. }
  185. }
  186. // 符合WebSocket定义的对象
  187. var ws = {
  188. send: sendSocketMessage,
  189. close: close
  190. }
  191. // 创建一个 WebSocket 连接
  192. function connect() {
  193. wx.connectSocket({
  194. url: config.wsurl,
  195. header: {
  196. token: that.globalData.token //从服务端获取一个token,服务端验证token是否允许连接,案例中没做限制
  197. }
  198. })
  199. }
  200. connect();
  201. // 监听 WebSocket 连接打开事件
  202. wx.onSocketOpen(function (res) {
  203. console.log("WebSocket 连接成功")
  204. socketConnected = true;
  205. ws.onopen();
  206. // 连接成功后,将队列中的消息发送出去
  207. let queueLength = messageQueue.length
  208. for (let i = 0; i < queueLength; i++) {
  209. sendSocketMessage(messageQueue.shift())
  210. }
  211. })
  212. // 监听 WebSocket 接受到服务器的消息事件
  213. wx.onSocketMessage(function (res) {
  214. ws.onmessage(res);
  215. })
  216. // 监听 WebSocket 错误事件
  217. wx.onSocketError(function (res) {
  218. console.log("WebSocket 错误事件")
  219. if (!socketConnected) {
  220. // 断线重连
  221. if (reconnect) {
  222. connect();
  223. }
  224. }
  225. })
  226. // 监听 WebSocket 连接关闭事件
  227. wx.onSocketClose(function (res) {
  228. console.log("WebSocket 连接关闭")
  229. socketConnected = false;
  230. // 断线重连
  231. if (reconnect) {
  232. connect();
  233. }
  234. })
  235. const Stomp = require('/utils/stomp.min.js').Stomp;
  236. /**
  237. * 定期发送心跳或检测服务器心跳
  238. * The heart-beating is using window.setInterval() to regularly send heart-beats and/or check server heart-beats.
  239. * 可看stomp.js的源码(195,207,489行),由于小程序没有window对象,所以我们要调用小程序的定时器api实现
  240. */
  241. Stomp.setInterval = function (interval, f) {
  242. return setInterval(f, interval);
  243. };
  244. // 结束定时器的循环调用
  245. Stomp.clearInterval = function (id) {
  246. return clearInterval(id);
  247. };
  248. const stompClient = Stomp.over(ws);
  249. that.globalData.socketClient = stompClient;
  250. stompClient.connect({}, function (callback) {
  251. // 订阅自己的
  252. stompClient.subscribe('/user/' + config.weapp.AppId + '/' + that.globalData.openId + '/message', function (message, headers) {
  253. console.log('收到只发送给我的消息:', message);
  254. that.globalData.socketReceiver(JSON.parse(message.body));
  255. // 通知服务端收到消息
  256. message.ack();
  257. });
  258. stompClient.subscribe('/topic/' + config.weapp.AppId, function (message, headers) {
  259. console.log('收到TOPIC的消息:', message);
  260. that.globalData.socketReceiver(JSON.parse(message.body));
  261. // 通知服务端收到消息
  262. //message.ack();
  263. });
  264. // 向服务端发送消息
  265. stompClient.send("/app/message", {}, JSON.stringify({
  266. 'msg': 'client: ' + that.globalData.openId
  267. }));
  268. })
  269. },
  270. //统一发送消息
  271. sendSocketMessage: function (msg) {
  272. this.globalData.socketClient.send("/app/message", {}, JSON.stringify(msg));
  273. }
  274. });