国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

麻將計分器:簡單的微信小程序開發(fā)

這篇具有很好參考價值的文章主要介紹了麻將計分器:簡單的微信小程序開發(fā)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

朋友們推薦了一個計分的小程序,但是這個小程序不僅打開有廣告,各個頁面都植入了廣告,用起來十分不適。

于是我就心里暗自下定決心,一定要擼一個沒有廣告的小程序。一周后,這個小程序發(fā)布了。

歡迎大家參觀和使用我的小程序!小程序名稱:MahjongScorer

打牌計分小程序源碼,小程序,前端,服務器,后端,微信小程序

思路

1.注冊,獲取頭像和昵稱。已注冊的用戶直接自動登錄。

2.創(chuàng)建房間,掃一掃加入房間或者轉發(fā)微信好友、群聊,通過點擊加入。

3.添加臺板以記錄每局抽出來的臺費(無需臺費可忽略)。

4.每一局對局結束后,記錄每個人的輸贏情況。

5.散場后,將本次游戲所有記錄保存至個人歷史記錄中,解散房間。

6.評價,隨機彈出評價頁面對此次體驗進行評價。

7.特色功能:為方便第 2 步的記錄,增加長按語音識別。

準備工作

前端

工具:HBuilderX、微信開發(fā)者工具

框架:uni-app(Vue3)、pinia
由于頁面簡單,所以沒有使用 UI 框架。

附 uni-app 基本項目結構:

┌─uniCloud 云空間目錄,阿里云為 uniCloud-aliyun,騰訊云為 uniCloud-tcb(詳見 uniCloud)
│─components 符合 vue 組件規(guī)范的 uni-app 組件目錄
│ └─comp-a.vue 可復用的 a 組件
├─hybrid App 端存放本地 html 文件的目錄
├─platforms 存放各平臺專用頁面的目錄
├─pages 業(yè)務頁面文件存放的目錄
│ ├─index
│ │ └─index.vue index 頁面
│ └─list
│ └─list.vue list 頁面
├─static 存放應用引用的本地靜態(tài)資源(如圖片、視頻等)的目錄,注意:靜態(tài)資源只能存放于此
├─uni_modules 存放 uni_modules 規(guī)范的插件。
├─wxcomponents 存放小程序組件的目錄
├─main.js Vue 初始化入口文件
├─App.vue 應用配置,用來配置 App 全局樣式以及監(jiān)聽 應用生命周期
├─manifest.json 配置應用名稱、appid、logo、版本等打包信息
└─pages.json 配置頁面路由、導航條、選項卡等頁面類信息
1.新建項目

在 HBuilderX 新建項目。
打牌計分小程序源碼,小程序,前端,服務器,后端,微信小程序

2.配置開發(fā)工具路徑

在 HBuilderX 配置微信開發(fā)者工具的安裝路徑:工具-設置-運行配置-小程序運行配置-微信開發(fā)者工具路徑。
打牌計分小程序源碼,小程序,前端,服務器,后端,微信小程序

3.開啟端口

在微信開發(fā)者工具,開啟端口:設置-安全設置-服務端口。
打牌計分小程序源碼,小程序,前端,服務器,后端,微信小程序

4.運行項目

在 HBuilderX 運行項目:運行-運行到小程序模擬器-微信開發(fā)者工具。
打牌計分小程序源碼,小程序,前端,服務器,后端,微信小程序

這時會根據第 2 步配置的路徑自動打開微信開發(fā)者工具。
打牌計分小程序源碼,小程序,前端,服務器,后端,微信小程序

至此,前端基礎工作準備完成。如果您想寫的小程序只有前端靜態(tài)頁面而無需后端服務,那么可以不用繼續(xù)往下看了,只需要:

  • 編寫靜態(tài)頁面的代碼
  • 在微信開發(fā)者工具左上角點擊登錄,點擊右上角詳情-基本信息-AppId,點擊修改為您注冊的小程序 ID,點擊上傳。
    打牌計分小程序源碼,小程序,前端,服務器,后端,微信小程序
    • 其中 AppID 獲取方式為:進入微信小程序官網,找到開發(fā)-開發(fā)管理-開發(fā)設置,在“開發(fā)者 ID”下即可獲取 AppID(小程序 ID)
  • 找到管理-版本管理-開發(fā)版本,點擊提交審核,待審核通過后將審核版本發(fā)布,即可完成小程序開發(fā)和發(fā)布。

后端

工具:IDEA

框架:SpringBoot

數據庫:MySQL

1.基礎工作

參考之前的博客:如何搭建自己的網站和如何搭建自己的網站(二)進行服務器的搭建和 jar 包的部署。

2.配置服務器域名

進入微信小程序官網,找到開發(fā)-開發(fā)管理-開發(fā)設置,在“開發(fā)者 ID”下獲取 AppID(小程序 ID)、AppSecret(小程序密鑰)并保存下來,后續(xù)接口需要使用。繼續(xù)下滑至“服務器域名”,在 request 合法域名、uploadFile 合法域名、downloadFile 合法域名中填寫服務器域名,即第 1 步基礎工作中部署的服務器域名。

編寫代碼

前端

打牌計分小程序源碼,小程序,前端,服務器,后端,微信小程序打牌計分小程序源碼,小程序,前端,服務器,后端,微信小程序

下面粘貼部分關鍵代碼。

1.pinia 狀態(tài)管理庫

由于有很多公用的全局的屬性和方法,所以將該部分內容都放在 pinia 的全局狀態(tài)管理庫里。

import { defineStore } from "pinia";

const useUserStore = defineStore("useUserStore", {
  state: () => {
    return {
      info: {
        // 用戶信息
        openid: "",
        avatar: "",
        nickname: "",
        roomid: "",
      },
      isLogin: null, // 是否登錄,用于判斷是否顯示登錄頁
      shareid: "", // 通過二維碼或點擊分享進入的房間id
      members: [], // 房間的成員
      records: [], // 本次游戲所有對局
      circle: 1, // 第幾局
      sumArr: [], // 本次游戲目前總分
      timer: null, // 定時器,在生成房間后 2 秒觸發(fā)一次監(jiān)聽房間成員的變更
      scene: null, // 場景:區(qū)分是否是通過朋友圈進入,朋友圈進入時無法獲取openid會導致報錯
      qrCode: "", // 房間二維碼
      baseURL: "https://xxxxx.xxx/mahjong/", // 后端接口前綴,省去每次調用接口寫一大堆前綴
    };
  },
  actions: {
    async updateInfo(data, mode) {}, // 添加用戶、修改頭像/昵稱
		async getOpenid() {}, // 獲取用戶的openid
		async autoLogin(roomid) {}, // 如果緩存中有用戶openid,則直接登錄,否則獲取用戶openid,并存到緩存。
		async getRecords() {}, // 獲取本次游戲所有對局
		async getMembers() {}, // 獲取房間的成員
		getSum() {}, // 獲取本次游戲目前總分
		async updateRoomid(roomid) {}, // 更新當前用戶的房間id
		async gameOver() {}, // 結束游戲并解散房間
		setTimer() {}, // 設置定時器獲取成員信息變更
});
2.注冊

注冊時,可以點擊頭像選擇頭像,不選就是默認頭點擊昵稱輸入昵稱,昵稱不可為空,且最多八個字。

<view class="container">
  <view class="avatarUrl">
    <button
      type="balanced"
      open-type="chooseAvatar"
      @chooseavatar="onChooseavatar"
    >
      <image
        :src="avatarUrl"
        class="refreshIcon"
        v-if="avatarUrl !== defaultAvatar"
      ></image>
      <image v-else src="/static/upload-avatar.svg" class="upload"></image>
    </button>
  </view>
  <view class="nickname">
    <input
      maxlength="8"
      type="nickname"
      :value="nickName"
      @blur="bindblur"
      placeholder="點擊輸入昵稱"
      @input="bindinput"
    />
  </view>
  <view class="operation">
    <button class="confirm" @click="onSubmit">保存</button>
    <button v-if="userStore.info.nickname" class="cancel" @click="cancel">
      取消
    </button>
  </view>
</view>
3.首頁

進入首頁,點擊自己頭像可以修改頭像、昵稱,點擊加號可以將房間分享聯系人或群聊,其他用戶可以通過點擊分享加入房間。

長按加號可以生成臺板,用于記錄臺費,點擊臺板可以刪除臺板。

點擊掃碼加入,可以生成當前房間小程序碼,其他用戶可通過掃描該小程序碼加入房間。

點擊開始,跳轉到計分面板。點擊結束,將會結束對局并解散當前房間,同時對局的得分情況也將保存至“記錄”菜單。

async generateCode() { // 生成當前房間小程序碼
  this.qrLoading = true
  uni.showLoading()
  let roomid = ''
  if (userStore.info.roomid) {
    roomid = userStore.roomid
  } else {
    roomid = md5(userStore.info.openid + new Date().getTime())
    userStore.updateRoomid(roomid)
  }
  let res = await uni.request({
    url: userStore.baseURL + `get-code?roomid=${userStore.info.roomid}`,
    method: 'post',
    responseType: 'arraybuffer',
  })
  userStore.qrCode = 'data:image/PNG;BASE64,' + uni.arrayBufferToBase64(res.data)
  uni.hideLoading()
  this.qrLoading = false
}
4.計分

在勝負欄選擇勝負,在得分欄輸入每個成員的得分。也可以不選擇勝負,直接在得分欄輸入正/負數。 最后一個成員的得分無需填寫,將會根據所有成員得分之和為 0 的規(guī)則自動計算。

長按確定按鈕可以進行語音識別,將識別出的結果自動填寫在得分欄中。語音模板為: 昵稱/第 n 個+輸/贏/加/減/正/勝/負+多少。

startRecording() {
  if (this.isRecording) return;
  this.isRecording = true;
  this.recorderManager.start({
    duration: 60000, // 錄音時長,單位為毫秒
    format: "mp3", // 錄音格式
  });
  this.recognitionResult = "正在講話…";
},
stopRecording() {
  if (!this.isRecording) return;
  this.isRecording = false;
  this.recorderManager.stop();
},
async handleRecordingStop(res) {
  let base64code = uni
    .getFileSystemManager()
    .readFileSync(res.tempFilePath, "base64");
  uni.showLoading();
  let rst = await uni.request({
    url: userStore.baseURL + "/translate/voice",
    method: "post",
    data: {
      data: base64code,
      customizationId: "xxxxxxxxxxxxxxxxxxxxx",
    },
    header: {
      "content-type": "application/x-www-form-urlencoded",
    },
  });
  uni.hideLoading();
  if (rst.data.Result) {
    this.recognitionResult = rst.data.Result;
    this.processingData();
  } else {
    this.recognitionResult = "";
    uni.showToast({
      title: "好像什么也沒有聽到~",
      icon: "none",
    });
  }
},
words2Number(words) { // 將句子轉換成數字
  const one2ten = [
    "一",
    "二",
    "三",
    "四",
    "五",
    "六",
    "七",
    "八",
    "九",
    "十",
    "兩",
  ];
  const wordArr = words.split("");
  let number = null;
  for (let i = 1; i < 12; i++) {
    if (wordArr.includes(one2ten[i - 1])) {
      number = i < 11 ? i : 2;
      break;
    }
  }
  return number;
},
processingData() {
  // 定義表示贏和輸的意思的詞及其對應的正負號
  const winKeywords = ["贏", "加", "正", "勝"];
  const loseKeywords = ["輸", "減", "負"];
  const indexs = ["第一個", "第二個", "第三個", "第四個", "第五個"];

  // 初始化結果對象
  const result = {};

  // 按照逗號分割文本
  const phrases = this.recognitionResult.split(",");

  // 遍歷每個短語
  phrases.forEach((phrase) => {
    let nickname = "";
    let score = 0;
    // 判斷短語中是否包含贏和輸的意思的詞
    const winKeyword = winKeywords.find((keyword) =>
      phrase.includes(keyword)
    );
    if (winKeyword) {
      // 提取昵稱和得分
      const data = phrase.split(winKeyword);
      if (data.length === 2) {
        nickname = data[0];
        indexs.forEach((x, i) => {
          if (nickname.includes(x))
            nickname = userStore.members[i].nickname;
        });
        const matchScore = data[1].match(/\d+/g);
        if (matchScore?.length) {
          score = 1 * matchScore[0];
        } else {
          score = this.words2Number(data[1]);
        }
      }
    } else {
      const loseKeyword = loseKeywords.find((keyword) =>
        phrase.includes(keyword)
      );
      if (loseKeyword) {
        // 提取昵稱和得分
        const data = phrase.split(loseKeyword);
        if (data.length === 2) {
          nickname = data[0];
          indexs.forEach((x, i) => {
            if (nickname.includes(x))
              nickname = userStore.members[i].nickname;
          });
          const matchScore = data[1].match(/\d+/g);
          if (matchScore?.length) {
            score = -1 * matchScore[0];
          } else {
            score = -1 * this.words2Number(data[1]);
          }
        }
      }
    }
    // 添加到結果對象中
    if (nickname && score) result[nickname] = score;
  });
  if (Object.keys(result).length === 0) {
    uni.showToast({
      title: "沒聽清~",
      icon: "none",
    });
  } else {
    for (let key in result) {
      userStore.members.forEach((x, i) => {
        if (key.includes(x.nickname) || x.nickname.includes(key)) {
          this.scores[i] = Math.abs(result[key]);
          this.outcomes[i] = result[key] >= 0 ? "+" : "-";
        }
      });
    }
    this.autoWriteLast(); // 自動填寫最后一個成員的得分
  }
}
5.記錄

點擊“記錄”菜單,可以查看自己所有歷史對局。

點擊對局可以查看該對局詳情。

6.詳情

點擊頭像可以顯示昵稱。

async showUser(record, index) {
  let nickname = ''
  let openid = record.openids.split(',')[index]
  let findUser = this.viewd.find((x) => x.openid === openid)
  if (findUser) {
    nickname = findUser.nickname
  } else {
    let res = await uni.request({
      url: userStore.baseURL + `search-info`,
      method: 'get',
      data: { openid },
    })
    nickname = res.data[0].nickname
    this.viewd.push({ openid, nickname }) // 已經點過的不再調用接口
    console.log(this.viewd)
  }
  uni.showToast({
    title: nickname,
    icon: 'none',
  })
}
7.評價

首先在pages.json里面引入「評價發(fā)布組件」。

"plugins": {
	"wxacommentplugin": {
		"version": "latest",
		"provider": "wx82e6ae1175f264fa"
	}
}

如果還未添加插件,則在開發(fā)者工具Console里點擊「添加插件」。
然后就可以在頁面的js文件里面調用組件接口。

var plugin = requirePlugin("wxacommentplugin");
plugin.openComment({
  // wx_pay_id: '4200001729202306024807578', // 交易評價類賬號選填
  success: (res)=>{
    console.log('plugin.openComment success', res)
  },
  fail: (res) =>{
    console.log('plugin.openComment fail', res)
  }
})

可在微信小程序官網的功能-體驗評價中查看評價。

后端

1.建表

使用了兩張表,一張用戶表 mahjong,一張對局表 room。

打牌計分小程序源碼,小程序,前端,服務器,后端,微信小程序

id:用戶id
openid:用戶的 openid
avatar:用戶的頭像
nickname:用戶的昵稱
roomid:用戶當前所在房間
updateTime: 用戶加入房間時間

打牌計分小程序源碼,小程序,前端,服務器,后端,微信小程序

id:對局id
roomid:房間id
openids:該局對局的所有成員的openid
scores:該局對局的得分情況
circle:局數
createTime:該局對局結束時間
active:游戲是否結束
2.注冊

① 前端通過 uni.login 這個請求獲取 code,通過該 code(js_code) 結合小程序的 appid、secret 以及 grant_type=authorization_code,調用微信官方接口“https://api.weixin.qq.com/sns/jscode2session”,返回用戶的openid。

public JSONObject getOpenid(String code) throws Exception {
    String appid = "xxx";
    String secret = "xxx";
    System.out.println("code=" + code);
    HttpClient httpClient = HttpClients.createDefault();
    URI url = new URIBuilder("https://api.weixin.qq.com/sns/jscode2session")
            .setParameter("appid", appid)
            .setParameter("secret", secret)
            .setParameter("js_code", code)
            .setParameter("grant_type", "authorization_code")
            .build();
    HttpGet httpGet = new HttpGet(url);
    JSONObject json = new JSONObject();
    try {
        HttpResponse res = httpClient.execute(httpGet);
        if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String result = EntityUtils.toString(res.getEntity());// 返回json格式:
            json = json.parseObject(result);
        } else {
            throw new Exception("獲取openid失??!");
        }
    } catch (Exception e) {
        throw new Exception("獲取openid異常!");
    }
    return json;
}

② 在用戶填完頭像和昵稱后,前端發(fā)送請求,后端將接收的頭像存儲至 minio 中并返回頭像路徑,然后結合 openid、昵稱、房間 id 等信息存儲到 mahjong 表中。

3.生成當前房間小程序碼

先通過 appid、secre、grant_type=client_credential 調用微信官方接口獲取 token,然后使用此 token 結合前端傳遞的當前房間 id,生成當前房間小程序碼。

public byte[] getCode(String roomid) throws Exception {
    String appid = "xxx";
    String secret = "xxx";
    HttpClient httpClient = HttpClients.createDefault();
    URI tokenURI = new URIBuilder("https://api.weixin.qq.com/cgi-bin/token")
            .setParameter("appid", appid)
            .setParameter("secret", secret)
            .setParameter("grant_type", "client_credential")
            .build();
    HttpGet httpGet = new HttpGet(tokenURI);
    JSONObject json = new JSONObject();
    try {
        HttpResponse res = httpClient.execute(httpGet);
        if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            json = json.parseObject(EntityUtils.toString(res.getEntity()));
            URI codeURI = new URIBuilder("https://api.weixin.qq.com/wxa/getwxacode")
                    .setParameter("access_token", json.getString("access_token"))
                    .build();
            HttpPost httpPost = new HttpPost(codeURI);
            String body = "{\"path\": \"pages/home/index?roomid=" + roomid + "\"}";
            httpPost.setEntity(new StringEntity(body));
            try {
                HttpResponse rst = httpClient.execute(httpPost);
                if (rst.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    return EntityUtils.toByteArray(rst.getEntity());
                } else {
                    throw new Exception("獲取小程序碼失?。?);
                }
            } catch (Exception e) {
                throw new Exception("獲取小程序碼異常!");
            }
        } else {
            throw new Exception("獲取token失?。?);
        }
    } catch (Exception e) {
        throw new Exception("獲取token異常!");
    }
}
4.語音識別

使用的是騰訊云的一句話識別,每個月免費 5000 次。前端將錄音臨時文件轉換成 base64 編碼傳遞至后端,結合使用場景 EngSerViceType、語音數據來源 SourceType(0:語音 URL;1:語音數據)、語音 Url、音頻格式 VoiceFormat 以及時間戳、熱詞、自學習模型。

public JSONObject voiceTrans(@RequestParam(required = false) String engSerViceType, @RequestParam(required = false) Long sourceType,
                              @RequestParam(required = false) String url, @RequestParam(required = false) String voiceFormat,
                              @RequestParam(required = false) String data, @RequestParam(required = false) String customizationId ) {
    if (engSerViceType == null) engSerViceType = "16k_zh";
    if (sourceType == null) {
        if (url == null) sourceType = 1L;
        else sourceType = 0L;
    }
    if (voiceFormat == null) voiceFormat = "mp3";
    JSONObject json = new JSONObject();
    String result = VoiceUtils.voiceTrans(engSerViceType, sourceType, url, voiceFormat, data, customizationId);
    json = json.parseObject(result);
    return json;
}

public static String voiceTrans(String EngSerViceType, Long SourceType, String Url, String VoiceFormat, String Data, String CustomizationId ) {
    try {
        // 密鑰可前往官網控制臺 https://console.cloud.tencent.com/cam/capi 進行獲取
        Credential cred = new Credential("xxx", "xxx");
        // 實例化一個http選項,可選的,沒有特殊需求可以跳過
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("asr.ap-beijing.tencentcloudapi.com");
        // 實例化一個client選項,可選的,沒有特殊需求可以跳過
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        // 實例化要請求產品的client對象,clientProfile是可選的
        AsrClient client = new AsrClient(cred, "", clientProfile);
        // 實例化一個請求對象,每個接口都會對應一個request對象
        SentenceRecognitionRequest req = new SentenceRecognitionRequest();
        req.setEngSerViceType(EngSerViceType);
        req.setSourceType(SourceType);
        req.setUrl(Url);
        req.setVoiceFormat(VoiceFormat);
        req.setData(Data);
        req.setWordInfo(1L);
        req.setReinforceHotword(1L);
        req.setCustomizationId(CustomizationId);
        // 返回的resp是一個SentenceRecognitionResponse的實例,與請求對象對應
        SentenceRecognitionResponse resp = client.SentenceRecognition(req);
        // 輸出json格式的字符串回包
        return SentenceRecognitionResponse.toJsonString(resp);
    } catch (TencentCloudSDKException e) {
        return e.toString();
    }
}
5.添加記錄

當一局結束后,將房間 id,所有成員 openid,分數,局數存儲至 room 表,并將 active 設置為 1。
先查詢 mahjong 表中是否存在此房間 id,如果不存在,說明對局結束,房間已經解散。然后查詢 room 表是否存在此房間 id 且 active 等于 1 的對局:
① 如果不存在且 circle 等于 1,再判斷該房間成員數量和提交的成員數量,如果前者大于后者,說明有新成員加入,此次提交不生效。
② 如果不存在且 circle 不等于 1,說明已經不是第一局,房間已經鎖定,其他人無法加入,所以不需要判斷,提交有效。
③ 如果存在且該房間最后一條對局記錄的局數小于提交的局數,提交有效。
④ 如果存在且該房間最后一條對局記錄的局數大于或等于提交的局數,說明已經有人在你提交前提交過了,提交無效。

public String addRecord(Room record) {
    String openids = record.getOpenids();
    Integer circle = record.getCircle();
    List<Room> records = mahjongMapper.searchRecords(openids);
    List<Mahjong> mahjong = mahjongMapper.searchInfo("", record.getRoomid());
    if (mahjong.isEmpty()) {
        return "對局已結束";
    } else {
        if (records.isEmpty()) {
            if (circle == 1) {
                if (mahjong.size() > record.getOpenids().split(",").length) {
                    return "有新成員加入";
                }
            }
            mahjongMapper.addRecord(record);
            return "true";
        } else {
            if (records.get(records.size() - 1).getCircle() < circle) {
                mahjongMapper.addRecord(record);
                return "true";
            } else {
                return "其他成員已提交";
            }
        }
    }

}
6.結束游戲

前端將此次游戲所有成員 openid、所有對局的 id、總分、以及房間 id 傳遞給后端,后端所做的工作依次為:
① 通過 mahjongMapper.gameOver(openids),遍歷 openids,將 mahjong 表中 openid 與之相等的用戶房間 id 清空。
② 通過 mahjongMapper.setActive(ids),遍歷所有對局 id,將 room 表中 id 與之相等的對局的 active 設置為 0。
③ 通過 mahjongMapper.addRecord(record),將總分作為一條對局記錄添加至 room 表中,其中 circle 等于-1,active 等于 0。

public void gameOver(String[] openids, String[] ids, String scores, String roomid) {
    mahjongMapper.gameOver(openids);
    mahjongMapper.setActive(ids);
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
    String createTime = simpleDateFormat.format(new Date());
    Room record = new Room(null, String.join(",", ids), String.join(",", openids), scores, -1, createTime, 0);
    mahjongMapper.addRecord(record);
}
7.查詢歷史記錄

這個接口邏輯寫的有點草率,后續(xù)可以優(yōu)化。

先通過個人 openid 查詢 room 表與之相關且 circle 等于-1 的歷史記錄,
然后查詢 mahjong 表中所有用戶信息,遍歷歷史記錄,遍歷用戶信息,
將歷史記錄的 openid 等于用戶信息的 openid 的用戶頭像提取出來,與歷史記錄一并返回。文章來源地址http://www.zghlxwxcb.cn/news/detail-768077.html

public List searchHistory(String openid) {
    List<Room> records = mahjongMapper.searchHistory(openid);

    List<Mahjong> mahjongs = mahjongMapper.searchAllInfo();

    for (Room record : records) {
        String[] openids = record.getOpenids().split(",");
        String avatars = "";
        String avatar = "";

        for (String id : openids) {
            avatar = "";
            for (Mahjong mahjong: mahjongs)
            {
                if(mahjong.getOpenid().equals(id)){
                    avatar = mahjong.getAvatar();
                    break;
                }
            }
            avatars += avatar + ',';
        }
        record.setAvatars(avatars.substring(0, avatars.length() - 1));
    }
    return records;
}

到了這里,關于麻將計分器:簡單的微信小程序開發(fā)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 教程&硬貨|微信小程序開發(fā)之基于vue的微信開發(fā)工具JS文件解讀(一)

    教程&硬貨|微信小程序開發(fā)之基于vue的微信開發(fā)工具JS文件解讀(一)

    鑒于前段時間出的第一篇記錄安裝Nodejs和HBuilderX搭建、部署微信小程序開發(fā)環(huán)境(一),有小伙伴問到關于微信開發(fā)工具的使用,特出本文帶大家簡單了解一下,開始“掃盲”! 微信公眾平臺:https://mp.weixin.qq.com/ 留意一下微信公眾平臺是注冊小程序賬號的,里面有個 AppID

    2024年02月09日
    瀏覽(50)
  • 【移動開發(fā)學習】 Android Studio 編寫一個簡單的微信界面

    【移動開發(fā)學習】 Android Studio 編寫一個簡單的微信界面

    Android Studio簡單還原微信ui 目標 實現3-4個tab的切換效果 技術需求 activity, xml, fragment, recyclerview 成果展示 其中聯系人界面通過recyclerview實現了可以滑動列表 ?? ?? ? ? 倉庫地址 https://github.com/SmileEX/wecaht.git 實現過程 主要ui 第一步我們首先把微信的ui主體做出來,即這三個部分

    2024年02月08日
    瀏覽(103)
  • 【移動開發(fā)學習】 Android Studio 編寫一個簡單的微信界面 (2)

    【移動開發(fā)學習】 Android Studio 編寫一個簡單的微信界面 (2)

    Android Studio簡單還原微信ui 上一期完成內容(前情提要) 上次我們簡單地實現了微信的幾個初始界面,并且在聯系人頁面通過recycleview添加了許多的view 目標 建立在上次的基礎上,我們來擴展聯系人界面的功能,給每一個view添加一個點擊功能,讓其可以跳轉到另一個activity,

    2024年02月05日
    瀏覽(93)
  • uniapp開發(fā)的微信小程序如何上傳至微信小程序平臺-完整簡單步驟

    uniapp開發(fā)的微信小程序如何上傳至微信小程序平臺-完整簡單步驟

    這個id請登錄微信小程序號? ?設置中查看 成功上傳。 message:Error: 系統(tǒng)錯誤,錯誤碼:80051,source size 3743KB exceed max limit 2MB? 如果這樣報錯可以嘗試分包或者減至2M以內。 分包方法參考此博文 uniapp如何分包 分包配置后無法讀取static文件夾_謹言不言的博客-CSDN博客_uniapp 分包

    2024年02月16日
    瀏覽(373)
  • 基于Uniapp+SSM+Vue的微信小程序設計與實現

    基于Uniapp+SSM+Vue的微信小程序設計與實現

    摘要:本文介紹了基于Uniapp+SSM+Vue技術棧開發(fā)的微信小程序——走失人員報備平臺的設計、實現與優(yōu)化。該平臺旨在為志愿者提供便捷的走失人員信息收集與報備功能,助力社會公益事業(yè)的發(fā)展。 :Uniapp;SSM;Vue;微信小程序;走失人員報備 一、引言 介紹走失人員問

    2024年01月17日
    瀏覽(19)
  • Mac電腦版微信】雙開方法,最簡單的微信多開教程

    Mac電腦版微信】雙開方法,最簡單的微信多開教程 最全軟件大全,保存永久有效 Mac微信雙開 最近比較多人咨詢的Mac微信的雙開方法,今天給大家來個圖文教程,很簡單,無需代碼??紤]到公眾號最近咨詢蘋果軟件的越來越多,決定逐步上一些蘋果軟件,希望能給更多的小伙

    2024年02月04日
    瀏覽(27)
  • 【微信小程序】如何上傳uniApp開發(fā)的微信小程序?

    【微信小程序】如何上傳uniApp開發(fā)的微信小程序?

    微信開發(fā)者工具下載鏈接 Hbuilder X下載鏈接 掃碼 選中賬號 登錄成功: ps: 如果之前沒有權限但是已經登錄此賬號,需要在獲取到權限后重新登錄一次?? ps: 不選中 運行時是否壓縮代碼 有可能代碼包不包含插件大小過大,導致上傳失敗?? 小程序性能優(yōu)化指南 操作1 操作

    2024年02月09日
    瀏覽(857)
  • 微信小程序開發(fā)教程:項目二微信小程序開發(fā)基礎 課后習題

    微信小程序開發(fā)教程:項目二微信小程序開發(fā)基礎 課后習題

    《微信小程序開發(fā)教程》主編/黃壽孟 易芳 陶延濤 湖南大學出版社 目錄 一、單選題 二、多選題 三、判斷題 四、填空題 五、簡答題 1.請簡單描述頁面樣式的單位rpx與px的關系。 2.簡單地介紹開發(fā)常用頁面組件。 六、編程題 1.請編寫一個商品列表頁面,展示商品名稱和價格。

    2024年02月09日
    瀏覽(16)
  • 【小程序云開發(fā)】不用后端也能構建完整的微信小程序

    【小程序云開發(fā)】不用后端也能構建完整的微信小程序

    ?創(chuàng)作者:全棧弄潮兒 ?? 個人主頁: 全棧弄潮兒的個人主頁 ??? 個人社區(qū),歡迎你的加入:全棧弄潮兒的個人社區(qū) ?? 專欄地址:小程序從入門到精通 【分享幾個國內免費可用的ChatGPT鏡像】 【10幾個類ChatGPT國內AI大模型】 【用《文心一言》1分鐘寫一篇博客簡直yyds】

    2024年02月02日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包