C端小程序
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

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