382941bc by simon

默认提交

1 parent d7a783c4
......@@ -18,15 +18,16 @@
"co": "^4.6.0",
"core-js": "^2.6.5",
"crypto-js": "^4.0.0",
"jsencrypt": "^3.0.0-rc.1",
"moment": "^2.29.1",
"glob": "^7.1.4",
"js-cookie": "^2.2.1",
"jsencrypt": "^3.0.0-rc.1",
"mockjs": "^1.0.1-beta3",
"moment": "^2.29.1",
"postcss-px2rem": "^0.3.0",
"postcss-pxtorem": "^4.0.1",
"sass-resources-loader": "^2.0.3",
"vant": "^2.2.11",
"vconsole": "^3.15.1",
"vue": "^2.6.10",
"vue-router": "^3.0.3",
"vuex": "^3.0.1"
......
......@@ -4,9 +4,8 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0"> -->
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- <script src="<%= BASE_URL %>static/js/weixin/jweixin-1.6.0.js"></script>
<script src="<%= BASE_URL %>static/js/kd/kd-sdk.1.0.0.js"></script>
......
module.exports = {
login: '/front/userApi/login', // 登录
code2session: "/front/wxApi/code2session", // code2session
profile: '/front/userApi/profile', // 个人信息
uploadProfile: '/front/userApi/uploadProfile', // 更新头像昵称
oauthLink: "/front/wxApi/oauthLink", // 获取oauth授权地址
wxJsSign: "/front/wxApi/jsSign", // 微信jsSign签名接口
upload: '/common/upload', // 上传文件 [x]
list: "xxx",
......
......@@ -3,6 +3,8 @@ import axios from 'axios';
import {
Toast
} from 'vant';
Toast.allowMultiple();
let loadingToast;
import router from '@/router'
import {
......@@ -21,25 +23,43 @@ import api from '@/api/api';
// axios的默认url
// axios.defaults.baseURL = ""
let base = process.env.VUE_APP_BASE_API;
const ENV = process.env.VUE_APP_ENV;
const MODULE_CODE = process.env.VUE_APP_MODULE_CODE;
let MODULE_CODE = process.env.VUE_APP_MODULE_CODE;
const IS_POST_ENC = process.env.VUE_APP_IS_POST_ENC;
let ENV = process.env.VUE_APP_ENV;
// 配置环境
// let host = location.host;
if (location.host.indexOf("192.168.") != -1 || location.host.indexOf("172.20.") != -1 || location.host.indexOf('dev.h5.kdao.xin') != -1) {
// 测试环境
ENV = "demo";
} else {
// if (location.host.indexOf("prod.h5.kdao.xin") != -1) {
// // 恪道正式环境
// }
}
// 默认超时
axios.defaults.timeout = 5000;
// 请求拦截器
// axios.interceptors.request.use(
// config => {
// // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
// // 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断
// const token = "token"; //这里写入token
// token && (config.headers.Authorization = token);
// return config;
// },
// error => {
// return Promise.error(error);
// })
axios.interceptors.request.use(
config => {
let {
opt
} = config;
if (opt && opt.loading) {
loadingToast = Toast.loading({
message: '加载中...',
forbidClick: true,
});
}
return config;
},
error => {
return Promise.error(error);
})
// 响应拦截器
axios.interceptors.response.use(
......@@ -50,6 +70,8 @@ axios.interceptors.response.use(
let {
opt
} = config;
if (loadingToast) loadingToast.clear();
// 服务器状态码
if (response.status === 200) {
......@@ -71,6 +93,15 @@ axios.interceptors.response.use(
removeToken();
break;
case 3001:
app.router.replace({
name: "errorTips",
query: {
code: 3001
}
})
break;
default:
break;
}
......@@ -113,7 +144,7 @@ function analysisParams(params) {
method
} = params;
if (IS_POST_ENC == 'true') {
if (method == 'post') {
if (method == 'post' || method == 'delete' || method == 'DELETE') {
data = makeEncrypt(data);
}
} else {
......@@ -184,6 +215,20 @@ export const httpPost = params => {
opt
}).then(res => res.data.content);
}
export const httpDelete = params => {
params.method = 'delete';
let {
reqUrl,
data,
headers,
opt,
method
} = analysisParams(params);
return axios.delete(reqUrl, {
data: data,
headers: headers,
}).then(res => res.data.content);
}
/**
......@@ -232,6 +277,31 @@ export const formdata = params => {
}
/**
* 获取bolb对象的图片
* @param {*} params
* @returns
*/
export const getBlob = params => {
let {
reqUrl,
data,
headers,
} = analysisParams(params);
return axios({
url: reqUrl,
method: 'get',
params: data,
headers: headers,
responseType: 'blob' // 改参数会以blob流格式返回
}).then((res) => {
let blob = new Blob([res.data])
let url = URL.createObjectURL(blob);
return url;
});
}
/**
......
......@@ -7,6 +7,8 @@ import api from '@/api/api'
import {
httpGet,
httpPost,
httpDelete,
getBlob,
formdata
} from '@/api/fetch-api.js'
......@@ -20,6 +22,9 @@ import {
import 'amfe-flexible/index.js'
import vant from '@/utils/vant-util'
// 微信签名
import wechat from '@/utils/wechat.js'
import '@/styles/index.scss' // global css
import '@/styles/fonticon.scss' // 图标字体
import '@/assets/fonts/font.scss' // 字体引入
......@@ -27,16 +32,40 @@ import '@/assets/fonts/font.scss' // 字体引入
Vue.config.productionTip = false
// vconsole 组件
import Vconsole from 'vconsole';
if (getQuery("test") || process.env.NODE_ENV == "development") {
const vConsole = new Vconsole();
}
function setHtmlFontSize() {
// 最大缩放单元
const MAX_REM_UNIT = 54;
let htmlDom = document.querySelector('html');
let fontSize = window.innerWidth / 10;
fontSize = fontSize > MAX_REM_UNIT ? MAX_REM_UNIT : fontSize;
htmlDom.style.fontSize = fontSize + 'px'
htmlDom.style.maxWidth = (MAX_REM_UNIT * 10) + "px"
htmlDom.style.position = "relative";
htmlDom.style.margin = "0 auto";
htmlDom.style.backgroundColor = "#f7f8fa";
}
// 重新设置大小
window.onresize = () => {
return (() => {
setHtmlFontSize();
})()
}
setHtmlFontSize()
import {
Dialog,
Toast
} from "vant";
// 原app节点请通过 document.getElementById('app') 获取
// routes里的component组件需要以import方式引入,否则页面创建的时候,app还没挂载。
let util = require('@/utils/utils');
let func = require('@/utils/func');
......@@ -44,6 +73,8 @@ let func = require('@/utils/func');
app.api = api;
app.get = httpGet;
app.post = httpPost;
app.delete = httpDelete;
app.getBlob = getBlob;
app.uploadFile = formdata;
app.router = router;
app.util = util;
......@@ -53,6 +84,8 @@ app.vant = {
Toast
}
window.app = app;
// 原app节点请通过 document.getElementById('app') 获取
// routes里的component组件需要以import方式引入,否则页面创建的时候,app还没挂载。
function initVue() {
......@@ -70,6 +103,11 @@ function initVue() {
},
render: h => h(VueApp)
}).$mount('#app')
// 微信初始化,微信签名,需要在index.html 引入 jweixin-1.6.0
// wechat.init().then(() => {
// // wx.wxShare("","","","");
// });
}
// 微信授权
......
......@@ -5,12 +5,28 @@ Vue.use(Vuex)
export default new Vuex.Store({
state: {
profile: null,
},
mutations: {
basicMutation(state, payload) {
Object.assign(state, payload);
},
},
actions: {
// 获取用户身份
async getProfile({
commit
}, payload) {
let res = await app.get({
url: app.api.profile,
data: {},
opt: {
toast: false
}
})
commit('basicMutation', {
profile: res
})
},
}
})
})
\ No newline at end of file
......
......@@ -15,10 +15,6 @@ div {
width: 750px;
}
.app__width {
width: 750px;
}
.app__inner {
margin: 20px;
}
......
......@@ -160,6 +160,49 @@ export function getObjByListKeyValue(value, key, list) {
return result;
}
/**
* 根据某个标识,树状数组
* @param {*} list
* @param {*} key
* @param {*} value
* @returns
*
* - 传入原始数组
* - 分类检索值
*
* 输出
* - keys
* - 树状列表
*/
export function getTreeByListKeyValue(list, key) {
let keys = [];
let result = [];
list.forEach(element => {
if (keys.indexOf(element[key]) == -1) {
keys.push(element[key]);
result.push({
text: element[key],
children: []
})
}
});
list.forEach(element => {
result.forEach(eleRes => {
if (element[key] == eleRes.text) {
eleRes.children.push(element);
}
});
});
return {
keys,
result
}
}
/**
* 获取环境信息
* @return {Object} 环境信息对象
......@@ -219,7 +262,7 @@ export function setTitle(title) {
$iframe.onload = function onIframeLoad() {
setTimeout(function () {
$iframe.onload = null;
onIframeLoad = null;
// onIframeLoad = null;
document.body.removeChild($iframe);
$iframe = null;
}, 0);
......@@ -279,10 +322,13 @@ export function formatBr(str) {
* @param {date} date 日期时间
* @param {string} fmt 格式,如:'yyyy-MM-dd hh:mm:ss'
*/
export function formatDate(date, fmt) {
export function formatDate(date, fmt = "yyyy-MM-dd hh:mm:ss") {
if (!date) return '-'
// 把-换成/ 避免iOS和安卓真机问题
var reg = /-/g;
if (typeof date == 'string' && date.length == 13 && !isNaN(date)) {
date = parseInt(date)
}
if (typeof date == 'object') {
date += "";
date = date && date.replace(reg, '/');
......
import Vue from 'vue'
import {
Search,
Button,
Swipe,
SwipeItem,
Lazyload,
Tab,
Tabs,
Tag,
Sticky,
Popup,
Tabbar,
TabbarItem,
Icon,
Uploader,
Area,
List,
Loading,
Circle,
CountDown,
GoodsAction,
GoodsActionIcon,
GoodsActionButton,
Divider,
Rate,
Field,
Form,
Area,
RadioGroup,
Radio,
List,
ImagePreview,
Step,
Steps,
Skeleton,
Toast,
Button
Dialog,
Cell,
CellGroup,
AddressList,
AddressEdit,
Checkbox,
CheckboxGroup,
Stepper,
Switch,
Badge,
Picker,
DatetimePicker,
Empty,
Sidebar,
SidebarItem,
SubmitBar,
IndexBar,
IndexAnchor,
Calendar,
ActionSheet
} from 'vant';
import {
Image as VanImage
} from 'vant';
Vue.use(Swipe).use(SwipeItem)
.use(Search)
.use(Button)
.use(Lazyload)
.use(Tab).use(Tabs)
.use(Sticky)
.use(Tag)
.use(Popup)
.use(Tabbar).use(TabbarItem)
.use(VanImage)
.use(Icon)
.use(Uploader)
.use(Loading)
.use(Circle)
.use(CountDown)
.use(GoodsAction)
.use(GoodsActionIcon)
.use(GoodsActionButton)
.use(Divider)
.use(Rate)
.use(Field)
.use(Form)
.use(Area)
.use(Radio)
.use(RadioGroup)
.use(List)
.use(Button)
.use(Toast);
.use(ImagePreview)
.use(Step)
.use(Steps)
.use(Skeleton)
.use(Cell)
.use(CellGroup)
.use(Toast)
.use(Dialog)
.use(AddressList)
.use(AddressEdit)
.use(Checkbox)
.use(CheckboxGroup)
.use(Stepper)
.use(Switch)
.use(Badge)
.use(Picker)
.use(DatetimePicker)
.use(Empty)
.use(Sidebar)
.use(SidebarItem)
.use(IndexBar)
.use(IndexAnchor)
.use(ActionSheet)
.use(Calendar)
.use(SubmitBar);
\ No newline at end of file
......
import wx from 'weixin-js-sdk';
wx.ready(function () { //通过ready接口处理成功验证
// config信息验证成功后会执行ready方法
wx.onMenuShareAppMessage({ // 分享给朋友 ,在config里面填写需要使用的JS接口列表,然后这个方法才可以用
title: '这里是标题', // 分享标题
desc: 'This is a test!', // 分享描述
link: '链接', // 分享链接
imgUrl: '图片', // 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
import {
isWeiXin
} from '@/utils/utils';
function wxSign() {
return new Promise((resolve, reject) => {
app.post({
url: app.api.wxJsSign,
data: {
url: location.href
},
// mode: "custom"
}).then(res => {
if (!window.wx) {
return
}
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: res.appId, // 必填,公众号的唯一标识
timestamp: res.timestamp, // 必填,生成签名的时间戳
nonceStr: res.nonceStr, // 必填,生成签名的随机串
signature: res.signature, // 必填,签名,见附录1
jsApiList: [
"updateAppMessageShareData",
"updateTimelineShareData",
"onMenuShareTimeline",
"onMenuShareAppMessage",
"chooseWXPay",
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(() => {
resolve()
})
});
})
}
function setShare(title, description, image, url) {
wx.updateAppMessageShareData({
title: title, // 分享标题
desc: description, // 分享描述
link: url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: image, // 分享图标
success() {
// 设置成功
}
});
wx.onMenuShareTimeline({ //分享朋友圈
title: '标题', // 分享标题
link: '链接',
imgUrl: '图片', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
wx.updateTimelineShareData({
title: title, // 分享标题
link: url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: image, // 分享图标
success() {
// 设置成功
}
});
});
wx.error(function (res) {//通过error接口处理失败验证
// config信息验证失败会执行error函数
});
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: '', // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名,见附录1
jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
}
let wechat = {
init() {
return new Promise((resolve, reject) => {
if (isWeiXin()) {
wxSign().then(() => {
resolve();
}).catch(e => {
resolve();
});
} else {
resolve();
}
});
},
wxShare(title, description, image, url) {
title = title || process.env.VUE_APP_MALL_NAME + "";
description = description || "";
image = image || "";
url = url || location.href;
return new Promise((resolve, reject) => {
if (isWeiXin()) {
wx.onMenuShareAppMessage({
title: title, // 分享标题
desc: description, // 分享描述
link: url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: image, // 分享图标
success: function () {
// 分享成功
// alert("ShareApp")
resolve("ShareApp")
}
});
wx.onMenuShareTimeline({
title: title, // 分享标题
link: url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: image, // 分享图标
success: function () {
// 分享成功
// alert("ShareTimeline")
resolve("ShareTimeline")
}
});
}
});
// if (isWeiXin()) {
// setShare(title, description, image, url);
// }
}
};
export default wechat;
\ No newline at end of file
......