提交 3e7c82a8 编写于 作者: VK1688's avatar VK1688

1.17.0

上级 849432e5
......@@ -92,7 +92,7 @@ export default {
url: config.error.url
});
},
onLaunch: function() {
onLaunch: function(options) {
// 注意:config.debug 在正式环境时,值为false,故此{}内的代码只有开发环境才会执行
if (config.debug) {
console.log(
......
## 1.17.0(2023-07-04)
* 1、【升级】`vk-unicloud-admin-ui` 包升级至 `1.17.0`
* 2、【重要】`万能表格``action` 属性支持传函数 [传送门 - 自定义function请求模式](https://vkdoc.fsq.pub/admin/2/table.html#%E8%87%AA%E5%AE%9A%E4%B9%89function%E8%AF%B7%E6%B1%82%E6%A8%A1%E5%BC%8F)
* 3、【重要】`万能表单``action` 属性支持传函数 [传送门 - 自定义function请求模式](https://vkdoc.fsq.pub/admin/3/form.html#%E8%87%AA%E5%AE%9A%E4%B9%89function%E8%AF%B7%E6%B1%82%E6%A8%A1%E5%BC%8F)
* 4、【修复】`万能表单` `group + object` 会报错的问题
* 5、【修复】`万能表单` `group` 内的组件 `disabled` 函数和字符串表达式不生效的问题
* 6、【修复】`万能表格` `group` 内的 `object``showLabel` 属性不生效的问题
* 7、【修复】`万能表格` `this.$refs.table1.updateRows` 执行后再次点击编辑会报错的问题
* 8、【优化】`万能表单` `tag` 组件支持 `max` 属性
* 9、【优化】`万能表单` `上传组件` 支持属性 `cloudDirectory` 可以设置上传至指定的云端目录
* 10、【优化】`万能表单` `file-select` 支持预览非图片和视频的文件(无法预览的会触发下载)
##### 框架更新步骤 [点击查看](https://vkdoc.fsq.pub/admin/1/update.html)
##### 框架学习Q群:`22466457` 欢迎萌新和大佬来使用和共同改进框架
##### 如果你觉得框架对你有用,可以在下方进行评论或赞赏。
## 1.16.2(2023-06-01)
* 1、【升级】`vk-unicloud-admin-ui` 包升级至 `1.16.15`
* 2、【修复】`缓存管理` 页面添加缓存后,`vk.globalDataCache.get(key);` 无法获取到数据的问题(需要手动替换目录`router/service/admin/system_uni/global-data/`
......
* 1、【升级】`vk-unicloud-admin-ui` 包升级至 `1.16.15`
* 2、【修复】`缓存管理` 页面添加缓存后,`vk.globalDataCache.get(key);` 无法获取到数据的问题(需要手动替换目录`router/service/admin/system_uni/global-data/`
* 3、【优化】`素材管理` 上传素材时的进度条样式
* 4、【优化】`万能表格` 新增 `needAlert` 属性,设为false可以取消默认的错误弹窗(默认为true)
* 1、【升级】`vk-unicloud-admin-ui` 包升级至 `1.17.0`
* 2、【重要】`万能表格``action` 属性支持传函数 [传送门 - 自定义function请求模式](https://vkdoc.fsq.pub/admin/2/table.html#%E8%87%AA%E5%AE%9A%E4%B9%89function%E8%AF%B7%E6%B1%82%E6%A8%A1%E5%BC%8F)
* 3、【重要】`万能表单``action` 属性支持传函数 [传送门 - 自定义function请求模式](https://vkdoc.fsq.pub/admin/3/form.html#%E8%87%AA%E5%AE%9A%E4%B9%89function%E8%AF%B7%E6%B1%82%E6%A8%A1%E5%BC%8F)
* 4、【修复】`万能表单` `group + object` 会报错的问题
* 5、【修复】`万能表单` `group` 内的组件 `disabled` 函数和字符串表达式不生效的问题
* 6、【修复】`万能表格` `group` 内的 `object``showLabel` 属性不生效的问题
* 7、【修复】`万能表格` `this.$refs.table1.updateRows` 执行后再次点击编辑会报错的问题
* 8、【优化】`万能表单` `tag` 组件支持 `max` 属性
* 9、【优化】`万能表单` `上传组件` 支持属性 `cloudDirectory` 可以设置上传至指定的云端目录
* 10、【优化】`万能表单` `file-select` 支持预览非图片和视频的文件(无法预览的会触发下载)
##### 框架更新步骤 [点击查看](https://vkdoc.fsq.pub/admin/1/update.html)
......
{
"id": "vk-unicloud-admin",
"name": "vk-unicloud-admin",
"version": "1.16.2",
"version": "1.17.0",
"displayName": "【开箱即用】vk-unicloud-admin-快速开发框架-打造unicloud最好用的admin",
"description": "vk-unicloud-admin是基于uniapp+unicloud+uni-id+vk-router+element的一套快速PC admin企业级开发框架。小白几分钟即完成一个页面CRUD。",
"keywords": [
......@@ -22,7 +22,7 @@
"dependencies": {
"element-ui": "2.15.13",
"umy-ui": "1.1.6",
"vk-unicloud-admin-ui": "^1.16.15"
"vk-unicloud-admin-ui": "^1.17.0"
},
"engines": {
"HBuilderX": "^3.1.10"
......
......@@ -87,7 +87,7 @@ export default {
vk.userCenter.checkToken({
loading: true,
success: data => {
that.login_success();
that.login_success(data);
}
});
},
......@@ -110,12 +110,13 @@ export default {
vk.setVuex("$user.login.username", "");
vk.setVuex("$user.login.password", "");
}
that.login_success();
that.login_success(data);
}
});
},
//登陆成功
login_success() {
login_success(data={}) {
let { userInfo={} } = data;
// 先清空下菜单缓存
vk.setVuex("$app.inited", false);
vk.setVuex("$app.navMenu", []);
......
......@@ -8,7 +8,7 @@
></vk-data-page-header>
<view class="page-body">
<!-- 表格组件开始 -->
<vk-data-table ref="table1" :data="table1.data" :columns="table1.columns"></vk-data-table>
<vk-data-table ref="table1" :data="table1.data" :columns="table1.columns" :row-no="true"></vk-data-table>
<!-- 表格组件结束 -->
</view>
<!-- 页面内容结束 -->
......
......@@ -61,7 +61,7 @@
:action="form1.props.action"
:form-type="form1.props.formType"
:columns='form1.props.columns'
label-width="80px"
label-width="120px"
@success="form1.props.show = false;refresh();"
></vk-data-form>
</vk-data-dialog>
......
'use strict';
module.exports = {
/**
* 获取支付宝小程序码
* @url user/kh/getAlipayMiniCode 前端调用的url参数地址
* data 请求参数
* @param {String} page 必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index, 根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面
* @param {String} scene 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
*/
main: async (event) => {
let { data = {}, userInfo, util, filterResponse, originalParam } = event;
let { customUtil, uniID, config, pubFun, vk, db, _ } = util;
let { uid } = data;
let res = { code: 0, msg: "" };
// 业务逻辑开始-----------------------------------------------------------
let {
page,
scene
} = data;
res = await vk.openapi.alipay.acode.getMiniCode(data);
res.base64 = res.qr_code_url_circle_blue; // 兼容其他小程序的返回字段
// 业务逻辑结束-----------------------------------------------------------
return res;
}
}
......@@ -19,11 +19,21 @@ module.exports = {
let res = {};
// 业务逻辑开始-----------------------------------------------------------
// 用户登录(账号+密码)
if (typeof data.username === "number") data.username = String(data.username).trim();
if (typeof data.password === "number") data.password = String(data.password).trim();
let {
needPermission,
username,
password,
queryField = ['username', 'email', 'mobile'], // 不指定queryField的情况下只会查询username
} = data;
res = await uniID.login({
...event.data,
// 不指定queryField的情况下只会查询username
queryField: ['username', 'email', 'mobile']
username,
password,
needPermission,
queryField
});
if (res.token) {
if (!res.msg) {
......@@ -42,4 +52,4 @@ module.exports = {
return res;
}
}
}
\ No newline at end of file
......@@ -21,7 +21,14 @@ module.exports = {
let { uid } = data;
let res = {};
// 业务逻辑开始-----------------------------------------------------------
let { email, code, type, password, needPermission, myInviteCode } = data;
let {
email,
code,
type,
password,
needPermission,
myInviteCode
} = data;
res = await uniID.loginByEmail({
email,
code,
......
......@@ -19,20 +19,36 @@ module.exports = {
let { uid } = data;
let res = { code: -1, msg: '' };
// 业务逻辑开始-----------------------------------------------------------
if (typeof data.username === "number") data.username = String(data.username).trim();
if (typeof data.password === "number") data.password = String(data.password).trim();
let {
username,
password,
needPermission,
myInviteCode
} = data;
// username必须以字母开头,长度在6~18之间,只能包含字母、数字和下划线
if (!vk.pubfn.test(username, "username")) {
return { code: -1, msg: "账号必须以字母开头,长度在6~18之间,只能包含字母、数字和下划线" };
}
// password 长度在6~18之间,只能包含字母、数字和下划线
if (!vk.pubfn.test(password, "pwd")) {
return { code: -1, msg: "密码长度在6~18之间,只能包含字母、数字和下划线" };
// 验证规则开始 -----------------------------------------------------------
let rules = {
username: [
{ required: true, validator: vk.pubfn.validator("username"), message: '用户名以字母开头,长度在3~32之间,只能包含字母、数字和下划线', trigger: ['blur', 'change'] }
],
password: [
{ validator: vk.pubfn.validator("password"), message: '密码长度在6~18之间,只能包含字母、数字和下划线', trigger: 'blur' }
]
};
// 验证规则结束 -----------------------------------------------------------
// 开始进行验证
let formRulesRes = vk.pubfn.formValidate({
data: data,
rules: rules
});
if (formRulesRes.code !== 0) {
// 表单验证未通过
return formRulesRes;
}
// 表单验证通过,下面写自己的业务逻辑
res = await uniID.register({
username,
password,
......
......@@ -32,6 +32,13 @@ module.exports = {
if (!vkmail) {
return { code: -1, msg: "请先添加公共模块:vk-mail(右键对应的云函数,点击管理公共模块或扩展库依赖,勾选vk-mail依赖)" };
}
// 参数非空检测
let nullKey = vk.pubfn.isNullOneByObject({ email, type });
if (nullKey) return { code: -1, msg: '参数 '+nullKey+' 不能为空' };
if (vk.pubfn.test(email, "email")) return { code: -1, msg: "邮箱格式错误" };
if (vk.pubfn.isNull(type)) return { code: -1, msg: "type不能为空" };
let code = vk.pubfn.random(6, "0123456789");
let param = {
code,
......
......@@ -50,6 +50,16 @@ module.exports = {
"user": "你的邮箱@qq.com",
"pass": "邮箱授权码"
}
},
// 163邮箱配置
"163":{
"host": "smtp.163.com",
"port": 465,
"secure": true,
"auth": {
"user": "",
"pass": ""
}
}
},
// 日志服务
......@@ -92,19 +102,37 @@ module.exports = {
}
},
// 其他小程序的密钥 当需要多个小程序绑定同一服务空间,并调用小程序服务端API时需要填写 暂只支持微信小程序
"oauth":{
"oauth": {
// 微信小程序
"weixin":{
"weixin": {
// 密钥列表
"list":[
{
"appid" : "",
"appsecret" : ""
},
{
"appid" : "",
"appsecret" : ""
}
"list": [
{ "appid": "", "appsecret": "" },
{ "appid": "", "appsecret": "" }
]
},
// 支付宝
"alipay": {
// 密钥列表
"list": [
{ "appid": "", "privateKey": "" },
{ "appid": "", "privateKey": "" }
]
},
// qq
"qq": {
// 密钥列表
"list": [
{ "appid": "", "appsecret": "" },
{ "appid": "", "appsecret": "" }
]
},
// 抖音
"toutiao": {
// 密钥列表
"list": [
{ "appid": "", "appsecret": "" },
{ "appid": "", "appsecret": "" }
]
}
}
......
## 2.15.0(2023-07-04)
* 1、【重要】注册接口统一去除前端的role参数(需替换目录 `router/service/user/pub`
* 2、【修复】云端表单验证不支持a.b的问题
* 3、【新增】`vk.sessionStorage` 本地会话缓存,仅h5可用
* 4、【优化】`vk.uploadFile` 新增参数 `cloudPathAsRealPath` 默认为true,代表支持阿里云目录
* 5、【优化】`vk.uploadFile` 新增参数 `cloudDirectory` 可以设置上传至指定的云端目录
* 6、【优化】`vk.request` 新增 `interceptor` 参数(该参数仅前端调用时生效)[传送门](https://vkdoc.fsq.pub/client/jsapi.html#vk-request-%E8%AF%B7%E6%B1%82http%E6%8E%A5%E5%8F%A3)
* 7、【优化】发送邮件验证码新增参数判断
* 8、【优化】云函数、云对象404时的错误提示
* 完整框架项目地址:`https://ext.dcloud.net.cn/plugin?id=2204`[点击查看](https://ext.dcloud.net.cn/plugin?id=2204)
## 2.14.3(2023-06-09)
* 1、【新增】支付宝小程序api [传送门](https://vkdoc.fsq.pub/client/uniCloud/plus/alipay.html)
* 2、【修复】因 `2.14.2` 更新导致的支付宝小程序报错问题。
* 3、【优化】注册接口前端全局防抖
* 完整框架项目地址:`https://ext.dcloud.net.cn/plugin?id=2204`[点击查看](https://ext.dcloud.net.cn/plugin?id=2204)
## 2.14.2(2023-06-01)
* 1、【优化】`user/kh/addUploadRecord` 细节
* 2、【优化】`vk.importObject` 支持 `importObjectOptions` 参数 [传送门](https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/cloudObject.html#uni-vk-importobject%E7%9A%84%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95)
......
{
"id": "vk-unicloud",
"displayName": "vk-unicloud-router开发框架核心库 - 已集成uni-id 框架内置了众多API。",
"version": "2.14.2",
"version": "2.15.0",
"description": "此为vk-unicloud-router框架核心库(新手建议下载完整框架项目)已集成uni-id支持云函数url化。众多现成API,内置小白也能轻松上手的数据库API。使你项目刚起步进度就是百分之50",
"keywords": [
"vk-unicloud-router",
......
{
"name": "vk-unicloud",
"version": "2.14.2",
"version": "2.15.0",
"description": "【云函数端SDK】VK云函数路由模式uniCloud开发框架,在router目录下执行 npm i vk-unicloud 进行安装和升级",
"main": "index.js",
"homepage": "https://gitee.com/vk-uni/vk-uni-cloud-router.git",
......
......@@ -8,6 +8,7 @@ import pubfn from './libs/function/index'
import modal from './libs/function/modal'
import navigate from './libs/function/vk.navigate'
import localStorage from './libs/function/vk.localStorage'
import sessionStorage from './libs/function/vk.sessionStorage'
import aliyunOSSUtil from './libs/function/aliyunOSSUtil'
import openapi from './libs/openapi/index'
import requestUtil from './libs/function/vk.request'
......@@ -80,8 +81,10 @@ var vk = {
$once: navigate.$once,
// 移除全局自定义事件监听器。
$off: navigate.$off,
// 本地缓存
// 本地持久
localStorage: localStorage,
// 本地会话缓存
sessionStorage: sessionStorage,
// 获取应用语言列表
getLocaleList: pubfn.getLocaleList,
......@@ -93,8 +96,10 @@ var vk = {
setLocale: pubfn.setLocale,
// 本地缓存
// 本地持久缓存
...localStorage,
// 本地会话缓存
...sessionStorage,
// 阿里云oss
aliyunOSSUtil,
// 更新管理器
......
......@@ -43,6 +43,8 @@ aliyunOSSUtil.uploadFile = function(obj) {
needSave = false,
category_id,
title,
cloudPathRemoveChinese = true, // 删除文件名中的中文
cloudDirectory,
} = obj;
let vk = getApp().globalData.vk;
if (title) vk.showLoading(title);
......@@ -179,9 +181,11 @@ function getConfig() {
// 生成文件名
function createFileName(obj = {}) {
let {
file,
filePath,
index = 0,
file,
filePath,
cloudPathRemoveChinese = true,
cloudDirectory
} = obj;
let vk = getApp().globalData.vk;
let aliyunOSS = getConfig();
......@@ -195,7 +199,9 @@ function createFileName(obj = {}) {
let suffixName = file.name.substring(file.name.lastIndexOf(".") + 1);
if (suffixName && suffixName.length < 5) oldName = file.name;
// 只保留["数字","英文",".","-"]
oldName = oldName.replace(/[^a-zA-Z.-d]/g, '');
if (cloudPathRemoveChinese) {
oldName = oldName.replace(/[^a-zA-Z.-d]/g, '');
}
if (oldName.indexOf(".") == 0) oldName = "0" + oldName;
}
let date = new Date();
......@@ -205,13 +211,26 @@ function createFileName(obj = {}) {
let dateTimeEnd8 = dateTime.substring(dateTime.length - 8, dateTime.length);
let randomNumber = vk.pubfn.random(8); // 8位随机数
// 文件路径 = 固定路径名 + 业务路径
// 业务路径
let servicePath = "";
let newFilePath = dirname + "/" + servicePath + dateYYYYMMDD + "/";
if (cloudDirectory) {
// 如果自定义了上传目录,则使用自定义的上传目录
if (cloudDirectory.lastIndexOf("/") !== cloudDirectory.length-1) {
cloudDirectory = cloudDirectory + "/";
}
servicePath = cloudDirectory;
} else {
// 否则,使用年月日作为上传目录
servicePath = dateYYYYMMDD + "/";
}
// 文件名 = 时间戳后8位 - 随机数8位 + 后缀名
let fileNickName = dateTimeEnd8 + randomNumber + "-" + oldName;
// 文件名全称(包含文件路径) = 外网域名 + 文件路径 + 文件名
let fileFullName = newFilePath + fileNickName;
// 外网地址 = 外网域名 + 文件路径 + 文件名
// 文件相对路径 = 业务目录 + 文件名
let fileRelativePath = servicePath + fileNickName;
// 文件名全称(包含文件路径) = 根目录 + 文件相对路径
let fileFullName = dirname + "/" + fileRelativePath;
// 外网地址 = 外网域名 + 文件名全称
let url = host + "/" + fileFullName;
fileObj.url = url;
fileObj.fileFullName = fileFullName;
......
......@@ -7,7 +7,7 @@ let timeoutArr = [];
* @param {Boolean} isImmediate 是否立即执行 默认true
* @param {String} timeoutName 定时器ID
* @return null
vk.pubfn.debounce(function() {
vk.pubfn.debounce(() => {
}, 1000);
*/
......@@ -18,16 +18,16 @@ function debounce(fn, time = 500, isImmediate = true, timeoutName = "default") {
// 立即执行一次
if (isImmediate) {
var callNow = !timeoutArr[timeoutName];
timeoutArr[timeoutName] = setTimeout(function() {
timeoutArr[timeoutName] = setTimeout(() => {
timeoutArr[timeoutName] = null;
}, time);
if (callNow){
if(typeof fn === 'function') fn();
if(typeof fn === 'function') return fn();
}
} else {
// 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时time毫秒后执行fn回调方法
timeoutArr[timeoutName] = setTimeout(function() {
if(typeof fn === 'function') fn();
timeoutArr[timeoutName] = setTimeout(() => {
if(typeof fn === 'function') return fn();
}, time);
}
}
......
......@@ -5,7 +5,7 @@
* sys - 系统级缓存 - 一般不删除
*
* 储存缓存
* vk.setStorageSync(key,data);
* vk.setStorageSync(key, data);
* 获取缓存
* vk.getStorageSync(key);
*/
......@@ -15,16 +15,16 @@ var localStorage = {};
* @param {String} key 本地缓存中的指定的 key
* @param {Any} data 需要存储的内容,只支持原生类型、及能够通过 JSON.stringify 序列化的对象
*/
localStorage.setStorageSync = function(key,data){
localStorage.setStorageSync = function(key, data) {
uni.setStorageSync(key, data);
watchLocalStorage({ type:"set", key, data });
watchLocalStorage({ type: "set", key, data });
};
/**
* 从本地缓存中异步获取指定 key 对应的内容。
* @param {String} key 本地缓存中的指定的 key
*/
localStorage.getStorageSync = function(key){
localStorage.getStorageSync = function(key) {
let data = uni.getStorageSync(key);
// get 没有必要监听
// watchLocalStorage({ type:"get", key, data });
......@@ -34,9 +34,9 @@ localStorage.getStorageSync = function(key){
/**
* 同步获取当前 storage 的相关信息。
*/
localStorage.getStorageInfoSync = function(){
localStorage.getStorageInfoSync = function() {
let info = uni.getStorageInfoSync();
let sizeInfo = calcSize(Number(info.currentSize), 1024, 3,["KB","MB","GB"]);
let sizeInfo = calcSize(Number(info.currentSize), 1024, 3, ["KB", "MB", "GB"]);
info.sizeInfo = sizeInfo;
return info;
};
......@@ -45,22 +45,22 @@ localStorage.getStorageInfoSync = function(){
* 从本地缓存中同步移除指定 key。
* @param {String} key 本地缓存中的指定的 key
*/
localStorage.removeStorageSync = function(key){
localStorage.removeStorageSync = function(key) {
uni.removeStorageSync(key);
watchLocalStorage({ type:"remove", key });
watchLocalStorage({ type: "remove", key });
};
/**
* 从本地缓存中异步移除指定 key。
*/
localStorage.removeStorage = function(obj){
localStorage.removeStorage = function(obj) {
uni.removeStorage({
key:obj.key,
success:function(res){
watchLocalStorage({ type:"remove", key:obj.key });
if(obj.success) obj.success(res);
key: obj.key,
success: (res) => {
watchLocalStorage({ type: "remove", key: obj.key });
if (obj.success) obj.success(res);
},
fail:obj.fail,
complete:obj.complete
fail: obj.fail,
complete: obj.complete
});
};
......@@ -69,21 +69,21 @@ localStorage.removeStorage = function(obj){
* @param {String} key 本地缓存中的指定的 key
* vk.clearStorageSync();
*/
localStorage.clearStorageSync = function(key){
if(key){
let { keys } = uni.getStorageInfoSync();
if(keys){
keys.map((keyName) => {
if(keyName.indexOf(key) == 0){
localStorage.clearStorageSync = function(key) {
if (key) {
let { keys } = uni.getStorageInfoSync();
if (keys) {
keys.map((keyName) => {
if (keyName.indexOf(key) == 0) {
localStorage.removeStorage({
key: keyName
});
}
});
}
}else{
watchLocalStorage({ type:"clear" });
});
}
} else {
uni.clearStorage();
watchLocalStorage({ type: "clear" });
}
};
......@@ -99,18 +99,18 @@ export default localStorage;
* arr 进制的数组,如["B","KB","MB","GB"]
* calcSize(length,1024,3,["B","KB","MB","GB"]);
*/
function calcSize (length=0,ary,precision,arr){
function calcSize(length = 0, ary, precision, arr) {
var size = parseFloat(length);
var mySize = 0;
var type = "";
if(size<ary || arr.length<=1){
if (size < ary || arr.length <= 1) {
type = arr[0];
mySize = parseFloat(size.toFixed(precision));
}else{
} else {
for (var i = 1; i < arr.length; i++) {
var g = arr[i];
size = size/ary;
if(size <ary){
size = size / ary;
if (size < ary) {
type = g;
mySize = parseFloat(size.toFixed(precision));
break;
......@@ -118,15 +118,14 @@ function calcSize (length=0,ary,precision,arr){
}
}
return {
size : mySize,
type : type,
title : mySize + " " + type
size: mySize,
type: type,
title: mySize + " " + type
}
};
function watchLocalStorage(obj){
if(typeof localStorage.watch === "function"){
function watchLocalStorage(obj) {
if (typeof localStorage.watch === "function") {
localStorage.watch(obj);
}
}
}
\ No newline at end of file
......@@ -224,7 +224,13 @@ util.originalTo = function() {
* vk.navigate.getOriginalPage();
*/
util.getOriginalPage = function() {
return uni.vk.getVuex('$app.originalPage');
if (typeof uni.vk.getVuex === "function") {
// 有安装vuex则使用vuex
return uni.vk.getVuex('$app.originalPage');
} else {
// 未安装则使用本地缓存
return uni.vk.getStorageSync('vk.navigate.originalPage');
}
};
/**
......@@ -233,7 +239,13 @@ util.getOriginalPage = function() {
*/
util.setOriginalPage = function(originalPage) {
uni.vk.navigate.originalPage = originalPage; // 兼容老版本
return uni.vk.setVuex('$app.originalPage', originalPage); // 新版本
if (typeof uni.vk.getVuex === "function") {
// 有安装vuex则使用vuex
return uni.vk.setVuex('$app.originalPage', originalPage);
} else {
// 未安装则使用本地缓存
return uni.vk.setStorageSync('vk.navigate.originalPage', originalPage);
}
};
......
......@@ -44,7 +44,7 @@ vk.request({
url: `https://www.xxx.com/api/xxxx`,
method:"POST",
header:{
"content-type": "application/x-www-form-urlencoded",
"content-type": "application/json; charset=utf-8",
},
data:{
......@@ -61,7 +61,7 @@ vk.request({
requestUtil.request = function(obj = {}) {
let vk = uni.vk;
// 去除值为 undefined 的参数
if(typeof obj.data === "object"){
if (typeof obj.data === "object") {
obj.data = vk.pubfn.copyObject(obj.data);
}
// 注入自定义全局参数开始-----------------------------------------------------------
......@@ -106,17 +106,24 @@ requestUtil.request = function(obj = {}) {
if (typeof obj.header === "undefined" && typeof obj.headers !== "undefined") {
obj.header = obj.headers;
}
// 自动注入token到请求头开始-----------------------------------------------------------
if (typeof vk.getToken === "function") {
let uni_id_token = vk.getToken();
if (uni_id_token) {
if (!obj.header) obj.header = {};
obj.header["uni_id_token"] = uni_id_token;
obj.header["uni-id-token"] = uni_id_token;
}
}
// 自动注入token到请求头结束-----------------------------------------------------------
let interceptor = obj.interceptor;
delete obj.interceptor;
if (interceptor && typeof interceptor.invoke === "function") {
let interceptorRes = interceptor.invoke(obj);
if (interceptorRes === false) {
return;
}
}
if (typeof obj.timeout === "undefined") obj.timeout = 30000; // 超时时间,单位 ms(默认30秒)
let Logger = {};
if (config.debug) {
......@@ -134,7 +141,13 @@ requestUtil.request = function(obj = {}) {
let promiseAction = new Promise(function(resolve, reject) {
uni.request({
...obj,
success: function(res) {
success: (res) => {
if (interceptor && typeof interceptor.success === "function") {
let interceptorRes = interceptor.success(res);
if (interceptorRes === false) {
return;
}
}
requestSuccess({
res,
params: obj,
......@@ -143,7 +156,13 @@ requestUtil.request = function(obj = {}) {
reject
});
},
fail: function(res) {
fail: (res) => {
if (interceptor && typeof interceptor.fail === "function") {
let interceptorRes = interceptor.fail(res);
if (interceptorRes === false) {
return;
}
}
requestFail({
res,
params: obj,
......@@ -151,7 +170,13 @@ requestUtil.request = function(obj = {}) {
reject
});
},
complete: function(res) {
complete: (res) => {
if (interceptor && typeof interceptor.complete === "function") {
let interceptorRes = interceptor.complete(res);
if (interceptorRes === false) {
return;
}
}
requestComplete({
res,
params: obj,
......@@ -190,7 +215,7 @@ function requestSuccess(obj = {}) {
}
if (vk.pubfn.isNotNullAll(errorMsgName, data[errorMsgName])) {
data.msg = data[errorMsgName];
if(typeof data[errorMsgName] === "string"){
if (typeof data[errorMsgName] === "string") {
delete data[errorMsgName];
}
}
......@@ -206,6 +231,8 @@ function requestSuccess(obj = {}) {
if (title) vk.hideLoading();
if (loading) vk.setLoading(false, loading);
if (needOriginalRes) data.originalRes = vk.pubfn.copyObject(res);
if (data.vk_uni_token) vk.callFunctionUtil.saveToken(data.vk_uni_token);
if (data.userInfo && data.needUpdateUserInfo) vk.callFunctionUtil.updateUserInfo(data);
if (typeof success === "function") success(data);
if (typeof resolve === "function") resolve(data);
}
......@@ -248,7 +275,7 @@ function requestFail(obj = {}) {
if (loading) vk.setLoading(false, loading);
let runKey = true;
// 自定义拦截器开始-----------------------------------------------------------
let { interceptor={} } = vk.callFunctionUtil.getConfig();
let { interceptor = {} } = vk.callFunctionUtil.getConfig();
if (interceptor.request && typeof interceptor.request.fail == "function") {
runKey = interceptor.request.fail({
vk,
......@@ -300,9 +327,12 @@ function requestComplete(obj = {}) {
console.log("【总体耗时】: ", Logger.runTime, "毫秒【含页面渲染】");
console.log("【请求时间】: ", vk.pubfn.timeFormat(Logger.startTime, "yyyy-MM-dd hh:mm:ss"));
if (Logger.error) {
console.error("【Error】: ", Logger.error);
let errorLog = console.warn || console.error;
if (Logger.error.err && Logger.error.err.stack) {
console.error("【Error】: ", Logger.error);
console.error("【Stack】: ", Logger.error.err.stack);
} else {
errorLog("【Error】: ", Logger.error);
}
}
console.log("%c--------【结束】【服务器请求】【" + Logger.action + "】--------", 'color: ' + colorStr + ';font-size: 12px;font-weight: bold;');
......@@ -380,4 +410,4 @@ requestUtil.deleteRequestGlobalParam = (globalParamName) => {
vk.setStorageSync(config.requestGlobalParamKeyName, globalParam);
}
export default requestUtil;
export default requestUtil;
\ No newline at end of file
/**
* vk依赖扩展 - sessionStorage 本地会话缓存(仅H5可用)
* sessionStorage 属性允许你访问一个,对应当前源的 session Storage 对象。
* 它与 localStorage 相似,不同之处在于 localStorage 里面存储的数据没有过期时间设置
* 而存储在 sessionStorage 里面的数据在页面会话结束时会被清除。
* pub - 公共的可随时删除的缓存
* kh - 跟登录账号有关联的缓存
* sys - 系统级缓存 - 一般不删除
*
* 储存缓存
* vk.setSessionStorageSync(key, data);
* 获取缓存
* vk.getSessionStorageSync(key);
*/
var storage = {};
/**
* 将 data 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个同步接口。
* @param {String} key 本地缓存中的指定的 key
* @param {Any} data 需要存储的内容,只支持原生类型、及能够通过 JSON.stringify 序列化的对象
* vk.setSessionStorageSync(key, data);
*/
storage.setSessionStorageSync = function(key, data = "") {
// #ifdef H5
let type = typeof data;
let value = {
type: typeof data,
data: data
};
sessionStorage.setItem(key, JSON.stringify(value));
watchSessionStorage({ type: "set", key, data });
// #endif
// #ifndef H5
console.warn("非H5环境不支持此API");
// #endif
};
/**
* 从本地缓存中异步获取指定 key 对应的内容。
* @param {String} key 本地缓存中的指定的 key
* vk.getSessionStorageSync(key);
*/
storage.getSessionStorageSync = function(key) {
// #ifdef H5
let data;
try {
let value = JSON.parse(sessionStorage.getItem(key));
data = value.data;
} catch (err) {
data = sessionStorage.getItem(key);
}
// get 没有必要监听
// watchSessionStorage({ type:"get", key, data });
return data;
// #endif
// #ifndef H5
console.warn("非H5环境不支持此API");
// #endif
};
/**
* 从本地缓存中同步移除指定 key。
* @param {String} key 本地缓存中的指定的 key
* vk.removeSessionStorageSync(key);
*/
storage.removeSessionStorageSync = function(key) {
// #ifdef H5
sessionStorage.removeItem(key);
watchSessionStorage({ type: "remove", key });
// #endif
// #ifndef H5
console.warn("非H5环境不支持此API");
// #endif
};
/**
* 同步清理本地数据缓存。若key有值,则清除键值为指定字符串开头的缓存
* @param {String} key 本地缓存中的指定的 key
* vk.clearSessionStorageSync();
*/
storage.clearSessionStorageSync = function(key) {
// #ifdef H5
if (key) {
let keys = Object.keys(sessionStorage);
if (keys) {
keys.map((keyName) => {
if (keyName.indexOf(key) == 0) {
sessionStorage.removeItem(keyName);
}
});
}
} else {
sessionStorage.clear();
watchSessionStorage({ type: "clear" });
}
// #endif
// #ifndef H5
console.warn("非H5环境不支持此API");
// #endif
};
export default storage;
/**
* 单位进制换算
* length 换算前大小
* ary 进制,如KB-MB-GB,进制1024
* precision 数值精度
* arr 进制的数组,如["B","KB","MB","GB"]
* calcSize(length,1024,3,["B","KB","MB","GB"]);
*/
function calcSize(length = 0, ary, precision, arr) {
var size = parseFloat(length);
var mySize = 0;
var type = "";
if (size < ary || arr.length <= 1) {
type = arr[0];
mySize = parseFloat(size.toFixed(precision));
} else {
for (var i = 1; i < arr.length; i++) {
var g = arr[i];
size = size / ary;
if (size < ary) {
type = g;
mySize = parseFloat(size.toFixed(precision));
break;
}
}
}
return {
size: mySize,
type: type,
title: mySize + " " + type
}
};
function watchSessionStorage(obj) {
if (typeof storage.watch === "function") {
storage.watch(obj);
}
}
......@@ -442,13 +442,24 @@ class CallFunctionUtil {
}
/**
* 云函数上传图片
* @param {String} filePath 要上传的文件对象
* @param {String} cloudPath 文件的绝对路径,包含文件名(若不传,会自动生成文件名)
* @param {String} fileType 文件类型,可选image、video、audio 默认image
* @param {Function} onUploadProgress 上传进度回调
* @param {Function} success 请求成功时,执行的回调函数
* @param {Function} fail 请求失败时,执行的回调函数
* @param {Function} complete 无论请求成功与否,都会执行的回调函数
* @param {String} title 上传时的loading提示语
* @param {String} file 要上传的文件对象,file与filePath二选一即可
* @param {String} filePath 要上传的文件路径,file与filePath二选一即可
* @param {String} suffix 指定上传后的文件后缀,如果传了file 参数,则此参数可不传
* @param {String} provider 云存储供应商,支持:unicloud、aliyun
* @param {String} cloudPath 指定上传后的云端文件路径(不指定会自动生成)cloudPath优先级大于cloudDirectory
* @param {String} cloudDirectory 指定上传后的云端文件目录(不指定会自动生成)
* @param {String} needSave 是否需要将图片信息保存到admin素材库
* @param {String} category_id 素材库分类id,当needSave为true时生效
* @param {String} uniCloud 上传到其他空间时使用,uniCloud和env二选一即可
* @param {String} env 上传到其他空间时使用,uniCloud和env二选一即可
* @param {String} cloudPathAsRealPath 阿里云目录支持,需HBX3.8.5以上版本才支持
* @param {String} cloudPathRemoveChinese 删除文件名中的中文
* @param {String} fileType 文件类型,可选image、video、audio 不用传,会自动识别
* @param {Function} onUploadProgress 上传进度回调
* @param {Function} success 上传成功时,执行的回调函数
* @param {Function} fail 上传失败时,执行的回调函数
* @param {Function} complete 无论上传成功与否,都会执行的回调函数
* vk.callFunctionUtil.uploadFile
*/
this.uploadFile = (obj = {}) => {
......@@ -470,7 +481,10 @@ class CallFunctionUtil {
needSave = false,
category_id,
uniCloud: myCloud,
env = "default"
env = "default",
cloudPathAsRealPath = true, // 阿里云目录支持,需HBX3.8.5以上版本才支持
cloudPathRemoveChinese = true, // 删除文件名中的中文
cloudDirectory,
} = obj;
// 获取文件类型(image:图片 video:视频 other:其他)
let fileType = this.getFileType(obj);
......@@ -500,6 +514,7 @@ class CallFunctionUtil {
filePath: filePath,
cloudPath: cloudPath,
fileType: fileType,
cloudPathAsRealPath,
onUploadProgress: function(progressEvent) {
let percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
......@@ -897,17 +912,22 @@ class CallFunctionUtil {
// 生成文件名
createFileName(obj = {}) {
let {
file,
filePath,
index = 0,
file,
filePath
cloudPathRemoveChinese = true,
cloudDirectory
} = obj;
let suffix = this.getFileSuffix(obj);
let oldName = index + "." + suffix;
// 注意:小程序无法获取到 file.name
if (file && file.name) {
let suffixName = file.name.substring(file.name.lastIndexOf(".") + 1);
if (suffixName && suffixName.length < 5) oldName = file.name;
// 只保留["数字","英文",".","-"]
oldName = oldName.replace(/[^a-zA-Z.-d]/g, '');
if (cloudPathRemoveChinese) {
oldName = oldName.replace(/[^a-zA-Z.-d]/g, '');
}
if (oldName.indexOf(".") == 0) oldName = "0" + oldName;
}
let date = new Date();
......@@ -917,10 +937,20 @@ class CallFunctionUtil {
let dateTimeEnd8 = dateTime.substring(dateTime.length - 8, dateTime.length);
let randomNumber = vk.pubfn.random(8); // 8位随机数
// 文件路径
let newFilePath = dateYYYYMMDD + "/";
// 文件名 = 时间戳 - 随机数32位 + 后缀名
let newFilePath = "";
if (cloudDirectory) {
// 如果自定义了上传目录,则使用自定义的上传目录
if (cloudDirectory.lastIndexOf("/") !== cloudDirectory.length-1) {
cloudDirectory = cloudDirectory + "/";
}
newFilePath = cloudDirectory;
} else {
// 否则,使用年月日作为上传目录
newFilePath = dateYYYYMMDD + "/";
}
// 文件名 = 时间戳后8位 - 随机数8位 + 原本文件名
let fileNickName = dateTimeEnd8 + "-" + randomNumber + "-" + oldName;
// 文件名全称(包含文件路径) = 外网域名 + 文件路径 + 文件名
// 文件名全称(包含文件路径) = 文件路径 + 文件名
let fileFullName = newFilePath + fileNickName;
return fileFullName;
}
......
......@@ -6,6 +6,8 @@ import callFunctionUtil from './vk-unicloud-callFunctionUtil.js'
var { callFunction, config, saveToken, deleteToken } = callFunctionUtil;
import debounce from '../function/debounce.js'
const debounceTime = 1000; // 防抖时长
const localeObj = {
"zh-Hans": {
"loading": "请求中...",
......@@ -55,11 +57,13 @@ export default {
* @param {String} uid 用户ID
*/
register(obj = {}) {
addLoading(obj, "register");
return callFunction({
...obj,
url: 'user/pub/register'
});
return debounce(() => {
addLoading(obj, "register");
return callFunction({
...obj,
url: 'user/pub/register'
});
}, debounceTime, true, "login");
},
/**
* 用户登录(用户名+密码)
......@@ -259,11 +263,13 @@ export default {
* @param {String} tokenExpired token过期时间
*/
loginBySms(obj = {}) {
addLoading(obj, "login");
return callFunction({
url: 'user/pub/loginBySms',
...obj
});
return debounce(() => {
addLoading(obj, "login");
return callFunction({
url: 'user/pub/loginBySms',
...obj
});
}, debounceTime, true, "login");
},
/**
* 发送手机号验证码
......@@ -494,7 +500,7 @@ export default {
*/
loginByWeixin(obj = {}) {
let that = this;
debounce(function() {
debounce(() => {
addLoading(obj, "login");
let { data = {} } = obj;
that.getWeixinCode().then((code) => {
......@@ -511,7 +517,7 @@ export default {
}
});
});
}, 500);
}, debounceTime, true, "login");
},
/**
* 获取微信openid
......@@ -612,11 +618,13 @@ export default {
* @param {String} tokenExpired token过期时间
*/
loginByWeixinPhoneNumber(obj = {}) {
addLoading(obj, "login");
return callFunction({
url: 'user/pub/loginByWeixinPhoneNumber',
...obj
});
return debounce(() => {
addLoading(obj, "login");
return callFunction({
url: 'user/pub/loginByWeixinPhoneNumber',
...obj
});
}, debounceTime, true, "login");
},
/**
* 生成微信小程序码
......@@ -698,7 +706,7 @@ export default {
*/
loginByAlipay(obj = {}) {
let that = this;
debounce(function() {
debounce(() => {
addLoading(obj, "login");
let { data = {} } = obj;
that.getAlipayCode().then((code) => {
......@@ -711,7 +719,7 @@ export default {
}
});
});
}, 500);
}, debounceTime, true, "login");
},
/**
* 获取支付宝openid
......@@ -773,6 +781,21 @@ export default {
url: 'user/kh/unbindAlipay',
});
},
/**
* 生成支付宝小程序码
* @param {String} page 必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index, 根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面
* @param {String} scene 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
* res 返回参数说明
* @param {Number} code 错误码,0表示成功
* @param {String} msg 详细信息
*/
getAlipayMiniCode(obj = {}) {
addLoading(obj, "create");
return callFunction({
...obj,
url: 'user/kh/getAlipayMiniCode',
});
},
/**
* 密码加密测试(暂不用)
*/
......@@ -965,7 +988,7 @@ export default {
*/
loginByQQ(obj = {}) {
let that = this;
debounce(function() {
debounce(() => {
addLoading(obj, "login");
let { data = {} } = obj;
that.getQQCode().then(({ code, accessToken } = {}) => {
......@@ -979,7 +1002,7 @@ export default {
}
});
});
}, 500);
}, debounceTime, true, "login");
},
/**
* 绑定QQ
......
......@@ -3,7 +3,7 @@
<vk-data-menu-nav
v-if="vk.getVuex('$app.inited')"
:data="vk.getVuex('$app.navMenu')"
:uniqueOpened="true"
:unique-opened="true"
:collapse="vk.getVuex('$app.leftCollapse')"
:collapse-transition="false"
:theme="theme"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册