diff --git a/miniprogram/tcb-demo-ocr/README.md b/miniprogram/tcb-demo-ocr/README.md
new file mode 100644
index 0000000..95d4cbe
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/README.md
@@ -0,0 +1,12 @@
+# 【通用文字识别】小程序云开发项目实战
+
+## 项目介绍
+
+此处为项目完整代码,可以直接部署使用;
+
+- 初始化云开发环境,如果有多个云开发环境造成wx.cloud.init错误,则在app.js处进行环境定义。
+- 将cloudfunctions文件夹内的4个云函数创建并部署
+
+## 参考文档
+
+- [云开发文档](https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/getting-started.html)
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/cloudfunctions/addimg/config.json b/miniprogram/tcb-demo-ocr/cloudfunctions/addimg/config.json
new file mode 100644
index 0000000..1cf8a5a
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/cloudfunctions/addimg/config.json
@@ -0,0 +1,9 @@
+{
+ "permissions": {
+ "openapi": [
+ "ocr.bankcard",
+ "ocr.printedText",
+ "ocr.idcard"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/cloudfunctions/addimg/index.js b/miniprogram/tcb-demo-ocr/cloudfunctions/addimg/index.js
new file mode 100644
index 0000000..2465ce1
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/cloudfunctions/addimg/index.js
@@ -0,0 +1,80 @@
+/**
+ * 云函数:添加并识别图片
+ * 用途:使用云调用识别文字能力,将小程序端上传的图片进行文字识别,将文字图片信息上传云数据库进行保存。
+ */
+const cloud = require('wx-server-sdk')
+
+//云开发初始化
+cloud.init();
+
+//将云开发数据库能力声明给db
+const db = cloud.database();
+
+//将云开发数据库command能力声明给 _
+const _ = db.command;
+
+//云函数运行主函数,为异步函数
+exports.main = async (event, context) => {
+
+ //声明一个mess,用于承载函数执行结果用于返回
+ var mess = {};
+ try {
+ /* 此代码段用于解析云存储File ID为url,用于之后的业务逻辑使用
+ event.img为小程序端的请求数据,为上传的图片fileid
+ 在正常业务中应该选择使用cloud.getTempFileURL()来获取临时url返回给用户 */
+ let first = event.img.indexOf('.');
+ let end = event.img.indexOf('/', first);
+ let httpsrc = 'https://' + event.img.slice(first + 1, end) + '.tcb.qcloud.la/' + event.img.slice(end + 1, event.img.length);
+ //解析云存储ID为url代码片段结束
+
+ //云调用能力,进行图片转换文字请求,相比于正常http请求,免除鉴权流程,整个代码逻辑更加轻便。
+ let result = null;
+
+ try{
+ /*==================从这里开始修复==========================*/
+ /* 当result=-1时会在前端显示识别失败! */
+ /* result应该是文字识别的结果集,它应该使用云开发的云调用能力 */
+ result = -1;
+ /* 我们将37行代码替换为以下代码,result获得文字识别云调用结果 */
+
+ // result = await cloud.openapi.ocr.printedText({
+ // type: 'photo',
+ // imgUrl: httpsrc
+ // })
+
+ /*==================到这里修复结束==========================*/
+ /* 当你修改完成后,在左边文件栏,右键点击此代码所在的文件夹 */
+ /* 在出现的列表里,点击【上传并部署:云端安装依赖】 */
+ /* 等待部署成功,你可以重新尝试上传图片操作,一定可以成功 */
+ }
+ catch (err) {
+ console.log(err);
+ result = -1;//约定信息,表示识别无效
+ }
+
+ //构建对象,承载云调用结果和图片信息
+ var obimg = {};
+ obimg.src = event.img;//图片地址
+ obimg.content = result;//识别结果
+
+ //根据用户的openid,存入上边识别的图片信息
+ await db.collection('list').where({
+ openid: event.userInfo.openId
+ }).update({
+ data: {
+ //_.push为云开发数据库中的command操作,含义为往数组中增加传入元素数据。
+ ocrlist: _.push([obimg])
+ }
+ });
+ mess.code = 0;
+
+ }
+ catch (e) {
+ //当发生错误时,如解构FileID等,将执行此代码段,code=-1为异常
+ console.log(e);
+ mess.code = -1;
+ mess.err = e;
+ }
+ //返回mess给前端
+ return mess;
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/cloudfunctions/addimg/package.json b/miniprogram/tcb-demo-ocr/cloudfunctions/addimg/package.json
new file mode 100644
index 0000000..d5a6b6d
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/cloudfunctions/addimg/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "addimg",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "wx-server-sdk": "latest"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/cloudfunctions/init/index.js b/miniprogram/tcb-demo-ocr/cloudfunctions/init/index.js
new file mode 100644
index 0000000..00b6f94
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/cloudfunctions/init/index.js
@@ -0,0 +1,62 @@
+/**
+ * 云函数:初始化列表
+ * 用途:根据用户的唯一openid构建数据库文档,用于存储用户的信息;每次调用时都要返回存储的信息。
+ */
+const cloud = require('wx-server-sdk')
+
+//云开发初始化
+cloud.init();
+
+//将云开发数据库能力声明给db
+const db = cloud.database();
+
+//云函数运行主函数,为异步函数
+exports.main = async (event, context) => {
+
+ //声明一个mess,用于承载函数执行结果用于返回
+ var mess = {};
+ try {
+
+ //利用数据库where查找,数据集中openid为用户所属的文档
+ const userdata = (await db.collection('list').where({
+ openid: event.userInfo.openId
+ }).get()).data;
+
+ //如果length不等于0,则证明存在用户所属文档
+ if (userdata.length != 0) {
+
+ //将用户的识别列表读取出来
+ mess.list = userdata[0].ocrlist;
+ //将文档id取出,用于小程序端上传图片时的文件夹命名。由于安全性,不可以将openid传给小程序端
+ mess.id = userdata[0]._id;
+ //正常标志code=0
+ mess.code = 0;
+ }
+ //如果length等于0,则没有用户文档需要创建
+ else {
+
+ //使用数据库add增加,根据data传入的JSON对象进行构建,返回的为构建的信息,包含文档id
+ let result = await db.collection('list').add({
+ data: {
+ openid: event.userInfo.openId,
+ ocrlist: []
+ }
+ });
+
+ //将文档id取出
+ mess.id = result._id;
+ //新建则识别列表为空
+ mess.list = [];
+ //正常标志code=0
+ mess.code = 0;
+ }
+ }
+ catch (e) {
+ //当发生错误时,如解构FileID等,将执行此代码段,code=-1为异常
+ console.log(e);
+ mess.code = -1;
+ mess.err = e;
+ }
+ //返回mess给前端
+ return mess;
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/cloudfunctions/init/package.json b/miniprogram/tcb-demo-ocr/cloudfunctions/init/package.json
new file mode 100644
index 0000000..251095f
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/cloudfunctions/init/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "init",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "wx-server-sdk": "latest"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/cloudfunctions/removeimg/index.js b/miniprogram/tcb-demo-ocr/cloudfunctions/removeimg/index.js
new file mode 100644
index 0000000..a8341fc
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/cloudfunctions/removeimg/index.js
@@ -0,0 +1,50 @@
+/**
+ * 云函数: 删除识别的图片
+ * 用途:根据图片地址,将云数据库保存的识别图片进行删除。
+ */
+const cloud = require('wx-server-sdk')
+
+//云开发初始化
+cloud.init();
+
+//将云开发数据库能力声明给db
+const db = cloud.database();
+
+//将云开发数据库command能力声明给 _
+const _ = db.command;
+
+//云函数运行主函数,为异步函数
+exports.main = async (event, context) => {
+
+ //声明一个mess,用于承载函数执行结果用于返回
+ var mess = {};
+ try {
+
+ //利用数据库where查找,数据集中openid为用户所属的文档,然后使用update进行更新操作
+ const userdata = await db.collection('list').where({
+ openid: event.userInfo.openId
+ }).update({
+ data: {
+ //_.pull为command能力,含义为将数组中src为event.img的元素删除
+ ocrlist: _.pull({
+ src: event.img
+ })
+ }
+ });
+ //使用云存储能力,根据列表的fileid地址删除文件
+ await cloud.deleteFile({
+ fileList: [event.img]
+ })
+
+ //在处理完全后,返回自定义的code码,表示一定的逻辑含义;在这里code=0为正常成功
+ mess.code = 0;
+ }
+ catch (e) {
+ //当发生错误时,如解构FileID等,将执行此代码段,code=-1为异常
+ console.log(e);
+ mess.code = -1;
+ mess.err = e;
+ }
+ //返回mess给前端
+ return mess;
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/cloudfunctions/removeimg/package.json b/miniprogram/tcb-demo-ocr/cloudfunctions/removeimg/package.json
new file mode 100644
index 0000000..2601d93
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/cloudfunctions/removeimg/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "removeimg",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "wx-server-sdk": "latest"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/cloudfunctions/reorc/config.json b/miniprogram/tcb-demo-ocr/cloudfunctions/reorc/config.json
new file mode 100644
index 0000000..1cf8a5a
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/cloudfunctions/reorc/config.json
@@ -0,0 +1,9 @@
+{
+ "permissions": {
+ "openapi": [
+ "ocr.bankcard",
+ "ocr.printedText",
+ "ocr.idcard"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/cloudfunctions/reorc/index.js b/miniprogram/tcb-demo-ocr/cloudfunctions/reorc/index.js
new file mode 100644
index 0000000..0b87049
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/cloudfunctions/reorc/index.js
@@ -0,0 +1,82 @@
+/**
+ * 云函数: 重新识别图片
+ * 用途:根据图片地址,重新使用云调用能力识别图片,并更新数据库的存储。
+ */
+const cloud = require('wx-server-sdk')
+
+//云开发初始化
+cloud.init();
+
+//将云开发数据库能力声明给db
+const db = cloud.database();
+
+//将云开发数据库command能力声明给 _
+const _ = db.command;
+
+//云函数运行主函数,为异步函数
+exports.main = async (event, context) => {
+ var mess = {};
+ try {
+ //首先先删除数据库中的该元素
+ //利用数据库where查找,数据集中openid为用户所属的文档,然后使用update进行更新操作
+ const userdata = await db.collection('list').where({
+ openid: event.userInfo.openId
+ }).update({
+ data: {
+ //_.pull为command能力,含义为将数组中src为event.img的元素删除
+ ocrlist: _.pull({
+ src: event.img
+ })
+ }
+ });
+
+ /* 此代码段用于解析云存储File ID为url,用于之后的业务逻辑使用
+ event.img为小程序端的请求数据,为上传的图片fileid
+ 在正常业务中应该选择使用cloud.getTempFileURL()来获取临时url返回给用户 */
+ let first = event.img.indexOf('.');
+ let end = event.img.indexOf('/', first);
+ let httpsrc = 'https://' + event.img.slice(first + 1, end) + '.tcb.qcloud.la/' + event.img.slice(end + 1, event.img.length);
+ //解析云存储ID为url代码片段结束
+
+ //云调用能力,进行图片转换文字请求,相比于正常http请求,免除鉴权流程,整个代码逻辑更加轻便。
+ let result = null;
+ try {
+ result = await cloud.openapi.ocr.printedText({
+ type: 'photo',
+ imgUrl: httpsrc
+ })
+ } catch (err) {
+ //当正常业务操作出现问题,比如云调用超过限制则执行此代码段
+ console.log(err);
+ result = -1;//约定信息,表示识别无效
+ }
+
+ //构建对象,承载云调用结果和图片信息
+ var obimg = {};
+ obimg.content = result;
+ obimg.src = event.img;
+
+ //根据用户的openid,存入上边识别的图片信息
+ await db.collection('list').where({
+ openid: event.userInfo.openId
+ }).update({
+ data: {
+ //_.push为云开发数据库中的command操作,含义为往数组中增加传入元素数据。
+ ocrlist: _.push([obimg])
+ }
+ });
+
+ //在处理完全后,返回自定义的code码,表示一定的逻辑含义;在这里code=0为正常成功
+ mess.code = 0;
+ //将重新识别的文字信息也返回,用于即时展示
+ mess.content = result;
+ }
+ catch (e) {
+ //当发生错误时,如解构FileID等,将执行此代码段,code=-1为异常
+ console.log(e);
+ mess.code = -1;
+ mess.err = e;
+ }
+ //返回mess给前端
+ return mess;
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/cloudfunctions/reorc/package.json b/miniprogram/tcb-demo-ocr/cloudfunctions/reorc/package.json
new file mode 100644
index 0000000..b8d663c
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/cloudfunctions/reorc/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "reorc",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "tcb-service-sdk": "^0.1.0",
+ "wx-server-sdk": "latest"
+ }
+}
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/app.js b/miniprogram/tcb-demo-ocr/miniprogram/app.js
new file mode 100644
index 0000000..b0c962b
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/app.js
@@ -0,0 +1,15 @@
+App({
+ onLaunch: function () {
+ if (!wx.cloud) {
+ console.error('请使用 2.2.3 或以上的基础库以使用云能力')
+ } else {
+ wx.cloud.init({
+ traceUser: true,
+ })
+ }
+ },
+ globalData: {
+ id:null,
+ nowimage:null
+ }
+})
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/app.json b/miniprogram/tcb-demo-ocr/miniprogram/app.json
new file mode 100644
index 0000000..5790358
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/app.json
@@ -0,0 +1,15 @@
+{
+ "pages": [
+ "pages/index/index",
+ "pages/ocr/ocr",
+ "pages/show/show"
+ ],
+ "window": {
+ "backgroundTextStyle": "light",
+ "navigationBarBackgroundColor": "#242b36",
+ "navigationBarTitleText": "",
+ "navigationBarTextStyle": "white"
+ },
+ "sitemapLocation": "sitemap.json",
+ "style": "v2"
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/app.wxss b/miniprogram/tcb-demo-ocr/miniprogram/app.wxss
new file mode 100644
index 0000000..e69de29
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.js b/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.js
new file mode 100644
index 0000000..b0ef8a2
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.js
@@ -0,0 +1,12 @@
+Page({
+ toocr() {
+ wx.navigateTo({
+ url: '../ocr/ocr',
+ })
+ },
+ onShareAppMessage(){
+ return {
+ title:"小程序云开发"
+ }
+ }
+})
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.json b/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.json
new file mode 100644
index 0000000..5dcaa7e
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.json
@@ -0,0 +1,4 @@
+{
+ "usingComponents": {},
+ "backgroundColor": "#242b36"
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.wxml b/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.wxml
new file mode 100644
index 0000000..b5291bb
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.wxml
@@ -0,0 +1,10 @@
+
+ 小程序·云开发
+ 微信与腾讯云联合开发的原生 serverless 云服务,具备简化运维、高效鉴权等优势,让你零门槛快速上线小程序。
+
+
+ ✔ 快速实现业务需求
+ ✔ 复杂开发轻松搞定
+ ✔ 集成多方面AI能力
+
+
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.wxss b/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.wxss
new file mode 100644
index 0000000..9ba9669
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/pages/index/index.wxss
@@ -0,0 +1,39 @@
+page{
+ width: 100%;
+ background-color: #242b36;
+}
+
+.title{
+ width: 90%;
+ margin: 30px auto;
+ color: white;
+}
+
+.big{
+ font-size:70rpx;
+}
+
+.small{
+ margin-top:15px;
+ font-size: 32rpx;
+}
+
+.des{
+ width: calc(90% - 10px);
+ margin: 10px auto;
+ padding: 10px;
+ background-color: #242b36;
+}
+
+.item{
+ font-size: 34rpx;
+ line-height: 35px;
+ color: white;
+}
+
+.btn{
+ min-width: 90%;
+ background-color: #186bf1;
+ border-radius: 0px;
+ color: white;
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.js b/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.js
new file mode 100644
index 0000000..acf5a25
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.js
@@ -0,0 +1,152 @@
+var app = getApp();
+Page({
+ data: {
+ imglist: []
+ },
+
+ onLoad(options){
+ this.initlist();
+ },
+
+ onPullDownRefresh(){
+ this.initlist();
+ },
+
+ toimgshow(e) {
+ app.globalData.nowimage = this.data.imglist[e.currentTarget.dataset.i];
+ wx.navigateTo({
+ url: '../show/show',
+ })
+ },
+
+ initlist() {
+ wx.showLoading({
+ title: '列表加载',
+ })
+ let that = this;
+ wx.cloud.callFunction({
+ name: 'init',
+ success(res) {
+ if (res.result.code == 0) {
+ app.globalData.id=res.result.id;
+ that.setData({
+ imglist: res.result.list
+ })
+ }
+ else if (res.result.code == -1) {
+ console.log(res.err);
+ that.showmodel('系统错误', '系统出现问题,请稍后再试!');
+ }
+ wx.stopPullDownRefresh();
+ wx.hideLoading();
+ },
+ fail(err) {
+ console.log(err);
+ that.showmodel('系统错误', '网络出现问题,请稍后再试!');
+ wx.hideLoading();
+ }
+ })
+ },
+
+ chooseimg() {
+ let that = this;
+ wx.chooseImage({
+ count: 1,
+ sizeType: ['original', 'compressed'],
+ sourceType: ['album', 'camera'],
+ success(res) {
+ let imgUrl = res.tempFilePaths[0];
+ that.uploadImgweb(imgUrl)
+ }
+ })
+ },
+
+ uploadImgweb(imgUrl) {
+ wx.showLoading({
+ title: '上传图片',
+ })
+ let that = this;
+ wx.cloud.uploadFile({
+ cloudPath: app.globalData.id + '/' + imgUrl.slice(imgUrl.length - 20, imgUrl.length),
+ filePath: imgUrl,
+ success: res => {
+ wx.hideLoading();
+ that.addimg(res.fileID);
+ },
+ fail: err => {
+ wx.hideLoading();
+ console.log("上传失败", err)
+ }
+ })
+ },
+
+ addimg(imgsrc) {
+ wx.showLoading({
+ title: 'AI赋能中',
+ })
+ let that = this;
+ wx.cloud.callFunction({
+ name: 'addimg',
+ data: {
+ img: imgsrc
+ },
+ success(res) {
+ if (res.result.code == 0) {
+ that.initlist();
+ }
+ else if (res.result.code == -1) {
+ console.log(res.err);
+ that.showmodel('系统错误', '系统出现问题,请稍后再试!');
+ }
+ },
+ fail(err) {
+ console.log(err);
+ that.showmodel('网络错误','网络出现问题,请稍后再试!');
+
+ }
+ })
+ },
+
+ removeimg(e) {
+ let that = this;
+ wx.showModal({
+ title: '确认删除',
+ content: '你是否确认删除这个图片以及识别结果?',
+ success(res) {
+ if (res.confirm) {
+ wx.showLoading({
+ title: '删除图片',
+ })
+ wx.cloud.callFunction({
+ name: 'removeimg',
+ data: {
+ img: e.currentTarget.dataset.img
+ },
+ success(res) {
+ if (res.result.code == 0) {
+ that.initlist();
+ }
+ else if (res.result.code == -1) {
+ console.log(res.err);
+ that.showmodel('系统错误', '系统出现问题,请稍后再试!');
+ }
+ },
+ fail(err) {
+ console.log(err);
+ that.showmodel('网络错误', '网络出现问题,请稍后再试!');
+ }
+ })
+ }
+ }
+ })
+ },
+
+ showmodel(title,msg){
+ wx.hideLoading();
+ wx.showModal({
+ title: title,
+ content: msg,
+ showCancel: false
+ })
+ }
+})
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.json b/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.json
new file mode 100644
index 0000000..a343db6
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.json
@@ -0,0 +1,6 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "识别文字",
+ "enablePullDownRefresh":true,
+ "backgroundColorTop":"#242b36"
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.wxml b/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.wxml
new file mode 100644
index 0000000..99fcfba
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.wxml
@@ -0,0 +1,23 @@
+
+
+
+
+ 这里使用了腾讯云AI图片文字识别能力
+ 你可以点击上传图片进行功能体验
+ 3行代码完成图片上传(小程序ocr.js第67行)
+ 1行代码完成文字识别(云函数reorc第44行)
+ 从图片上传到识别、列表管理、删除图片整个流程
+ 只需要20分钟的开发时长
+
+
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.wxss b/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.wxss
new file mode 100644
index 0000000..029f9fc
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/pages/ocr/ocr.wxss
@@ -0,0 +1,33 @@
+.imglist{
+ width: 100%;
+}
+.images{
+ width: calc(50% - 4px);
+ height: 375rpx;
+ margin: 2px;
+ background-color: #f8f8f8;
+ float: left;
+}
+.addbtn{
+ position: fixed;
+ bottom:15px;
+ min-width: 700rpx;
+ left:25rpx;
+ color: #b6c4ff;
+ background-color: #186bf1;
+ color: white;
+ border-radius: 0px;
+}
+.intro{
+ width:90%;
+ margin:10px auto;
+}
+.intro_item{
+ font-size: 30rpx;
+ line-height: 70rpx;
+ color:#242b36;
+ font-weight:900;
+}
+.carve{
+ margin-top: 40px;
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/pages/show/show.js b/miniprogram/tcb-demo-ocr/miniprogram/pages/show/show.js
new file mode 100644
index 0000000..b5b30b8
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/pages/show/show.js
@@ -0,0 +1,66 @@
+let app = getApp();
+Page({
+ data: {
+ imgdata:{}
+ },
+ onLoad: function (options) {
+ let imgdata = app.globalData.nowimage;
+ this.setData({
+ imgdata:imgdata
+ })
+ },
+ reocr(){
+ wx.showLoading({
+ title: '文字识别中',
+ })
+ let that = this;
+ wx.cloud.callFunction({
+ name: 'reorc',
+ data: {
+ img: that.data.imgdata.src
+ },
+ success(res) {
+ console.log(res.result);
+ if (res.result.code == 0) {
+ let imgdata=that.data.imgdata;
+ imgdata.content = res.result.content;
+ that.setData({
+ imgdata:imgdata
+ })
+ }
+ else if (res.result.code == -1) {
+ console.log(res.err);
+ wx.showModal({
+ title: '系统错误',
+ content: '系统出现问题,请稍后再试!',
+ })
+ }
+ wx.hideLoading();
+ },
+ fail(err) {
+ console.log(err);
+ wx.showModal({
+ title: '网络错误',
+ content: '网络出现问题,请稍后再试!',
+ })
+ wx.hideLoading();
+ }
+ })
+ },
+ copytext(){
+ let items=this.data.imgdata.content.items;
+ let text="";
+ for(let i=0;i
+
+
+
+
+
+
+
+
+ {{item.text}}
+
+
+ 识别失败!请打开cloudfunctions/addimg/index.js文件34行,按照前后说明将其修复,以此来体验云开发的开发过程。
+
+
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/pages/show/show.wxss b/miniprogram/tcb-demo-ocr/miniprogram/pages/show/show.wxss
new file mode 100644
index 0000000..532223a
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/pages/show/show.wxss
@@ -0,0 +1,31 @@
+.topshow{
+ width: 100%;
+ height: 500rpx;
+}
+.topimg{
+ height: 100%;
+ width: 100%;
+ background-color: #f8f8f8
+}
+.btngroup{
+ margin-top:10px;
+ width: 100%;
+ display: flex;
+}
+.rebtn{
+ border-radius: 0;
+}
+.reocr{
+ background-color:#399fff;
+ color:white;
+}
+.content{
+ width: 90%;
+ margin: 10px auto;
+}
+.textitem{
+ font-size: 12px;
+ color:#676767;
+ letter-spacing: 3px;
+ margin-bottom: 10px;
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/miniprogram/sitemap.json b/miniprogram/tcb-demo-ocr/miniprogram/sitemap.json
new file mode 100644
index 0000000..ca02add
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/miniprogram/sitemap.json
@@ -0,0 +1,7 @@
+{
+ "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+ "rules": [{
+ "action": "allow",
+ "page": "*"
+ }]
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-ocr/project.config.json b/miniprogram/tcb-demo-ocr/project.config.json
new file mode 100644
index 0000000..452c4b5
--- /dev/null
+++ b/miniprogram/tcb-demo-ocr/project.config.json
@@ -0,0 +1,57 @@
+{
+ "miniprogramRoot": "miniprogram/",
+ "cloudfunctionRoot": "cloudfunctions/",
+ "setting": {
+ "urlCheck": true,
+ "es6": true,
+ "postcss": true,
+ "minified": true,
+ "newFeature": true,
+ "enhance": true
+ },
+ "appid": "wx694097825114c417",
+ "projectname": "%E5%BE%AE%E4%BF%A1%E5%85%AC%E5%BC%80%E8%AF%BEPRO-%E4%BA%91%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98",
+ "libVersion": "2.8.1",
+ "simulatorType": "wechat",
+ "simulatorPluginLibVersion": {},
+ "cloudfunctionTemplateRoot": "cloudfunctionTemplate",
+ "condition": {
+ "search": {
+ "current": -1,
+ "list": []
+ },
+ "conversation": {
+ "current": -1,
+ "list": []
+ },
+ "plugin": {
+ "current": -1,
+ "list": []
+ },
+ "game": {
+ "list": []
+ },
+ "gamePlugin": {
+ "current": -1,
+ "list": []
+ },
+ "miniprogram": {
+ "current": 0,
+ "list": [
+ {
+ "id": -1,
+ "name": "db guide",
+ "pathName": "pages/databaseGuide/databaseGuide",
+ "query": ""
+ },
+ {
+ "id": -1,
+ "name": "pages/ocr/ocr",
+ "pathName": "pages/ocr/ocr",
+ "query": "",
+ "scene": null
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/README.md b/miniprogram/tcb-demo-sec/README.md
new file mode 100644
index 0000000..38e28e1
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/README.md
@@ -0,0 +1,12 @@
+# 【内容安全检查】小程序云开发项目实战
+
+## 项目介绍
+
+此处为项目完整代码,可以直接部署使用;
+
+- 初始化云开发环境,如果有多个云开发环境造成wx.cloud.init错误,则在app.js处进行环境定义。
+- 将cloudfunctions文件夹内的2个云函数创建并部署
+
+## 参考文档
+
+- [云开发文档](https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/getting-started.html)
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/cloudfunctions/imagesec/config.json b/miniprogram/tcb-demo-sec/cloudfunctions/imagesec/config.json
new file mode 100644
index 0000000..4c12646
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/cloudfunctions/imagesec/config.json
@@ -0,0 +1,7 @@
+{
+ "permissions": {
+ "openapi": [
+ "security.imgSecCheck"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/cloudfunctions/imagesec/index.js b/miniprogram/tcb-demo-sec/cloudfunctions/imagesec/index.js
new file mode 100644
index 0000000..f10ddd9
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/cloudfunctions/imagesec/index.js
@@ -0,0 +1,15 @@
+const cloud = require('wx-server-sdk');
+cloud.init()
+
+exports.main = async (event, context) => {
+ const imgmsg = (await cloud.downloadFile({
+ fileID: event.img,
+ })).fileContent;
+
+ return cloud.openapi.security.imgSecCheck({
+ media: {
+ contentType: 'image/png',
+ value: imgmsg
+ }
+ })
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/cloudfunctions/imagesec/package.json b/miniprogram/tcb-demo-sec/cloudfunctions/imagesec/package.json
new file mode 100644
index 0000000..2b645d9
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/cloudfunctions/imagesec/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "imagetext",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "fs": "0.0.1-security",
+ "wx-server-sdk": "~1.7.0"
+ }
+}
diff --git a/miniprogram/tcb-demo-sec/cloudfunctions/textsec/config.json b/miniprogram/tcb-demo-sec/cloudfunctions/textsec/config.json
new file mode 100644
index 0000000..555df89
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/cloudfunctions/textsec/config.json
@@ -0,0 +1,7 @@
+{
+ "permissions": {
+ "openapi": [
+ "security.msgSecCheck"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/cloudfunctions/textsec/index.js b/miniprogram/tcb-demo-sec/cloudfunctions/textsec/index.js
new file mode 100644
index 0000000..fbd8d7d
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/cloudfunctions/textsec/index.js
@@ -0,0 +1,8 @@
+const cloud = require('wx-server-sdk')
+cloud.init()
+
+exports.main = async (event, context) => {
+ return await cloud.openapi.security.msgSecCheck({
+ content:event.text
+ })
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/cloudfunctions/textsec/package.json b/miniprogram/tcb-demo-sec/cloudfunctions/textsec/package.json
new file mode 100644
index 0000000..804d150
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/cloudfunctions/textsec/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "textsec",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "wx-server-sdk": "~1.7.0"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/miniprogram/app.js b/miniprogram/tcb-demo-sec/miniprogram/app.js
new file mode 100644
index 0000000..c0f32ec
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/miniprogram/app.js
@@ -0,0 +1,11 @@
+App({
+ onLaunch: function() {
+ if (!wx.cloud) {
+ console.error('请使用 2.2.3 或以上的基础库以使用云能力');
+ } else {
+ wx.cloud.init({
+ traceUser: true,
+ });
+ }
+ }
+});
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/miniprogram/app.json b/miniprogram/tcb-demo-sec/miniprogram/app.json
new file mode 100644
index 0000000..9ae4abd
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/miniprogram/app.json
@@ -0,0 +1,13 @@
+{
+ "pages": [
+ "pages/index/index"
+ ],
+ "window": {
+ "backgroundColor": "#F6F6F6",
+ "backgroundTextStyle": "light",
+ "navigationBarBackgroundColor": "#286dee",
+ "navigationBarTitleText": "内容安全",
+ "navigationBarTextStyle": "white"
+ },
+ "sitemapLocation": "sitemap.json"
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.js b/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.js
new file mode 100644
index 0000000..4f6de4c
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.js
@@ -0,0 +1,92 @@
+const app = getApp()
+Page({
+ textin(e){
+ this.text = e.detail.value;
+ },
+ textcheck:function(){
+ let text = this.text;
+ if(text==""||text==null){
+ return;
+ }
+ wx.showLoading({
+ title: '检查中',
+ mask:true
+ })
+ wx.cloud.callFunction({
+ name:"textsec",
+ data:{
+ text:text
+ },
+ success(e){
+ wx.hideLoading();
+ wx.showToast({
+ title: '内容安全'
+ })
+ },
+ fail(e){
+ wx.hideLoading();
+ wx.showModal({
+ title: '风险提示',
+ content: '这是不安全的内容',
+ showCancel:false
+ })
+ }
+ })
+ },
+
+ imgcheck:function(){
+ let that=this;
+ wx.chooseImage({
+ count: 1,
+ success (res) {
+ that.setData({
+ showimg:res.tempFilePaths[0]
+ })
+ that.upload(res.tempFilePaths[0]);
+ }
+ })
+ },
+ upload(img){
+ let that=this;
+ wx.showLoading({
+ title:"上传文件中"
+ })
+ wx.cloud.uploadFile({
+ cloudPath: Number(Math.random().toString().substr(3,3) + Date.now()).toString(36)+'.png',
+ filePath: img,
+ success: res => {
+ that.imgcheckcall(res.fileID);
+ }
+ })
+ },
+ imgcheckcall(ID){
+ wx.showLoading({
+ title:"检查中"
+ })
+ wx.cloud.callFunction({
+ name:"imagesec",
+ data:{
+ img:ID
+ },
+ success(e){
+ wx.hideLoading();
+ wx.showToast({
+ title: '内容安全'
+ })
+ },
+ fail(e){
+ wx.hideLoading();
+ wx.showModal({
+ title: '风险提示',
+ content: '这是不安全的内容',
+ showCancel:false
+ })
+ },
+ complete(){
+ wx.cloud.deleteFile({
+ fileList:[ID]
+ })
+ }
+ })
+ }
+})
diff --git a/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.json b/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.json
new file mode 100644
index 0000000..8835af0
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.json
@@ -0,0 +1,3 @@
+{
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.wxml b/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.wxml
new file mode 100644
index 0000000..dfc218f
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.wxml
@@ -0,0 +1,9 @@
+
+
+
+ 检测输入文本是否含有违规内容
+
+
+ 检测上传的图片是否违规
+
+
diff --git a/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.wxss b/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.wxss
new file mode 100644
index 0000000..6726bab
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/miniprogram/pages/index/index.wxss
@@ -0,0 +1,36 @@
+Page{
+ background-color:#f2f2f2;
+}
+.textinput{
+ background-color: white;
+ width: 650rpx;
+ margin: 40rpx;
+ padding: 10rpx;
+ line-height: 50rpx;
+ font-size: 34rpx;
+}
+.textbtn , .imagebtn{
+ color: white;
+ width: 650rpx;
+}
+.textbtn{
+ background-color: #286dee;
+}
+.imagebtn{
+ background-color: #f17a72;
+}
+.tips{
+ color:#898989;
+ font-size:25rpx;
+ width: 650rpx;
+ margin: 10rpx 50rpx;
+ text-align: center;
+}
+.front{
+ margin-top: 50px;
+}
+.imageshow{
+ width: 650rpx;
+ margin: 10px 50rpx;
+ height: 0;
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/miniprogram/sitemap.json b/miniprogram/tcb-demo-sec/miniprogram/sitemap.json
new file mode 100644
index 0000000..ca02add
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/miniprogram/sitemap.json
@@ -0,0 +1,7 @@
+{
+ "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+ "rules": [{
+ "action": "allow",
+ "page": "*"
+ }]
+}
\ No newline at end of file
diff --git a/miniprogram/tcb-demo-sec/project.config.json b/miniprogram/tcb-demo-sec/project.config.json
new file mode 100644
index 0000000..7eb60fc
--- /dev/null
+++ b/miniprogram/tcb-demo-sec/project.config.json
@@ -0,0 +1,44 @@
+{
+ "miniprogramRoot": "miniprogram/",
+ "cloudfunctionRoot": "cloudfunctions/",
+ "setting": {
+ "urlCheck": true,
+ "es6": true,
+ "postcss": true,
+ "minified": true,
+ "newFeature": true,
+ "enhance": true
+ },
+ "appid": "",
+ "projectname": "%E5%86%85%E5%AE%B9%E5%AE%89%E5%85%A8",
+ "libVersion": "2.8.1",
+ "simulatorType": "wechat",
+ "simulatorPluginLibVersion": {},
+ "condition": {
+ "search": {
+ "current": -1,
+ "list": []
+ },
+ "conversation": {
+ "current": -1,
+ "list": []
+ },
+ "plugin": {
+ "current": -1,
+ "list": []
+ },
+ "game": {
+ "list": []
+ },
+ "miniprogram": {
+ "current": 0,
+ "list": [
+ {
+ "id": -1,
+ "name": "db guide",
+ "pathName": "pages/databaseGuide/databaseGuide"
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file