国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲

人工智能 新聞
此項(xiàng)目是用最新版DevEco Studio 3.1 Release并創(chuàng)建端云一體開發(fā),由于目前此版本不支持直接調(diào)用云數(shù)據(jù)庫,不過可以通過云函數(shù)調(diào)用云數(shù)據(jù)庫,也就是在服務(wù)卡片業(yè)務(wù)邏輯里通過調(diào)用云函數(shù)來完成游戲數(shù)據(jù)保存到云數(shù)據(jù)庫。

1.前言

翻牌游戲萬能卡片,隨機(jī)生成16張共包含8張完全不同的圖像,游戲的目標(biāo)是在有限30秒時(shí)間內(nèi),將16張卡片中包含相同的圖像的卡片兩兩配對。匹配的規(guī)則是連續(xù)點(diǎn)擊兩張卡片,若卡背面的圖像相同,則匹配成功,若不同則配對失敗。游戲主要考察玩家的記憶力,因?yàn)橛螒蜻€規(guī)定翻開的卡片數(shù)量至多有兩張,否則一開始被點(diǎn)擊而翻開的卡片將再次蓋上(若該張卡片沒有匹配成功)。此項(xiàng)目是用最新版DevEco Studio 3.1 Release并創(chuàng)建端云一體開發(fā),由于目前此版本不支持直接調(diào)用云數(shù)據(jù)庫,不過可以通過云函數(shù)調(diào)用云數(shù)據(jù)庫,也就是在服務(wù)卡片業(yè)務(wù)邏輯里通過調(diào)用云函數(shù)來完成游戲數(shù)據(jù)保存到云數(shù)據(jù)庫,開發(fā)工具支持本地函數(shù)調(diào)用測試,大大方便了開發(fā),此貼重點(diǎn)講解云函數(shù)和云數(shù)據(jù)庫開發(fā),從而進(jìn)一步學(xué)習(xí)Serverless知識,翻牌游戲萬能卡片效果圖如下:

鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_元服務(wù)鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_元服務(wù)

2.知識點(diǎn)

為豐富HarmonyOS對云端開發(fā)的支持、實(shí)現(xiàn)HarmonyOS生態(tài)端云聯(lián)動(dòng),DevEco Studio推出了云開發(fā)功能,開發(fā)者在創(chuàng)建工程時(shí)選擇云開發(fā)模板,即可在DevEco Studio內(nèi)同時(shí)完成HarmonyOS應(yīng)用/服務(wù)的端側(cè)與云側(cè)開發(fā),體驗(yàn)端云一體化協(xié)同開發(fā)。

相比于傳統(tǒng)開發(fā)模式,云開發(fā)模式具備成本低、效率高、門檻低等優(yōu)勢,具體區(qū)別見下表。

2.1. 開發(fā)流程

HarmonyOS應(yīng)用端云一體化開發(fā)流程如下圖所示。

鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_游戲卡片_02鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_游戲卡片_02

2.2. 創(chuàng)建端云一體化開發(fā)工程

2.2.1  新建原子化服務(wù)工程

2.2.2  工程初始化配置

2.2.3  端云一體化開發(fā)工程介紹

2.3. 開發(fā)云工程

2.3.1  開發(fā)云函數(shù)

2.3.2  開發(fā)云數(shù)據(jù)庫

2.4. 部署云工程

2.4.1  部署云工程

2.5. 小結(jié)

了解這些端云一體化開發(fā)知識點(diǎn)后,下面圍繞翻牌游戲萬能卡片,在云數(shù)據(jù)庫里設(shè)計(jì)卡片表結(jié)構(gòu)和游戲記錄表結(jié)構(gòu),然后再編寫相關(guān)云函數(shù),在元服務(wù)業(yè)務(wù)邏輯調(diào)用云函數(shù)。

3.云數(shù)據(jù)庫開發(fā)講解

3.1. objecttype創(chuàng)建

3.1.1 展開CloudProgram -> clouddb -> objecttype 右擊objecttype目錄,創(chuàng)建 -> Cloud DB Object Type 輸入Object Type Name為t_form,點(diǎn)擊確認(rèn),代碼內(nèi)容如下:

{
  "fields": [
    {
      "isNeedEncrypt": false,
      "fieldName": "formId",
      "notNull": true,
      "belongPrimaryKey": true,
      "fieldType": "String"
    },
    {
      "isNeedEncrypt": false,
      "fieldName": "formName",
      "notNull": true,
      "defaultValue": "",
      "belongPrimaryKey": false,
      "fieldType": "String"
    },
    {
      "isNeedEncrypt": false,
      "fieldName": "dimension",
      "notNull": true,
      "defaultValue": "0",
      "belongPrimaryKey": false,
      "fieldType": "Integer"
    }
  ],
  "indexes": [
    {
      "indexName": "formId",
      "indexList": [{ "fieldName": "formId", "sortType": "ASC" }]
    }
  ],
  "objectTypeName": "t_form",
  "permissions": [...]
}

3.1.2 展開CloudProgram -> clouddb -> objecttype 右擊objecttype目錄,創(chuàng)建 -> Cloud DB Object Type 輸入Object Type Name為t_record,點(diǎn)擊確認(rèn),代碼內(nèi)容如下:

{
  "fields": [
    {
      "isNeedEncrypt": false,
      "fieldName": "formId",
      "notNull": true,
      "belongPrimaryKey": true,
      "fieldType": "String"
    },
    {
      "isNeedEncrypt": false,
      "fieldName": "matrixNum",
      "notNull": true,
      "defaultValue": "",
      "belongPrimaryKey": false,
      "fieldType": "String"
    },
    {
      "isNeedEncrypt": false,
      "fieldName": "bestScore",
      "notNull": true,
      "defaultValue": "0",
      "belongPrimaryKey": false,
      "fieldType": "Double"
    }
  ],
  "indexes": [
    {
      "indexName": "formId",
      "indexList": [{ "fieldName": "formId", "sortType": "ASC" }]
    }
  ],
  "objectTypeName": "t_record",
  "permissions": [...]
}

3.2. dataentry創(chuàng)建

3.2.1 展開CloudProgram -> clouddb -> dataentry 右擊dataentry目錄,創(chuàng)建 -> Cloud DB Data Entry 這里先選擇上面創(chuàng)建的Object Type為t_form,再輸入Data Entry Name為form_data,點(diǎn)擊確認(rèn),代碼內(nèi)容如下:

{
  "cloudDBZoneName": "widgetCard",
  "objectTypeName": "t_form",
  "objects": [
    {
      "formId": "x000001",
      "formName": "卡片1",
      "dimension": 2
    }
  ]
}

3.2.2 展開CloudProgram -> clouddb -> dataentry 右擊dataentry目錄,創(chuàng)建 -> Cloud DB Data Entry 這里先選擇上面創(chuàng)建的Object Type為t_record,再輸入Data Entry Name為record_data,點(diǎn)擊確認(rèn),修改內(nèi)容如下:

{
  "cloudDBZoneName": "widgetCard",
  "objectTypeName": "t_record",
  "objects": [
    {
      "formId": "x000001",
      "matrixNum": "4x4",
      "bestScore": 2.234
    }
  ]
}

3.3. 小結(jié)

其實(shí)dataentry文件可以不創(chuàng)建,這里對兩個(gè)表都初始化了一條數(shù)據(jù),是方便下面的調(diào)用使用,云數(shù)據(jù)庫就是定義好表結(jié)構(gòu)、權(quán)限配置就可以,數(shù)據(jù)的添加、修改、刪除、查詢都可以通過云函數(shù)來完成。

4.云函數(shù)開發(fā)講解

4.1. 卡片云函數(shù)創(chuàng)建

4.1.1 展開CloudProgram -> cloudfunctions 右擊cloudfunctions目錄,創(chuàng)建 -> Cloud Function 輸入Cloud Function Name為form,點(diǎn)擊確認(rèn), 卡片云函數(shù)里包含了增刪改查操作,所以在form下,創(chuàng)建不同的文件夾來區(qū)分,目錄結(jié)構(gòu)如下:

鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_Serverless_03鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_Serverless_03

4.1.2 首先說一下與云數(shù)據(jù)庫交互文件,t_form.js對應(yīng)的是云數(shù)據(jù)庫實(shí)體類,如各屬性的get和set方法,之前FA模式下的DevEco Studio端云一體化開發(fā),支持直接調(diào)用云數(shù)據(jù)庫,現(xiàn)在Stage模式下的DevEco Studio端云一體化開發(fā),還不支持直接調(diào)用云數(shù)據(jù)庫,通過云函數(shù)來調(diào)用,所以這里的云數(shù)據(jù)庫實(shí)體類,可以通過AGC導(dǎo)出,然后復(fù)制到t_form文件內(nèi),導(dǎo)出步驟圖:

鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_游戲卡片_04鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_游戲卡片_04

如卡片實(shí)例體類:

class t_form {
    getFieldTypeMap() {
        let fieldTypeMap = new Map();
        fieldTypeMap.set('formId', 'String');
        fieldTypeMap.set('formName', 'String');
        fieldTypeMap.set('dimension', 'Integer');
        return fieldTypeMap;
    }
    
    getClassName() {
        return 't_form';
    }

    getPrimaryKeyList() {
        let primaryKeyList = [];
        primaryKeyList.push('formId');
        return primaryKeyList;
    }

    getIndexList() {
        let indexList = [];
        return indexList;
    }

    getEncryptedFieldList() {
        let encryptedFieldList = [];
        return encryptedFieldList;
    }

	// set and get
    setFormId(formId) {this.formId = formId;}
    getFormId() {return this.formId;}
    setFormName(formName) {this.formName = formName;}
    getFormName() {return this.formName;}
    setDimension(dimension) {this.dimension = dimension;}
    getDimension() {return this.dimension;}
}

module.exports = {t_form}

4.1.3 CloudDBZoneWrapper操作云數(shù)據(jù)庫,這里主要列舉構(gòu)造函數(shù)和增加方法內(nèi)容:

import * as clouddb from '@agconnect/database-server';
import { t_form as FormBean } from './models/t_form';
import * as agconnect from '@agconnect/common-server';

const ZONE_NAME = "widgetCard";

export class CloudDBZoneWrapper {
  logger;
  cloudDbZone;

  constructor(credential, logger) {
    this.logger = logger;
    try {
      // 初始化AGCClient
      let agcClient;
      try {
        agcClient = agconnect.AGCClient.getInstance();
      } catch {
        agconnect.AGCClient.initialize(credential);
        agcClient = agconnect.AGCClient.getInstance();
      }
      // 初始化AGConnectCloudDB實(shí)例
      let cloudDbInstance;
      try {
        cloudDbInstance = clouddb.AGConnectCloudDB.getInstance(agcClient);
      } catch {
        clouddb.AGConnectCloudDB.initialize(agcClient);
        cloudDbInstance = clouddb.AGConnectCloudDB.getInstance(agcClient);
      }
      // 創(chuàng)建CloudDBZoneConfig配置對象,并設(shè)置云側(cè)CloudDB zone名稱,打開Cloud DB zone實(shí)例
      const cloudDBZoneConfig = new clouddb.CloudDBZoneConfig(ZONE_NAME);
      this.cloudDbZone = cloudDbInstance.openCloudDBZone(cloudDBZoneConfig);
    } catch (err) {
      logger.error("xx [form-func]CloudDBZoneWrapper init CloudDBZoneWrapper error: " + err);
    }
  }

  async insert(addForm) {
    if (!this.cloudDbZone) {
      this.logger.error("xx  [form-func]CloudDBZoneWrapper->insert CloudDBClient is null, try re-initialize it");
    }

    try {
      let res = await this.cloudDbZone.executeUpsert(addForm);
      this.logger.info("xx  [form-func]CloudDBZoneWrapper->insert Insert " + res + " records success");
    } catch (error) {
      this.logger.error("xx  [form-func]CloudDBZoneWrapper->insert executeInsert addressRecords failed " + error);
    }
  }
}

4.1.4 新增卡片函數(shù)form-insert,關(guān)鍵代碼如下:

import { CloudDBZoneWrapper } from '../clouddb/CloudDBZoneWrapper.js';
import * as Utils from '../utils/Utils.js';

export const myHandler = async function (event, context, callback, logger) {
  const credential = Utils.getCredential(context, logger);
  try {
    const cloudDBZoneWrapper = new CloudDBZoneWrapper(credential, logger);
    let formObj = cloudDBZoneWrapper.getForm(event);
    await cloudDBZoneWrapper.insert(formObj);

    callback({
      ret: { code: 0, desc: "SUCCESS" },
    });
  } catch (err) {
    logger.error("xx [form-func]insert func error:" + err.message + " stack:" + err.stack);
    callback({
      ret: { code: -1, desc: "ERROR" },
    });
  }
};

4.1.5 卡片云函數(shù)主入口,關(guān)鍵代碼如下:

let myHandler = async function (event, context, callback, logger) {
  let operation;
  let params;

  logger.info("xx enter form func with operation " + event.operation);
  operation = event.body ? JSON.parse(event.body).operation : event.operation;
  params = event.body ? JSON.parse(event.body).params : event.params;

  switch (operation) {
    case "query":
      query.myHandler(params, context, callback, logger);
      break;
    case "queryById":
      queryById.myHandler(params, context, callback, logger);
      break;
    case "insert":
      insert.myHandler(params, context, callback, logger);
      break;
    case "update":
      update.myHandler(params, context, callback, logger);
      break;
    case "delete":
      deleteByObj.myHandler(params, context, callback, logger);
      break;
    default:
      callback({
        ret: { code: -1, desc: "no such function" },
      });
  }

};
module.exports.myHandler = myHandler;

4.2. 記錄云函數(shù)創(chuàng)建

4.2.1 展開CloudProgram -> cloudfunctions 右擊cloudfunctions目錄,創(chuàng)建 -> Cloud Function 輸入Cloud Function Name為record,點(diǎn)擊確認(rèn), 成績云函數(shù)里包含了增刪改查操作,所以在record下,創(chuàng)建不同的文件夾來區(qū)分,目錄結(jié)構(gòu)如下:

鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_Serverless_05鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_Serverless_05

4.2.2 記錄表云數(shù)據(jù)庫操作與卡片操作一樣,這里就不在重復(fù)了,可以參考一下上面卡片操作方法就可以。

5.元服務(wù)開發(fā)

5.1. 1*2卡片開發(fā)

5.1.1 創(chuàng)建卡片步驟:

鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_端云一體化開發(fā)_06鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_端云一體化開發(fā)_06

鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_端云一體化開發(fā)_07鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_端云一體化開發(fā)_07

鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_Serverless_08鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_Serverless_08

5.1.2 卡片模板創(chuàng)建好后,修改為翻牌游戲UI, 就是左邊顯示一張獎(jiǎng)牌圖片,右邊顯示最快記錄時(shí)間,圖片效果為:

鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_游戲卡片_09鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_游戲卡片_09

UI代碼如下:

build() {
    Row() {
      Image($r('app.media.cup'))
        .width(32).height(32).objectFit(ImageFit.Cover)
      Text(`最快成績:${this.totalBestScore}'s`)
        .fontSize($r('app.float.font_size'))
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.SpaceEvenly)
    .onClick(() => {
      postCardAction(this, {
        "action": 'router',
        "abilityName": 'EntryAbility',
        "params": {
          "message": 'view history'
        }
      });
    })
  }

5.2. 4*4卡片開發(fā)

5.2.1 創(chuàng)建卡片步驟如上面步驟。

5.2.2 卡片模板創(chuàng)建好后,修改為翻牌游戲UI, 就是頂部顯示游戲信息,如:游戲標(biāo)題,當(dāng)前用時(shí),倒計(jì)時(shí),開始游戲,中部顯示16張卡片,圖片效果為:

鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_Serverless_10鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲_Serverless_10

UI部分代碼如下:

build() {
    Column() {
      Row() {
        Text('記憶翻牌游戲')
        // Text(`最快:${this.totalBestScore}'s`)
        //   .fontSize(10)
        Text(`當(dāng)前:${this.tookTime}'s`)
          .fontSize(10)
        Text(`倒計(jì)時(shí):${this.timeCount}'s`)
          .fontSize(10)
        Text('開始')
          .visibility(this.isStart ? Visibility.Visible : Visibility.Hidden)
          .onClick(() => {
            this.startGame()
          })
      }
      .width(FULL_WIDTH_PERCENT)
      .justifyContent(FlexAlign.SpaceBetween)
      .height(30)

      Stack(){
        Flex({wrap: FlexWrap.Wrap, direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceEvenly}) {
          ForEach(this.arr, (idx) => {
            GameCard({card: this.cards[idx], cardArray: $cards, startTime: this.startTime})
          }, (idx) => idx.toString())
        }

        Text(this.resultMessage)
          .width(FULL_WIDTH_PERCENT)
          .height(FULL_HEIGHT_PERCENT)
          .textAlign(TextAlign.Center)
          .fontColor(Color.White)
          .backgroundColor('rgba(0,0,0,0.5)')
          .visibility(this.isStart ? Visibility.Visible : Visibility.None)
      }
      .width(FULL_WIDTH_PERCENT)
      .layoutWeight(1)
    }
    .width(FULL_WIDTH_PERCENT)
    .height(FULL_HEIGHT_PERCENT)
    .padding(10)
  }

6.代碼講解

6.1. 云函數(shù)調(diào)用公共類

export class DatabaseUtils {

  async callWithParams(context, trigger, operation, params) {
    await getAGConnect(context);
    let body = {
      "operation": operation,
      "params": params
    }

    try {
      let functionCallable = agconnect.function().wrap(trigger);
      let functionResult = await functionCallable.call(body);
      return functionResult.getValue();
    }
    catch (err) {
      return {
        "ret": {"code": -1, "desc": "ERROR"}
      }
    }
  }
    
  async invoke(context: any, trigger?: string, operation?: string, params?: object) {
    console.info(CommonConstants.DATABASE_TAG, 'xx invoke params: '+JSON.stringify(params))
    return await this.callWithParams(context, trigger, operation, params);
  }

  /**
   * 插入卡片數(shù)據(jù)。
   *
   * @param{Form}Form表單實(shí)體。
   * @param{DataRdb.RdbStore}RDB存儲(chǔ)RDB數(shù)據(jù)庫。
   * @return返回操作信息。
   */
  async insertForm(context: any, form: Form) {
    let res = await this.invoke(context, Triggers.FormFunc, RequestType.Insert, form);
    console.info(CommonConstants.DATABASE_TAG, 'xx insertForm result: ' + JSON.stringify(res));
  }
  ......
}

6.2. 卡片Ability調(diào)用公共類

EntryFormAbility.ets卡片生命周期代碼如下:

onAddForm(want) {
    // 獲取卡片ID:ohos.extra.param.key.form_identity
    let formId: string = want.parameters[CommonConstants.FORM_PARAM_IDENTITY_KEY] as string;
    // 獲取卡片名稱:ohos.extra.param.key.form_name
    let formName: string = want.parameters[CommonConstants.FORM_PARAM_NAME_KEY] as string;
    // 獲取卡片規(guī)格:ohos.extra.param.key.form_dimension
    let dimensionFlag: number = want.parameters[CommonConstants.FORM_PARAM_DIMENSION_KEY] as number;

    // 卡片信息
    let form: Form = new Form();
    form.formId = formId;
    form.formName = formName;
    form.dimension = dimensionFlag;

    // 保存卡片信息到數(shù)據(jù)庫
    DatabaseUtils.insertForm(this.context, form);
    // 獲取最優(yōu)成績
    getScoreById(this.context, dimensionFlag, formId);

    // 每五分鐘刷新一次
    formProvider.setFormNextRefreshTime(formId, CommonConstants.FORM_NEXT_REFRESH_TIME, (error, data) => {
      if (error) {
        console.error(CommonConstants.ENTRY_FORM_ABILITY_TAG, 'xx onAddForm 更新卡片失敗:' + JSON.stringify(error))
      } else {
        console.info(CommonConstants.ENTRY_FORM_ABILITY_TAG, 'xx onAddForm 更新卡片成功')
      }
    });

    // 返回初始化卡片數(shù)據(jù)
    let formData: FormData = new FormData();
    formData.formId = formId;
    formData.bestScore = 0;
    formData.matrixNum = '1x1';
    formData.totalBestScore = 0;
    return formBindingData.createFormBindingData(formData);
  }

6.3. 主界面調(diào)用公共類

@Entry
@Component
struct Index {
  @State scoreDataList: Array<FormData> = []

  aboutToAppear() {
    // 請求通知欄權(quán)限
    this.requestNotification();
    // 更新卡片信息
    DatabaseUtils.updateForms(getContext(this));
    // 獲取成績歷史記錄
    this.getScoreListData()
  }
  onPageShow() {
    // 更新卡片信息
    DatabaseUtils.updateForms(getContext(this));
    // 獲取成績歷史記錄
    this.getScoreListData()
  }
    // 獲取成績歷史數(shù)據(jù)
  getScoreListData() {
    DatabaseUtils.getScoreListData(getContext(this))
      .then((res) => {
        this.scoreDataList = res;
        // 發(fā)送通知
        NotificationUtils.sendNotifications(this.scoreDataList[0].totalBestScore);
      }).catch((error) => {
      console.error(CommonConstants.MAIN_PAGE_TAG, 'xx aboutToAppear or onPageShow getScoreListData error ' + JSON.stringify(error));
    });
  }

  build() {...}
}

7.總結(jié)

通過翻牌小游戲元服務(wù)使用Serverless云函數(shù)、云數(shù)據(jù)庫,學(xué)習(xí)到不少知識,開始時(shí)不懂得怎么使用云函數(shù)調(diào)用云數(shù)據(jù)庫,一邊參考官方商城模板,一邊測試,到使用到這個(gè)小游戲上, 總結(jié)這個(gè)項(xiàng)目用到以下知識點(diǎn):

  • 使用Notification發(fā)布通知。
  • 使用端云一體化開發(fā)、開發(fā)云函數(shù)、開發(fā)云數(shù)據(jù)庫。
  • 使用FormExtensionAbility創(chuàng)建、更新、刪除元服務(wù)卡片。

各位也可以點(diǎn)擊元服務(wù)官網(wǎng),了解更多相關(guān)信息。

元服務(wù)官網(wǎng)鏈接: https://developer.huawei.com/consumer/cn/harmonyos/fa?ha_source=yuanfuwuGW&ha_sourceld=89000452


?著作權(quán)歸作者所有:來自51CTO博客作者狼哥Army的原創(chuàng)作品,請聯(lián)系作者獲取轉(zhuǎn)載授權(quán),否則將追究法律責(zé)任 鴻蒙萬能卡片開發(fā)詳解-記憶翻牌游戲 https://blog.51cto.com/u_15008042/6972493

責(zé)任編輯:張燕妮 來源: 51CTO博客
相關(guān)推薦

2023-05-31 15:42:06

游戲開發(fā)關(guān)系型數(shù)據(jù)庫

2023-06-14 15:10:36

鴻蒙游戲開發(fā)

2016-11-24 12:07:42

Android萬能圓角ImageView

2023-03-22 09:00:38

2023-08-07 12:53:05

開發(fā)服務(wù)

2020-06-16 08:32:00

人工智能技術(shù)機(jī)器學(xué)習(xí)

2022-11-21 09:57:18

網(wǎng)關(guān)系統(tǒng)

2023-08-11 14:00:42

鴻蒙元服務(wù)

2022-06-23 18:10:15

多云

2009-02-27 13:48:00

Mdaemon郵件服務(wù)器

2021-07-29 06:09:05

萬能指針C語言void

2011-06-16 15:57:25

Android

2021-08-17 14:25:11

人臉識別人工智能身份識別

2022-06-27 08:36:08

PythonLambda

2014-02-17 10:56:21

Hadoop

2021-11-11 10:41:25

代碼開發(fā)工具

2022-11-30 13:13:41

節(jié)能減碳PUE
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

欧美日韩国产区一| 678五月天丁香亚洲综合网| 国产a级毛片一区| 69视频在线免费观看| 户外极限露出调教在线视频| 国产农村妇女精品一区二区| 精品成人免费| 在线国产精品一区| 国产成人免费电影| 欧美精品激情| 国产青春久久久国产毛片| 色喇叭免费久久综合| 亚洲影院在线看| 一区二区自拍| 天堂精品视频| 久久久久99精品国产片| 国内一区二区三区在线视频| 免费福利视频一区二区三区| 91麻豆精品国产| 免费女人黄页| 日韩电影在线一区二区三区| 日韩av片免费在线观看| 免费观看亚洲| 欧美精品久久99| 网站一区二区三区| 午夜先锋成人动漫在线| 亚洲成av人综合在线观看| 日本va中文字幕| 亚洲国产三级网| 中文字幕中文字幕在线中心一区| 高清电影在线免费观看| 日本不卡一区二区三区| 欧美激情视频一区| 99热这里只有精品在线播放| 视频精品一区二区三区| 亚洲一卡二卡三卡四卡五卡| 精品久久久久久久久久中文字幕| 一个色免费成人影院| 欧美日本一区二区三区四区| 亚洲一区精品电影| 97netav| 日韩免费在线电影| 91色.com| 久久精品国产久精国产思思| 欧美一区二区三区爽大粗免费| 成人涩涩网站| 欧美成人精品二区三区99精品| 不卡一卡2卡3卡4卡精品在| 永久免费在线| 男女精品网站| 久久久国产精品视频| 午夜亚洲成人| 麻豆精品国产传媒mv男同| 亚洲国产精品一区二区三区| 国产免费又粗又猛又爽| 日韩欧美高清在线播放| 国产午夜精品一区二区三区嫩草 | 成人做爽爽免费视频| 国产精品拍拍拍| 九九99久久精品在免费线bt| 18成人在线视频| 国新精品乱码一区二区三区18| 日韩电影免费观| 国产成人自拍高清视频在线免费播放| 国产精品久久久久久免费观看| 国产亚洲久久| 日韩中文在线不卡| 欧美女同在线观看| 亚洲人metart人体| 91精品国产91| 欧美亚洲人成在线| 粉嫩欧美一区二区三区高清影视| 45www国产精品网站| 亚洲第一二三四区| 亚洲自拍偷拍麻豆| 午夜国产一区二区三区| 成人激情校园春色| 国产精品伦子伦免费视频| 成人影院www在线观看| 91福利资源站| 波多野结衣在线| 日韩精品视频网站| wwwxx欧美| 日本大胆欧美| 亚洲欧美国产一区二区三区| 日本黄在线观看| 国产精品麻豆一区二区| 亚洲7777| 美女国产一区二区三区| 国产精品久久久久999| 日韩影视在线| 亚洲欧美中文字幕| 又黄又爽在线观看| 色悠悠亚洲一区二区| 成人毛片高清视频观看| kk眼镜猥琐国模调教系列一区二区| jizzjizzjizz亚洲女| 国产亚洲精品aa午夜观看| 精品一区二区三区毛片| 91美女片黄在线| 国产精品黄页网站在线播放免费| 久久精品99国产精品日本| 日本一区二区三不卡| 日韩福利视频网| 亚洲色图38p| 国产精品网站一区| 色视频在线播放| 制服视频三区第一页精品| 中文字幕在线视频久| 国产精品欧美日韩久久| 欧美一级久久| 高清一区二区视频| 欧美va天堂va视频va在线| 91精品入口| 欧美与黑人午夜性猛交久久久| 群体交乱之放荡娇妻一区二区| 精品精品国产国产自在线| 成人性片免费| 国产成人精品视频在线| 国产成人精品一区二区免费看京 | 性欧美freesex顶级少妇| 精品国产乱码久久久久久图片| www555久久| 九九久久久久99精品| 激情久久婷婷| 国产精品乱码久久久久| 亚洲男人av电影| 妖精视频成人观看www| av在线免费观看网站| 国产精品久久激情| 一区二区三区四区视频精品免费 | 欧美网站一区二区| 麻豆蜜桃在线观看| 欧美美女18p| 久久精品成人| 2020中文字字幕在线不卡| 久久偷看各类女兵18女厕嘘嘘| 亚洲精品社区| 国产一二三区在线观看| 国产精品久久久久久久久影视| 91精品国产福利| 欧美军人男男激情gay| 中文在线аv在线| 97蜜桃久久| 果冻天美麻豆一区二区国产| 欧美成人综合在线| 9l视频白拍9色9l视频| 激情综合电影网| 欧美 日本 亚洲| 男人天堂a在线| 国产成人97精品免费看片| 日韩视频免费直播| 激情综合电影网| 五月天亚洲激情| 99re在线观看视频| 国产99久久精品一区二区| 日韩美女在线播放| 国产专区一区二区| 在线成人性视频| bt天堂新版中文在线地址| 羞羞小视频视频| 毛片免费在线播放| 成人video亚洲精品| 欧美一级做一级爱a做片性| 亚洲高清资源在线观看| 久久精品国产久精国产爱| 久久色.com| 在线观看中文字幕不卡| 国产一区二区三区在线看| 精品久久久久久一区| 日韩一级性生活片| 求av网址在线观看| 精品国产一区二区三区成人影院| 欧美另类亚洲| 成人黄色在线看| 自拍偷拍国产精品| 日韩欧美在线看| 欧美羞羞免费网站| 日韩中文有码在线视频| 2018中文字幕一区二区三区| 性视频1819p久久| 91在线免费看网站| 欧美日韩一区二区三区在线观看免| 亚洲一区二区精品在线观看| 综合激情丁香| 影音先锋导航| 国产午夜视频在线观看| 中文字幕高清在线观看| 超碰在线人人| 国产激情视频在线看| 99久久国产综合色|国产精品| 亚洲天堂影视av| 亚洲精品一区av在线播放| 91精品国产综合久久国产大片| 日韩欧美久久一区| 日韩网站在线观看| 国产精品扒开腿做爽爽爽的视频| 日韩 欧美 视频| 免费观看一级欧美片| 久久福利资源站|