初始化万家商超用户端仓库

This commit is contained in:
wangxiaowei
2025-04-30 14:04:34 +08:00
commit 022c640d89
425 changed files with 160005 additions and 0 deletions

1
common/amap-wx.js Normal file

File diff suppressed because one or more lines are too long

33
common/api/index.js Normal file
View File

@ -0,0 +1,33 @@
import Request from './request';
import { API_BASE_URL, SERIAL, IS_DEV, ACCEPT_PLATFORM } from '../config.js';
const http = new Request();
http.setConfig((config) => {
config.baseUrl = API_BASE_URL;
return config
})
http.interceptor.request((config, cancel) => {
config.header = {
...config.header,
'user-token': global.token || global.user_token || '',
'user-group': 1,
'Accept-Language': global.locale,
'Accept-Platform': ACCEPT_PLATFORM,
'Accept-Serial': SERIAL,
//CUSTOM_HEADER
}
if (IS_DEV == 2) {
config.data = {
...config.data,
ismock: 0,
}
}
return config;
})
http.interceptor.response((response) => {
return response;
})
export {
http
};

171
common/api/request.js Normal file
View File

@ -0,0 +1,171 @@
import { navigateToLogin } from '@/common/utils/utils.js';
import store from '@/store/index';
import { dev_host, mock_host, product_host, needProductUrl } from '../config.js';
export default class Request {
config = {
baseUrl: '',
header: {
'Content-Type': 'application/json; charset=utf-8',
},
method: 'GET',
dataType: 'json',
responseType: 'text',
success() { },
fail() { },
complete() { }
}
static posUrl(url) { /* 判断url是否为绝对路径 */
return /(http|https):\/\/([\w.]+\/?)\S*/.test(url)
}
interceptor = {
request: (f) => {
if (f) {
this.requestBeforeFun = f
}
},
response: (f) => {
if (f) {
this.requestComFun = f
}
}
}
static requestBeforeFun(config) {
return config
}
static requestComFun(response) {
return response
}
setConfig(f) {
this.config = f(this.config)
return this
}
testNeedProductUrl(url) {
return needProductUrl.findIndex(ele => ele == url) != -1;
}
request(options = {}) {
if (this.testNeedProductUrl(options.url)) {
options.baseUrl = product_host + '/api';
} else {
options.baseUrl = options.baseUrl || this.config.baseUrl;
}
options.dataType = options.dataType || this.config.dataType;
if (options.url == undefined) return Promise.reject();
options.url = Request.posUrl(options.url) ? options.url : (options.baseUrl + options.url);
options.data = options.data || {};
options.header = options.header || this.config.header;
options.method = options.method || this.config.method;
if (options['Content-Type']) options.header['Content-Type'] = options['Content-Type'];
return new Promise((resolve, reject) => {
let next = true
let _config = null
options.complete = (response) => {
let statusCode = response.statusCode
response.config = _config
response = this.requestComFun(response)
if (statusCode != 200) {
let errMessage = '';
switch (statusCode) {
case 400:
errMessage = global.i18n.t('请求错误(400)');
break;
case 401:
errMessage = global.i18n.t('未授权,请重新登录(401)');
uni.showToast({
title: global.i18n.t('登录失效'),
icon: 'none',
position: 'bottom',
duration: 1500
})
store.commit('logout');
break;
case 403:
errMessage = global.i18n.t('拒绝访问(403)');
break;
case 404:
errMessage = global.i18n.t('请求出错(404)');
break;
case 408:
errMessage = global.i18n.t('请求超时(408)');
break;
case 500:
errMessage = global.i18n.t('服务器错误(500)');
break;
case 501:
errMessage = global.i18n.t('服务未实现(501)');
break;
case 502:
errMessage = global.i18n.t('网络错误(502)');
break;
case 503:
errMessage = global.i18n.t('服务不可用(503)');
break;
case 504:
errMessage = global.i18n.t('网络超时(504)');
break;
case 505:
errMessage = global.i18n.t('HTTP版本不受支持(505)');
break;
default:
// errMessage = global.i18n.t("服务器错误!");
errMessage = '';
break;
}
if (statusCode != 401) {
if (errMessage) {
uni.showToast({
title: errMessage,
icon: 'none',
position: 'bottom',
duration: 1500
})
}
uni.$emit('netWorkError', { msg: global.i18n.t('服务器太拥挤了~请您稍后重试') })
}
reject({ statusCode, errMessage })
} else {
let _code = response.data.code;
if (_code == '-201' || _code == '-202' || _code == '-203') {
uni.showToast({
title: global.i18n.t('登录失效,请重新登录'),
icon: 'none',
})
store.commit("logout");
navigateToLogin();
} else {
resolve(response)
}
}
uni.stopPullDownRefresh();
}
let cancel = (t = 'handle cancel') => {
let err = {
errMsg: t,
config: afC
}
reject(err)
next = false
}
let afC = { ...this.config, ...options }
_config = { ...afC, ...this.requestBeforeFun(afC, cancel) }
if (!next) return
uni.request(_config)
})
}
get(url, data, options = {}) {
options.url = url
options.data = data
options.method = 'GET'
return this.request(options)
}
post(url, data, options = {}) {
options.url = url
options.data = data
options.method = 'POST'
return this.request(options)
}
}

150
common/api/url.js Normal file
View File

@ -0,0 +1,150 @@
import {
API_VERSION,
PAAS_URL
} from '@/common/config.js';
const publicApi = {
postRecommentGoods: `/${API_VERSION}/5fd9a32379116`, //智能推荐
numberOfShoppingCart: ``, //获取购物车数量
publicUpdateAPP: `/${API_VERSION}/5b5bdc44796e8`, // 静默更新
publicUpdateAPP1: `/${API_VERSION}/6728701f5e8bc`, // 静默更新
queryAutograph: `/v1/63be0e760981e`, // 获取oss配置接口
UPLOAD_IMAGE_URL: `/${API_VERSION}/62ddf0e4eadde`, // 本地图片上传接口
// UPLOAD_FILE_URL: `/${API_VERSION}/5d5fa8984f0c2`, // 文件上传接口
GetVerifyCode: `/${API_VERSION}/5b5bdc44796e8`, // 发送验证码
Get5d8b062aefc08: `/${API_VERSION}/5d8b062aefc08`, // 更新用户设备的client_id
post5c78c4772da97: `/${API_VERSION}/5c78c4772da97`, //获取会员详细信息
post636d04052bb00: `/${API_VERSION}/636d04052bb00`, //钱包-1
post5cb54af125f1c: `/${API_VERSION}/5cb54af125f1c`, //个人资料修改
post636f7683cf195: `/${API_VERSION}/636f7683cf195`, //收货地址列表
post5cadd0d3a0c93: `/${API_VERSION}/636f773e8d763`, //删除收货地址
post6389ad65f28d9: `/${API_VERSION}/6389ad65f28d9`, //设置默认地址-1
post637defdbd53ef: `/${API_VERSION}/637defdbd53ef`, //添加地址 -01-3-1
post636fd7826b3ee: `/${API_VERSION}/636fd7826b3ee`, // 地址管理-获取地址信息-1
post637df1ea39d16: `/${API_VERSION}/637df1ea39d16`, //编辑地址 -01-3-1
postRegister: `/${API_VERSION}/5cad9f63e4f94`, // 注册
postPasswordLogin: `/${API_VERSION}/5c78dbfd977cf`, // 密码登录
postCodeLogin: `/${API_VERSION}/5c78dca45ebc1`, // 验证码登录
postForgotPass: `/${API_VERSION}/5caeeba9866aa`, // 验证码登录
getSwiperList: `/${API_VERSION}/636e02b419726`, // 获取轮播图 2=首页 3=分类
getCateList: `/${API_VERSION}/64895b9fd996b`, // 获取首页分类
getSecondCateList: `/${API_VERSION}/64895bd999e93`, // 获取二级分类
getShopList: `/${API_VERSION}/64895cd1c3d04`, // 获取店铺列表
getShopDetail: `/${API_VERSION}/6489628bdf8da`, // 获取店铺详情
getGoodsCate: `/${API_VERSION}/6489684eab924`, // 获取商品分类
getGoodsDetail: `/${API_VERSION}/6486cd1135581`, // 获取商品详情
getShopCommentNums: `/${API_VERSION}/648c38061c2db`, // 获取店铺评论数量
getShopCommentList: `/${API_VERSION}/648c3585e8af8`, // 获取店铺评论
getGoodsDetailGoodsList: `/${API_VERSION}/64896912c1d22`, // 获取商品详情商品列表
getAddressLabelList: `/${API_VERSION}/5ff6859e3c4fd`, // 获取地址标签
postAddAddressLabel: `/${API_VERSION}/641846b264ece`, // 添加地址标签
postEditAddressLabel: `/${API_VERSION}/5ff6859e3c4fd`, // 编辑地址标签
feedbackTypes: `/${API_VERSION}/636dbfbfd7b81`, // 获取意见反馈类型
feedbackAdd: `/${API_VERSION}/636dc0bcb5991`, // 提交意见反馈
reportTypes: `/${API_VERSION}/649f88bd22592`, // 获取举报类型
reportAdd: `/${API_VERSION}/649f89a752ad5`, // 提交举报
myFeedback: `/${API_VERSION}/636dc7436d54d`, // 获取 意见反馈
editUserinfo: `/${API_VERSION}/5cb54af125f1c`, // 修改个人信息
postAddCart: `/${API_VERSION}/648aac5e094b8`, // 添加购物车
postMinusCart: `/${API_VERSION}/648aad454d5a6`, // 减少购物车
postDelCart: `/${API_VERSION}/648aae903cbcb`, // 删除购物车
getCartList: `/${API_VERSION}/648aaee3b3ee5`, // 获取购物车列表
getSettleInfo: `/${API_VERSION}/648ab46e107ad`, // 获取结算信息
postCreateOrder: `/${API_VERSION}/648aba3bde8cb`, // 创建订单
postPayOrder: `/${API_VERSION}/63feb2ce76ac6`, // 余额支付订单
getXieyi: `/${API_VERSION}/636c78ae2216b`, // 获取协议
getOrderList: `/${API_VERSION}/648ac3f7e946f`, // 获取订单列表
getOrderDetail: `/${API_VERSION}/648ac83704d15`, // 获取订单详情
postCancelOrder: `/${API_VERSION}/648ad6ebd84be`, // 取消订单
postDelOrder: `/${API_VERSION}/648ae27931659`, // 删除订单
postAddOrderComment: `/${API_VERSION}/648c268310fae`, // 提交评价
getCommentList: `/${API_VERSION}/648d71bd4b5ff`, // 取消订单
get64a530ab891d9: `/${API_VERSION}/64a530ab891d9`, // 获取下单时积分
get64a533a675a0a: `/${API_VERSION}/64a533a675a0a`, // 下单时备注
get64a62b3d77830: `/${API_VERSION}/64a62b3d77830`, // 获取支付信息
get64a633e0099ce: `/${API_VERSION}/64a633e0099ce`, // 抵用券抵扣
getHotSearch: `/${API_VERSION}/648d6c026d7b9`, // 获取热门搜索记录
postDelSearch: `/${API_VERSION}/648d6e1945d16`, // 删除搜索记录
getSearchHistory: `/${API_VERSION}/648d6db56078d`, // 获取搜索历史
getPromotionList: `/${API_VERSION}/648bb98977746`, // 获取促销列表
getPromotionDetail: `/${API_VERSION}/648bbb939cfbd`, // 获取促销详情
getFooterList: `/${API_VERSION}/636cabd662b22`, // 获取足迹/收藏
getScoreList: `/${API_VERSION}/649165fd2d3a7`,
getContributionList: `/${API_VERSION}/64916225e43d9`, // 获取积分列表
post64916daebef0c: `/${API_VERSION}/64916daebef0c`, // 获取抵用券详情
post648fb89315da5: `/${API_VERSION}/648fb89315da5`,
post648fb49f85c1c: `/${API_VERSION}/648fb49f85c1c`,
Get636c78ae2216b: `/${API_VERSION}/636c78ae2216b`,
post649175157d9de: `/${API_VERSION}/649175157d9de`,
post649b9700c9ff1: `/${API_VERSION}/649b9700c9ff1`,
post5f6db4db8abcf: `/${API_VERSION}/5f6db4db8abcf`,
post5f6c915d69d1f: `/${API_VERSION}/5f6c915d69d1f`,
post648bc370be940: `/${API_VERSION}/648bc370be940`,
post636caf10164ce: `/${API_VERSION}/636caf10164ce`,
post6483f11510991: `/${API_VERSION}/6483f11510991`,
post649baca5b33e8: `/${API_VERSION}/649baca5b33e8`,
post649a5059d4e18: `/${API_VERSION}/649a5059d4e18`,
post649e2989f16bd: `/${API_VERSION}/649e2989f16bd`, // 删除评价
shopCategorys: `/${API_VERSION}/6484441b0a326`,
authInfoSubmit: `/${API_VERSION}/648445ffb4866`, //提交审核
getAllCate: `/${API_VERSION}/649fc8e9a8127`, // 获取全部分类
getSendTime: `/${API_VERSION}/649bd02180fce`, // 获取配送时间
scanPay: `/${API_VERSION}/649f8f5546102`, // 扫码支付
wxPay: `/${API_VERSION}/62e335233b477`,
// wxPay: `/${API_VERSION}/670cf72bd30c1`,
aliPay: `/${API_VERSION}/62e342a23919c`,
getShopStatus: `/${API_VERSION}/648450b13a386`,
authInfoCheck: `/${API_VERSION}/648450b13a386`,
getDistanceList: `/${API_VERSION}/64a298d3c38f1`,
get6437c0cb9d5b4: `/${API_VERSION}/6437c0cb9d5b4`,
post5f6010f4df24a: `/${API_VERSION}/5f6010f4df24a`,
get6437c28c6c105: `/${API_VERSION}/6437c28c6c105`,
get6437c2a476843: `/${API_VERSION}/6437c2a476843`,
get6437c2dc0386c: `/${API_VERSION}/6437c2dc0386c`,
IMAuthenticate: `/${API_VERSION}/5fbb84a54d991`,
postForgetPassword: `/${API_VERSION}/5caeeba9866aa`,
post5f5ee8e86c27b: `/${API_VERSION}/5f5ee8e86c27b`,
post5f601350edaa4: `/${API_VERSION}/5f601350edaa4`,
postBuyAgain: `/${API_VERSION}/64a8d14ccbbea`,
postUserSocialLogin: `/${API_VERSION}/5d7660a421e69`,
postLoginByWechat: `/${API_VERSION}/5d7757d28d076`,
getLevel: `/${API_VERSION}/650a64a2b2c85`,
getIsSupportSend: `/${API_VERSION}/650a4737366d0`,
getPayCode: `/${API_VERSION}/66f1200287aaa`,
post6710d191613f2: `/${API_VERSION}/6710d191613f2`,
post67306fc87dbd7: `/${API_VERSION}/67306fc87dbd7`,
post67306ffb6ec75: `/${API_VERSION}/67306ffb6ec75`,
post673572b0bebd7: `/${API_VERSION}/673572b0bebd7`,
post6735bb9284e19: `/${API_VERSION}/6735bb9284e19`,
post6747c61bebd27: `/${API_VERSION}/6747c61bebd27`,
post637c458b131e3: `/${API_VERSION}/637c458b131e3`,
post636c78ae2216b: `/${API_VERSION}/636c78ae2216b`,
post637c4d70d3aa8: `/${API_VERSION}/637c4d70d3aa8`,
getRiderInfo: `/${API_VERSION}/674d6a65730f3`,
post6757f462c15d3: `/${API_VERSION}/6757f462c15d3`,
post674d6a65730f3: `/${API_VERSION}/674d6a65730f3`,
post67ac5d9302006: `/${API_VERSION}/67ac5d9302006`,
post67ac3a198d7bd: `/${API_VERSION}/67ac3a198d7bd`,
post67fe2ff7032c4: `/${API_VERSION}/67fe2ff7032c4`
}
const modulesFiles = require.context('../../pages/', true, /\api.js$/);
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1');
const value = modulesFiles(modulePath);
Object.assign(modules, value.default);
return modules;
}, publicApi);
export default modules;
/**
* 如果是第一套代码,删掉下面的对象即可
* 如果不是第一套代码,导出下面的对象即可
* 如果哪一套的代码都有,下面的对象合并到上面的对象即可
* */
const del = {}

16762
common/city.json Normal file

File diff suppressed because it is too large Load Diff

188
common/config.js Normal file
View File

@ -0,0 +1,188 @@
// export const dev_host = 'https://app.wanjiashangchao.com'; // 开发环境域名
export const dev_host = 'https://ltstore.stnav.com'; // 开发环境域名
export const mock_host = 'https://ltstore.stnav.com'; // MOCK环境域名
// export const mock_host = 'http://mock.zhongbenruanjian.com'; // MOCK环境域名
export const product_host = 'http://zbphp.zhongbenzx.com'; // 生产环境域名
export const WEBSOCKET = 'wss://zbphp.zhongbenzx.com/socket/';
export const PAAS_URL = 'https://yufabu.saizhuge.net'; // paas域名
export const IS_DEV = 1; // 0:生产环境 1:开发环境 2:mock环境 3:paas环境
export const SERVER_TYPE = 1; // 服务端类型 0:赛诸葛 1:java 其他待添加开发
export const PAGE_SIZE = 15; // 分页配置 每页条数
export const API_VERSION = 'm3576'; //APP接口版本号 正常是V1 使用天添客m加企业ID
let _host = ''
switch (IS_DEV) {
case 0:
_host = product_host
break;
case 1:
_host = dev_host
break;
case 2:
_host = mock_host
break;
case 3:
_host = PAAS_URL
break;
default:
break;
}
export const GAODE_KEY = '886bfe2d6c32bd8eac97c2e6d821ed0b'
export const host = _host; // 项目中接口地址host
export const UPLOAD_IMAGE_URL = `${host}/api/m3576/62ddf0e4eadde`
export const SHAREURL = host + '/h5/#/'; // 分享的H5地址
export const SERIAL = ''; // 项目序列号(千万千万千万不要修改!!!!)
export const BenBenChooseFileKey = ''; // 文件选择原生插件key
export const BASE_URL = `${host}`; // 基础路径
export const API_BASE_URL = `${host}/api`; // 接口请求基础路径
export const STATIC_URL = 'https://lvtai-files.oss-cn-beijing.aliyuncs.com/mini/'; // 静态资源目录
export const IMG_BASE_URL = `${host}/upload/`; // 图片基础路径 公共filters assembleImgSrc依赖此配置
export const HOME_PAGE_URL = ["/pages/tabBar/homePage/homePage"] // 配置首页路由 主要用于跳转首页
// tabBar配置
export const tabbarConfig = {
"roleTabBarShow": [
[0, 1, 2, 3, 4]
],
"listNum": 5
}
// 主题色配置
export const themeColorConfig = [{
"colorConfig": ["#333333", "#666666", "#999999", "#ffffff", "#1178F0", "#F02325", "#FC9C3A", "#4DC777", "#F2CC98",
"#F2CC66"
],
"bgColorConfig": ["#EBEDF8", "#FFFFFF", "#1178F0", "#FC9C3A", "#FC9ffff", "#E6F333", "#E6F1FE",
"linear-gradient(301deg, #EBBA7B 0%, #F8D9AD 100%)", "linear-gradient(180deg, #F5588E 0%, #F0403C 100%)",
"linear-gradient(179deg, #FFD033 0%, #F4890E 100%)"
],
"bdColorConfig": ["#EBEDF8", "#FFFFFF", "#1178F0", "#FC9C3A", "#333333", "#666666", "#999999", "#ffffff",
"#1178F0", "#F02325"
]
}]
// #ifdef APP-PLUS || H5
export const LOGIN_PAGE_URL = '/pages/tabBar/passwordLogin/passwordLogin' // 登录页面路由 request.js 依赖此配置 主要用于登录失效跳转
// #endif
// #ifdef MP-WEIXIN
export const LOGIN_PAGE_URL = '/pages/tabBar/passwordLogin/passwordLogin' // 登录页面路由 request.js 依赖此配置 主要用于登录失效跳转
// #endif
export const LANGUAGES = [{
title: '中文 (简体)',
type: 'zh',
default: true
}]; //语言包配置
let _platform = uni.getSystemInfoSync().platform;
// #ifdef APP-PLUS
_platform = _platform === 'android' ? 'Android' : 'IOS';
// #endif
// #ifdef H5
_platform = 'Web';
// #endif
// #ifdef MP-WEIXIN
_platform = 'Wechat';
// #endif
// #ifdef MP-ALIPAY
_platform = 'Alipay';
// #endif
// #ifdef MP-BAIDU
_platform = 'Baidu';
// #endif
// #ifdef MP-TOUTIAO
_platform = 'ByteBounce';
// #endif
// #ifdef MP-360
_platform = '360';
// #endif
// #ifdef QUICKAPP-WEBVIEW
_platform = 'FastApp';
// #endif
export const ACCEPT_PLATFORM = _platform; //所属平台
export const SYSTEM_CONFIG = { // 系统配置
logo: '/static/logo.png',
appName: '萬家商超',
appVersion: '1.0.8',
platform: _platform,
}
export const needProductUrl = [];
const needPageUrl = [
"/pages/dl/bindPhone/bindPhone", "/pages/xtsz/systemSettings/systemSettings",
"/pages/my/myFans/myFans", "/pages/my/revenueDetails/revenueDetails", "/pages/my/orderDetails/orderDetails",
"/pages/my/pointsDetails/pointsDetails", "/pages/my/detailsPage/detailsPage",
"/pages/my/contributionValue/contributionValue", "/pages/xtsz/declassifyPage/declassifyPage",
"/pages/xtsz/setNewpswd/setNewpswd", "/pages/xtsz/changeBindphone/changeBindphone",
"/pages/xtsz/bindNewphone/bindNewphone", "/pages/my/certificationAudit/certificationAudit",
"/pages/my/myProfile/myProfile", "/pages/hd/eventDetails/eventDetails", "/pages/my/myEvaluation/myEvaluation",
"/pages/my/addressManagement/addressManagement", "/pages/my/mapSite/mapSite",
"/pages/my/siteClassification/siteClassification", "/pages/xtsz/historicalFeedback/historicalFeedback",
"/pages/dd/orderDetails/orderDetails", "/pages/dd/orderReceiving/orderReceiving",
"/pages/sy/selectlocationAddress/selectlocationAddress", "/pages/sy/citySelection/citySelection",
"/pages/sy/searchPage/searchPage", "/pages/sy/searchResult/searchResult",
"/pages/sy/allLIstcategories/allLIstcategories",
"/pages/tabBar/nearbyMerchants/nearbyMerchants",
"/pages/dpxq/merchantQualification/merchantQualification", "/pages/dpxq/reportingMerchants/reportingMerchants",
"/pages/dpxq/settlementPage/settlementPage", "/pages/dpxq/addRemarks/addRemarks",
"/pages/dpxq/paymentResults/paymentResults",
"/pages/dpxq/searchWithin/searchWithin", "/pages/dpxq/searchResult/searchResult",
"/pages/dpxq/allEvaluations/allEvaluations", "/pages/dpxq/productList/productList",
"/pages/dpxq/productDetails/productDetails", "/pages/dpxq/storeResults/storeResults",
"/pages/dpxq/ImmediatEevaluation/ImmediatEevaluation", "/pages/dpxq/evaluateResults/evaluateResults"
];
const defNeedLoginPage = [
"/pages/user/address/address-list/index",
"/pages/user/address/address-add/index",
"/pages/index/setting/change-pay-password/index",
"/pages/index/setting/modify-pay-password/index",
"/pages/index/setting/change-password/index",
"/pages/service-mssage/message/message-list/index",
"/pages/user/user/info/index",
"/pages/user/user/avatar-cropping/index",
"/pages/index/setting/setting/index",
"/pages/index/setting/feedback/index",
"/pages/index/setting/my-feedback/index",
"/pages/index/setting/verify-oldphone/index",
"/pages/index/setting/change-newphone/index",
"/pages/user/wallet/my-wallet/index",
"/pages/user/wallet/consumer-detail/index",
"/pages/user/wallet/recharge/index",
"/pages/user/wallet/recharge-log/index",
"/pages/user/wallet/withdraw/index",
"/pages/user/wallet/withdraw-success/index",
"/pages/user/wallet/account-bind/index",
"/pages/user/wallet/alipay-bind/index",
"/pages/user/wallet/wechat-bind/index",
"/pages/user/user/my-favorites/index",
"/pages/user/user/my-footprint/index",
"/pages/order/afterorder/afterorder-apply/index",
"/pages/order/afterorder/afterorder-status-list/index",
"/pages/order/afterorder/afterorder-detail/index",
"/pages/order/afterorder/afterorder-sendback/index",
"/pages/order/order-process/confirm-order/index",
"/pages/order/order-process/pay-order/index",
"/pages/order/order-process/pay-success/index",
"/pages/order/order-process/choos_coupon/index",
"/pages/order/order-list/all-order/index",
"/pages/order/orderdetail/order-detail/index",
"/pages/order/orderdetail/express-delivery/index",
"/pages/order/evaluation/order-evaluation/index",
"/pages/news/article/article-favoriters/index",
"/pages/goods/ask-answer/my-ask-answer/index",
"/pages/service-message/message/message-type/index",
"/pages/user/coupon/my-coupon/index",
"/pages/integral/myintegral/my-integral/index",
"/pages/distribution/distribution/my-distribution/index",
"/pages/service-message/service/service-detail/index",
"/pages/user/invite/user-invite/index",
"/pages/index/setting/modify-password-verify-phone/index",
"/pages/index/setting/modify-password/index",
"/pages/my/myCollection/myCollection",
"/pages/my/myFotprint/myFotprint",
"/pages/xtsz/feedbackRecord/feedbackRecord",
"/pages/my/merchantSettlement/merchantSettlement",
"/pages/my/myMessage/myMessage",
"/pages/dpxq/storeDetails/storeDetails",
"/pages/xtsz/payCode/payCode"
]
let needLoginPage = defNeedLoginPage;
if (Array.isArray(needPageUrl)) {
needLoginPage = defNeedLoginPage.concat(needPageUrl);
}
export const needLoginPages = needLoginPage;

120
common/filter/index.js Normal file
View File

@ -0,0 +1,120 @@
import Vue from 'vue';
import Dayjs from '@/libs/day.js';
import store from '@/store/index.js';
import richText from '@/common/utils/richText.js';
// 格式化富文本内容
Vue.filter('richTextFormat', richText.format);
// 识别图片路径是否为全路径 若不是则进行拼接
Vue.filter('assembleImgSrc', src => {
src = src || ''
if (src.indexOf('http://') != -1 || src.indexOf('https://') != -1) {
return src
}
if (src.indexOf('/uploads/') != -1 || src.indexOf('/uploads/') != -1) {
return BASE_URL + src
} else {
return IMG_BASE_URL + src
}
});
// 日期格式转换
Vue.filter('formatDate', (date, format = 'YYYY-MM-DD HH:mm:ss') => {
return Dayjs(date).format(format)
});
// 格式化数字
Vue.filter('formatNumber', (number, tag = 'w') => {
number = Number(number);
if (number >= 10000) {
return (Math.floor(number / 1000) / 10).toFixed(1) + tag;
} else {
return number;
}
});
// 格式化角标数字
Vue.filter('formatTagNumber', number => {
if (number >= 100) {
return "99+";
} else {
return number;
}
});
// 过滤商品价格
Vue.filter('filterGoodsPrice', function (value, isActive) {
// console.log('filterGoodsPrice',value)
if (!value) return '';
let isMember = store.getters.isMember; // 是否是会员
let isActivity = value.activity_type == undefined || value.activity_type == 0 ? false : true; // 是否是活动
// 拼团时是点击单独购买value.isActive == false还是发起拼团value.isActive == true,单独购买就不属于活动了
if (value.isActive == false) {
isActivity = false;
// console.log('是否活动1', value.isActive);
}
// 过滤价格时若是传入第二参数isActive == false则说明页面显示正常商品价格就不属于活动了
if (isActive == false) {
isActivity = false;
// console.log('是否活动2', isActivity);
}
// console.log('是否会员',isMember);
// console.log('是否活动',isActivity);
// let member_activity_price = value.member_activity_price ? value.member_activity_price : value.activity_price; //会员活动价
let member_activity_price = value.activity_price; //活动不区分会员还是非会员
let activity_price = value.activity_price; // 活动价
let member_price = value.member_price ? value.member_price : value.shop_price; // 会员价
let shop_price = value.shop_price; // 售卖价
if (isActivity && isMember) {
// console.log("会员活动价",member_activity_price);
return member_activity_price;
} else if (isActivity && !isMember) {
// console.log("活动价",activity_price);
return activity_price;
} else if (!isActivity && isMember) {
// console.log("会员价",member_price);
return member_price;
} else if (!isActivity && !isMember) {
// console.log("普通价",shop_price);
return shop_price;
}
return '';
})
// 手机号脱敏
Vue.filter('filterMobile', function (val) {
if (!val) return "";
return val.substr(0, 3) + "****" + val.substr(-4);
})
/**
* @description 输出数字价格/小数点
* @param {String} name 要过滤的字符
* @param {Number} type 取值类型1=价格2=小数点
* @param {Number} textCount 小数点位数
* */
Vue.filter('formatPrice', function (name, type, textCount) {
let num, smore;
let data = name
textCount = textCount || 2
if (!data || isNaN(data)) {
num = data
smore = ''
} else {
let arr = Number(data).toFixed(textCount).split('.')
num = arr[0]
smore = arr[1]
}
if (type == 1) { //输出数字
return num
} else { //输出小数点
return smore
}
})
Vue.filter('frontPrice', function (val) {
let e = +val
if (isNaN(e)) return '0'
return e.toFixed(2).split('.')[0] + '.'
})
Vue.filter('laterPrice', function (val) {
let e = +val
if (isNaN(e)) return '.00'
return e.toFixed(2).split('.')[1]
})

185
common/mixin/biological.js Normal file
View File

@ -0,0 +1,185 @@
export default {
name: 'verifyAgain',
onShow() {
console.log('开始二次验证', '用户token==>', this.$store.state.userInfo.user_token, '是否需要==>', this.$store.state.gestureAgain)
// 获取当前页面的URL
this.currentURL = this.$mp.page.route;
// 只有再用户登录 且 需要二次验证 的情况下判断才有意义
if (this.$store.state.userInfo.user_token && this.$store.state.gestureAgain) {
console.log('开始判断设备...==>', uni.getSystemInfoSync().platform)
if (uni.getSystemInfoSync().platform == "ios") {
this.appleORan == 1;
this.getingSupport(1);
console.log('设备为ios')
} else if (uni.getSystemInfoSync().platform === "android") {
this.appleORan == 0;
this.getingSupport(0);
console.log('设备为安卓')
} else {
this.appleORan == 0;
this.getingSupport(0);
console.log('设备未知,默认为安卓')
}
}
},
destroyed() {
// this.$store.commit('setGestureAgain',true);
},
data() {
return {
appleORan: null, // 判断是苹果还是安卓(苹果:1;安卓:0;)
currentURL: null, // 获取当前页面的URL
}
},
methods: {
// 获取支持的生物监测
getingSupport(type) {
console.log('appleORan==3')
let that = this;
// #ifdef H5
that.goingHandPassward();
// #endif
// #ifndef H5
uni.checkIsSupportSoterAuthentication({
success(res) {
// console.log("获取支持的生物监测成功==>", res.supportMode.indexOf("facial") != -1,that.appleORan == 1);
// 如果支持人脸识别,就优先人脸识别,否则就去指纹识别(人脸识别还需要判断是否是ios设备如果不是直接指纹。)
if (res.supportMode.indexOf("facial") != -1 && type == 1) {
console.log('进入人脸识别')
that.examineFaceID();
} else if (res.supportMode.indexOf("fingerPrint") != -1) {
console.log('进入指纹识别')
that.examineFingetprint();
} else {
that.goingHandPassward();
}
},
fail(err) {
console.log("获取支持的生物监测失败==>", err);
that.goingHandPassward();
},
});
// #endif
},
// 手势密码入口
goingHandPassward() {
// 如果保存的有密码那就是解锁模式,如果没有那就是设置模式
if (this.$store.state.userInfo.hand_password == '') {
console.log('跳转到设置手势密码')
uni.showToast({
title: this.$t('请先设置你的密码'),
duration: 500,
icon: 'none'
});
this.$urouter.redirectTo({
url: '/pages/index/setting/gesturePassword',
params: {
"type": 2,
}
})
} else {
console.log('跳转到手势密码')
// 跳转到手势密码的页面时也到带上当前的页面路径
this.$urouter.redirectTo({
url: '/pages/index/setting/gesturePassword',
params: {
"type": 1,
"currentURL": this.currentURL
}
})
}
},
// 检查是否录入指纹
examineFingetprint() {
let that = this;
uni.checkIsSoterEnrolledInDevice({
checkAuthMode: "fingerPrint",
success(res) {
console.log("检查是否录入指纹==>", res);
// 如果没有录入指纹就跳转到设备的设置页面(不过应该用不到)
if (res.isEnrolled) {
that.startFingerprint();
}
},
fail(err) {
console.log(err);
},
});
},
// 检查是否录入faceID
examineFaceID() {
let that = this;
uni.checkIsSoterEnrolledInDevice({
checkAuthMode: "facial",
success(res) {
console.log("检查是否录入faceID", res);
// 检查是否录入人脸
if (res.isEnrolled) {
that.startFaceID();
}
},
fail(err) {
console.log(err);
},
});
},
// 开始指纹识别
startFingerprint() {
let that = this;
uni.startSoterAuthentication({
requestAuthModes: ["fingerPrint"],
challenge: this.$t("要携带的参数"),
authContent: this.$t("请用指纹解锁"),
success(res) {
that.$store.commit('setGestureAgain', false);
console.log("指纹识别成功==>", res);
// 如果识别成功就
uni.showToast({
title: this.$t("识别成功"),
duration: 500,
});
},
fail(err) {
console.log(err);
uni.showToast({
title: this.$t('验证失败'),
duration: 1000,
icon: 'none'
});
setTimeout(() => {
that.$urouter.navigateBack()
}, 1000)
},
});
},
// 开始人脸识别
startFaceID() {
let that = this;
uni.startSoterAuthentication({
requestAuthModes: ["facial"],
challenge: this.$t("要携带的参数"),
authContent: this.$t("请用FaceID解锁"),
success(res) {
console.log("人脸识别成功==>", res);
that.$store.commit('setGestureAgain', false);
// 如果识别成功就
uni.showToast({
title: this.$t("识别成功"),
duration: 500,
});
},
fail(err) {
console.log(err);
uni.showToast({
title: this.$t('验证失败'),
duration: 1000,
icon: 'none'
});
setTimeout(() => {
that.$urouter.navigateBack()
}, 1000)
},
});
},
},
};

183
common/mixin/calendar.js Normal file
View File

@ -0,0 +1,183 @@
export default {
data() {
return {
calendar: [], //日历数组
currentDate: [], //当前日期
time:'',//选中日期
start_time:'',//开始日期
end_time:'',//结束日期
}
},
onLoad() {
let currentDate = this.currentime();
this.currentDate = currentDate;
let currentYear = currentDate[0];
let currentMonth = currentDate[1] > 9 ? currentDate[1] : '0'+currentDate[1];
let currentDay = currentDate[2] > 9 ? currentDate[2] : '0'+currentDate[2];
// 足迹01页面日期筛选默认值
this.time = `${currentYear}-${currentMonth}-${currentDay}`;
// 足迹02页面日期筛选赋值 默认三个月
// 开始时间
if(currentDate[1] > 4){
let prevMonth = currentDate[1]-3 > 9 ? currentDate[1]-3 : '0'+(currentDate[1]-3) ;
let prevDay = currentDate[2] > 9 ? currentDate[2] : '0'+currentDate[2];
this.start_time = `${currentDate[0]}-${prevMonth}-${prevDay}`;
}else{
let prevYear = currentDate[0]-1;
let prevMonth = currentDate[1]-3 + 12 > 9 ? currentDate[1]-3 + 12 : '0'+(currentDate[1]-3 + 12) ;
let prevDay = currentDate[2] > 9 ? currentDate[2] : '0'+currentDate[2];
this.start_time = `${prevYear}-${prevMonth}-${prevDay}`;
}
// 结束时间
this.end_time = `${currentYear}-${currentMonth}-${currentDay}`;
// 日历赋值
this.calendar = this.getCalendar(currentDate[0], currentDate[1]);
},
methods: {
/**
* @description 获取当前时间函数
*/
currentime() {
var date = new Date();
var y = Number(date.getFullYear());
var m = Number(date.getMonth() + 1);
var d = Number(date.getDate());
return [y, m, d];
},
/**
* @author 邓东方
* @description 获取日历
* @param {String,Number} y 年
* @param {String,Number} m 月
* @param {String,Number} currentDay 当前日 传入了显示 当前日 active == true
*/
getCalendar(y, m) {
// 求解cy年cm月cd日是星期几,parseInt代表取整 d=1是去每个月第一天
var cc = parseInt(y / 100); //c
var cy = y - cc * 100; //y
var cm = m; //m
var cd = 1; //d
// 某年的1、2月要看作上一年的13、14月来计算比如2003年1月1日要看作2002年的13月1日来计算
if (m == 1 || m == 2) {
cc = parseInt((y - 1) / 100);
cy = y - 1 - cc * 100;
cm = 12 + m;
}
//w=y+[y/4]+[c/4]-2c+[26(m+1/10]+d-1
// var csum = y + [y / 4] + [c / 4] - 2c+[26(m + 1/10]+d-1;
var csum = cy + parseInt(cy / 4) + parseInt(cc / 4) - 2 * cc + parseInt(26 * (cm + 1) / 10) + cd - 1;
// 注意使用蔡勒公式时出现负数情况 fd 每月第一天星期几
if (csum < 0) {
var fd = parseInt((csum % 7 + 7) % 7);
} else {
var fd = parseInt(csum % 7);
}
// 上个月天数
var cond1 = y % 4 == 0; //条件1年份必须要能被4整除
var cond2 = y % 100 != 0; //条件2年份不能是整百数
var cond3 = y % 400 == 0; //条件3年份是400的倍数
//当条件1和条件2同时成立时就肯定是闰年所以条件1和条件2之间为“与”的关系。
//如果条件1和条件2不能同时成立但如果条件3能成立则仍然是闰年。所以条件3与前2项为“或”的关系。
//所以得出判断闰年的表达式:
var cond = cond1 && cond2 || cond3;
//判断当月有多少天
var allDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][m - 1];
if (cond && m == 2) {
allDays = 29;
}
//上个月是不是去年
let prevYear = y;
let prevMonth = m - 1;
if (m == 1) {
prevYear = y - 1;
prevMonth = 12;
}
let _prevMonth = prevMonth>9?prevMonth:'0'+prevMonth;
let _m = m>9?m:'0'+m;
//判断上个月天数
var prevDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][prevMonth - 1];
var arr = [];
//这里塞入上个月末尾日期
//day 日 active 是否选择 isNot 是不是这个月 formData 日期格式 isBg 是否加背景色(日期段筛选时使用)
for (let i = 1; i <= fd; i++) {
let prevDay = prevDays - fd + i;
let _prevDay = prevDay>9?prevDay:'0'+prevDay;
arr.push({
'day': prevDay,
'active': false,
'isNot': true,
'formData': prevYear + '-' + _prevMonth + '-' + _prevDay
})
}
//这里塞入正常这个月的日期
for (let i = 1; i <= allDays; i++) {
let _i = i>9?i:'0'+i;
arr.push({
'day': i,
'active': false,
'isNot': false,
'formData': y + '-' + _m + '-' + _i
})
}
//下个月是不是下一年
let nextYear = y;
let nextMonth = m + 1;
if (m == 12) {
nextYear = y + 1;
nextMonth = 1;
}
let _nextMonth = nextMonth>9?nextMonth:'0'+nextMonth;
//判断数组最后一排剩余几个位置塞入下个月日期
let takedie = arr.length % 7;
if (7 - takedie > 0 && 7 - takedie < 7) {
for (let i = 1; i <= 7 - takedie; i++) {
let _i = i>9?i:'0'+i;
arr.push({
'day': i,
'active': false,
'isNot': true,
'formData': nextYear + '-' + _nextMonth + '-' + _i
})
}
}
// 处理数组钩子
if(this.handleCalendarFn){
arr = this.handleCalendarFn(arr);
}
return arr;
},
/**
* @description 上月
*/
prevMonth() {
let currentDate = this.currentDate;
if (currentDate[1] - 1 == 0) {
currentDate = [currentDate[0] - 1, 12];
} else {
currentDate = [currentDate[0], currentDate[1] - 1];
}
this.currentDate = currentDate;
this.calendar = this.getCalendar(currentDate[0], currentDate[1]);
},
/**
* @description 下月
*/
nextMonth() {
let currentDate = this.currentDate;
if (currentDate[1] == 12) {
currentDate = [Number(currentDate[0]) + 1, 1];
} else {
currentDate = [Number(currentDate[0]), Number(currentDate[1]) + 1];
}
this.currentDate = currentDate;
this.calendar = this.getCalendar(currentDate[0], currentDate[1]);
}
}
}

49
common/mixin/floor.js Normal file
View File

@ -0,0 +1,49 @@
export default {
data(){
return {
scrollInfo:[], // 页码滚动初始化
scrollSize:1, // 滚动页码位置判断
}
},
// 监听滚动传值
onPageScroll(res) {
let _this = this
_this.type = 1
this.$emit('gunShowPage', res)
// console.log('页面正在滚动',res.scrollTop)
var pageIndex =null ;
// scrollSize 所处的高度在哪个哪个页码的下标下
// currentPage 当前页码
// 下滑页码改变时 记录页码增加时的高度,上拉页码改变时
if(this.currentPage > this.scrollSize){
this.scrollSize = this.currentPage
this.scrollInfo.push(res.scrollTop)
// console.log(this.scrollInfo)
}else if(this.currentPage < this.scrollSize){
this.scrollSize = this.currentPage
console.log(this.scrollInfo)
}
// 判断滚动条有历史记录的情况下 返回
if(this.scrollInfo[this.scrollSize-2] >res.scrollTop){
this.currentPage--
this.scrollSize = this.currentPage
}
// 判断滚动条在有历史记录的情况下 下滑
if(this.scrollInfo[this.currentPage-1] < res.scrollTop ){
this.currentPage++
this.scrollSize = this.currentPage
}
clearTimeout(this.timer)
this.timer = setTimeout(function () {
console.log('悬浮按钮状态切换', this.timer)
_this.type = 2
}, 800)
// console.log(this.model)
if (res.scrollTop > 50) {
this.isShow = true
} else {
this.isShow = false
}
}
}

294
common/mixin/index.js Normal file
View File

@ -0,0 +1,294 @@
import Vue from 'vue';
import { Router } from '@/common/utils/index.js';
import { needLoginPages, STATIC_URL, HOME_PAGE_URL, LOGIN_PAGE_URL, ACCEPT_PLATFORM, SYSTEM_CONFIG } from '@/common/config.js';
const router = new Router({ needLoginPages });
Vue.mixin({
data() { return { STATIC_URL: STATIC_URL, isPublish: false } },
computed: {
i18n() {
return this.$t('defVal');
},
},
methods: {
// #ifdef APP-PLUS
toJSON() { },
// #endif
getPublishStatus() {
this.$api.post(global.apiUrls.post673572b0bebd7, {app_version: SYSTEM_CONFIG.appVersion, type: ACCEPT_PLATFORM == 'IOS' ? 'ios' : 'android'}) .then(res => {
if (res.data.code == 1) {
this.isPublish = !res.data.data.is_listing;
}
})
},
// 页面抛出事件
benbenThrowPageEvent(event, data) {
uni.$emit(event, data)
},
//修改uniapi为promise类型
syncUniApi(apiName, params) {
return new Promise((resolve, reject) => {
uni[apiName]({
...params,
success: (res) => {
resolve(res)
},
fail: (err) => {
reject(err)
},
});
})
},
// 跳转首页
toHomeDiy() {
router.switchTab(HOME_PAGE_URL[global.appTabBarType]);
},
// 跳转登录页
toLoginDiy() {
router.navigateTo(LOGIN_PAGE_URL);
},
//微信支付
requestPaymentWx(data) {
return new Promise((resolve, reject) => {
uni.requestPayment({
provider: 'wxpay',
// #ifdef MP-WEIXIN
timeStamp: data.timeStamp,
nonceStr: data.nonceStr,
package: data.package,
signType: data.signType,
paySign: data.paySign,
// #endif
// #ifdef APP-PLUS
orderInfo: data,
// #endif
success: (e) => {
console.log('success', e)
if (e.errMsg == 'requestPayment:ok') {
resolve()
}
},
fail: (e) => {
// #ifdef APP-PLUS
let failMsg = 'requestPayment:fail canceled';
// #endif
// #ifndef APP-PLUS
let failMsg = 'requestPayment:fail cancel';
// #endif
if (e.errMsg == failMsg) {
this.$message.info(this.$t('取消支付'));
} else {
this.$message.info(this.$t("支付失败,请稍后重试"));
}
reject(e)
},
complete: () => {
}
});
})
},
// 支付宝支付
requestPaymentAli(data) {
return new Promise((resolve, reject) => {
uni.requestPayment({
provider: 'alipay',
orderInfo: data,
success: (e) => {
if (e.errMsg == 'requestPayment:ok') {
resolve()
}
},
fail: (e) => {
if (e.errMsg == 'requestPayment:fail canceled') {
this.$message.info(this.$t('取消支付'));
} else {
this.$message.info(this.$t("支付失败,请稍后重试"));
}
reject(e)
},
complete: () => {
}
})
})
},
// diy点击事件处理函数
handleEven(e, params) {
let dataset = e.currentTarget && e.currentTarget.dataset;
let type, data;
if (dataset) {
type = dataset.event_type
data = dataset.event_params
} else {
type = e
data = params
}
console.log('点击事件触发', dataset, type, data);
this.$util.handleAllFn(type, data);
},
// 设置自定义头部
setNavigationBarTitle(title) {
uni.setNavigationBarTitle({
title: title
})
},
// 点击复制
copyText(data) {
uni.setClipboardData({
data: data,
success: () => {
this.$message.success('复制成功')
}
});
},
// 点击打电话
callMobile(phoneNumber) {
let STORE_PERMISSION = uni.getStorageSync('PLATFORM_PERMISSION_PHONE') || false;
if (!STORE_PERMISSION && ACCEPT_PLATFORM == 'Android') {
this.$util.showModal({
title: '提示',
content: '萬家商超访问电话权限及功能用于联系平台,是否允许?',
confirmColor: "#FF2020",
// confirmText: this.i18n['允许'],
// cancelText:this.i18n["取消"],
success: (res) => {
if (res.confirm) {
uni.setStorageSync('PLATFORM_PERMISSION_PHONE', true)
this.$util.showModal({
title: '拨打电话给', content: phoneNumber + '', confirmText: '拨打', success: res => {
if (res.confirm) {
uni.makePhoneCall({
phoneNumber: phoneNumber,
});
}
},
})
}
},
});
return false;
}
this.$util.showModal({
title: '拨打电话给', content: phoneNumber + '', confirmText: '拨打', success: res => {
if (res.confirm) {
uni.makePhoneCall({
phoneNumber: phoneNumber,
});
}
},
})
},
// 判断是否多值是否成立
in_array(type, str) {
let arr = []
// str 是否为字符串
if (typeof str === 'string') arr = str.split(',')
// str 是否为数组
if (typeof str === 'object') arr = str
let index = -1
index = arr.findIndex(item => type == item)
console.log('index-------------', index);
if (index == -1) {
return false
}
return true
},
// 设置自定义底部
setTabBarItem() {
// uni.setTabBarItem({
// index: 0,
// text: global.i18n.t('首页'),
// })
// uni.setTabBarItem({
// index: 1,
// text: global.i18n.t('分类'),
// })
// uni.setTabBarItem({
// index: 2,
// text: global.i18n.t('购物车'),
// })
// uni.setTabBarItem({
// index: 3,
// text: global.i18n.t('我的'),
// })
},
// 页面跳转
handleJump(e) {
let target = e.currentTarget || e.target,
url = target.dataset.url || 'back',
type = target.dataset.type;
if (url == '' || url == '#') return;
switch (type) {
case 'SWITCH':
router.switchTab(url);
break;
case 'REDIRECT':
router.redirectTo(url);
break;
case 'RELAUNCH':
router.reLaunch(url);
break;
case 'BACK':
router.navigateBack();
break;
default:
router.navigateTo(url);
break;
}
},
// Diy页面跳转
handleJumpDiy(e) {
let target = e.currentTarget || e.target,
url = target.dataset.url || 'back',
type = target.dataset.type;
if (url == '' || url == '#') return;
switch (type) {
case 'switchTab':
router.switchTab(url);
break;
case 'redirectTo':
router.redirectTo(url);
break;
case 'reLaunch':
router.reLaunch(url);
break;
case 'navigateTo':
router.navigateTo(url);
break;
case 'back':
router.navigateBack(+url);
break;
default:
router.navigateTo(url);
break;
}
},
mixinToPlayVideo(src) {
let parm = encodeURIComponent(src)
router.navigateTo(`/pages/benben-built-in/playVideo/playVideo?src=${parm}`)
},
singleImagePreview(url) {
uni.previewImage({
current: url,
urls: [url]
});
},
multiImagePreview(url, images, field) {
let arr = []
if (field) {
images.map((item) => {
arr.push(item[field])
})
} else {
arr = images
}
uni.previewImage({
current: url,
urls: arr
});
}
}
})

View File

@ -0,0 +1,98 @@
export default {
data() {
return {
allowOnloadGetList: true, // 是否允许页面onload生命周期进入后立马执行getlist
minixPagingListsApi: '', // 接口地址
pageingListApiMethod: 'post', // 接口请求方法
pagingListPage: 1, // 分页
pagingListAllowLoadMore: true, // 允许加载更多
pagingListLoadedAll: false, // 已加载全部数据
pagingListNoListData: false, // 没有列表数据,
isOrder: false, // 订单页面
listData: [],
isLoadInit: false, // 初始化数据之后,若无数据再显示无数据图标
}
},
computed: {
listDataLength() {
return this.listData.length
}
},
// 下拉刷新
onPullDownRefresh() {
uni.stopPullDownRefresh();
if (this.allowOnloadGetList) {
this.pagingListToggle(() => {
// uni.stopPullDownRefresh();
});
} else {
// uni.stopPullDownRefresh();
}
},
onLoad() {
if (this.allowOnloadGetList) this.pagingListGetLists();
},
//上拉加载更多
onReachBottom() {
this.pagingListGetLists();
},
methods: {
// 列表切换
pagingListToggle(fn) {
this.pagingListPage = 1
this.pagingListAllowLoadMore = true
this.pagingListLoadedAll = false
this.pagingListNoListData = false
this.listData.splice(0, this.listData.length)
// this.listData = []
if (fn) this.pagingListGetLists(fn);
else this.pagingListGetLists();
},
// 获取列表数据
pagingListGetLists(fn) {
console.log(this.pagingListLoadedAll)
if (!this.pagingListAllowLoadMore || this.pagingListLoadedAll || this.pagingListNoListData) return;
this.pagingListAllowLoadMore = false;
let postData = {
page: this.pagingListPage,
pagesize: global.PAGE_SIZE,
list_rows: global.PAGE_SIZE
}
if (this.pagingListPostData) {
postData = Object.assign({}, postData, this.pagingListPostData());
}
this.isShowLoading = true
this.$api[this.pageingListApiMethod](this.minixPagingListsApi, postData).then(res => {
this.isShowLoading = false
if (res.data.code == 1) {
if (this.pagingListBeforeResponseData) res.data.data = this.pagingListBeforeResponseData(res);
let tempLists = res.data.data.data || res.data.data.list,
totalPage = res.data.data.last_page || 1
if (this.pagingListResponseData) tempLists = this.pagingListResponseData(tempLists);
this.listData.push(...tempLists);
this.pagingListAllowLoadMore = true;
if (this.pagingListPage >= totalPage) this.pagingListLoadedAll = true;
if (this.pagingListPage == 1 && this.listData.length == 0) this.pagingListNoListData = true;
this.pagingListPage = this.pagingListPage + 1;
} else {
this.pagingListAllowLoadMore = true;
this.pagingListLoadedAll = true;
if (this.pagingListPage == 1 && this.listData.length == 0) this.pagingListNoListData = true;
}
this.isLoadInit = true;
if (fn) fn();
}).catch(err => {
console.log(err);
this.isShowLoading = false
this.pagingListAllowLoadMore = true;
this.isLoadInit = true;
})
}
}
}

272
common/permission.js Normal file
View File

@ -0,0 +1,272 @@
/**
* 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启
*/
var isIos
// #ifdef APP-PLUS
isIos = (plus.os.name == "iOS")
// #endif
// 判断推送权限是否开启
function judgeIosPermissionPush() {
var result = false;
var UIApplication = plus.ios.import("UIApplication");
var app = UIApplication.sharedApplication();
var enabledTypes = 0;
if (app.currentUserNotificationSettings) {
var settings = app.currentUserNotificationSettings();
enabledTypes = settings.plusGetAttribute("types");
console.log("enabledTypes1:" + enabledTypes);
if (enabledTypes == 0) {
console.log("推送权限没有开启");
} else {
result = true;
console.log("已经开启推送功能!")
}
plus.ios.deleteObject(settings);
} else {
enabledTypes = app.enabledRemoteNotificationTypes();
if (enabledTypes == 0) {
console.log("推送权限没有开启!");
} else {
result = true;
console.log("已经开启推送功能!")
}
console.log("enabledTypes2:" + enabledTypes);
}
plus.ios.deleteObject(app);
plus.ios.deleteObject(UIApplication);
return result;
}
// 判断定位权限是否开启
function judgeIosPermissionLocation() {
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var status = cllocationManger.authorizationStatus();
result = (status != 2)
console.log("定位权限开启:" + result);
// 以下代码判断了手机设备的定位是否关闭,推荐另行使用方法 checkSystemEnableLocation
/* var enable = cllocationManger.locationServicesEnabled();
var status = cllocationManger.authorizationStatus();
console.log("enable:" + enable);
console.log("status:" + status);
if (enable && status != 2) {
result = true;
console.log("手机定位服务已开启且已授予定位权限");
} else {
console.log("手机系统的定位没有打开或未给予定位权限");
} */
plus.ios.deleteObject(cllocationManger);
return result;
}
// 判断麦克风权限是否开启
function judgeIosPermissionRecord() {
var result = false;
var avaudiosession = plus.ios.import("AVAudioSession");
var avaudio = avaudiosession.sharedInstance();
var permissionStatus = avaudio.recordPermission();
console.log("permissionStatus:" + permissionStatus);
if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
console.log("麦克风权限没有开启");
} else {
result = true;
console.log("麦克风权限已经开启");
}
plus.ios.deleteObject(avaudiosession);
return result;
}
// 判断相机权限是否开启
function judgeIosPermissionCamera() {
var result = false;
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
console.log("authStatus:" + authStatus);
if (authStatus == 3) {
result = true;
console.log("相机权限已经开启");
} else {
console.log("相机权限没有开启");
}
plus.ios.deleteObject(AVCaptureDevice);
return result;
}
// 判断相册权限是否开启
function judgeIosPermissionPhotoLibrary() {
var result = false;
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
var authStatus = PHPhotoLibrary.authorizationStatus();
console.log("authStatus:" + authStatus);
if (authStatus == 3) {
result = true;
console.log("相册权限已经开启");
} else {
console.log("相册权限没有开启");
}
plus.ios.deleteObject(PHPhotoLibrary);
return result;
}
// 判断通讯录权限是否开启
function judgeIosPermissionContact() {
var result = false;
var CNContactStore = plus.ios.import("CNContactStore");
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
if (cnAuthStatus == 3) {
result = true;
console.log("通讯录权限已经开启");
} else {
console.log("通讯录权限没有开启");
}
plus.ios.deleteObject(CNContactStore);
return result;
}
// 判断日历权限是否开启
function judgeIosPermissionCalendar() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
if (ekAuthStatus == 3) {
result = true;
console.log("日历权限已经开启");
} else {
console.log("日历权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
// 判断备忘录权限是否开启
function judgeIosPermissionMemo() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
if (ekAuthStatus == 3) {
result = true;
console.log("备忘录权限已经开启");
} else {
console.log("备忘录权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
// Android权限查询
function requestAndroidPermission(permissionID) {
return new Promise((resolve, reject) => {
plus.android.requestPermissions(
[permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
function(resultObj) {
var result = 0;
for (var i = 0; i < resultObj.granted.length; i++) {
var grantedPermission = resultObj.granted[i];
console.log('已获取的权限:' + grantedPermission);
result = 1
}
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
var deniedPresentPermission = resultObj.deniedPresent[i];
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
result = 0
}
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
var deniedAlwaysPermission = resultObj.deniedAlways[i];
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
result = -1
}
resolve(result);
// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
// if (result != 1) {
// gotoAppPermissionSetting()
// }
},
function(error) {
console.log('申请权限错误:' + error.code + " = " + error.message);
resolve({
code: error.code,
message: error.message
});
}
);
});
}
// 使用一个方法,根据参数判断权限
function judgeIosPermission(permissionID) {
if (permissionID == "location") {
return judgeIosPermissionLocation()
} else if (permissionID == "camera") {
return judgeIosPermissionCamera()
} else if (permissionID == "photoLibrary") {
return judgeIosPermissionPhotoLibrary()
} else if (permissionID == "record") {
return judgeIosPermissionRecord()
} else if (permissionID == "push") {
return judgeIosPermissionPush()
} else if (permissionID == "contact") {
return judgeIosPermissionContact()
} else if (permissionID == "calendar") {
return judgeIosPermissionCalendar()
} else if (permissionID == "memo") {
return judgeIosPermissionMemo()
}
return false;
}
// 跳转到**应用**的权限页面
function gotoAppPermissionSetting() {
if (isIos) {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
// var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
} else {
// console.log(plus.device.vendor);
var Intent = plus.android.importClass("android.content.Intent");
var Settings = plus.android.importClass("android.provider.Settings");
var Uri = plus.android.importClass("android.net.Uri");
var mainActivity = plus.android.runtimeMainActivity();
var intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
mainActivity.startActivity(intent);
}
}
// 检查系统的设备服务是否开启
// var checkSystemEnableLocation = async function () {
function checkSystemEnableLocation() {
if (isIos) {
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var result = cllocationManger.locationServicesEnabled();
console.log("系统定位开启:" + result);
plus.ios.deleteObject(cllocationManger);
return result;
} else {
var context = plus.android.importClass("android.content.Context");
var locationManager = plus.android.importClass("android.location.LocationManager");
var main = plus.android.runtimeMainActivity();
var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
var result = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER);
console.log("系统定位开启:" + result);
return result
}
}
module.exports = {
judgeIosPermission: judgeIosPermission,
requestAndroidPermission: requestAndroidPermission,
checkSystemEnableLocation: checkSystemEnableLocation,
gotoAppPermissionSetting: gotoAppPermissionSetting
}

849
common/utils/area-code.js Normal file
View File

@ -0,0 +1,849 @@
export default [{
"city": "中国大陆",
"code": "+86"
},
{
"city": "中国香港",
"code": "+852"
},
{
"city": "中国澳门",
"code": "+853"
},
{
"city": "中国台湾",
"code": "+886"
},
{
"city": "新加坡",
"code": "+65"
},
{
"city": "阿富汗",
"code": "+93"
},
{
"city": "阿尔巴尼亚",
"code": "+355"
},
{
"city": "阿尔格拉",
"code": "+213"
},
{
"city": "安道尔",
"code": "+376"
},
{
"city": "安哥拉",
"code": "+244"
},
{
"city": "安圭拉",
"code": "+1264"
},
{
"city": "阿森松岛",
"code": "+247"
},
{
"city": "安提瓜和巴布达",
"code": "+1268"
},
{
"city": "阿根廷",
"code": "+54"
},
{
"city": "亚美尼亚",
"code": "+374"
},
{
"city": "阿鲁巴",
"code": "+297"
},
{
"city": "澳大利亚",
"code": "+61"
},
{
"city": "奥地利",
"code": "+43"
},
{
"city": "阿塞拜疆",
"code": "+994"
},
{
"city": "巴哈马",
"code": "+1242"
},
{
"city": "巴林",
"code": "+973"
},
{
"city": "孟加拉国",
"code": "+880"
},
{
"city": "巴巴多斯",
"code": "+1246"
},
{
"city": "白俄罗斯",
"code": "+375"
},
{
"city": "比利时",
"code": "+32"
},
{
"city": "伯利兹",
"code": "+501"
},
{
"city": "贝宁",
"code": "+229"
},
{
"city": "百慕大",
"code": "+1441"
},
{
"city": "不丹",
"code": "+975"
},
{
"city": "玻利维亚",
"code": "+591"
},
{
"city": "波斯尼亚和黑塞哥维那",
"code": "+387"
},
{
"city": "博茨瓦纳",
"code": "+267"
},
{
"city": "巴西",
"code": "+55"
},
{
"city": "文莱",
"code": "+673"
},
{
"city": "保加利亚",
"code": "+359"
},
{
"city": "布基纳法索",
"code": "+226"
},
{
"city": "布隆迪",
"code": "+257"
},
{
"city": "柬埔寨",
"code": "+855"
},
{
"city": "喀麦隆",
"code": "+237"
},
{
"city": "加拿大",
"code": "+1"
},
{
"city": "佛得角",
"code": "+238"
},
{
"city": "开曼群岛",
"code": "+1345"
},
{
"city": "中非共和国",
"code": "+236"
},
{
"city": "乍得",
"code": "+235"
},
{
"city": "智利",
"code": "+56"
},
{
"city": "哥伦比亚",
"code": "+57"
},
{
"city": "科摩罗",
"code": "+269"
},
{
"city": "刚果共和国",
"code": "+242"
},
{
"city": "刚果民主共和国",
"code": "+243"
},
{
"city": "库克群岛",
"code": "+682"
},
{
"city": "哥斯达黎加",
"code": "+506"
},
{
"city": "科特迪沃",
"code": "+225"
},
{
"city": "克罗地亚",
"code": "+385"
},
{
"city": "古巴",
"code": "+53"
},
{
"city": "塞浦路斯",
"code": "+357"
},
{
"city": "+捷克共和国",
"code": "+420"
},
{
"city": "丹麦",
"code": "+45"
},
{
"city": "吉布提",
"code": "+253"
},
{
"city": "多米尼加",
"code": "+1767"
},
{
"city": "多米尼加共和国",
"code": "+1809"
},
{
"city": "厄瓜多尔",
"code": "+593"
},
{
"city": "埃及",
"code": "+20"
},
{
"city": "艾萨尔瓦多",
"code": "+503"
},
{
"city": "爱沙尼亚",
"code": "+372"
},
{
"city": "埃塞俄比亚",
"code": "+251"
},
{
"city": "法罗群岛",
"code": "+298"
},
{
"city": "斐济",
"code": "+679"
},
{
"city": "芬兰",
"code": "+358"
},
{
"city": "法国",
"code": "+33"
},
{
"city": "法属圭亚那",
"code": "+594"
},
{
"city": "法属波利尼西亚",
"code": "+689"
},
{
"city": "加蓬",
"code": "+241"
},
{
"city": "冈比亚",
"code": "+220"
},
{
"city": "格鲁吉亚",
"code": "+995"
},
{
"city": "德国",
"code": "+94"
},
{
"city": "加纳",
"code": "+233"
},
{
"city": "直布罗陀",
"code": "+350"
},
{
"city": "希腊",
"code": "+30"
},
{
"city": "格陵兰",
"code": "+299"
},
{
"city": "格林纳达",
"code": "+1473"
},
{
"city": "瓜德罗普",
"code": "+590"
},
{
"city": "关岛",
"code": "+1671"
},
{
"city": "危地马拉",
"code": "+502"
},
{
"city": "几内亚",
"code": "+240"
},
{
"city": "根西",
"code": "+44"
},
{
"city": "几内亚",
"code": "+224"
},
{
"city": "圭亚那",
"code": "+592"
},
{
"city": "海地",
"code": "+509"
},
{
"city": "洪都拉斯",
"code": "+504"
},
{
"city": "缅甸",
"code": "+95"
},
{
"city": "匈牙利",
"code": "+36"
},
{
"city": "冰岛",
"code": "+354"
},
{
"city": "印度",
"code": "+91"
},
{
"city": "印度尼西亚",
"code": "+62"
},
{
"city": "伊朗",
"code": "+98"
},
{
"city": "伊拉克",
"code": "+964"
},
{
"city": "爱尔兰",
"code": "+353"
},
{
"city": "马恩岛",
"code": "+44"
},
{
"city": "以色列",
"code": "+972"
},
{
"city": "意大利",
"code": "+93"
},
{
"city": "牙买加",
"code": "+1876"
},
{
"city": "日本",
"code": "+81"
},
{
"city": "泽西岛",
"code": "+44"
},
{
"city": "约旦",
"code": "+962"
},
{
"city": "哈萨克斯坦",
"code": "+7"
},
{
"city": "肯尼亚",
"code": "+254"
},
{
"city": "科索沃",
"code": "+383"
},
{
"city": "科威特",
"code": "+965"
},
{
"city": "吉尔吉斯斯坦",
"code": "+996"
},
{
"city": "老挝",
"code": "+856"
},
{
"city": "拉脱维亚",
"code": "+371"
},
{
"city": "黎巴嫩",
"code": "+961"
},
{
"city": "莱索托",
"code": "+266"
},
{
"city": "利比里亚",
"code": "+231"
},
{
"city": "利比亚",
"code": "+218"
},
{
"city": "列支敦士登",
"code": "+423"
},
{
"city": "立陶宛",
"code": "+370"
},
{
"city": "卢森堡",
"code": "+352"
},
{
"city": "马其顿",
"code": "+389"
},
{
"city": "马达加斯加",
"code": "+261"
},
{
"city": "马拉维",
"code": "+265"
},
{
"city": "马来西亚",
"code": "+60"
},
{
"city": "马尔代夫",
"code": "+960"
},
{
"city": "马里",
"code": "+223"
},
{
"city": "马耳他",
"code": "+356"
},
{
"city": "马提尼克",
"code": "+596"
},
{
"city": "毛里塔尼亚",
"code": "+222"
},
{
"city": "毛里求斯",
"code": "+230"
},
{
"city": "马约特",
"code": "+262"
},
{
"city": "墨西哥",
"code": "+52"
},
{
"city": "摩尔多瓦",
"code": "+373"
},
{
"city": "摩纳哥",
"code": "+377"
},
{
"city": "蒙古",
"code": "+976"
},
{
"city": "黑山",
"code": "+382"
},
{
"city": "蒙特塞拉特",
"code": "+1664"
},
{
"city": "摩洛哥",
"code": "+212"
},
{
"city": "莫桑比克",
"code": "+258"
},
{
"city": "纳米比亚",
"code": "+264"
},
{
"city": "尼泊尔",
"code": "+977"
},
{
"city": "荷兰",
"code": "+31"
},
{
"city": "荷属安的列斯",
"code": "+599"
},
{
"city": "新喀里多尼亚",
"code": "+687"
},
{
"city": "新西兰",
"code": "+64"
},
{
"city": "尼加拉瓜",
"code": "+505"
},
{
"city": "尼日尔",
"code": "+227"
},
{
"city": "尼日利亚",
"code": "+234"
},
{
"city": "挪威",
"code": "+47"
},
{
"city": "阿曼",
"code": "+968"
},
{
"city": "巴基斯坦",
"code": "+92"
},
{
"city": "巴勒斯坦",
"code": "+970"
},
{
"city": "巴拿马",
"code": "+507"
},
{
"city": "巴布亚新几内亚",
"code": "+675"
},
{
"city": "巴拉圭",
"code": "+595"
},
{
"city": "秘鲁",
"code": "+51"
},
{
"city": "菲律宾",
"code": "+63"
},
{
"city": "波兰",
"code": "+48"
},
{
"city": "葡萄牙",
"code": "+351"
},
{
"city": "波多黎各",
"code": "+1"
},
{
"city": "库塔",
"code": "+974"
},
{
"city": "留尼汪",
"code": "+262"
},
{
"city": "罗马尼亚",
"code": "+40"
},
{
"city": "俄罗斯",
"code": "+7"
},
{
"city": "卢旺达",
"code": "+250"
},
{
"city": "萨摩亚东部",
"code": "+684"
},
{
"city": "萨摩亚西部",
"code": "+685"
},
{
"city": "圣马力诺",
"code": "+378"
},
{
"city": "圣多美和普林西比",
"code": "+239"
},
{
"city": "沙特阿拉伯",
"code": "+966"
},
{
"city": "塞内加尔",
"code": "+221"
},
{
"city": "塞尔维亚",
"code": "+381"
},
{
"city": "塞舌尔",
"code": "+248"
},
{
"city": "塞拉利昂",
"code": "+232"
},
{
"city": "斯洛伐克",
"code": "+421"
},
{
"city": "斯洛文尼亚",
"code": "+386"
},
{
"city": "南非",
"code": "+27"
},
{
"city": "韩国",
"code": "+82"
},
{
"city": "西班牙",
"code": "+34"
},
{
"city": "斯里兰卡",
"code": "+94"
},
{
"city": "圣基茨和尼维斯",
"code": "+1869"
},
{
"city": "圣卢西亚",
"code": "+1758"
},
{
"city": "圣文森特",
"code": "+1784"
},
{
"city": "苏丹",
"code": "+249"
},
{
"city": "苏里南",
"code": "+597"
},
{
"city": "斯威士兰",
"code": "+268"
},
{
"city": "瑞典",
"code": "+46"
},
{
"city": "瑞士",
"code": "+41"
},
{
"city": "叙利亚",
"code": "+963"
},
{
"city": "塔吉克斯坦",
"code": "+992"
},
{
"city": "坦桑尼亚",
"code": "+255"
},
{
"city": "泰国",
"code": "+66"
},
{
"city": "东帝汶",
"code": "+670"
},
{
"city": "多哥",
"code": "+228"
},
{
"city": "汤加",
"code": "+676"
},
{
"city": "特立尼达和多巴哥",
"code": "+1868"
},
{
"city": "突尼斯",
"code": "+216"
},
{
"city": "土耳其",
"code": "+90"
},
{
"city": "土库曼斯坦",
"code": "+993"
},
{
"city": "特克斯和凯科斯群岛",
"code": "+1649"
},
{
"city": "乌干达",
"code": "+256"
},
{
"city": "乌克兰",
"code": "+380"
},
{
"city": "阿拉伯联合酋长国",
"code": "+971"
},
{
"city": "英国",
"code": "+44"
},
{
"city": "美国",
"code": "+1"
},
{
"city": "乌拉圭",
"code": "+598"
},
{
"city": "乌兹别克斯坦",
"code": "+998"
},
{
"city": "瓦努阿图",
"code": "+678"
},
{
"city": "委内瑞拉",
"code": "+58"
},
{
"city": "越南",
"code": "+84"
},
{
"city": "维尔京群岛",
"code": "+1340"
},
{
"city": "也门",
"code": "+967"
},
{
"city": "赞比亚",
"code": "+260"
},
{
"city": "津巴布韦",
"code": "+263"
}
]

54
common/utils/fs.js Normal file
View File

@ -0,0 +1,54 @@
// #ifdef APP-PLUS
// 获取文件内容
async function getFileContext(path, dirEntry) {
let deffered;
let fileReader = new plus.io.FileReader();
fileReader.onloadend = function(evt) {
deffered(evt.target.result);
}
let file = await getFile(path, dirEntry);
fileReader.readAsText(file, 'utf-8');
return new Promise((resolve) => {
deffered = resolve;
});
}
// 获取文件
async function getFile(fileName, dirEntry) {
return new Promise(async (resolve) => {
let fileEntry = await getFileEntry(fileName, dirEntry);
fileEntry.file(function(file) {
resolve(file);
});
})
}
// 获取文件
async function getFileEntry(fileName, dirEntry) {
return new Promise((resolve) => {
plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
let entry = dirEntry || fs.root;
entry.getFile(fileName, {
create: true
}, function(fileEntry) {
resolve(fileEntry);
});
});
})
}
// #endif
// #ifdef MP-WEIXIN
async function getFileContext(path, dirEntry) {
let FileSystemManager = wx.getFileSystemManager();
let content = FileSystemManager.readFileSync(path,'utf-8');
return content;
}
// #endif
function initI18n(){
return Promise.resolve();
}
export default {
getFileContext,
initI18n,
}

17
common/utils/index.js Normal file
View File

@ -0,0 +1,17 @@
import Router from './router.js'
import UploadImage from './upload-image.js'
import UploadFileToQINIU from './upload-file-to-qiniu.js'
import UploadFileToOSS from './upload-file-to-oss.js'
import { message } from './message.js'
import { validate } from './validate.js'
export {
message,
validate,
UploadImage,
UploadFileToQINIU,
UploadFileToOSS,
Router
}

60
common/utils/message.js Normal file
View File

@ -0,0 +1,60 @@
const message = {
success(params) {
if (typeof params !== 'object') params = {
content: params + ''
};
uni.showToast({
title: params.content || '',
icon: 'success',
duration: params.duration || 1500,
success: params.resolve
})
return true
},
error(params) {
if (typeof params !== 'object') params = {
content: params + ''
};
uni.showToast({
title: params.content,
icon: 'error',
duration: params.duration || 1500,
success: params.resolve
})
return true
},
info(params) {
if (typeof params !== 'object') params = {
content: params + ''
};
uni.showToast({
title: params.content || '',
icon: 'none',
// position: 'bottom',
duration: params.duration || 1500,
success: params.resolve
})
return true
},
tips(params) {
if (typeof params !== 'object') params = {
content: params + ''
};
uni.showToast({
title: params.content || '',
icon: 'none',
// position: 'bottom',
duration: params.duration || 1500,
success: params.resolve
})
return true
}
}
export {
message
};

View File

@ -0,0 +1,92 @@
function showView(permissions) {
// #ifdef APP-PLUS
const permissionTipsArr = [{
"keyName": "android.permission.INTERNET",
"title": '使用网络权限',
"content": '与服务器进行数据交换,如同步用户数据、获取最新信息等'
}, {
"keyName": "android.permission.READ_EXTERNAL_STORAGE",
"title": '读写SD卡权限',
"content": '访问用户的媒体库,如照片相册等'
}, {
"keyName": "android.permission.WRITE_EXTERNAL_STORAGE",
"title": '读写SD卡权限',
"content": '访问用户的媒体库,如照片相册等'
}, {
"keyName": "android.permission.READ_PHONE_STATE",
"title": '读取设备标识权限',
"content": '根据设备特征提供定制化的用户体验'
}, {
"keyName": "android.permission.CAMERA",
"title": '拍照权限',
"content": '请求相机权限,使用相机,用于扫描二维码或者上传图片'
}, {
"keyName": "android.permission.ACCESS_COARSE_LOCATION",
"title": '定位权限',
"content": '根据用户位置提供附近的商家、餐厅等信息'
}, {
"keyName": "android.permission.ACCESS_FINE_LOCATION",
"title": '定位权限',
"content": '根据用户位置提供附近的商家、餐厅等信息'
},{
"keyName": "android.permission.CALL_PHONE",
"title": '拨打电话权限',
"content": '请求拨打电话权限,用于联系商家或者平台'
}]
const permissionTips = Array.isArray(permissionTipsArr) ? permissionTipsArr.reduce((accumulator, {
keyName,
title,
content,
}) => {
accumulator[keyName] =
`<div class='tips-item'><div class='title'>${title}</div><div class='center'>${content}</div></div>`;
return accumulator;
}, {}) : {};
let tips = ''
permissions.map(key => {
if (permissionTips[key]) {
tips += permissionTips[key]
} else {
console.log(key + '未配置提示语');
}
})
if (!tips) return null
const systemInfo = uni.getSystemInfoSync()
let wvPath = '/static/permissionTips.html'
let wv = new plus.webview.create(
wvPath, 'permissionTips', {
'uni-app': 'none',
top: systemInfo.statusBarHeight,
left: 0,
width: systemInfo.screenWidth,
height: systemInfo.screenHeight - systemInfo.statusBarHeight,
background: 'transparent',
}, {
tips,
}
)
wv.show()
return wv
// #endif
return null
}
export function permissionListener() {
// showView(["android.permission.CAMERA", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.READ_PHONE_STATE", "android.permission.READ_EXTERNAL_STORAGE"])
let view = null
let createRequestPermissionListener = uni.createRequestPermissionListener();
createRequestPermissionListener.onRequest((e) => {
console.log('onRequest', e);
});
createRequestPermissionListener.onConfirm((e) => {
console.log('onConfirm', e);
if (view && view.close) view.close()
if (view && view.destroy) view.destroy()
view = showView(e)
});
createRequestPermissionListener.onComplete((e) => {
if (view && view.close) view.close()
if (view && view.destroy) view.destroy()
view = null
console.log('onComplete', e);
});
}

77
common/utils/richText.js Normal file
View File

@ -0,0 +1,77 @@
/*
graceUI rich-text 加强工具
link : graceui.hcoder.net
author : 5213606@qq.com 深海
版权声明 :
GraceUI 的版权约束是不能转售或者将 GraceUI 直接发布到公开渠道!
侵权必究,请遵守版权约定!
*/
// 正则变量
var graceRichTextReg;
// 批量替换的样式 [ 根据项目需求自行设置 ]
var GRT = [
// div 样式
['div', "line-height:2em;width:auto;height:auto;"],
// h1 样式
['h1', "font-size:3em; line-height:1.5em;"],
// h2 样式
['h2', "font-size:2em; line-height:1.8em;"],
// h3 样式
['h3', "font-size:1.6em; line-height:2em;"],
// h4 样式
['h4', "font-size:1.2em; line-height:2em;"],
// h5 样式
['h5', "font-size:1em; line-height:2em;"],
// h6 样式
['h6', "font-size:0.9em; line-height:2em;"],
// p 样式
['p', "font-size:1em; line-height:2em;"],
// b 样式
['b', "font-size:1em; line-height:2em;"],
// strong 样式
['strong', "font-size:1em; line-height:2em;"],
// code 样式
['code', "font-size:1em; line-height:1.2em; background:#F6F7F8; padding:8px 2%; width:96%;"],
// img 样式
['img', "width:100%; display: block;"],
// blockquote
['blockquote', "font-size:1em; border-left:3px solid #D1D1D1; line-height:2em; border-radius:5px; background:#F6F7F8; padding:8px 2%;"],
// li 样式
['ul', "padding:5px 0; list-style:none; padding:0; margin:0;"],
['li', "line-height:1.5em; padding:5px 0; list-style:none; padding:0; margin:0; margin-top:10px;"],
// table
['table', "width:100%; border-left:1px solid #F2F3F4; border-top:1px solid #F2F3F4;"],
['th', "border-right:1px solid #F2F3F4; border-bottom:1px solid #F2F3F4;"],
['td', "border-right:1px solid #F2F3F4; border-bottom:1px solid #F2F3F4; padding-left:5px;"]
];
export default {
format: function (html) {
html = html.replace(/<pre.*pre>?/gis, function (word) {
word = word.replace(/[\n]/gi, '<br />');
word = word.replace(/ /gi, '<span style="padding-left:2em;"></span>');
return word.replace(/[\t]/gi, '<span style="padding-left:2em;"></span>');
});
html = html.replace(/<pre/gi, '<p style="font-size:1em; margin:12px 0; line-height:1.2em; background:#F6F7F8; border-radius:5px; padding:8px 4%; width:92%;"');
html = html.replace(/<\/pre/gi, "</p");
for (let i = 0; i < GRT.length; i++) {
graceRichTextReg = new RegExp('<' + GRT[i][0] + '>|<' + GRT[i][0] + ' (.*?)>', 'gi');
html = html.replace(graceRichTextReg, function (word) {
// 分析 dom 上是否带有 style=""
if (word.indexOf('style=') != -1) {
var regIn = new RegExp('<' + GRT[i][0] + '(.*?)style="(.*?)"(.*?)(/?)>', 'gi');
return word.replace(regIn, '<' + GRT[i][0] + '$1style="$2 ' + GRT[i][1] + '"$3$4>');
} else {
var regIn = new RegExp('<' + GRT[i][0] + '(.*?)(/?)>', 'gi');
return word.replace(regIn, '<' + GRT[i][0] + '$1 style="' + GRT[i][1] + '$2">');
}
});
}
return html;
}
}

74
common/utils/router.js Normal file
View File

@ -0,0 +1,74 @@
import { LOGIN_PAGE_URL } from '../config.js'
export default class Router {
needLoginPages = []
constructor(options) {
if (options) this.needLoginPages = options.needLoginPages || [];
}
splicingUrl(res) {
return typeof res === 'string' ? res : res.params ? res.url + '?' + Object.keys(res.params).map(item =>
`${item}=${res.params[item]}`).join('&') : res.url;
}
testingNeedLogin(url) {
return this.needLoginPages.findIndex(item => item == url || url.startsWith(item)) != -1
}
getNeedLoginPages() {
return this.needLoginPages
}
switchTab(url) {
url = this.splicingUrl(url)
if (this.testingNeedLogin(url)) {
if (global.token) {
uni.switchTab({
url
});
} else {
uni.navigateTo({
url: LOGIN_PAGE_URL
})
}
return false;
}
uni.switchTab({
url
});
}
redirectTo(url) {
url = this.splicingUrl(url)
if (this.testingNeedLogin(url)) {
uni.redirectTo({
url: global.token ? url : LOGIN_PAGE_URL
});
return false;
}
uni.redirectTo({
url
});
}
reLaunch(url) {
uni.reLaunch({
url
});
}
navigateBack(num) {
uni.navigateBack({ delta: num || 1 });
}
navigateTo(url) {
url = this.splicingUrl(url)
console.log(url)
if (this.testingNeedLogin(url)) {
uni.navigateTo({
url: global.token ? url : LOGIN_PAGE_URL
});
return false;
}
uni.navigateTo({
url
});
}
}

View File

@ -0,0 +1,70 @@
import { message } from './message.js'
import { http } from '@/common/api/index.js';
export default class UploadFileToOSS {
/**
* [constructor description]
* @param {[Array]} files [chooseImg选中的tempFilePaths、chooseVideo选中的rempFilePath]
* @param {[Object]} json [success每上传成功一张调用 complete全部上传完成调用]
* @return {[void]} [description]
*/
constructor(files, json) {
if (!Array.isArray(files)) {
throw new Error('Class UploadFileToOSS parameter must be an array');
}
this.data = [];
this.fn = json.success;
this.complete = json.complete;
this.files = files;
this.fileLen = this.files.length;
this.curIndex = 0;
uni.showLoading({
title: global.i18n.t('上传中')
});
this.upload();
}
upload() {
http.get(global.apiUrls.queryAutograph).then(res => {
if (res.data.code == 1) {
let ossData = res.data.data;
uni.uploadFile({
url: ossData.host,
filePath: this.files[this.curIndex],
name: 'file',
formData: {
key: ossData.key, // 文件名
policy: ossData.policy, // 后台获取超时时间
OSSAccessKeyId: ossData.OSSAccessKeyId, // 后台获取临时ID
success_action_status: ossData.success_action_status, // 让服务端返回200,不然默认会返回204
signature: ossData.signature // 后台获取签名
},
success: res => {
console.log(res);
if (res.statusCode == 200) {
this.data.push({
id: ossData.key,
path: ossData.host + '/' + ossData.key
});
if (this.fn) this.fn(this.data);
} else {
message.info(global.i18n.t('上传失败,请重试'))
}
},
complete: () => {
this.curIndex++; // 当前文件执行完上传后,开始上传下一张
if (this.curIndex == this.fileLen) { // 当文件传完时,停止调用
this.complete(this.data);
uni.hideLoading()
} else { // 若文件还没有传完,则继续调用函数
this.upload();
}
}
});
}
})
}
}

View File

@ -0,0 +1,70 @@
import { message } from './message.js'
import { http } from '@/common/api/index.js';
export default class UploadFileToQINIU {
/**
* [constructor description]
* @param {[Array]} files [chooseImg选中的tempFilePaths、chooseVideo选中的rempFilePath]
* @param {[Object]} json [success每上传成功一张调用 complete全部上传完成调用]
* @return {[void]} [description]
*/
constructor(files, json) {
if (!Array.isArray(files)) {
throw new Error('Class UploadFileToQINIU parameter must be an array');
}
this.data = [];
this.fn = json.success;
this.complete = json.complete;
this.files = files;
this.fileLen = this.files.length;
this.curIndex = 0;
uni.showLoading({
title: global.i18n.t('上传中')
});
this.upload();
}
upload() {
http.post(global.apiUrls.postQINIUToken).then(res => {
console.log(res)
if (res.data.code == 1) {
let ossData = res.data.data;
uni.uploadFile({
url: 'https://up-z2.qiniup.com', // 七牛云资源存储地区 默认华南地区
filePath: this.files[this.curIndex],
name: 'file',
formData: {
key: ossData.fileName, // 文件名
token: ossData.token, // token
},
success: res => {
console.log(res);
if (res.statusCode == 200) {
let videoInfo = JSON.parse(res.data)
console.log(videoInfo)
this.data.push({
id: videoInfo.key,
path: ossData.baseUrl + videoInfo.key,
cover: ossData.baseUrl + videoInfo.key + '?vframe/jpg/offset/0'
});
if (this.fn) this.fn(this.data);
} else {
message.info(global.i18n.t('视频上传失败,请重试'))
}
},
complete: () => {
this.curIndex++; // 当前文件执行完上传后,开始上传下一张
if (this.curIndex == this.fileLen) { // 当文件传完时,停止调用
this.complete(this.data);
uni.hideLoading()
} else { // 若文件还没有传完,则继续调用函数
this.upload();
}
}
});
}
})
}
}

View File

@ -0,0 +1,65 @@
import { UPLOAD_IMAGE_URL,SERIAL } from '../config.js'
import { message } from './message.js'
export default class UploadImg {
/**
* [constructor description]
* @param {[Array]} files [chooseImg选中的tempFilePaths]
* @param {[Object]} json [success每上传成功一张调用 complete全部上传完成调用]
* @return {[void]} [description]
*/
constructor(files, json) {
if (!Array.isArray(files)) {
throw new Error('Class UploadImg parameter must be an array');
}
let _this = this;
_this.data = [];
_this.fn = json.success;
_this.complete = json.complete;
_this.files = files;
_this.fileLen = _this.files.length;
_this.curIndex = 0;
uni.showLoading({
title: global.i18n['上传中'],
mask: true
});
_this.upload();
}
upload() {
let _this = this;
uni.uploadFile({
url: UPLOAD_IMAGE_URL,
filePath: this.files[this.curIndex],
name: 'file',
header: {
'user-token': global.token || '',
'Accept-Language': global.locale,
'Accept-Serial': SERIAL,
},
formData: {
'module': '',
'dir': ''
},
success: res => {
let data = JSON.parse(res.data);
if (data.code == 1) {
console.log("返回结果",data);
this.data.push(data.data[0]);
if (this.fn) this.fn(this.data);
} else {
message.info(global.i18n['图片上传失败,请重试'])
}
},
complete: () => {
this.curIndex++; // 这个图片执行完上传后,开始上传下一张
if (this.curIndex == this.fileLen) { // 当图片传完时,停止调用
this.complete(this.data);
uni.hideLoading()
} else { // 若图片还没有传完,则继续调用函数
this.upload();
}
}
});
}
}

View File

@ -0,0 +1,258 @@
import {
message
} from './message.js'
import { host, SERIAL, API_VERSION, SERVER_TYPE } from '../config.js'
import {
http
} from '@/common/api/index.js';
import dayjs from '@/libs/day.js'
const getUUID = () => {
const S4 = () => ((((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1))
return (S4() + S4() + '' + S4() + '' + S4() + '' + S4() + '' + S4() + S4() + S4()) + new Date().getTime()
}
// 获取文件后缀名
const getSuffix = (fileName) => {
let pos = fileName.lastIndexOf('.')
return pos != -1 ? fileName.substring(pos) : ''
}
/* 判断url路径处理 */
function posUrl(url) {
let newUrl = ''
if (/(http|https):\/\/([\w.]+\/?)\S*/.test(url)) {
newUrl = url
} else {
newUrl = `${host}/api/${url}`
}
return newUrl
}
// 赛诸葛上传
class SaiZhuGeUploadFiles {
/**
* [constructor description]
* @param {[Array]} files [chooseImg选中的tempFilePaths、chooseVideo选中的rempFilePath]
* @param {[Object]} json [success每上传成功一张调用 complete全部上传完成调用]
* @return {[void]} [description]
*/
constructor(files, json) {
if (!Array.isArray(files)) {
throw new Error('Class UploadFileToOSS parameter must be an array');
}
this.data = [];
this.fn = json.success;
this.complete = json.complete;
this.files = files;
this.fileLen = this.files.length;
this.curIndex = 0;
this.resData = false;
uni.showLoading({
title: '加载中',
mask: true
})
if (!this.resData) this.getUploadConfig()
}
async getUploadConfig() {
try {
let { data: { code, msg, data } } = await http.post(global.apiUrls.queryAutograph, { member_id: API_VERSION.replace(/\D/g, "") })
if (code != 1) {
uni.hideLoading()
message.info(msg)
return
}
this.resData = data
this.uploadFile()
} catch (error) {
uni.hideLoading()
message.info(msg)
}
}
uploadFile() {
let resData = this.resData
const fileInfo = this.files[this.curIndex]
let allowUploadFile = this.uploadVerification(fileInfo, resData.is_public, +resData.size)
if (allowUploadFile !== true) {
uni.hideLoading()
return message.info('文件超出大小限制')
}
// deploy 1 本地服务器上传 否则 上传至oss
if (resData.deploy == 1) this.uploadFileToLocal(resData)
else this.uploadFileToOSS(resData)
}
// oss 上传验证
uploadVerification(file, isPublic = 1, size = 2048) {
const fileName = file.name
let isSizt = isPublic === 1 ? file.size / 1024 < size : true
if (!isSizt) return false
return true
}
// 本地上传
uploadFileToLocal(resData) {
let fileInfo = this.files[this.curIndex]
uni.uploadFile({
url: posUrl(global.apiUrls.UPLOAD_IMAGE_URL),
filePath: fileInfo.path,
name: 'file',
// #ifdef MP-DINGTALK
fileType: "image",
// #endif
header: {
'user-token': global.token || '',
'Accept-Language': global.locale,
'Accept-Serial': SERIAL,
},
formData: {
'module': '',
'dir': resData.dir || ''
},
success: res => {
let data = JSON.parse(res.data);
if (data.code == 1) {
this.data.push({ name: fileInfo.name, ...data.data[0] });
if (this.fn) this.fn(this.data);
} else {
message.info('上传失败,请重试')
}
},
complete: () => {
this.curIndex++; // 这个图片执行完上传后,开始上传下一张
if (this.curIndex >= this.fileLen) { // 当图片传完时,停止调用
this.complete(this.data);
uni.hideLoading()
} else { // 若图片还没有传完,则继续调用函数
this.uploadFile();
}
}
});
}
// oss上传
uploadFileToOSS(ossData) {
const fileInfo = this.files[this.curIndex]
let joint = getUUID()
let fileName = `${joint}${getSuffix(fileInfo.name ?? fileInfo.path)}`
let filePath = `${ossData.dir}${dayjs(new Date()).format('YYYY-MM-DD')}/${fileName}`
let fileNetworkPath = `${ossData.host}/${filePath}`
uni.uploadFile({
url: ossData.host,
filePath: fileInfo.path,
// #ifdef MP-DINGTALK
fileType: "image",
// #endif
name: 'file',
formData: {
key: filePath, // 文件名
policy: ossData.policy, // 后台获取超时时间
OSSAccessKeyId: ossData.accessid, // 后台获取临时ID
success_action_status: 200, // 让服务端返回200,不然默认会返回204
signature: ossData.signature // 后台获取签名
},
success: res => {
console.log(res);
if (res.statusCode == 200) {
this.data.push({
id: fileNetworkPath,
name: fileInfo.name || fileName,
path: fileNetworkPath,
thumb: fileNetworkPath + '?x-oss-process=video/snapshot,t_1000,m_fast',
})
if (this.fn) this.fn(this.data);
} else {
message.info('上传失败,请重试')
}
},
fail(err) {
console.log(err);
},
complete: () => {
this.curIndex++; // 当前文件执行完上传后,开始上传下一张
if (this.curIndex >= this.fileLen) { // 当文件传完时,停止调用
this.complete(this.data);
uni.hideLoading()
} else { // 若文件还没有传完,则继续调用函数
this.uploadFile();
}
}
})
}
}
// 普通上传
class OrdinaryUploadFiles {
/**
* [constructor description]
* @param {[Array]} files [chooseImg选中的tempFilePaths]
* @param {[Object]} json [success每上传成功一张调用 complete全部上传完成调用]
* @return {[void]} [description]
*/
constructor(files, json) {
if (!Array.isArray(files)) {
throw new Error('Class UploadImg parameter must be an array');
}
let _this = this;
_this.data = [];
_this.fn = json.success;
_this.url = json.url ? host + '/api' + json.url : host + '/api' + global.apiUrls.UPLOAD_IMAGE_URL;
_this.complete = json.complete;
_this.files = files;
_this.formData = json.formData || {};
_this.fileLen = _this.files.length;
_this.curIndex = 0;
uni.showLoading({
// title: '上传中'
title: global.i18n.t('上传中')
});
_this.upload();
}
upload() {
uni.uploadFile({
url: this.url,
filePath: this.files[this.curIndex].path,
name: 'file',
header: {
'user-token': global.token || '',
'Accept-Language': global.locale,
'Accept-Serial': SERIAL,
},
formData: {
'module': '',
'dir': '',
...this.formData
},
success: res => {
let data = JSON.parse(res.data);
if (data.code == 1) {
let file = Array.isArray(data.data) ? data.data[0] : data.data
file.thumb = file.path + '?x-oss-process=video/snapshot,t_1000,m_fast'
this.data.push(file);
if (this.fn) this.fn(this.data);
} else {
message.info(global.i18n.t('上传失败,请重试'))
}
},
complete: () => {
this.curIndex++; // 这个图片执行完上传后,开始上传下一张
if (this.curIndex >= this.fileLen) { // 当图片传完时,停止调用
this.complete(this.data);
uni.hideLoading()
} else { // 若图片还没有传完,则继续调用函数
this.upload();
}
}
});
}
}
let UploadFiles = null
switch (SERVER_TYPE) {
case 0://赛诸葛
UploadFiles = SaiZhuGeUploadFiles
break;
case 1://java
UploadFiles = OrdinaryUploadFiles
break;
default:
UploadFiles = OrdinaryUploadFiles
break;
}
export default UploadFiles

640
common/utils/utils.js Normal file
View File

@ -0,0 +1,640 @@
import { LOGIN_PAGE_URL, needLoginPages } from '../config.js';
import { Router } from '@/common/utils/index.js';
/**
* 节流原理:在一定时间内,只能触发一次
*
* @param {Function} func 要执行的回调函数
* @param {Number} wait 延时的时间
* @param {Boolean} immediate 是否立即执行
* @return null
*/
let throttleTimer, throttleFlag;
export function throttle(func, wait = 500, immediate = true) {
if (immediate) {
if (!throttleFlag) {
throttleFlag = true;
// 如果是立即执行则在wait毫秒内开始时执行
typeof func === 'function' && func();
throttleTimer = setTimeout(() => {
throttleFlag = false;
}, wait);
}
} else {
if (!throttleFlag) {
throttleFlag = true
// 如果是非立即执行则在wait毫秒内的结束处执行
throttleTimer = setTimeout(() => {
throttleFlag = false
typeof func === 'function' && func();
}, wait);
}
}
};
/**
* 时间戳转为多久之前
* @param String timestamp 时间戳
* @param String | Boolean format 如果为时间格式字符串,超出一定时间范围,返回固定的时间格式;
* 如果为布尔值false无论什么时间都返回多久以前的格式
*/
export function timeFrom(timestamp = null, format = 'yyyy-mm-dd') {
if (timestamp == null) timestamp = Number(new Date());
timestamp = parseInt(timestamp);
// 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
if (timestamp.toString().length == 10) timestamp *= 1000;
var timer = (new Date()).getTime() - timestamp;
timer = parseInt(timer / 1000);
// 如果小于5分钟,则返回"刚刚",其他以此类推
let tips = '';
switch (true) {
case timer < 300:
tips = global.i18n.t('刚刚');
break;
case timer >= 300 && timer < 3600:
tips = parseInt(timer / 60) + global.i18n.t('分钟前');
break;
case timer >= 3600 && timer < 86400:
tips = parseInt(timer / 3600) + global.i18n.t('小时前');
break;
case timer >= 86400 && timer < 2592000:
tips = parseInt(timer / 86400) + global.i18n.t('天前');
break;
default:
// 如果format为false则无论什么时间戳都显示xx之前
if (format === false) {
if (timer >= 2592000 && timer < 365 * 86400) {
tips = parseInt(timer / (86400 * 30)) + global.i18n.t('个月前');
} else {
tips = parseInt(timer / (86400 * 365)) + global.i18n.t('年前');
}
} else {
tips = timeFormat(timestamp, format);
}
}
return tips;
}
// 判断arr是否为一个数组返回一个bool值
export function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
}
// 深度克隆
export function deepClone(obj) {
// 对常见的“非”值,直接返回原来值
if ([null, undefined, NaN, false].includes(obj)) return obj;
if (typeof obj !== "object" && typeof obj !== 'function') {
//原始类型直接返回
return obj;
}
var o = isArray(obj) ? [] : {};
for (let i in obj) {
if (obj.hasOwnProperty(i)) {
o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
}
}
return o;
}
export function timeFormat(timestamp = null, fmt = 'yyyy-mm-dd') {
// padStart 的 polyfill因为某些机型或情况还无法支持es7的padStart比如电脑版的微信小程序
// 所以这里做一个兼容polyfill的兼容处理
if (!String.prototype.padStart) {
// 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解
String.prototype.padStart = function (maxLength, fillString = ' ') {
if (Object.prototype.toString.call(fillString) !== "[object String]") throw new TypeError(
'fillString must be String')
let str = this
// 返回 String(str) 这里是为了使返回的值是字符串字面量,在控制台中更符合直觉
if (str.length >= maxLength) return String(str)
let fillLength = maxLength - str.length,
times = Math.ceil(fillLength / fillString.length)
while (times >>= 1) {
fillString += fillString
if (times === 1) {
fillString += fillString
}
}
return fillString.slice(0, fillLength) + str;
}
}
// 其他更多是格式化有如下:
// yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合
timestamp = parseInt(timestamp);
// 如果为null,则格式化当前时间
if (!timestamp) timestamp = Number(new Date());
// 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
if (timestamp.toString().length == 10) timestamp *= 1000;
console.log('timestamp', timestamp)
let date = new Date(timestamp);
console.log(date);
let ret;
let opt = {
"y+": date.getFullYear().toString(), // 年
"m+": (date.getMonth() + 1).toString(), // 月
"d+": date.getDate().toString(), // 日
"h+": date.getHours().toString(), // 时
"M+": date.getMinutes().toString(), // 分
"s+": date.getSeconds().toString() // 秒
// 有其他格式化字符需求可以继续添加,必须转化成字符串
};
for (let k in opt) {
ret = new RegExp("(" + k + ")").exec(fmt);
if (ret) {
fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
};
};
return fmt;
}
/**
* 防抖原理一定时间内只有最后一次操作再过wait毫秒后才执行函数
*
* @param {Function} func 要执行的回调函数
* @param {Number} wait 延时的时间
* @param {Boolean} immediate 是否立即执行
* @return null
*/
let timeout = null;
export function debounce(func, wait = 500, immediate = false) {
// 清除定时器
if (timeout !== null) clearTimeout(timeout);
// 立即执行,此类情况一般用不到
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(function () {
timeout = null;
}, wait);
if (callNow) typeof func === 'function' && func();
} else {
// 设置定时器当最后一次操作后timeout不会再被清除所以在延时wait毫秒后执行func回调方法
timeout = setTimeout(function () {
typeof func === 'function' && func();
}, wait);
}
}
//1都不支持 2安卓指纹 3 苹果指纹 4 苹果人脸 5 苹果人脸加指纹
export function biometrics() {
return new Promise((resolve) => {
//#ifdef APP-PLUS || MP-WEIXIN
uni.checkIsSupportSoterAuthentication({
success(res) {
// console.log('检测支持的认证方式', res);
if (res.errMsg === 'checkIsSupportSoterAuthentication:ok') {
let support = 1;
let supportMode = res.supportMode;
let platform = uni.getSystemInfoSync().platform;
// "facial" 人脸 "fingerPrint" 指纹识别
console.log('supportMode', supportMode);
// 如果都不支持 隐藏该选项
if (supportMode.length === 0) {
support = 1;
}
// 如果是安卓机 只让用指纹识别
if (platform === 'android' && supportMode.findIndex(item => item === 'fingerPrint') !== -1) {
support = 2;
}
// 如果是苹果机 看是否是支持人脸还是指纹
if (platform === 'ios') {
// 指纹
if (supportMode.findIndex(item => item === 'fingerPrint') !== -1) {
support = 3;
}
// 人脸
if (supportMode.findIndex(item => item === 'facial') !== -1) {
support = 4;
}
// 指纹人脸同时存在
if (supportMode.findIndex(item => item === 'facial') !== -1 && supportMode.findIndex(item => item === 'fingerPrint') !== -1) {
support = 5;
}
}
resolve(support);
}
},
fail(err) {
console.log(err);
resolve(1);
},
})
// #endif
//#ifndef APP-PLUS || MP-WEIXIN
return 1;
// #endif
})
}
const router = new Router({ needLoginPages });
/**
* @description showModal 弹窗封装
* @param {Object} options = 参数同 uni-app 官方用法
* */
export function showModal(options) {
// #ifndef APP-PLUS
uni.showModal(options);
// #endif
// #ifdef APP-PLUS
if (uni.getSystemInfoSync().platform === 'android') {
global.$showModal(options)
.then(res => {
console.log('RES', res);
//确认
}).catch(err => {
//取消
console.log('ERR', err);
})
} else {
uni.showModal(options);
}
// #endif
}
/**
* @description 验证登录权限,接受一个回调函数,登录则执行回调函数,非登录状态则跳转登录页
* @param {Function} cb = 回调函数
* */
export function actionAuth(cb) {
if (global.token) {
cb && cb();
} else {
navigateToLogin();
}
}
/**
* @description 判断是app端还是小程序端登录
* */
let timer = null; // 登录页跳转防抖
export function navigateToLogin() {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
const pages = getCurrentPages();
if (pages.length != 0) {
const lastPage = '/' + pages.pop().route;
let url = LOGIN_PAGE_URL;
if (lastPage == url) return;
uni.navigateTo({
url
});
} else {
uni.switchTab({
url: '/pages/tab/home/shopindex'
})
}
}, 200)
}
/**
* @description 倒计时计算
* */
export function downTime(time) {
var days = parseInt(time / (1000 * 60 * 60 * 24));
var hours = parseInt(time / (1000 * 60 * 60) % 24);
var minutes = parseInt(time / (1000 * 60) % 60);
var seconds = parseInt(time / 1000 % 60);
return {
days,
hours: hours < 10 ? '0' + hours : hours,
minutes: minutes < 10 ? '0' + minutes : minutes,
seconds: seconds < 10 ? '0' + seconds : seconds,
}
}
/**
* @description 参数序列化
* */
export function serialize(data) {
let str = '';
Object.keys(data).forEach(key => {
str += key + '=' + data[key] + '&'
})
str = str.substr(0, str.length - 1);
return str;
}
/**
* @description 设置状态栏颜色
* @param {String} color dark or light
* @example this.$util.setNavigationBarColor('dark');
* */
export function setNavigationBarColor(color) {
if (color == 'dark') {
// #ifdef APP-PLUS
plus.navigator.setStatusBarStyle('dark');
// #endif
// #ifdef MP-WEIXIN
wx.setNavigationBarColor({
frontColor: '#000000',
backgroundColor: '#FFFFFF'
})
// #endif
} else if (color == 'light') {
// #ifdef APP-PLUS
plus.navigator.setStatusBarStyle('light');
// #endif
// #ifdef MP-WEIXIN
wx.setNavigationBarColor({
frontColor: '#FFFFFF',
backgroundColor: '#000000'
})
// #endif
}
}
/**
* base64图片缓存到本地,返回本地路径
* */
export function base64ToPath(base64) {
return new Promise(function (resolve, reject) {
if (typeof window === 'object' && 'document' in window) {
base64 = base64.split(',')
var type = base64[0].match(/:(.*?);/)[1]
var str = atob(base64[1])
var n = str.length
var array = new Uint8Array(n)
while (n--) {
array[n] = str.charCodeAt(n)
}
return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], {
type: type
})))
}
var extName = base64.match(/data\:\S+\/(\S+);/)
if (extName) {
extName = extName[1]
} else {
reject(new Error('base64 error'))
}
var fileName = Date.now() + '.' + extName
if (typeof plus === 'object') {
var bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
bitmap.loadBase64Data(base64, function () {
var filePath = '_doc/uniapp_temp/' + fileName
bitmap.save(filePath, {}, function () {
bitmap.clear()
resolve(filePath)
}, function (error) {
bitmap.clear()
reject(error)
})
}, function (error) {
bitmap.clear()
reject(error)
})
return
}
if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
var filePath = wx.env.USER_DATA_PATH + '/' + fileName
wx.getFileSystemManager().writeFile({
filePath: filePath,
data: base64.replace(/^data:\S+\/\S+;base64,/, ''),
encoding: 'base64',
success: function () {
resolve(filePath)
},
fail: function (error) {
reject(error)
}
})
return
}
reject(new Error('not support'))
})
}
export function postMsgToParent(message) {
console.log('postMsgToParent', message);
window.parent.postMessage(message, '*');
}
/**
*
* @param {*} type 点击类型 navigateTo
* @param {*} data
*/
export function handleAllFn(type, data) {
// 无点击事件
if (type == 'niente') {
return false
}
/**
* 转页面类型
* navigateTo
* data结构
* {
* url: String 路径,
* auth: Boolean (选填)是否验证登录状态true 验证
* params: Object (选填) 携带的参数
* }
*/
if (type == 'navigate') {
router[data.type]('/' + data.url)
return false
}
/**
*
* type: back
* 返回
* data(选填) 不填返回一页
*/
if (type == 'back') {
uni.navigateBack({
delta: data.delta || 1
});
}
/**
*
* type: backReference
* 返回页面携带参数
* data{
* name:String 目标页面接受参数名
* params: 参数
* }
*/
if (type == "backReference") {
if (!data.name) {
return false
}
let pages = getCurrentPages(); //获取当前页面js里面的pages里的所有信息。
let prevPage = pages[pages.length - 2];
//prevPage 是获取上一个页面的js里面的pages的所有信息。 -2 是上一个页面,-3是上上个页面以此类推。
prevPage.backWithParams({
[data.name]: data.params
})
uni.navigateBack({
delta: 1 // 返回上一级页面。
})
return false
}
/**
* type showModal 弹窗封装
* data 参数同 uni-app 官方用法
* */
if (type == 'showModal') {
// #ifndef APP-PLUS
uni.showModal(data);
// #endif
// #ifdef APP-PLUS
if (uni.getSystemInfoSync().platform === 'android') {
global.$showModal(options)
.then(res => {
console.log('RES', res);
//确认
}).catch(err => {
//取消
console.log('ERR', err);
})
} else {
uni.showModal(data);
}
// #endif
return false
}
// 打开指定弹窗
if (type == 'showModalDiy') {
let pages = getCurrentPages(); //获取当前页面js里面的pages里的所有信息。
let prevPage = pages[pages.length - 1];
prevPage['popupShow' + data.showCancel] = true
return false
}
/**
*
* type: downloadFile
* 下载文件
* data 下载路径
* .then(res=>{}) 接收下载成功回调
* .catch(res=>{}) 接收下载失败回调
*/
if (type == 'downloadFile') {
return new Promise((resolve, reject) => {
const downloadTask = uni.downloadFile({
url: data.url,
success: (res) => {
uni.showToast({
title: '下载成功',
icon: 'success',
mask: true
})
// resolve(res)
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function () {
console.log('save success');
}
});
},
fail: (err) => {
uni.showToast({
title: '下载失败',
icon: 'fail',
mask: true
})
reject(err)
},
complete: () => { }
})
// 中断下载
// downloadTask.abort();
// 监听下载进度
// downloadTask.onProgressUpdate(res => {
// console.log('下载进度' + res.progress);
// console.log('已经下载的数据长度' + res.totalBytesWritten);
// console.log('预期需要下载的数据总长度' + res.totalBytesExpectedToWrite);
// })
})
}
/**
*
* type: uploadFile
* 上传文件
* data{
* url:String 上传路径
* files: 仅app与h5支持该选项
* ffileType: 仅支付宝小程序支持且必填 images/video/audio
* filePath: 文件路径
* name: 后台接收key
* header: 选填
* formData: 选填 携带参数
* progressCallback: 选填 监听上传载进度
* }
*/
if (type == 'uploadFile') {
return new Promise((resolve, reject) => {
const uploadTask = uni.uploadFile({
url: config.baseUrl + data.url,
// #ifdef APP-PLUS || H5
files: data.files || [],
// #endif
// #ifdef MP-ALIPAY
fileType: data.fileType,
// #endif
// #ifdef H5
file: data.file || null,
// #endif
filePath: data.filePath,
name: data.name,
header: data.header ? data.header : {},
formData: data.formData ? data.formData : {},
complete: (response) => {
if (response.statusCode == 200) {
resolve(response)
} else {
reject(response)
}
}
})
if (data.progressCallback && typeof (data.progressCallback) == 'function') {
uploadTask.onProgressUpdate(res => {
data.progressCallback(res.progress + '%');
})
}
})
}
/**
*
* type: getLoaction
* 获取定位
*
**/
if (type == 'getLoaction') {
console.log('我要获取定位');
return new Promise((resolve, reject) => {
uni.getLocation({
type: 'wgs84',
success: function (res) {
console.log('当前位置的经度:' + res.longitude);
console.log('当前位置的纬度:' + res.latitude);
uni.showToast({
title: JSON.stringify(res),
icon: "none"
})
resolve(res)
},
fail: function (err) {
reject(err)
}
});
})
}
/**
*
* type: richiesta
* 点赞 收藏
* data{
* url:String 上传路径
* files: 仅app与h5支持该选项
* ffileType: 仅支付宝小程序支持且必填 images/video/audio
* filePath: 文件路径
* name: 后台接收key
* header: 选填
* formData: 选填 携带参数
* progressCallback: 选填 监听上传载进度
* }
*/
if (type == 'richiesta') {
}
}

109
common/utils/validate.js Normal file
View File

@ -0,0 +1,109 @@
const validate = (value, vtype,lgh) => {
// 自定义正则校验
if ('regular' === vtype) {
return lgh.test(value);
}
//长度校验
if(vtype === 'length'){
let val = lgh.split(',')
let len = value.length
if (val.length == 1){
return val == len
} else {
return len >= val[0] && len <= val[1]
}
}
if ('require' === vtype) {
return !!value;
}
if ('phone' === vtype) {
return /^1[3-9]\d{9}$/.test(value);
}
// 验证码
if ('captcha' === vtype) {
return /^[0-9]{4,6}$/.test(value);
}
// 不知道干啥的
if ('isnumber' === vtype) {
return /^[0-9]{5,11}$/.test(value);
}
if ('isqq' === vtype) {
return /^[1-9][0-9]{4,10}$/.test(value);
}
// 身份证号码验证不准确
if ('idcard' === vtype) {
return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(value);
}
if ('password' === vtype) {
return /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9a-zA-Z]{6,12}$/.test(value);
}
// 邀请码验证
if ('invitecode' === vtype) {
return /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9a-zA-Z]$/.test(value);
}
// 判断不准确 比如123.
if ('ismoney' === vtype) {
return /^(([1-9]\d*)|\d)(\.\d{1,2})?$/.test(value);
}
if ('email' === vtype) {
// return /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value);
return /^[0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+){1,2}$/.test(value);
}
if ('url' === vtype) {
return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value);
}
if ('paragraph' === vtype) {
return /^[A-Z0-9]{18}$/.test(value);
}
// 银行卡验证
if ('card' === vtype) {
let bankno = value;
let lastNum = bankno.substr(bankno.length - 1, 1); //取出最后一位与luhm进行比较
let first15Num = bankno.substr(0, bankno.length - 1); //前15或18位
let newArr = [];
// 前15或18位倒序存进数组
for (let i = first15Num.length - 1; i > -1; i--) newArr.push(first15Num.substr(i, 1));
let arrJiShu = []; // 奇数位*2的积 <9
let arrJiShu2 = []; // 奇数位*2的积 >9
let arrOuShu = []; // 偶数位数组
for (let j = 0; j < newArr.length; j++) {
if ((j + 1) % 2 == 1) { //奇数位
if (parseInt(newArr[j]) * 2 < 9) arrJiShu.push(parseInt(newArr[j]) * 2);
else arrJiShu2.push(parseInt(newArr[j]) * 2);
} else arrOuShu.push(newArr[j]); // 偶数位
}
let jishu_child1 = []; //奇数位*2 >9 的分割之后的数组个位数
let jishu_child2 = []; //奇数位*2 >9 的分割之后的数组十位数
for (let h = 0; h < arrJiShu2.length; h++) {
jishu_child1.push(parseInt(arrJiShu2[h]) % 10);
jishu_child2.push(parseInt(arrJiShu2[h]) / 10);
}
let sumJiShu = 0; //奇数位*2 < 9 的数组之和
let sumOuShu = 0; //偶数位数组之和
let sumJiShuChild1 = 0; //奇数位*2 >9 的分割之后的数组个位数之和
let sumJiShuChild2 = 0; //奇数位*2 >9 的分割之后的数组十位数之和
let sumTotal = 0;
for (let m = 0; m < arrJiShu.length; m++) sumJiShu = sumJiShu + parseInt(arrJiShu[m]);
for (let n = 0; n < arrOuShu.length; n++) sumOuShu = sumOuShu + parseInt(arrOuShu[n]);
for (let p = 0; p < jishu_child1.length; p++) {
sumJiShuChild1 = sumJiShuChild1 + parseInt(jishu_child1[p]);
sumJiShuChild2 = sumJiShuChild2 + parseInt(jishu_child2[p]);
}
//计算总和
sumTotal = parseInt(sumJiShu) + parseInt(sumOuShu) + parseInt(sumJiShuChild1) + parseInt(sumJiShuChild2);
//计算Luhm值
let k = parseInt(sumTotal) % 10 == 0 ? 10 : parseInt(sumTotal) % 10;
let luhm = 10 - k;
return lastNum == luhm;
}
}
export {
validate
};