基于云开发的打分小程序开发总结

  • 1、TAKE打分小程序
    • 1.1、项目简介
      • 1.1.1、开发背景
      • 1.1.2、项目介绍
    • 1.2、项目效果图
      • 1.2.1、主页
      • 1.2.2、评分流程页
      • 1.2.3、项目详情页
      • 1.2.4、组别页面
      • 1.2.5、使用说明及导出记录页面
      • 1.2.6、导出excel表格
  • 2、技术应用
  • 3、功能开发详解
    • 3.1、发起评分
    • 3.2、用户评分
    • 3.3、组别功能
    • 3.4、订阅通知
    • 3.5、生成并导出excel表格
    • 3.6、二维码生成
    • 3.7、自定义组件
  • 4、总结
    • 4.1、不足
    • 4.2、改善建议
    • 4.3、作者的话

1、TAKE打分小程序

1.1、项目简介

1.1.1、开发背景

市面上评分类型的小程序,基本都有以下不足:

  1. 界面元素驳杂、美观效果不佳
  2. 操作模糊复杂
  3. 功能单一

1.1.2、项目介绍

“TAKE 打分”小程序是一款用于活动评分并实时得出分数的一款小程序,可适用于项目评分、活动现场评分等场所。

评分是以二维码扫码评分的形式,由项目组负责人发起评分并生成相应的二维码,用户即可通过扫描二维码进行评分,结果将以订阅通知形式推送给负责人。

同时小程序还有一个**“组别”的功能,若一个活动有多个项目,可先由活动负责人创建组别并生成密码,小程序将通过订阅通知**的形式把密码发送给活动负责人。各个项目组在发起评分时选择对应的组别,后续活动负责人即可通过输入密码下载该组别下的所有项目组信息。

1.2、项目效果图

1.2.1、主页

1.2.2、评分流程页

1.2.3、项目详情页

1.2.4、组别页面

1.2.5、使用说明及导出记录页面

1.2.6、导出excel表格

2、技术应用

开发模式:微信小程序云开发
UI界面使用到的组件:Vant组件、ColorUI组件库、自定义组件
接口:微信开发文档提供的多个接口

3、功能开发详解

3.1、发起评分

功能思路:项目发起者可通过界面的“发起评分”按钮进入活动信息填写界面,提交活动信息后,小程序将自动生成二维码,其他用户扫描此二维码即可评分。
技术要点

  1. 数据合法性校验
    检验用户输入数据的合法性,即输入数据不为空。而判断数据不为空,应不止要判断是否为空字符串,还应判断是否输入空格,见以下代码示例:
 if (this.name == "" || this.name.indexOf(" ") >= 0) { //遍历搜索字符串中是否存在空格ml_showToast('名称不可为空!请重新输入!')this.setData({inputTxt: ""})return}
  1. 数据类型转换
    如输入评分人数时,由于小程序在获取input组件的数据时,默认类型为String型,因此需要将其转换为Int型,可通过parseInt()方法实现,见以下代码示例:
this.raters = parseInt(params.raters)
  1. 图片上传
    图片上传使用的是wx.chooseImage()接口,具体可见微信开发文档,以下为项目示例:
wx.chooseImage({count: 4, //默认9sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有sourceType: ['album'], //从相册选择success: (res) => {if (this.data.imgList.length != 0) {this.setData({imgList: this.data.imgList.concat(res.tempFilePaths)})} else {this.setData({imgList: res.tempFilePaths})}that.imgListInfo = that.imgListInfo.concat(res.tempFilePaths)}});
  1. 图片放大预览
    图片预览使用的是wx.previewImage()接口,具体可见微信开发文档,以下为项目示例:
wx.previewImage({urls: this.data.imgList,current: e.currentTarget.dataset.url});

3.2、用户评分

功能思路:用户可通过”扫描二维码“或者”搜索活动名称“的方式进入评分页面,选择分数提交即可
技术要点

  1. 用户信息授权
    在用户第一次评分时,小程序需要获取到用户的基本信息,因此需要取得用户的授权,这里使用的是wx.getUserProfile()接口,见以下代码示例:
 let res = await wx.getUserProfile({desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写})console.log(res.userInfo)
  1. 匿名与实名制评分
    用户在提交评分时可自主选择是否匿名,若用户选择匿名,则小程序后台会只获取到用户的openId、分数及备注信息,收集用户的openId也是为了后续区分用户是否重复提交。

3.3、组别功能

功能思路:给用户1对n的用户体验,即一个管理者可以管理多个活动。具体应用场景如高校期末答辩,教师可以先创建一个班级分组,创建成功将随机生成密码并通过订阅通知的方式,将密码推送给教师,教师可通过此密码下载班级所有活动信息,学生只需要在创建活动的时候选择该分组即可。
技术要点

  1. 分组实现
    由于项目是基于云开发平台开发,所以在实现分组时,可以创建一张数据表用于存储所有组别信息,同时在项目活动表新增一个组别字段,用户在创建活动时可选择对应组别,并将数据更新到项目活动表中即可。
  //提交新增组别信息async submitNewStuInfo(e) {//表单输入框提交的内容包含在e参数中var that = thislet isExist = false //判断组别是否存在let className = e.detail.value.className //获取输入框输入的组别名称//判断输入是否为空 或 都是空格的情况if (className == '' || className.indexOf(" ") >= 0) {ml_showToast('请输入组别名称')return} else {ml_showLoading()let res = (await classInfoExcel.get()).data //获取classInfo表的数据,便于下面组别唯一性检查for (let i = 0; i < res.length; i++) {if (res[i].className == className) {isExist = truebreak}}}//如果组别名存在,则isExist=trueif (isExist) {ml_hideLoading()ml_showToast('名称重复!请重新填写!')return}//判断组别信息是否填写正确,填写正确则isCurrent为true,用于判断是否可成功订阅通知this.isCurrent = truethat.className = className// 每一个组别会随机生成一个密码,并将该密码发送订阅通知给用户let password = Math.random() * 1000000password = Math.round(password)that.password = password//将组别信息添加进classInfo表await classInfoExcel.add({data: {className: className,password: password}})ml_hideLoading()//vant的弹窗组件Dialog.alert({title: '密码',message: '组别密码为' + password + ',请谨慎保管!建议开启订阅通知,系统将自动推送密码信息!',}).then(() => {// on close});},

3.4、订阅通知

功能思路:用于给用户推送订阅通知,如评分成绩、组别密码等。
技术要点

  1. 订阅通知功能

    接口使用方法可见微信开发文档,具体示例如下:
  • 发起订阅请求
// 订阅通知async requestSubscribe() {var that = thisconst templateId = 'laCv9R0SmaX-E_GHAd2uv3jPB0KCaIK6IuIHEcfZ60I' // 模板ID// 发起订阅通知请求await wx.requestSubscribeMessage({tmplIds: [templateId],success: (res) => {if (res[templateId] === 'accept') {// 订阅成功,订阅记录存入数据库db.collection("class_subscribe").add({data: {subMsg: {thing1: {value: '您的组别' + that.className},thing4: {value: '密码为' + that.password},},status: 1, //发送状态 0表示已发送,1表示未发送createTime: new Date(),templateId: templateId // 模板ID},success(res) {console.log("成功存入数据库!")},fail(res) {console.log("存入数据库失败!")}})//消息订阅成功窗口wx.showToast({icon: "success",title: '消息订阅成功',})//订阅按钮切换选中状态this.setData({switchInfo: true})//发送订阅通知this.sendSubscribe()} else {//拒绝订阅请求wx.showToast({icon: 'none',title: '消息订阅失败',})//订阅按钮切换未选中状态this.setData({switchA: false})}}})},
  • 发送订阅信息
// 发送订阅消息async sendSubscribe() {const templateId = 'laCv9R0SmaX-E_GHAd2uv3jPB0KCaIK6IuIHEcfZ60I' //模板ID//获取当前用户的openIdlet loginidRes = await wx.cloud.callFunction({name: 'loginid'})const openid = loginidRes.result.openid // 用户的openiddb.collection('class_subscribe').where({ //查找数据库中模板ID对应未发送的记录_openid: openid,status: 1,templateId: templateId}).limit(1).get({success: res => {console.log(res)const id = res.data[0]._id //存储该条数据的id// 调用云函数发送订阅消息wx.cloud.callFunction({name: "subscribe",data: res.data[0]}).then(res => {console.log("推送成功", res)// 根据id修改该条数据状态,设置为已发送db.collection('class_subscribe').where({_id: id}).update({data: {status: "0"}})}).catch(res => {console.log(res)})},fail: err => {wx.showToast({icon: 'none',title: '查询订阅消息记录失败'})}});},
  • 发送订阅信息的云函数
// 云函数入口文件
const cloud = require('wx-server-sdk')cloud.init()
const db = cloud.database()// 云函数入口函数
// 发送订阅通知
exports.main = async (event, context) => {const sendmsg = await cloud.openapi.subscribeMessage.send({touser: event._openid,  // 要推送的用户openidtemplateId: event.templateId, // 模板IDpage: "pages/home/home", // 要跳转的小程序界面data: event.subMsg, //模板数据填充部分miniprogramState: 'developer' //小程序类型,默认为正式版,这里设置为开发者模式});return sendmsg; // 返回执行结果
}

3.5、生成并导出excel表格

功能思路:用户可将活动信息及具体评分信息生成excel表格并导出
技术要点

  1. 生成导出excel文件

    详细用法可参考“编程小石头”博主的文章( 文章链接 ),以下为示例代码:
const cloud = require('wx-server-sdk')cloud.init({env: cloud.DYNAMIC_CURRENT_ENV //拿到当前环境的Id
})
const xlsx = require('node-xlsx') //导入Excel类库
const db = cloud.database() //声明数据库对象
const _ = db.command// 下载Excel表格
exports.main = async (event, context) => { //主函数入口let testData = event.namelet type = event.type// 下载具体活动的信息if (type == 'detail') {try {let StuInfo = await db.collection('activity').where({name: event.name}).get() //将获取到的数据对象赋值给变量,接下来需要用该对象向Excel表中添加数据let dataCVS = event.name + `.xlsx`//声明一个Excel表,表的名字用随机数产生let alldata = [];let row = ['活动名称', '活动内容', '作者', '归属组别', '满分', '参与评分成员', '评分成绩', '总评分人数', '最终成绩']; //表格的属性,也就是表头说明对象alldata.push(row); //将此行数据添加到一个向表格中存数据的数组中let arr = [];arr.push(StuInfo.data[0].name);arr.push(StuInfo.data[0].content);arr.push(StuInfo.data[0].author);arr.push(StuInfo.data[0].activityClass);arr.push(StuInfo.data[0].grade_max);arr.push(StuInfo.data[0].grade[0].userName);arr.push(StuInfo.data[0].grade[0].result);arr.push(StuInfo.data[0].raters);arr.push(StuInfo.data[0].grade_final);alldata.push(arr)let arr_grade = StuInfo.data[0].grade// 接下来是通过循环将数据存到向表格中存数据的数组中for (let key = 1; key < arr_grade.length; key++) {let arr = [];arr.push(" ");arr.push(" ");arr.push(" ");arr.push(" ");arr.push(" ");arr.push(arr_grade[key].userName);arr.push(arr_grade[key].result);arr.push(" ");arr.push(" ");alldata.push(arr)}var buffer = await xlsx.build([{name: "mySheetName",data: alldata}]);//将表格存入到存储库中并返回文件IDreturn await cloud.uploadFile({cloudPath: dataCVS,fileContent: buffer, //excel二进制文件})} catch (error) {console.error(error)return testData}}// 下载组别活动的信息if (type == 'classInfo') {try {let StuInfo = await db.collection('activity').where({activityClass: event.name}).get() //将获取到的数据对象赋值给变量,接下来需要用该对象向Excel表中添加数据let dataCVS = event.name + `.xlsx`//声明一个Excel表,表的名字用随机数产生let alldata = [];let row = ['活动名称', '活动内容', '作者', '归属组别', '满分', '总评分人数', '最终成绩']; //表格的属性,也就是表头说明对象alldata.push(row); //将此行数据添加到一个向表格中存数据的数组中// 接下来是通过循环将数据存到向表格中存数据的数组中for (let key = 0; key < StuInfo.data.length; key++) {let arr = [];arr.push(StuInfo.data[key].name);arr.push(StuInfo.data[key].content);arr.push(StuInfo.data[key].author);arr.push(StuInfo.data[key].activityClass);arr.push(StuInfo.data[key].grade_max);arr.push(StuInfo.data[key].raters);arr.push(StuInfo.data[key].grade_final);alldata.push(arr)}var buffer = await xlsx.build([{name: "mySheetName",data: alldata}]);//将表格存入到存储库中并返回文件IDreturn await cloud.uploadFile({cloudPath: dataCVS,fileContent: buffer, //excel二进制文件})} catch (error) {console.error(error)return testData}}}

3.6、二维码生成

功能思路:用户创建活动后会生成对应该活动的二维码,便于其他用户扫码进行评分
技术要点

  1. 生成二维码

    小程序码的生成有以上三种接口,对应的使用场景也已在图中表示。本项目中使用的是wxacode.get()接口,三种接口的具体使用方法可参考微信开发文档,以下为代码示例:
  • 云函数
// 云函数入口文件
const cloud = require('wx-server-sdk')cloud.init()
const log = cloud.logger()const uploadFile = async function (arrayBuffer, path) {let {fileID} = await cloud.uploadFile({cloudPath: path,fileContent: arrayBuffer,})return fileID
}// 云函数入口函数
// 获取二维码
exports.main = async (event, context) => {const wxContext = cloud.getWXContext()// const type=event.typeconst id = event.idconst name = event.namelet fileName = name + '/' + 'QRcode' + '.jpg'try {let {buffer} = await cloud.openapi.wxacode.get({path: 'pages/score/score?id=' + id,width: 439,auto_color: false,is_hyaline: false})fileID = await uploadFile(buffer, fileName) //将生成的二维码上传到云存储中return fileID} catch (error) {log.error({error})return {error,}}
}
  • js代码
  onLoad: function (options) {console.log('获取到的options=', options)console.log('获取到的name=', options.name)this.id = options.idthis.name = options.namethis.setData({name: this.name})this.getUnlimited()},//获取二维码图片fileID并显示到页面中async getUnlimited() {var that = thisconsole.log(that.id)console.log(that.name)ml_showLoading()let res = await wx.cloud.callFunction({name: 'qrCode',data: {id: that.id,name: that.name,}})console.log(res)let fileID = res.resultthat.result = fileIDthis.setData({fileID})ml_hideLoading()},
  • wxml
<view class="all"><!-- 活动名称 --><view class="name">{{name}}</view><!-- 二维码 --><image class="image" src="{{fileID}}" mode="widthFix" bindtap="handlePrevewImage"></image>
</view>

3.7、自定义组件

功能思路:以css为主,开发编写自定义组件,如小程序中的魔方组件
技术要点

  1. 自定义魔方组件示例

    魔方组件会不停地自动选择,这种动态效果可以缓解用户视觉疲劳
  • wxml
<!-- 发起评分组件 -->
<view class="body"><view class="top div"></view><!--上 --><view class="bottom  div"></view><!--下 --><view class="left div"></view><!--左 --><view class="right div"></view><!--右 --><view class="after div"></view><!--后 --><view class="before div"></view><!--前 --><view class="info div">发起评分</view>
</view>
  • css

.div{width: 150rpx;height: 150rpx;position: absolute;opacity: 0.3;text-align: center;line-height: 150rpx;
}
.body{position: relative;transform-style: preserve-3d;/* height: 20vh; */animation: fram1 10s ease infinite;                  /*引用动画*//* width: 20vw; */display: flex;justify-content: center;align-items: center;
}.info{animation:  1s 0; color: rgb(0, 0, 0);font-size: 35rpx;position: absolute;opacity: 1;font-weight: bold;
}.top{background-color:rgb(255, 232, 216);transform:rotateX(90deg) translateZ(38px);}
.bottom{background-color:rgb(245, 196, 161);transform:rotateX(-90deg) translateZ(38px);
}
.left{background-color:rgb(248, 235, 215);transform:rotateY(-90deg) translateZ(38px);
}
.right{background-color:rgb(251, 255, 255);transform:rotateY(90deg) translateZ(38px);}
.after{background-color:rgb(255, 223, 201);transform:rotateY(180deg) translateZ(38px);
}
.before{background-color:rgb(255, 219, 194);transform:rotateY(0deg) translateZ(38px);
}@keyframes fram1{       /*动画旋转X轴与Y轴*/0%,100%{transform: rotateY(0deg) rotateX(0deg);}50%{transform: rotateY(360deg) rotateX(360deg);}
}@keyframes fram2{       /*动画旋转X轴与Y轴*//* 0%{transform: rotateY(0deg) rotateX(0deg);} */50%{transform: rotateY(180deg) rotateX(180deg);}
}
  • json
{"component": true,"usingComponents": {}
}
  1. 自定义动态背景组件

背景组件为不停往上冒泡的魔方块

  • wxml
<!-- 发起评分组件 -->
<!-- 背景组件 -->
<view class="bg-bubbles"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</view>
  • css

.bg-bubbles {position: absolute;top: 0;left: 0;width: 100%;height: 100%;background-color: #ffffff;opacity:1; top: 0;z-index: -1
}
.bg-bubbles li {position: absolute;bottom: -160rpx;width: 100rpx;height: 100rpx;background-color: rgba(0, 0, 0, 0.15);list-style: none;animation: square 6s infinite;transition-timing-function: linear;
}
.bg-bubbles li:nth-child(1) {left: 10%;
}
.bg-bubbles li:nth-child(2) {left: 20%;width: 90rpx;height: 90rpx;animation-delay: 2s;animation-duration: 7s;
}
.bg-bubbles li:nth-child(3) {left: 25%;animation-delay: 4s;
}
.bg-bubbles li:nth-child(4) {left: 40%;width: 80rpx;height: 80rpx;animation-duration: 8s;background-color: rgba(255, 255, 255, 0.3);
}
.bg-bubbles li:nth-child(5) {left: 70%;
}
.bg-bubbles li:nth-child(6) {left: 80%;width: 120rpx;height: 120rpx;animation-delay: 3s;background-color: rgba(255, 255, 255, 0.2);
}
.bg-bubbles li:nth-child(7) {left: 32%;width: 160rpx;height: 160rpx;animation-delay: 2s;
}
.bg-bubbles li:nth-child(8) {left: 55%;width: 60rpx;height: 60rpx;animation-delay: 4s;animation-duration: 15s;
}
.bg-bubbles li:nth-child(9) {left: 25%;width: 70rpx;height: 70rpx;animation-delay: 2s;animation-duration: 12s;background-color: rgba(255, 255, 255, 0.3);
}
.bg-bubbles li:nth-child(10) {left: 85%;width: 160rpx;height: 160rpx;animation-delay: 5s;
}
@keyframes square {0% {opacity: 0.5;transform: translateY(0px) rotate(45deg);}25% {opacity: 0.75;transform: translateY(-400px) rotate(90deg);}50% {opacity: 1;transform: translateY(-600px) rotate(135deg);}100% {opacity: 0;transform: translateY(-1000px) rotate(180deg);}
}
  • json
{"component": true,"usingComponents": {}
}

4、总结

4.1、不足

  • 二维码有时候需扫描两次才会跳转到指定评分页
  • 代码封装方面做得不够,还可再提取重复代码并封装

4.2、改善建议

  • 可新增数据分析图表,将评分信息直观体现
  • 可修改评分功能,设置在xx时间内,用户可重复提交分数,以最后一次提交的分数为准。

4.3、作者的话

本项目是一个团队开发项目,我个人也是担任队长的角色。但其实在开发过程中,存在很多的不足,在这里我想给看完文章的你几点建议:

  • 不管是什么项目,开发前一定要确认好需求,并编写好需求说明书,避免后续开发过程中,出现“加这加那”的情况!
  • 如果你是一个团队的leader,那就要在开发前自己过一遍项目说明书,确认好开发方案,并且合理安排好团队成员的分工!
  • 把开发项目的工作当成是一份兴趣,不要有排斥心理,既然没有决定一切的能力,就要去努力适应环境,改变好心态,打代码也会很愉快!

PS:

  • 小程序已经上线,大家可以搜索“TAKE打分”即可体验,由于云开发模块涉及到的内容有点多,我将重新找个时间总结并分享自己踩过的坑,在本文中就没过多阐述。
  • 第一次使用云开发模式去开发一个小程序,可能有很多不足,希望大家可以一起交流学习(o゚▽゚)o
  • 看完有帮助记得顺便点赞收藏哦!

基于云开发模式的评分小程序总结!二维码、导出excel表格等实用干货!相关推荐

  1. 基于云开发的答题活动小程序v2.0-用云开发的聚合能力实现从题库中随机出题功能

    项目技术栈 微信原生小程序+云开发.为什么选择微信原生小程序进行开发呢?因为能够直接应用它的云开发能力吖. 我这里主要使用了云开发能力中的小程序端SDK,说白了就是在javascript中就能直接操作 ...

  2. 基于云开发的答题活动小程序v2.0-答题记录页

    项目技术栈 微信原生小程序+云开发.我这里主要使用了云开发能力中的小程序端SDK,说白了就是在javascript中就能直接操作数据库. 本篇前言 基于云开发的答题活动小程序v2.0的源码地址,以及手 ...

  3. 基于云开发的答题活动小程序v1.0,开开开源啦

    基于云开发的微信答题活动小程序v1.0,开开开源啦!!!这个答题小程序,技术栈是基于云开发的微信原生小程序. 搭建教程系列文章 11月是全国"119"消防宣传月,不少企事业单位会举 ...

  4. 基于云开发的答题活动小程序v2.0-结合具体场景谈谈路由传参以及组件化思想

    项目技术栈 微信原生小程序+云开发.我这里主要使用了云开发能力中的小程序端SDK,说白了就是在javascript中就能直接操作数据库. 本篇前言 基于云开发的答题活动小程序v2.0的源码地址,以及手 ...

  5. 获取微信code、调用小程序云函数、获取小程序支付二维码、小程序授权、小程序获取SeesionId

    获取微信code.调用小程序云函数.获取小程序支付二维码.小程序授权.小程序获取SeesionId 只需要调用对应的接口就行了 1. 小程序code获取 基本信息 接口状态: 已完成 接口URL: h ...

  6. 张小龙详细解读:微信小程序扫描二维码可进入(附实录)

    在今天举行的2017微信公开课PRO版上,腾讯微信负责人张小龙表示,微信小程序特性是:无须安装.触手可及.用完即走.无须卸载. 张小龙解答了关于小程序的疑问,并透露小程序计划于2017年1月9日正式上 ...

  7. 微信小程序获取二维码

    原文链接:https://blog.csdn.net/w410589502/article/details/77702358/ 版权归原有博主,此处为了方便自己是查看,故copy一份,B接口调用,亲测 ...

  8. 最新在线客服系统php代码微信软件公众号小程序app二维码聊天网站源码

    最新在线客服系统php代码微信软件公众号小程序app二维码聊天网站源码 管理界面 独家长期更新日志(欢迎反馈BUG) 1.添加手机端前后台声音提示 2.添加后台客户管理显示在线离线 3.添加清空当前对 ...

  9. 飞鹅小票打印机嵌入生成指定小程序页面二维码的解决方案 | 扫普通链接二维码打开小程序示例 | 生成正方形小程序码

    部分朋友不需要打印机的业务,则 忽略有关打印机的部分 即可. 其他有关 微信小程序配置的介绍是通用的!通用的! 生成正方形小程序码,请看 标题一. 扫普通链接生成的二维码打开小程序,请看 标题二. 目 ...

最新文章

  1. nova虚拟机打不开console
  2. dpkg安装软件流程_ubuntu安装搜狗输入法linux版
  3. 实例 18错误输出信息与调试信息
  4. android 如何实现无限列表,在Android中解析和创建无限/无限级别的List /子列表中的XML...
  5. [云炬创业基础笔记]第六章商业模式测试16
  6. C#异步编程(一):异步基础
  7. MyBatis 源码解读-XMLConfigBuilder
  8. 书籍推荐 《移动Web手册》 奇舞团
  9. 数说海南——简单分析海南各市县近六年人口吸引力情况
  10. 关于路由器,锐捷破解,mentohust的使用
  11. 0x00007FF872444FD9 处(位于 Project1.exe 中)有未经处理的异常: Microsoft C++ 异常: cv::Exception,位于内存位置 0x000000F11
  12. html 鼠标形状箭头,CSS各种鼠标样式介绍
  13. cc2530:<3>ADC采集光照度案例
  14. Java --- JVM动态链接与方法调用
  15. QQ2012[QQ圈子]功能试用:按照真实生活将好友分圈
  16. Numerical Optimization Ch17. Penalty and Augmented Lagragian Methods
  17. 计算机毕业设计(附源码)python智能仓储进出货管理系统
  18. 如何向服务器远程传输文件,如何向服务器远程传输文件
  19. 纯Java文档阅读器(word、pdf等)
  20. C#获取感JY901M_485姿态传器的X Y Z角度

热门文章

  1. solidworks二次开发 学习日记--3使用solidworks sdk api 和vc做简单开发
  2. python将10到1递减_递归地将列表递减1
  3. 使用CDN加速你的博客
  4. 计算机2级可以搞小抄吗,计算机二级excel公式总结小抄
  5. 利用计算机形考试二,国开电大21年计算机应用基础形考任务二答案
  6. ✠OpenGL-4-管理3D图形数据
  7. 互动媒体技术——基于p5.js创作一幅自画像
  8. PHP+Mysql服装商城 网上服装购物商城 基于PHP服装商城的系统设计与实现(3)用户注册
  9. 推荐一个GO语言CMS后台管理系统
  10. bugku平台 头等舱