Browse Source

【新增】 完善项目所需要的依赖文件引入,请求方法封装等

【新增】 登录页
master
邓平艺 4 years ago
parent
commit
3f45fef4e4
  1. 25
      App.vue
  2. 1
      common/SparkMD5.js
  3. 1
      common/bigc.js
  4. 71
      common/dateFtt.js
  5. 60
      common/directoss.js
  6. 33
      common/http.interceptor.js
  7. 109
      common/mixin.js
  8. 105
      common/request.js
  9. 27
      common/requestMessage.js
  10. 9
      common/sha1.min.js
  11. 25
      config/index.js
  12. 31
      main.js
  13. 7
      pages.json
  14. 176
      pages/login/login.vue
  15. 13
      service/oss.js

25
App.vue

@ -1,13 +1,36 @@
<script> <script>
export default { export default {
globalData: {
wxlogin: () => {}, //
},
onLaunch: function() { onLaunch: function() {
console.log('App Launch')
console.log('App Launch');
this.globalData.wxlogin = this.wxlogin;
}, },
onShow: function() { onShow: function() {
console.log('App Show') console.log('App Show')
}, },
onHide: function() { onHide: function() {
console.log('App Hide') console.log('App Hide')
},
methods: {
wxlogin(){
return new Promise((resolve, rejecj) => {
uni.login({
complete: result => {
if(result.errMsg == 'login:ok'){
let code = result.code;
console.log("login.code", code);
// this.$http(this.API.API_WXLOGIN, { code }).then(res => {
// console.log("", res);
// uni.setStorageSync('userinfo', res.data);
// resolve(res.data);
// })
}
}
})
})
},
} }
} }
</script> </script>

1
common/SparkMD5.js
File diff suppressed because it is too large
View File

1
common/bigc.js
File diff suppressed because it is too large
View File

71
common/dateFtt.js

@ -0,0 +1,71 @@
/**
* @description 格式化任意时间
* @param {type} date
* @return { fmt }
*/
export default function dateFtt(date){
return parseInt(date / 60) + ":" + date % 60
}
/**
* 日期格式化
*/
export function dateFormat(date, format) {
format = format || 'yyyy-MM-dd hh:mm:ss';
if (date !== 'Invalid Date') {
let o = {
"M+": date.getMonth() + 1, //month
"d+": date.getDate(), //day
"h+": date.getHours(), //hour
"m+": date.getMinutes(), //minute
"s+": date.getSeconds(), //second
"q+": Math.floor((date.getMonth() + 3) / 3), //quarter
"S": date.getMilliseconds() //millisecond
}
if (/(y+)/.test(format)) format = format.replace(RegExp.$1,
(date.getFullYear() + "").substr(4 - RegExp.$1.length));
for (let k in o)
if (new RegExp("(" + k + ")").test(format))
format = format.replace(RegExp.$1,
RegExp.$1.length === 1 ? o[k] :
("00" + o[k]).substr(("" + o[k]).length));
return format;
}
return '';
}
/**
* 生成对应的时间字符串
*/
export function recordTime(options = {}){
if(Object.prototype.toString.call(options.time) !== '[object Date]'){
options.time = new Date();
}
if(typeof options.separator === 'undefined'){
options.separator = "-";
}
if(typeof options.swf === 'undefined'){
options.swf = "all";
}
let { time, separator, swf } = options;
function cover(par) {
par = par.toString()[1] ? par : "0" + par;
return par;
}
let year = time.getFullYear();
let month = time.getMonth() + 1;
let day = time.getDate();
let hour = time.getHours();
let min = time.getMinutes();
let ppn = time.getSeconds();
if(swf === "time"){
return [hour, min, ppn].map(cover).join(":");
}else if(swf === "date"){
return [year, month, day].map(cover).join(String(separator));
}else{
return [year, month, day].map(cover).join(String(separator)) +" "+ [hour, min, ppn].map(cover).join(":");
}
}

60
common/directoss.js

@ -0,0 +1,60 @@
import { getOssToken } from "@/service/oss.js"
/**
* dispose oss直传文件(视频图片)传入以下两个参数返回一个上传后的Array[urlLink] Promise对象
* @params pathList Array(String || Object[String]) 需要上传到oss的文件列表
* @params fileType String 上传到oss的文件类型imagevideo
* 图片上传调用let imageList = await dispose(res.tempFilePaths, 'image');
* 视频上传调用let videoList = await dispose([res.tempFilePath], 'video');
*/
export async function dispose(pathList = [], fileType = 'image'){
let ossResult = await getOssToken(); // 获取oss权限
let oss = ossResult.data;
let premiseList = [];
pathList.map((item, index) => {
let promiseItem = new Promise((resolve, reject) => {
let tiemr = new Date();
let ext = getFileExtendingName(item.tempFilePath || item);
let nameStr = oss.dir + tiemr.getTime() + index + ext;
uni.uploadFile({
url: oss.host,
filePath: item.tempFilePath || item,
name: 'file',
fileType,
formData: {
'key': nameStr,
"OSSAccessKeyId": oss.accessid,
"policy": oss.policy,
"Signature": oss.signature,
"success_action_status": 200,
},
success: result => {
if (result.statusCode == 200) {
let fileUrl = oss.host + '/' + nameStr;
resolve(fileUrl);
}else{
reject(result);
}
},
fail: err => {
reject(err);
}
})
})
premiseList.push(promiseItem);
});
return Promise.all(premiseList);
}
// 获取文件后缀
function getFileExtendingName(filename){
var reg = /\.[^\.]+$/;
var matches = reg.exec(filename);
if (matches) {
return matches[0];
}
return '';
}

33
common/http.interceptor.js

@ -0,0 +1,33 @@
import { BASE_URL } from "@/config/index.js"
const install = (Vue, vm) => {
// 请求全局配置
Vue.prototype.$u.http.setConfig({
baseUrl: BASE_URL,
method: 'POST',
dataType: 'json', // 返回数据时自动 JSON.parse()
showLoading: false, // 是否显示请求中的loading
loadingText: '正在加载',
loadingTime: 800 // 延迟800毫秒时显示加载框
});
// 请求前拦截, 现在不做拦截
Vue.prototype.$u.http.interceptor.request = config => {
return true;
};
// 响应拦截
Vue.prototype.$u.http.interceptor.response = res => {
if(res.code == 0) {
return res;
} else {
vm.$msg(res.msg);
return false;
}
// res.code == 9998 手机号 res.code == 9999 用户信息
}
}
export default {
install
}

109
common/mixin.js

@ -8,8 +8,70 @@ export default{
this.pageScrollTop = res.scrollTop; this.pageScrollTop = res.scrollTop;
}, },
methods: { methods: {
$isRight(val){
return this.$shared.isRight(val);
// 判断对错/是否显示,万能校验
$isRight(obj){
if (isValueType(obj) === 'string') {
obj = obj.trim();
if (obj === 'null' || obj === 'undefined') {
return false;
}
} else if (isValueType(obj) === 'number' && (isValueType(obj) === "number" && !isNaN(obj)) && obj !== 0) {
return true;
} else if (isValueType(obj) === 'boolean') {
return obj
}
for (var key in obj) {
return true;
}
return false;
},
// 判断一个值所属的类型,返回一个字符串
$valueType(value){
let str = Object.prototype.toString.call(value);
return str.match(/\[object (.*?)\]/)[1].toLowerCase();
},
$msg(title = '', param = {}) {
return new Promise((resolve, reject) => {
if(!title){
reject();
return;
}
uni.showToast({
title,
duration: param.duration || 1500,
mask: param.mask || true, // 默认应该加mask 禁止提示时操作
icon: param.icon || 'none',
complete: result => {
setTimeout(() => {
resolve();
}, param.duration || 1500);
}
});
})
},
$url(url, options = {}){
this.$u.throttle(() => {
if(options.type && options.type !== ''){
if(options.type === 'redirect'){ // 关闭当前,跳转
uni.redirectTo({ url })
}else if(options.type === 'switch'){ // 跳转
uni.switchTab({ url })
}else if(options.type === 'launch'){ // 关闭所有,跳转
uni.reLaunch({ url })
}
}else{
uni.navigateTo({ url }) // 跳转
}
}, 100);
},
$toBack(){
let pages = getCurrentPages(); // 当前页
let beforePage = pages[pages.length - 2]; // 上个页面
if(beforePage && beforePage.route){
uni.navigateBack();
}else{
uni.reLaunch({url:'/pages/index/index'});
}
}, },
$check(str, type) { $check(str, type) {
switch (type) { switch (type) {
@ -55,49 +117,6 @@ export default{
default: default:
return true; return true;
} }
},
$msg(title = '', param = {}) {
return new Promise((resolve, reject) => {
if(!title){
reject();
return;
}
uni.showToast({
title,
duration: param.duration || 1500,
mask: param.mask || true, // 默认应该加mask 禁止提示时操作
icon: param.icon || 'none',
complete: result => {
setTimeout(() => {
resolve();
}, param.duration || 1500);
}
});
})
},
$url(url, options = {}){
this.$u.throttle(() => {
if(options.type && options.type !== ''){
if(options.type === 'redirect'){ // 关闭当前,跳转
uni.redirectTo({ url })
}else if(options.type === 'switch'){ // 跳转
uni.switchTab({ url })
}else if(options.type === 'launch'){ // 关闭所有,跳转
uni.reLaunch({ url })
}
}else{
uni.navigateTo({ url }) // 跳转
}
}, 100);
},
$toBack(){
let pages = getCurrentPages(); // 当前页
let beforePage = pages[pages.length - 2]; // 上个页面
if(beforePage && beforePage.route){
uni.navigateBack();
}else{
uni.switchTab({url:'/pages/index/index'});
}
} }
} }
} }

105
common/request.js

@ -0,0 +1,105 @@
let sha1 = require("./sha1.min.js");
let SparkMD5 = require("./SparkMD5.js"); // 签名加密js文件
function getsign(params) {
let s_data = "";
let keys = [];
for (const key in params) {
if (params.hasOwnProperty(key)) {
const value = params[key];
keys.push(key);
}
}
let arr = [];
keys.sort();
for (let i = 0; i < keys.length; i++) {
let k = keys[i];
let v = params[k];
arr.push(k + '=' + v);
}
s_data = arr.join('&');
let sign = sha1(SparkMD5.hash(s_data) + 'Leadfyy@123');
params.sign = sign;
return params;
}
export const request = options => {
let { url, data, method, showLoading } = options;
if(typeof data === 'undefined'){
data = {};
}
return new Promise((resolve, reject) => {
// 绑定this
let that = this;
// 获取当前请求来自哪个页面
let pages = getCurrentPages();
data.create_page = pages[pages.length - 1].route;
// 当前请求时间戳
if (!data.timestamp) {
data.timestamp = Math.round(new Date().getTime() / 1000);
}
// 当前请求随机数
if(!data.rand){
data.rand = Math.round(Math.random() * 1000000);
}
// 当前请求来自的平台
data.platform = 'wxmini';
// #ifdef APP-PLUS
data.platform = 'app'; // 来自app平台,其他平台写法类似
// #endif
// 当前小程序版本号
// data.version = that.API.VERSION;
// 获取设备唯一deviceId,如果没有,自动生成一个
let sysInfo = uni.getSystemInfoSync();
if(typeof sysInfo.deviceId == 'undefined'){
let deviceId = uni.getStorageSync('deviceId');
if(deviceId){
sysInfo.deviceId = deviceId;
}else{
let date_time = String(new Date().getTime());
let md5_deviceId = SparkMD5.hash(date_time);
uni.setStorageSync('deviceId', md5_deviceId);
sysInfo.deviceId = md5_deviceId;
}
}
if (sysInfo) {
data.device_info = JSON.stringify(sysInfo);
}
// 判断传入用户token和id
let userinfo = uni.getStorageSync('userinfo') || {};
if(userinfo && userinfo.token && !data.token){
data.token = userinfo.token;
}
if(userinfo && userinfo.id && !data.user_id){
data.user_id = userinfo.id;
}
// 获取页面options参数
let _mergeParam = that._mergeParam;
for (let _keyVar in _mergeParam) {
let _k = _keyVar
if (data[_k]) {
_k = '_' + _k;
}
data[_k] = _mergeParam[_keyVar];
}
// 生成sign
getsign(data);
console.log(url, data);
// 动态赋值是否显示loading加载框 TODO验证一下是否有问题
if(that.$shared.isValueType(showLoading) != 'undefined'){
that.$u.http.setConfig({showLoading});
}
let httpData = method == 'get' ? {params: data} : data;
// 发起请求
that.$u[method](url, httpData).then(res => {
resolve(res);
}).catch(err => {
reject(err);
})
});
}

27
common/requestMessage.js

@ -0,0 +1,27 @@
/**
* @description token失效时跳转登录页方法
* @return { Function }
*/
export const httpMessage = (function () {
let isTp = true
// 返回一个闭包来保证同时间段的多次请求错误都只弹出一个窗口
return function (msg) {
if (isTp) {
isTp = false
uni.showModal({
title: '提示',
content: msg,
showCancel: false,
confirmText: '确定',
success: (res) =>{
if (res.confirm) {
isTp = true
uni.reLaunch({
url: '/pages/login/login',
})
}
}
})
}
}
})()

9
common/sha1.min.js
File diff suppressed because it is too large
View File

25
config/index.js

@ -0,0 +1,25 @@
module.exports = (() => {
const config = exports = {}
config.mode = {
app: '/app', //APP功能模块
}
config.tenantId = "000000" // 管理组租户编号
config.tokenHeader = 'Blade-Auth'
config.clientId = 'weixin' // 客户端id
config.clientSecret = 'weixin_secret' // 客户端密钥
config.Authorization = 'c2FiZXI6c2FiZXJfc2VjcmV0' // 客户端id和客户端密钥联合进行base64转码生成的加密字符串
config.Timeout = 10000 // 请求超时时间,单位 ms
// 基础服务器地址
// config.BASE_URL = '' // 开发环境
// config.BASE_URL = '' // 生产环境
if(process.env.NODE_ENV === 'production'){
config.BASE_URL = ''; // 发行时固定生产环境
}
return {
...config
}
})()

31
main.js

@ -1,26 +1,23 @@
import Vue from 'vue'
import App from './App' import App from './App'
import uView from '@/uni_modules/uview-ui' import uView from '@/uni_modules/uview-ui'
import mixin from '@/common/mixin.js'; import mixin from '@/common/mixin.js';
import httpInterceptor from '@/common/http.interceptor.js';
Vue.config.productionTip = false;
App.mpType = 'app'
Vue.mixin(mixin); Vue.mixin(mixin);
Vue.use(uView);
// 线上模式禁用 console.log
if(process.env.NODE_ENV === 'production') console.log = () => {};
// #ifndef VUE3
import Vue from 'vue'
Vue.config.productionTip = false
Vue.use(uView)
App.mpType = 'app'
const app = new Vue({ const app = new Vue({
...App ...App
})
app.$mount()
// #endif
});
// 引入http拦截器 TODO 待请求测试
// Vue.use(httpInterceptor, app);
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif
app.$mount();

7
pages.json

@ -58,6 +58,13 @@
"navigationBarTitleText": "评卡查询", "navigationBarTitleText": "评卡查询",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
},
{
"path": "pages/login/login",
"style": {
"navigationBarTitleText": "用户登录",
"enablePullDownRefresh": false
}
} }
], ],
"subPackages": [{ "subPackages": [{

176
pages/login/login.vue

@ -0,0 +1,176 @@
<template>
<view>
<view class="lf-row-center lf-flex-column box">
<!-- <image class="img" :src="userInfo.avatar" v-if="userInfo.avatar"></image> -->
<!-- <image class="img" src="../../static/logo.png" v-else></image> -->
<image class="img" src="../../static/logo.png" ></image>
<view class="lf-m-t-30 lf-font-32" v-if="type == 'phone'">{{ userInfo.nickname || '游客用户' }}</view>
<block v-if="type == 'userinfo'">
<button class="btn" @click="getUserProfile">
<text class="le lf-icon-weixin lf-font-60 lf-text-vertical"></text>
<text class="lf-m-l-20">微信快捷登录</text>
</button>
<!-- <view class="lf-m-t-40 lf-font-28" @click="$toBack()">暂不绑定继续操作</view> -->
<view class="mask" v-if="!checked" @click="$msg('您未同意协议条款')"></view>
</block>
<block v-else-if="type == 'phone'">
<button class="btn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">
<text class="le lf-icon-weixin lf-font-60 lf-text-vertical"></text>
<text class="lf-m-l-20">绑定手机号</text>
</button>
<!-- <view class="lf-m-t-40 lf-font-28" @click="$url('/pages/login/accountLogin')">使用手机号登录</view> -->
<view class="mask" v-if="!checked" @click="$msg('您未同意协议条款')"></view>
</block>
</view>
<!-- 服务条款 -->
<view class="fixed-bottom lf-flex" v-show="agreement.title">
<checkbox-group @change="checkboxChange" style="display: inline-block;">
<checkbox class="lf-text-vertical" :checked="checked"></checkbox>
</checkbox-group>
<view class="lf-m-l-10 lf-font-24 lf-color-gray" style="display: inline-block;">
<text>请认真阅读并同意</text>
<text @click="enterAgree" class="text-orange">{{ agreement.title }}</text>
<text>在小程序下单购买即表示您已默认同意</text>
<text @click="enterAgree" class="text-orange">{{ agreement.title }}</text>
<text>的所有条款</text>
</view>
</view>
</view>
</template>
<script>
export default {
data(){
return {
checked: false, //
isLogin: false, //
userInfo: {},
type: 'userinfo', // phone | userinfo
agreement: {} //
}
},
onLoad(options){
this.type = options.type || this.type;
this.getAgree();
getApp().globalData.wxlogin().then(res => {
this.userInfo = res;
});
},
methods: {
//
getAgree(){
this.$http(this.API.API_WXLOGIN_VIEW).then(res => {
this.agreement = res.data?.agreement;
})
},
//
enterAgree(){
this.$url('/pages/agreement/agreement?id='+ this.agreement.article_id);
},
//
checkboxChange(event){
this.checked = event.detail.value.length > 0;
},
//
getPhoneNumber(event){
console.log(event);
if(event.detail.errMsg == 'getPhoneNumber:ok'){
let encryptedData = event.detail.encryptedData;
let iv = event.detail.iv;
// let userInfo = uni.getStorageSync('userinfo') || {};
this.$http(this.API.API_WECHAT_SETPHONE, {
encryptedData,
iv,
// token: userInfo.token //
}).then(res => {
console.log("更新手机号", res);
this.$msg('更新成功', {icon: 'success'});
uni.setStorageSync('userinfo', res.data);
setTimeout(() => {
this.$toBack();
}, 1000);
})
}
},
//
getUserProfile(){
uni.getUserProfile({
desc: '您的信息将用于时空网显示',
lang: 'zh_CN',
complete: result => {
console.log(result)
if(result.errMsg == 'getUserProfile:ok'){
let encryptedData = result.encryptedData;
let iv = result.iv;
let signature = result.signature;
// let userInfo = uni.getStorageSync('userinfo') || {};
this.$http(this.API.API_WECHAT_SETPROFILE, {
encryptedData,
iv,
// token: userInfo.token //
}).then(res => {
console.log("更新用户信息", res);
this.$msg('更新成功', {icon: 'success'});
uni.setStorageSync('userinfo', res.data);
setTimeout(() => {
this.$toBack();
}, 1000);
})
}
}
});
}
}
}
</script>
<style>
page{
overflow: hidden;
}
</style>
<style lang="scss" scoped="scoped">
.box{
padding: 60rpx 32rpx;
width: 750rpx;
height: auto;
box-sizing: border-box;
position: relative;
.img{
width: 180rpx;
height: 180rpx;
border-radius: 50%;
}
.btn{
background-color: #09BB07;
color: #FFFFFF;
width: 100%;
height: 88rpx;
border-radius: 42rpx;
font-size: 32rpx;
line-height: 88rpx;
margin-top: 80rpx;
}
}
.fixed-bottom{
position: fixed;
bottom: 60rpx;
left: 0;
padding: 0 32rpx;
.highlight{
color: #1e90ff;
}
}
.mask{
position: absolute;
bottom: 46rpx;
left: 0;
width: 100%;
height: 190rpx;
}
.display-inline-block{
display: inline-block;
}
</style>

13
service/oss.js

@ -0,0 +1,13 @@
import request from '@/common/request.js'
/**
* @description 获取oss权限
* @param { Object } params API参数
* @return { Promise }
*/
export async function getOssToken() {
return await request({
url: '/blade-resource/oss/endpoint/getUploadId',
method: 'get',
})
}
Loading…
Cancel
Save