C端小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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