• 基于腾讯地图实现精准定位,实现微信小程序考勤打卡功能


    页面效果展示

    集成腾讯地图SDK

    腾讯位置服务为微信小程序提供了基础的标点能力、线和圆的绘制接口等地图组件和位置展示、地图选点等地图API位置服务能力支持,使得开发者可以自由地实现自己的微信小程序产品。 在此基础上,腾讯位置服务微信小程序JavaScript SDK是专为小程序开发者提供的LBS数据服务工具包,可以在小程序中调用腾讯位置服务的POI检索、关键词输入提示、地址解析、逆地址解析、行政区划和距离计算等数据服务,让您的小程序更强大!

    文档地址:微信小程序JavaScript SDK

    使用步骤说明:

    1.申请开发者密钥(key):申请密钥

    2.开通webserviceAPI服务

    控制台 ->应用管理 -> 我的应用 ->添加key-> 勾选WebServiceAPI -> 保存

    (小程序SDK需要用到webserviceAPI的部分服务,所以使用该功能的KEY需要具备相应的权限)

    3.下载微信小程序JavaScriptSDK

    微信小程序JavaScriptSDK v1.1   JavaScriptSDK v1.2 ,这里推荐下载1.2版本,将下载好的SDK放在对应文件夹中,去引用它(即 qqmap-wx-jssdk.min.js 文件)引用到你小程序项目中。

    4.安全域名设置

    小程序管理后台 -> 开发 -> 开发管理 -> 开发设置 -> “服务器域名” 中设置request合法域名,添加https://apis.map.qq.com

    • 这个操作需要小程序管理员进到后台去配置
    • 本地环境开发只需设置 勾上 不校验合法域名 即可

    5.小程序核心代码示例

    1. // 引入SDK核心类,js文件根据自己业务,位置可自行放置
    2. var QQMapWX = require('../../libs/qqmap-wx-jssdk.js');
    3. var qqmapsdk;
    4. Page({
    5. onLoad: function () {
    6. // 实例化API核心类
    7. qqmapsdk = new QQMapWX({
    8. key: '申请的key'
    9. });
    10. },
    11. onShow: function () {
    12. // 调用接口
    13. qqmapsdk.search({
    14. keyword: 'DreamCoders',
    15. success: function (res) {
    16. console.log(res);
    17. },
    18. fail: function (res) {
    19. console.log(res);
    20. },
    21. complete: function (res) {
    22. console.log(res);
    23. }
    24. });
    25. }
    26. })

    微信小程序代码

    wx.getLocation(Object object)

    以 Promise 风格 调用:支持

    用户授权:需要 scope.userLocation

    小程序插件:支持,需要小程序基础库版本不低于 1.9.6

    微信 Windows 版:支持

    微信 Mac 版:支持

    功能描述

    获取当前的地理位置、速度。当用户离开小程序后,此接口无法调用。开启高精度定位,接口耗时会增加,可指定 highAccuracyExpireTime 作为超时时间。地图相关使用的坐标格式应为 gcj02。 高频率调用会导致耗电,如有需要可使用持续定位接口 wx.onLocationChange。 基础库 2.17.0 版本起 wx.getLocation 增加调用频率限制,相关公告

    使用方法

    自 2022 年 7 月 14 日后发布的小程序,若使用该接口,需要在 app.json 中进行声明,否则将无法正常使用该接口,2022年7月14日前发布的小程序不受影响。具体规则见公告

    申请开通

    暂只针对如下类目的小程序开放,需要先通过类目审核,再在小程序管理后台,「开发」-「开发管理」-「接口设置」中自助开通该接口权限。 接口权限申请入口将于2022年3月11日开始内测,于3月31日全量上线。并从4月18日开始,在代码审核环节将检测该接口是否已完成开通,如未开通,将在代码提审环节进行拦截。

    微信小程序获取定位关键方法 getLocation。因此需要在 app.json 中进行声明,后期小程序上线还需要单独申请getLocation 接口权限。

    app.json 部分关键代码

    1. {
    2. "pages": [
    3. "pages/index/index",
    4. "pages/sign/sign"
    5. ],
    6. "window": {
    7. "backgroundTextStyle": "light",
    8. "navigationBarBackgroundColor": "#fff",
    9. "navigationBarTitleText": "Weixin",
    10. "navigationBarTextStyle": "black"
    11. },
    12. "tabBar": {
    13. "custom": false,
    14. "backgroundColor": "#fefefe",
    15. "color": "#999999",
    16. "selectedColor": "#1C9D9D",
    17. "list": [{
    18. "pagePath": "pages/index/index",
    19. "text": "首页",
    20. "iconPath": "/images/home.png",
    21. "selectedIconPath": "/images/home_cur.png"
    22. },
    23. {
    24. "pagePath": "pages/sign/sign",
    25. "text": "打卡",
    26. "iconPath": "/images/day.png",
    27. "selectedIconPath": "/images/day_cur.png"
    28. },
    29. {
    30. "pagePath": "pages/index/index",
    31. "text": "我的",
    32. "iconPath": "/images/my.png",
    33. "selectedIconPath": "/images/my_cur.png"
    34. }
    35. ]
    36. },
    37. "permission": {
    38. "scope.userLocation": {
    39. "desc": "您的位置信息将用于小程序考勤签到功能"
    40. }
    41. },
    42. "requiredPrivateInfos":[
    43. "getLocation"
    44. ],
    45. "style": "v2",
    46. "sitemapLocation": "sitemap.json",
    47. "lazyCodeLoading": "requiredComponents"
    48. }

    sign.wxml代码

     部分UI代码参考苏苏就是小苏苏

    1. <view class="index">
    2. <view class="head ">
    3. <view class="head_box flex-row" style="justify-content:left">
    4. <view class="user_ava">
    5. <open-data type="userAvatarUrl">open-data>
    6. view>
    7. <view>
    8. <view class="user_name">DreamCoders <text>{{tip}}text>view>
    9. <view class="user_add">新的一天开始了,加油哦~view>
    10. view>
    11. <view class="mealBtn" bindtap="ToMealTap">
    12. <image src="/images/meal.png">image>
    13. <view class="mealText">{{is_meal==2 ? '已订':'订餐'}}view>
    14. view>
    15. view>
    16. view>
    17. <view class="contentBox">
    18. <view class="signRecord">
    19. <view class="signInfo">上班打卡
    20. <text class="text-green">{{record[0].times ? record[0].times : '未打卡'}}text>
    21. <view class="sign_address">
    22. <view class="">{{record[0].address ? record[0].address : '暂无打卡地址'}}view>
    23. view>
    24. view>
    25. <view class="signInfo">下班打卡
    26. <text class="text-green">{{record[1].times ? record[1].times : '未打卡'}}text>
    27. <view class="sign_address">
    28. <view class="">{{record[1].address ? record[1].address : '暂无打卡地址'}}view>
    29. view>
    30. view>
    31. view>
    32. <view class="dateInfo ">
    33. <text>{{nowDate}} {{nowDay}}text>
    34. view>
    35. <view class="c_clock flex-column">
    36. <view class="clock_time flex-column j_c {{status==1?'c1':''}} {{is_out==2 ? 'outArea' : ''}}" catchtap="signTap">
    37. <text>{{signType>0 ? "下班打卡" : "上班打卡"}}text>
    38. <text>{{now_time}}text>
    39. view>
    40. <view class="clock_time_over flex-column j_c {{status==1?'c2':''}}" catchtap="clockInStart">
    41. <text>已打卡text>
    42. <text>{{now_time_stop}}text>
    43. view>
    44. view>
    45. <view class="clock_address ">
    46. <image src="/images/add0.png" class="add_icon" />
    47. <text>{{current_address}}text>
    48. view>
    49. <view class="refresh" catchtap="refreshAdd">刷新位置view>
    50. view>
    51. view>

    sign.js代码

    具体业务逻辑根据实际情况改写

    1. let qqMapSdk= require("../../utils/qqmap.js");
    2. let util = require('../../utils/util.js')
    3. Page({
    4. /**
    5. * 页面的初始数据
    6. */
    7. data: {
    8. signType:0,//0上班打卡 1下班打卡
    9. is_out:2,//1办公地点打卡 2外勤打卡
    10. is_meal:1,//1未定餐 2已订餐
    11. now_time: '',//当前时间
    12. nowDate:'',//当前年月日
    13. nowDay:'',//星期几
    14. tip:'',//提示 上午好、下午好
    15. current_address: '',//当前定位地址
    16. status: 0, //0未打卡 1已打卡
    17. latlng:[],//经纬度
    18. now_time_stop: '', //已打卡时间
    19. area:{},//考勤点多个
    20. record:[],//打卡记录
    21. },
    22. onLoad: function (options) {
    23. this.getCurrentTime();
    24. this.setData({
    25. now_time: this.getTime(),
    26. nowDate: util.formatTime(new Date()),
    27. nowDay: util.formatDay(new Date()),
    28. tip: util.formatSole(),
    29. })
    30. },
    31. onShow: function () {
    32. this.getLocation();
    33. this.setData({
    34. status:0,
    35. current_address:'',
    36. })
    37. },
    38. signTap() {
    39. var that = this;
    40. if (!that.data.current_address) {
    41. return wx.showToast({
    42. title: '未获取当前定位',
    43. icon: 'error'
    44. })
    45. }
    46. var list = that.data.record.concat({'times':that.data.now_time,'address':that.data.current_address});
    47. wx.vibrateLong();//手机震动提示
    48. that.getSignRecord();
    49. that.setData({
    50. status: 1, //已打卡
    51. record:list,
    52. now_time_stop: that.data.now_time,
    53. })
    54. console.log(list);
    55. console.log(that.data.record);
    56. wx.showToast({
    57. title: '打卡成功',
    58. icon: 'none'
    59. })
    60. },
    61. getCurrentTime: function () {
    62. var time = setInterval(() => {
    63. this.setData({
    64. now_time: this.getTime()
    65. })
    66. }, 1000)
    67. },
    68. getTime() {
    69. let dateTime = '';
    70. let hh = new Date().getHours()
    71. let mf = new Date().getMinutes() < 10 ? '0' + new Date().getMinutes() :
    72. new Date().getMinutes()
    73. let ss = new Date().getSeconds() < 10 ? '0' + new Date().getSeconds() :
    74. new Date().getSeconds()
    75. dateTime = hh + ':' + mf + ':' + ss;
    76. return dateTime;
    77. },
    78. // 请求获取定位授权
    79. getUserAuth: function () {
    80. return new Promise((resolve, reject) => {
    81. wx.authorize({
    82. scope: 'scope.userLocation'
    83. }).then(() => {
    84. resolve()
    85. }).catch(() => {
    86. let that = this;
    87. wx.getSetting({
    88. success: (res) => {
    89. if (res.authSetting['scope.userLocation'] != undefined && res.authSetting['scope.userLocation'] != true) {
    90. wx.showModal({
    91. title: '请求授权当前位置',
    92. content: '需要获取您的地理位置,请确认授权',
    93. success: function (res) {
    94. if (res.cancel) {
    95. wx.showToast({
    96. title: '拒绝授权',
    97. icon: 'none',
    98. duration: 1000
    99. })
    100. } else if (res.confirm) {
    101. wx.openSetting({
    102. success: function (dataAu) {
    103. if (dataAu.authSetting["scope.userLocation"] == true) {
    104. //再次授权,调用wx.getLocation的API
    105. that.getLocation();
    106. } else {
    107. wx.showToast({
    108. title: '授权失败',
    109. icon: 'none',
    110. duration: 1000
    111. })
    112. }
    113. }
    114. })
    115. }
    116. }
    117. })
    118. } else if (res.authSetting['scope.userLocation'] == undefined) {
    119. that.getLocation();
    120. } else {
    121. that.getLocation();
    122. }
    123. }
    124. })
    125. })
    126. })
    127. },
    128. getLocation: function () {
    129. const that = this
    130. // 实例化腾讯地图API核心类
    131. const QQMapWX = new qqMapSdk({
    132. key: '你申请的KEY'// KEY必填
    133. });
    134. //获取当前位置
    135. wx.getLocation({
    136. type: 'gcj02',
    137. success: function(res) {
    138. that.latitude = res.latitude
    139. that.longitude = res.longitude
    140. QQMapWX.reverseGeocoder({
    141. location: {
    142. latitude: res.latitude,
    143. longitude: res.longitude
    144. },
    145. success: function(res) {
    146. let address = res.result.address + res.result.formatted_addresses.recommend;
    147. that.getSignRecord();
    148. that.setData({
    149. current_address:address,
    150. latlng:[res.result.location.lat,res.result.location.lng]
    151. })
    152. },
    153. fail: function(res) {
    154. this.getUserAuth()
    155. wx.showToast({
    156. title: '获取定位失败,请打开手机定位,重新进入!',
    157. icon: 'none'
    158. });
    159. }
    160. })
    161. },
    162. })
    163. },
    164. // 刷新定位
    165. refreshAdd() {
    166. this.getLocation(),
    167. this.getSignRecord()
    168. },
    169. //处理打卡记录及判断打卡位置是否办公地点打卡
    170. getSignRecord: function () {
    171. var that = this;
    172. console.log(that.data.latlng);
    173. var distance = that.getDistance(that.data.latlng[0],that.data.latlng[1],31.370450,121.228252);
    174. if(distance < 200000000000000){
    175. that.setData({
    176. is_out:1,
    177. })
    178. }
    179. },
    180. //经纬度距离计算
    181. getDistance:function (lat1, lng1, lat2, lng2, unit = false) {
    182. var radLat1 = lat1 * Math.PI / 180.0
    183. var radLat2 = lat2 * Math.PI / 180.0
    184. var a = radLat1 - radLat2
    185. var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0
    186. var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
    187. Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)))
    188. s = s * 6378.137 // EARTH_RADIUS;
    189. s = Math.round(s * 10000) / 10000 //输出为公里
    190. if (0) { //是否返回带单位
    191. if (s < 1) { //如果距离小于1km返回m
    192. s = s.toFixed(3)
    193. s = s * 1000 + "m"
    194. } else {
    195. s = s.toFixed(2)
    196. s = s + "km"
    197. }
    198. } else {
    199. s = s.toFixed(3)
    200. s = s * 1000
    201. }
    202. return s
    203. },
    204. //订餐操作
    205. ToMealTap:function (e) {
    206. wx.showToast({
    207. title: '订餐成功',
    208. icon: 'none'
    209. })
    210. this.setData({
    211. is_meal: 2,
    212. })
    213. }
    214. })

    sign.json 代码

    1. {
    2. "usingComponents": {},
    3. "navigationBarTitleText": "考勤打卡"
    4. }

    sign.wxss 代码

    1. page {
    2. height: calc(100% - 10px)
    3. }
    4. .index {
    5. margin-top: 10px;
    6. background: #fff;
    7. min-height: 100%;
    8. }
    9. .head {
    10. padding-bottom: 10rpx;
    11. border-bottom: 2rpx solid #E5E5E5;
    12. }
    13. .head_box {
    14. padding: 26rpx 28rpx 8px;
    15. width: 750rpx;
    16. box-sizing: border-box;
    17. }
    18. .user_ava {
    19. width: 116rpx;
    20. height: 116rpx;
    21. overflow: hidden;
    22. border-radius: 25%;
    23. margin-right: 32rpx;
    24. }
    25. .user_name {
    26. font-size: 32rpx;
    27. font-weight: 600;
    28. color: #333333;
    29. margin-bottom: 18rpx;
    30. }
    31. .user_name text {
    32. font-size: 24rpx;
    33. color: #999999;
    34. font-weight: 400;
    35. margin-left: 40rpx;
    36. }
    37. .user_add {
    38. font-size: 28rpx;
    39. color: #3380F3;
    40. }
    41. .contentBox {
    42. padding: 44rpx 28rpx;
    43. }
    44. .signRecord{
    45. display: flex;
    46. flex-flow: row nowrap;
    47. justify-content: space-between;
    48. margin-top: 15px;
    49. }
    50. .dateInfo{
    51. text-align: center;
    52. position: relative;
    53. top: 50px;
    54. font-size: 35rpx;
    55. }
    56. .c_title {
    57. font-size: 28rpx;
    58. color: #666666;
    59. margin-bottom: 26rpx;
    60. }
    61. .c_section .c_item {
    62. position: relative;
    63. font-size: 30rpx;
    64. font-weight: 600;
    65. color: #333333;
    66. padding-left: 40rpx;
    67. margin-bottom: 110rpx;
    68. }
    69. .c_section text {
    70. color: #307CED;
    71. text-overflow: ellipsis;
    72. overflow: hidden;
    73. width: 80%;
    74. white-space: nowrap;
    75. }
    76. .c_section .c_item::before {
    77. content: '';
    78. position: absolute;
    79. width: 18rpx;
    80. height: 18rpx;
    81. border: 2rpx solid #999999;
    82. left: 0;
    83. top: 50%;
    84. margin-top: -9rpx;
    85. border-radius: 50%;
    86. }
    87. .c_section {
    88. position: relative;
    89. }
    90. .c_section .c_item::after {
    91. content: '';
    92. position: absolute;
    93. width: 2rpx;
    94. height: 178rpx;
    95. background: #E6E6E6;
    96. left: 10rpx;
    97. top: 34rpx;
    98. }
    99. .c_section view:last-child::after {
    100. display: none;
    101. }
    102. .start_lo {
    103. position: absolute;
    104. top: 30px;
    105. left: -5px;
    106. }
    107. .start_end {
    108. position: absolute;
    109. bottom: -108px;
    110. left: 20px;
    111. }
    112. .c_clock {
    113. margin: 180rpx auto 0;
    114. width: 350rpx;
    115. height: 380rpx;
    116. perspective: 1500;
    117. -webkit-perspective: 1500;
    118. -moz-perspective: 1500;
    119. }
    120. .clock_time {
    121. width: 350rpx;
    122. height: 350rpx;
    123. margin-bottom: 30rpx;
    124. position: absolute;
    125. transition: all 1s;
    126. backface-visibility: hidden;
    127. }
    128. .clock_time::after {
    129. content: '';
    130. top: 0;
    131. left: 0;
    132. width: 350rpx;
    133. height: 350rpx;
    134. border-radius: 50%;
    135. position: absolute;
    136. z-index: 9;
    137. background: rgba(48, 124, 237, 0.08);
    138. animation: scale 1s infinite alternate-reverse;
    139. }
    140. /* 已打卡 */
    141. .clock_time_over {
    142. width: 350rpx;
    143. height: 350rpx;
    144. margin-bottom: 30rpx;
    145. border-radius: 50%;
    146. background: rgba(48, 124, 237, 0.08);
    147. position: absolute;
    148. transition: all 1s;
    149. backface-visibility: hidden;
    150. transform: rotateY(-180deg);
    151. }
    152. .clock_time_over::after {
    153. position: absolute;
    154. z-index: 11;
    155. content: '';
    156. width: 320rpx;
    157. height: 320rpx;
    158. background: #C6CED9;
    159. border-radius: 50%;
    160. top: 50%;
    161. left: 50%;
    162. transform: translate(-50%, -50%);
    163. }
    164. .clock_time_over text {
    165. position: relative;
    166. z-index: 13;
    167. color: #FFFFFF;
    168. }
    169. .clock_time_over text:first-child {
    170. font-size: 36rpx;
    171. margin-bottom: 14rpx;
    172. }
    173. .clock_time_over text:last-child {
    174. font-size: 28rpx;
    175. }
    176. @keyframes scale {
    177. 0% {
    178. transform: scale(1.1);
    179. }
    180. 100% {
    181. transform: scale(1);
    182. }
    183. }
    184. .clock_time::before {
    185. position: absolute;
    186. z-index: 11;
    187. content: '';
    188. width: 320rpx;
    189. height: 320rpx;
    190. background: rgb(48, 124, 237, 0.79);
    191. border-radius: 50%;
    192. top: 50%;
    193. left: 50%;
    194. transform: translate(-50%, -50%);
    195. }
    196. .clock_time text {
    197. position: relative;
    198. z-index: 13;
    199. color: #FFFFFF;
    200. }
    201. .clock_time text:first-child {
    202. font-size: 36rpx;
    203. margin-bottom: 14rpx;
    204. }
    205. .clock_time text:last-child {
    206. font-size: 45rpx;
    207. }
    208. .clock_address {
    209. text-align: center;
    210. font-size: 30rpx;
    211. color: #333333;
    212. width: 80%;
    213. margin: 20px auto;
    214. overflow:hidden;
    215. text-overflow:ellipsis;
    216. white-space:nowrap;
    217. }
    218. .clock_address text {
    219. vertical-align: middle;
    220. }
    221. .add_icon {
    222. width: 28rpx;
    223. height: 36rpx;
    224. margin-right: 16rpx;
    225. vertical-align: middle;
    226. }
    227. .refresh {
    228. margin-top: 25px;
    229. color: #307CED;
    230. display: flex;
    231. align-items: center;
    232. justify-content: center;
    233. }
    234. .now_location {
    235. font-size: 24rpx;
    236. color: #333333 !important;
    237. }
    238. .upload_box {
    239. width: 260rpx;
    240. height: 180rpx;
    241. background: #F5F5F8;
    242. border-radius: 5rpx;
    243. }
    244. .upload_box text {
    245. font-size: 20rpx;
    246. color: #999 !important;
    247. font-weight: 100;
    248. }
    249. .camera_icon {
    250. width: 42rpx;
    251. height: 44rpx;
    252. margin-bottom: 10rpx;
    253. }
    254. .clock_img {
    255. width: 100%;
    256. height: 100%;
    257. }
    258. .del_icon {
    259. width: 32rpx;
    260. height: 32rpx;
    261. position: absolute;
    262. right: -4px;
    263. top: -11rpx;
    264. }
    265. .ative::before {
    266. background: #307cedc9;
    267. border: 2rpx solid #307cedc9 !important;
    268. }
    269. .c1 {
    270. transform: rotateY(180deg)
    271. }
    272. .c1::after {
    273. animation: none !important;
    274. }
    275. .c2 {
    276. transform: rotateY(0deg)
    277. }
    278. .mealBtn{
    279. position: absolute;
    280. right: 15px;
    281. }
    282. .mealBtn image{
    283. width: 27px;
    284. height: 27px;
    285. }
    286. .mealText{
    287. font-size: 12px;
    288. color: #999999;
    289. }
    290. .outArea::before{
    291. background: #f44336 !important;
    292. }
    293. .signInfo{
    294. width: 48%;
    295. height: 65px;
    296. background: #f1f1f1;
    297. padding: 10px;
    298. border-radius: 5px;
    299. }
    300. .signInfo text{
    301. float: inline-end;
    302. }
    303. .sign_address{
    304. display: flex;
    305. margin-top: 5px;
    306. }
    307. .sign_address view{
    308. white-space: nowrap;
    309. text-overflow: ellipsis;
    310. overflow: hidden;
    311. font-size: 14px;
    312. margin-top: 1px !important;
    313. color: #5f5a5a;
    314. }
    315. .text-green{
    316. color: green;
    317. }

    util.js 代码

    1. function formatTime(date) {
    2. var year = date.getFullYear()
    3. var month = date.getMonth() + 1
    4. var day = date.getDate()
    5. return year + "年" + month + "月" + day + "日";
    6. }
    7. const formatDay = dates => {
    8. let _day = new Array('星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六');
    9. let date = new Date(dates);
    10. date.setDate(date.getDate());
    11. let day = date.getDay();
    12. return _day[day];
    13. }
    14. const formatSole = () => {
    15. let timeNow = new Date();
    16. let hours = timeNow.getHours();
    17. let text = ``;
    18. if (hours >= 0 && hours <= 6) {
    19. text = `深夜了,不要熬夜太久哟`;
    20. } else if (hours > 6 && hours <= 8) {
    21. text = `早上好`;
    22. } else if (hours > 8 && hours <= 10) {
    23. text = `上午好`;
    24. } else if (hours > 10 && hours <= 13) {
    25. text = `中午好`;
    26. } else if (hours > 13 && hours <= 17) {
    27. text = `下午好`;
    28. } else if (hours > 17 && hours <= 23) {
    29. text = `晚上好`;
    30. }
    31. return text;
    32. }
    33. module.exports = {
    34. formatTime: formatTime,
    35. formatDay: formatDay,
    36. formatSole: formatSole
    37. }

    源码地址:

    https://gitee.com/iGaoWei/miniWxDemo

  • 相关阅读:
    唐山海德教育二级建造师报考-----考试科目
    HBuilderX在IOS上进行真机调试步骤
    线束测试仪怎么使用的,ATX-3000线束检测仪基本操作流程
    C++ 运算符
    SQL语言概述与SQL语言的数据定义
    Vue 计算属性
    ChatGPT专业术语及有效使用方法概述
    本科生学深度学习-Attention机制
    appliedzkp zkevm(8)中的Plookup Table
    只会建数据库怎么写API?database2api 能帮到你!
  • 原文地址:https://blog.csdn.net/qq_31766533/article/details/125968189