柚子快报激活码778899分享:Apicloud
创建第一个app
https://docs.apicloud.com/APICloud/creating-first-app
开发工具下载
https://www.apicloud.com/devtools
源码地址
https://github.com/apicloudcom
signature 源码
https://github.com/apicloudcom/APICloud-Modules/tree/master/signature/android/sourceCode
打包发布APP-云编译
注意项:
1. 如果装的话,需要将之前【调试的 loader】 先卸载后再装,否则提示“安装失败,安装包版本太低”等问题
步骤:
1. 修改 logo(png格式)
2. 修改启动页
3. 云编译,打包
资源:
搞定抠图https://www.gaoding.com/
在线PShttp://www.uupoop.com/
拷贝模拟器中的文件?
在安卓手机 文件管理器 / $MuMu共享文件夹
APP运行的文件是存在于 /UZMap/APP目录 下
在电脑上有对应的文件夹与之对应
APICloud七天在线培训课教程
https://github.com/apicloudcom/APICloud-7Days-Online-Training-Tutorials
课程第一天 https://docs.apicloud.com/Seven/Day1
一周一APP 完整技术架构和流程
https://github.com/xiaoqiang730730/vue_apicloud/blob/master/doc/oneweekoneapp.md
AUI框架
https://github.com/liulangnan/aui
http://www.auicss.com/
APICloud WiFi 真机预览效果
https://docs.apicloud.com/Dev-Tools/wifi-debug
与 Vue 整合开发的相关资料
方式一: vue-cli + vant
【运行方式】 启动 Vue 服务器,然后在 手机应用上同步才可以看到效果 【注意】 浏览器中是看不到效果的,因为创建 vue 组件是在 api_ready 下才成功创建的。
vue 脚手架开发
https://github.com/xiaoqiang730730/vue_apicloud/tree/master/doc
vant 移动端UI库
https://youzan.github.io/vant/#/zh-CN/quickstart
vue: command not found
【解决办法】 写全命令路径
/usr/local/Cellar/node/6.2.2/lib/node_modules/vue-cli/bin/vue init xiaoqiang730730/vue_apicloud ee-app-vant
Vue项目中如何使用APICloud的接口
直接调用即可,不过需要在模拟器中进行调用才行。在浏览器中,会提示找不到对象
例如,在点击函数中,双向数据绑定:
this.msg = api.systemType
知识点积累
路由跳转
this.$router.push('/register');
引入库
采用全局导入组件的方式【推荐】
cnpm i vant -S
在 src/main.js 全部导入 vant 的组件
import Vant from 'vant';
import 'vant/lib/vant-css/index.css';
Vue.use(Vant);
之前的babel方式,有点麻烦,【不推荐使用】
.barelrc 配置。当然安装依赖什么的,就直接参考文档安装即可。
vue init xiaoqiang730730/vue_apicloud my-project
cnpm install
cnpm i babel-plugin-import -D
cnpm i vant -S
cnpm run start
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime", ["import", {
"libraryName": "vant",
"libraryDirectory": "es",
"style": true
}]],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]
}
}
}
2. 使用组件
关闭elint验证, config/index.js, 配置选项:
useEslint: false,
import { Button } from "vant";
export default {
name: "HelloWorld",
components: {
[Button.name]: Button
},
};
3. APICloud 源代码配置,采用热更新的方式,其中配置方式,可参考方式二中的 相关文章
主要步骤
(1)APIStudio 新建项目
(2)网页云控制台,模块/编译自定义 Loader
编辑 模板案例 中的 index.html 文件,修改结构 和 js 代码
window.apiready = function(){
var header = $api.byId('header');
//适配iOS 7+,Android 4.4+状态栏
$api.fixStatusBar(header);
var headerPos = $api.offset(header);
var main = $api.byId('main');
var mainPos = $api.offset(main);
api.openFrame({
name: 'main',
//url: 'dist/html/index.html',
//url: 'html/main.html',
//url: 'http://172.16.5.6:8010/index.html',
url: 'http://172.16.5.6:8080',
bounces: true,
rect: {
x: 0,
y: headerPos.h,
w: 'auto',
h: mainPos.h
}
});
};
方式二: vue + sui
史上最快的开发方式,基于webpack2+vue2搭建的apicloud脚手架 https://community.apicloud.com/bbs/forum.php?mod=viewthread&tid=55876&extra=&page=1
SUI 淘宝的移动端UI框架
http://m.sui.taobao.org/getting-started/
/>
.bar-nav {
background-color: #0099FF;
}
.bar-nav .title {
color: #fff;
}
window.apiready = function () {
// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = { template: '
const Bar = { template: '
// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
routes: routes // (缩写) 相当于 routes: routes
})
// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
router: router
}).$mount('#app')
};
其他技术知识点
APP store 开发流程
https://github.com/xiaoqiang730730/vue_apicloud/blob/master/doc/appstore.md
vue中调用api的模块
https://community.apicloud.com/bbs/forum.php?mod=viewthread&tid=100823&highlight=vue
命令行工具
https://docs.apicloud.com/Dev-Tools/apicloud-cli
npm install -g apicloud-cli
找到安装目录
/usr/local/Cellar/node/6.2.2/bin/apicloud
export PATH=/usr/local/Cellar/node/6.2.2/bin:$PATH
可以将PATH写到 系统的路径里 /etc/profile
也可以写到用户的 配置环境里 如果用的是bash 则在用户目录~/.bash_profile 添加路径
把修改后的文件用source命令生效下就行 也可以重启下系统
vi ~/.bash_profile
source ~/.bash_profile
vue-cli启动
npm run wifistart
https://github.com/xiaoqiang730730/vue_apicloud/blob/master/doc/oneweekoneapp.md
_apiConfig.xml
可以把content改成http://xxxx:8080, 就能够运行vue的项目了。
在安装自定义loader之后,按照如图所示,
这个时候就需求apicloud-cli了,2个步骤
wifi开启同步 apicloud wifiStart --port 8686 或者 npm run wifistart
wifi服务同步所有文件 apicloud wifiSync --project ./src --updateAll true --port 8686 或者 npm run wifiupdateall
参考模块
拍照模块 FNPhotograph
https://docs.apicloud.com/Client-API/Func-Ext/FNPhotograph
支持距离调整等
组件化,结合vue的实现代码
/*
使用说明
v-if="showCamera" v-on:before-close="closeCamera" :exam-student-id="'xxxx-xxx-xxx'" :exam-index="0" >
this.showCamera = true;
closeCamera: function(imagePath) {
alert("closeCamera")
alert(imagePath)
this.showCamera = false;
},
import TakePhoto from './TakePhoto'
components: {
TakePhoto
},
*/
export default {
name: 'TakePhoto',
props: [
'examStudentId',
'examIndex',
],
mounted() {
alert("开始拍照!");
// 拍照
var FNPhotograph = api.require('FNPhotograph');
FNPhotograph.openCameraView({
rect: {
x: 0,
y: 0,
w: 'auto',
h: api.winHeight - 100
},
orientation: 'landscapeRight',
fixedOn: api.frameName
}, function(ret) {
if (!ret.status) {
alert('相机打开失败,请确认已经授权使用相机!');
}
// alert('openCameraView ret:'+JSON.stringify(ret));
})
},
methods: {
takePhoto: function() {
var examPhotoPath = this.EXAM_PHOTO_PATH;
examPhotoPath += this.examStudentId;
examPhotoPath += '/' + this.examIndex;
// 拍照
var FNPhotograph = api.require('FNPhotograph');
FNPhotograph.takePhoto({
quality: 'medium',
path: examPhotoPath,
album: false
}, (ret) => {
var imagePath = (ret.imagePath);
FNPhotograph.closeCameraView((ret) => {
if (ret) {
alert("拍照成功!");
this.$emit("before-close", imagePath);
}
});
});
},
},
}
.camera {
position: absolute;
z-index: 999;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #000000;
}
.btn {
position: absolute;
bottom: 10px;
left: 50%;
margin-left: -30px;
width: 60px;
line-height: 50px;
cursor: pointer;
font-size:40px;
text-align: center;
color:white;
border:2px solid white;
border-radius:50%;
padding:5px;
}
拍照旋转问题
【解决方法】将图片通过 css 样式旋转,即可纠正旋转的照片
style="transform:rotate(-90deg); "
获取旋转角度,注意要传入图片路径,官方代码中没有包含图片路径参数。
FNPhotograph.getRotateDegree({
imgPath: imagePath
}, function(ret) {
if (ret) {
alert(JSON.stringify(ret));
}
});
编译自定义Loader后,调用摄像头代码,如下:
var FNPhotograph = api.require('FNPhotograph');
FNPhotograph.open({
path: 'fs://savePath',
album: false ,
quality: 'medium' // quality: 'low'
}, function(ret){
if (ret.eventType == "show") {
} else if (ret.eventType == "takePhoto") {
alert(ret.imagePath);
FNPhotograph.close();
} else if (ret.eventType == "close") {
alert("close");
} else {
alert(JSON.stringify(ret));
}
});
拍照像素问题
设为低像素
FNPhotograph.takePhoto({
quality: 'low',
qualityValue: 12,
path: examPhotoPath,
自定义Frame操作
FNPhotograph.openCameraView({
rect: {
x: 0,
y: 0,
w: 'auto',
h: 'auto'
},
orientation: 'landscapeLeft',
fixedOn: api.frameName
}, function(ret) {
alert('sss'+JSON.stringify(ret));
FNPhotograph.takePhoto({
quality: 'medium',
path: 'fs://FNPhotograph/01.png',
album: false
}, function(ret) {
alert(ret.imagePath);
FNPhotograph.close(
function(ret) {
if (ret) {
alert(JSON.stringify(ret));
}
});
});
});
参考:https://community.apicloud.com/bbs/forum.php?mod=viewthread&tid=73629&highlight=openCameraView
模块使用流程
1. 添加模块,同步代码2. 编译自定义 loader,使用自定义Loader进行测试
前置摄像头
setCamera
设置前置/后置摄像头(注意此方法与openCameraView配合使用)
setCamera({params})
params
camera:
类型:字符串
描述:(可选项)摄像头
默认值:back
取值范围:
front:前置摄像头
back:后置摄像头
trans 转换模块的使用
转换图片编码等
var trans = api.require('trans');
trans.decodeImgToBase64({
imgPath: ret.imagePath
}, (ret, err) => {
if (ret.status) {
// console.log(ret.base64Str);
...
socketManager 通讯模块
状态定义:
101 //创建成功
102 //连接成功
https://docs.apicloud.com/Client-API/Func-Ext/socketManager#3
创建连接、发送数据等操作
https://docs.apicloud.com/Client-API/Func-Ext/socketManager#3
var socketManager = api.require("socketManager");
socketManager.createSocket({
host: '192.168.10.1',
port: 6001
}, function(ret, err) {
if (ret) {
alert(JSON.stringify(ret));
} else {
alert(JSON.stringify(err));
}
});
SocketManager发送16进制数据
https://community.apicloud.com/bbs/forum.php?mod=viewthread&tid=74184&extra=page%253D1
下载图片 base64 编码多了1个等于号 => 直接字符串替换掉
Mac 下 TCP/UDP 测试工具
https://www.jianshu.com/p/ca1910ac691a
ajax模块
上传多个文件
api.ajax({
url: url,
method: 'post',
timeout: 60*60*2,
headers: {
'token': this.token
},
data: {
files: {
"file": ['fs://1.jpg', 'fs://2.jpg']
}
}
}, (ret, err) => {
if (ret) {
...
后台接收
@Login
@PostMapping("question/uploadpic")
@ApiOperation("上传1个考生正常考试抓取的图片")
public R uploadpic(@RequestParam String examStudentID,
@RequestParam("file") MultipartFile[] files) {
...
发送字符串数组
api.ajax({
url: url,
method: 'post',
timeout: 60*60*2,
headers: {
'Content-Type': 'application/json;charset=utf-8',
'token': this.token
},
data: {
body: examPhotoList
}
}, (ret, err) => {
if (ret) {
...
后台接收
@Login
@PostMapping("question/uploadpic")
@ApiOperation("上传1个考生正常考试抓取的图片")
public R uploadpic(@RequestParam String examStudentID,
@RequestBody List
...
遇到的问题:
JsonMappingException: Can not deserialize instance of java.lang.Integer out of START_OBJECT token
【解决方法】 前端传递的是对象,而后端接受的是 List,类型不匹配
示例代码
简单登录效果实现
https://community.apicloud.com/bbs/forum.php?mod=viewthread&tid=47580https://community.apicloud.com/bbs/forum.php?mod=viewthread&tid=47580
技术知识点
ajax 的封装
// 自定义的ajax接口
// obj 参数:
// {
// method: 'get' 'post'
// url: ''
// data: {},
// sucess: (ret) => {}
// fail: (ret) => {}
// }
Vue.prototype.eeAjax = function (obj) {
if (this.token == null) {
this.$router.push("/")
return ;
}
var prefix = "http://192.168.1.111:8080/ee-server";
obj.url = prefix + obj.url;
if (obj.data) {
var arr = [];
for (var k in obj.data) {
arr.push( k + "=" + obj.data[k]);
}
if (arr.length >= 0) {
obj.url += "?";
obj.url += arr.join('&')
}
}
// 表单方式提交数据或文件
api.ajax({
url: obj.url,
method: 'get',
headers: {
'Content-Type': 'application/json;charset=utf-8',
'token': this.token
}
}, (ret, err) => {
if (ret) {
if (ret.code == 0) {
obj.success && obj.success(ret);
} else if (ret.code == 403) {
// token失效,请重新登录
alert(ret.msg);
this.$router.push("/")
} else {
obj.fail && obj.fail(ret)
}
}
});
}
全局变量实现
export default function install (Vue, options) {
// 服务器信息记录
Vue.prototype.KEY_SERVER_INFO = "KEY_SERVER_INFO";
Vue.prototype.getGLibExamStudent = function () {
return Vue.prototype.gLibExamStudent;
}
}
// main.js
import utils from './utils';
Vue.use(utils); //将全局函数当做插件来进行注册
系统参数存储
// 同步获取app参数
var dbIndex = api.getPrefs({
sync: true,
key: 'dbIndex'
});
// 设置app参数
if (!dbIndex) {
api.setPrefs({
key: 'dbIndex',
value: '1'
});
}
获取摄像头图像或系统相册中的图片
https://docs.apicloud.com/Client-API/api#20
api.getPicture({
sourceType: 'library',
encodingType: 'jpg',
mediaValue: 'pic',
destinationType: 'base64',
allowEdit: false,
quality: 50,
targetWidth: 100,
targetHeight: 100,
saveToPhotoAlbum: false
}, function(ret, err) {
if (ret) {
alert(JSON.stringify(ret));
} else {
alert(JSON.stringify(err));
}
});
写文件
var dbf = dbFilePath + "/" + dbIndex + "/" + (dbFileCount++);
api.writeFile({
path: dbf,
data: imgData
}, function(ret, err) {
if (ret.status) {
alert("保存成功");
} else {
alert("dbFilePath保存失败:" + JSON.stringify(err));
}
});
数据库操作
https://docs.apicloud.com/Client-API/Func-Ext/db
https://www.cnblogs.com/mr-yuan/p/6696288.html
CSS 边框测试代码
border-bottom-color: #ff0000;
border-bottom-style: solid;
border-bottom-width: 5px;
Vue 默认图片显示
data: {
noPhoto: 'this.src="' + require("../assets/StartExam/NoPhoto.gif") + '"',
}
Java Base64图片编码
注意生成的图片前面有前缀表示
// 保存图片数据,转换成 Base64 编码
Byte[] photo = worker.getPhoto();
int n = photo.length;
byte[] b = new byte[n];
for (int i = 0; i < n; i++) {
b[i] = photo[i];
}
// 保存 Base64 编码格式显示
examStudentForm.setPhoto("data:image/jpeg;base64," +
Base64.encodeBase64String(b));
前端中的显示:
{
noPhoto: 'this.src="' + require("../assets/StartExam/NoPhoto.png") + '"',
问题及解决
该操作仅对使用 git-svn 检出的 SVN 项目有效.如果是标准 Git 项目,直接使用 push 命令即可.
重新用 apistudio 工具从网站检出之后,将检出的文件夹 替换 编译即可。
Vue 区分开发版本还是发布版本
下面2个表达式,可以在 vue 的组件总直接来使用
开发版本
process.env.NODE_ENV === 'development'
发布版本
process.env.NODE_ENV === 'production'
// 组件中的使用
this.isDev = (process.env.NODE_ENV === 'development');
文件操作模块
fs 模块使用手册
https://docs.apicloud.com/Client-API/Func-Ext/fs#31
使用模块时,需要先添加模块,才能使用这些功能
var fs = api.require('fs');
var bakDir = "fs://exam/bak";
// var ret = fs.createDirSync({
// path: bakDir
// });
// if (ret.status) {
// alert('创建成功!');
// } else {
// alert('创建失败!');
// }
var ret = fs.existSync({
var ret = fs.openSync({
var ret = fs.writeSync({
fd: this.bak.fd,
data: JSON.stringify(this.stuExamList),
overwrite: true
});
// if (ret.status) {
// alert('保存成功!');
// } else {
// alert('保存失败!');
// }
加密模块
signature
https://docs.apicloud.com/Client-API/Func-Ext/signature
添加模块
var signature = api.require('signature');
signature.desECB({
data: txt,
key: '4OzEDGPUvkym9SkU'
}, (ret, err) => {
if (!ret.status) {
signature 源码
https://github.com/apicloudcom/APICloud-Modules/tree/master/signature/android/sourceCode
参照源代码
Java 端
import org.apache.commons.codec.binary.Base64;
str = new String(Base64.decodeBase64(afterDecrypt.getBytes("UTF-8")));
【注意】测试时候的字符一定要准确
Wifi模块
https://docs.apicloud.com/Client-API/Device-Access/bgnWiFi
与apicloud配套使用的vant框架
环境搭建
cnpm install -g @vue/cli-init
vue init xiaoqiang730730/vue_apicloud si-app-vant
去除eslint的验证
config/index.js
useEslint: false,
启动项目
npm run start
编译加上传
npm run build && gulp upload
柚子快报激活码778899分享:Apicloud
发表评论