game-play-web.nvue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. <template>
  2. <view class="web-view">
  3. <!-- :src="url" src = 'http://192.168.0.108:7456/build/index.html' -->
  4. <!-- @receivedtitle="onReceivedTitle" @pagefinish="onPageFinish"-->
  5. <web-view class="web-view-child" :src="url" ref="webview" @pagestart="onPageStart"
  6. @onPostMessage="handlePostMessage" @error="onError"></web-view>
  7. <view class="web-back" @click="navBack">
  8. <image style="width: 40rpx;height: 40rpx;" src="/static/gameCloseW.png"></image>
  9. </view>
  10. </view>
  11. </template>
  12. <script>
  13. import reqUtil from "@/util/util-js/requstUtil.js";
  14. import config from "@/common/config.js";
  15. import fruit from "@/components/fruitMachine/fruit.js"
  16. var currentWebview;
  17. import {
  18. mapState,
  19. mapMutations
  20. } from 'vuex';
  21. export default {
  22. computed: mapState(['avatarUrl', 'gender', 'userName', 'city', 'BLEConnectDevice']),
  23. data() {
  24. return {
  25. url: '',
  26. pagefinish: '',
  27. error: '',
  28. canGoBack: false,
  29. canGoForward: false,
  30. PageStart: false, // 记录网页请求的加载状态,true 加载成功 false 加载失败
  31. }
  32. },
  33. onLoad(option) {
  34. if (option && option.item) {
  35. this.decodeItem = JSON.parse(decodeURIComponent(option.item));
  36. this.url = this.decodeItem.gameWebUrl;
  37. let temp = {
  38. fObjectId: this.decodeItem.gameId,
  39. recentlyType: 0
  40. }
  41. // console.log("game temp:", config.URL.RECENTLYPLAYINGADD);
  42. //添加最近在玩的游戏
  43. reqUtil.requestData(config.URL.RECENTLYPLAYINGADD, temp).then(res => {
  44. console.log('RECENTLYPLAYINGADD =====', res);
  45. if (res.code == 0) {}
  46. },
  47. e => {
  48. console.log(e)
  49. });
  50. }
  51. // #ifdef APP-PLUS
  52. var pages = getCurrentPages();
  53. var page = pages[pages.length - 1];
  54. currentWebview = page.$getAppWebview();
  55. // #endif
  56. // 监听事件
  57. uni.$on('callbackCloseBLE', this.callbackCloseBLE);
  58. uni.$on('callbackBLEState', this.callbackBLEState);
  59. uni.$on('updateBLEDeviceData', this.callback);
  60. },
  61. onUnload() {
  62. uni.$off('callbackCloseBLE', this.callbackCloseBLE);
  63. uni.$off('callbackBLEState', this.callbackBLEState);
  64. uni.$off('updateBLEDeviceData', this.callback);
  65. },
  66. methods: {
  67. ...mapMutations([ 'addlocalCalorie']),
  68. navBack() {
  69. uni.navigateBack();
  70. },
  71. //蓝牙断开连接时候
  72. callbackCloseBLE() {
  73. this.sendMessage("onDeviceClose", {
  74. msg: '设备断开连接。'
  75. });
  76. },
  77. //蓝牙状态回调
  78. callbackBLEState(res) {
  79. // console.log("game callbackBLEState==", res);
  80. // 暂时只返回数据连接错误信息
  81. // uni.$emit("callbackBLEState", {
  82. // state: -1,
  83. // msg: "设备数据错误"
  84. // });
  85. this.sendMessage("onDeviceState", res)
  86. },
  87. callback(data) {
  88. // 设备回调后面用这个接口
  89. this.sendMessage("onDeviceUpdateData", data);
  90. },
  91. /**
  92. * 图片转化base64
  93. * @param {Object} url
  94. * @param {Object} callback
  95. */
  96. urlToBase64(url, callback) {
  97. let toBase64Url;
  98. uni.request({
  99. url: url,
  100. method: 'GET',
  101. responseType: 'arraybuffer',
  102. success: async res => {
  103. let base64 = uni.arrayBufferToBase64(res.data);
  104. toBase64Url = 'data:image/jpeg;base64,' + base64;
  105. if (callback)
  106. callback(toBase64Url,res.data);
  107. }
  108. })
  109. },
  110. /**
  111. * 初始化发送数据给游戏
  112. */
  113. sendGameInit() {
  114. if (!this.PageStart) {
  115. uni.showModal({
  116. title: "暴躁的提示",
  117. content: "只有网页加载成功了才可以传参过去,不然无效哦。。"
  118. })
  119. return false;
  120. }
  121. this.urlToBase64(this.avatarUrl, (toBase64Url) => {
  122. let device = null;
  123. if (this.BLEConnectDevice) {
  124. device = {
  125. cname: this.BLEConnectDevice.cname,
  126. ename: this.BLEConnectDevice.ename,
  127. name: this.BLEConnectDevice.name
  128. }
  129. }
  130. /**
  131. * 卡路里消耗参数
  132. */
  133. let calorieParams ={
  134. runUnit:10,
  135. jumpUnit:20
  136. };
  137. // console.log(this.BLEConnectDevice, device);
  138. let gameData = {
  139. avatarUrl: this.avatarUrl,
  140. avatarBase64Url: toBase64Url,
  141. userName: this.userName,
  142. gender: this.gender,
  143. caloriUnit: 10,
  144. calorieParams:calorieParams,
  145. //蓝牙连接的设备
  146. device: device
  147. }
  148. this.sendMessage("onGameInit", gameData);
  149. })
  150. },
  151. /**
  152. * 统一发送信息
  153. * @param {Object} gameData
  154. */
  155. sendMessage(functionName, gameData) {
  156. let data = {
  157. "funName": functionName,
  158. "gameData": gameData
  159. }
  160. let initStr = JSON.stringify(data);
  161. this.$refs.webview.evalJs("onWebViewMessage(" + initStr + ")");
  162. },
  163. sendMessageToWebview() {
  164. if (!this.PageStart) {
  165. uni.showModal({
  166. title: "暴躁的提示",
  167. content: "只有网页加载成功了才可以传参过去,不然无效哦。。"
  168. })
  169. return false;
  170. }
  171. /**
  172. * 下面的 jsfunction 代码你要自己在你的网页里面写一个方法 大致如下
  173. * 下面就是你基本的html知识了,我就不想说什么了,自己学。
  174. window.jsfunction = function(data){
  175. console.log('data', data);
  176. }
  177. */
  178. this.sendMessage("onDeviceUpdateData", {
  179. H: 1
  180. });
  181. },
  182. handlePostMessage: function(postData) {
  183. console.log("handlePostMessage得到参数", postData.detail);
  184. let temp = postData.detail.data[0];
  185. if (temp.funName == "uploadInfo") {
  186. //TODO 后续游戏数据处理
  187. this.sendMessage("onUploadInfo", {});
  188. let gameData = temp.gameData;
  189. //TODO:写入排行榜分数,后面需要在游戏完结里面调用
  190. //TODO: 后面游戏时间,卡路里的需要写入数据库,目前只是处理了分数
  191. // let num = Math.round(Math.random() * 10000);
  192. //1. gameScore 处理上传的分数
  193. reqUtil.requestData(config.URL.UPLOADRANKING, {
  194. gameId: this.decodeItem.gameId,
  195. score: gameData.gameScore,
  196. cityCode: this.city.cityCode,
  197. }, "POST").then(res => {
  198. console.log('UPLOADRANKING =====', res);
  199. if (res.code == 0) {}
  200. },
  201. e => {
  202. console.log(e)
  203. });
  204. //2. calorieBurned 处理卡路里
  205. // 记录卡路里到本地
  206. this.addlocalCalorie(gameData.calorieBurned);
  207. //3. gameTime 游戏时间
  208. //TODO 后面处理游戏时长
  209. } else if (temp.funName == "gameInit") {
  210. // 获取游戏信息
  211. this.sendGameInit();
  212. } else if (temp.funName == "aiRandomInfo") {
  213. // 获取aiRandomInfo
  214. reqUtil.requestData(config.URL.AIRANDOMINFO, {}).then(res => {
  215. console.log('AIRANDOMINFO =====', res);
  216. if (res.code == 0) {
  217. let data = res.data;
  218. this.urlToBase64(data.aiAvatar, (toBase64Url) => {
  219. let sendData = {
  220. aiId: data.aiId,
  221. aiName: data.aiName,
  222. aiGender: data.aiGender,
  223. aiType: data.aiType,
  224. aiAvatarBase64Url: toBase64Url
  225. }
  226. this.sendMessage("onAiRandomInfo", sendData);
  227. })
  228. }
  229. },
  230. e => {
  231. console.log(e)
  232. });
  233. } else if (temp.funName == "fruitInfo") {
  234. let gameData = temp.gameData;
  235. let fruitIndexArray = [0, 0, 0];
  236. if (temp.gameData.hasOwnProperty("calorie")) {
  237. fruitIndexArray = fruit.getFruitIndex(gameData.calorie);
  238. }
  239. this.urlToBase64("https://bbeng-bucket.oss-cn-beijing.aliyuncs.com/cocos/fruitMachine.png", (toBase64Url) => {
  240. this.sendMessage("onFruitInfo", {
  241. // 水果雪碧图
  242. fruitBase64Url: toBase64Url,
  243. // 雪碧图 单张图片宽高
  244. unitWidth: 100,
  245. unitHeight: 100,
  246. unit: "px",
  247. imageStartPosY: 0,
  248. imageEndPosY: -1200,
  249. fruitIndexArray: fruitIndexArray
  250. });
  251. })
  252. }else if(temp.funName == "urlToBase64"){
  253. let gameData = temp.gameData;
  254. if(gameData.url){
  255. this.urlToBase64(gameData.url, (toBase64Url) => {
  256. this.sendMessage("onUrlToBase64", {
  257. base64: toBase64Url,
  258. });
  259. })
  260. }else{
  261. this.sendMessage("onUrlToBase64", {
  262. base64: {},
  263. });
  264. }
  265. }
  266. },
  267. goBack: function() {
  268. // 返回
  269. var webview = weex.requireModule('webview');
  270. webview.goBack(this.$refs.webview);
  271. },
  272. goForward: function() {
  273. //前进
  274. var webview = weex.requireModule('webview');
  275. webview.goForward(this.$refs.webview);
  276. },
  277. onPageStart: function(e) {
  278. // 监听页面加载成功
  279. this.PageStart = true;
  280. console.log("onPageStart==", e);
  281. },
  282. onPageFinish: function(e) {
  283. //clearHistory
  284. // currentWebview.clear();
  285. console.log("onPageFinish==", e);
  286. // if (e.url)
  287. // this.pagefinish = e.url;
  288. // if (e.canGoBack)
  289. // this.canGoBack = e.canGoBack;
  290. // if (e.canGoForward)
  291. // this.canGoForward = e.canGoForward;
  292. // var tn = currentWebview.getStyle().titleNView;
  293. // tn.titleText = e.detail.title || '郁野科技游戏';
  294. // currentWebview.setStyle({
  295. // titleNView: tn
  296. // });
  297. },
  298. onError: function(e) {
  299. // 监听页面加载错误
  300. // this.error = this.url;
  301. console.error(e);
  302. },
  303. onReceivedTitle: function(e) {
  304. // if (e.title) {
  305. // var tn = currentWebview.getStyle().titleNView;
  306. // tn.titleText = e.detail.title || '郁野科技游戏';
  307. // currentWebview.setStyle({
  308. // titleNView: tn
  309. // });
  310. // }
  311. },
  312. reloadWebviewUrl() {
  313. // 刷新网页
  314. var webview = weex.requireModule('webview');
  315. webview.reload(this.$refs.webview);
  316. }
  317. }
  318. }
  319. </script>
  320. <style>
  321. /* #ifdef APP-PLUS */
  322. .web-view {
  323. flex: 1;
  324. flex-direction: column;
  325. border-style:solid;
  326. border-width: 1rpx;
  327. }
  328. .web-view-child {
  329. width: 750rpx;
  330. flex: 1;
  331. }
  332. /* #endif */
  333. /* #ifdef H5 */
  334. .web-view {
  335. display: flex;
  336. flex-direction: column;
  337. position: absolute;
  338. bottom: 0;
  339. top: 0;
  340. left: 0;
  341. right: 0;
  342. }
  343. .web-view-child {
  344. position: relative;
  345. width: 100%;
  346. height: 100%;
  347. }
  348. /* #endif */
  349. .sendMessage {
  350. width: 300rpx;
  351. position: fixed;
  352. bottom: 100rpx;
  353. left: 50rpx;
  354. }
  355. .web-back {
  356. position: fixed;
  357. top: 20px;
  358. right: 20px;
  359. width: 140rpx;
  360. height: 60rpx;
  361. border-radius: 45px;
  362. /* border: 0.5rpx solid #FFFFFF; */
  363. box-shadow: 0px 0px 1px #FFFFFF;
  364. background-color: rgba(0, 0, 0, 0.3);
  365. /* #ifndef APP-PLUS-NVUE */
  366. z-Index: 10;
  367. display: flex;
  368. /* #endif */
  369. justify-content: center;
  370. align-items: center;
  371. }
  372. </style>