15 changed files with 630 additions and 63 deletions
-
25App.vue
-
1common/SparkMD5.js
-
1common/bigc.js
-
71common/dateFtt.js
-
60common/directoss.js
-
33common/http.interceptor.js
-
109common/mixin.js
-
105common/request.js
-
27common/requestMessage.js
-
9common/sha1.min.js
-
25config/index.js
-
31main.js
-
7pages.json
-
176pages/login/login.vue
-
13service/oss.js
1
common/SparkMD5.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
1
common/bigc.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -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(":"); |
|||
} |
|||
} |
|||
@ -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的文件类型,如:image、video |
|||
* 图片上传调用: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 ''; |
|||
} |
|||
@ -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 |
|||
} |
|||
@ -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); |
|||
}) |
|||
}); |
|||
} |
|||
@ -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
File diff suppressed because it is too large
View File
@ -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 |
|||
} |
|||
})() |
|||
@ -1,26 +1,23 @@ |
|||
import Vue from 'vue' |
|||
import App from './App' |
|||
import uView from '@/uni_modules/uview-ui' |
|||
import mixin from '@/common/mixin.js'; |
|||
import httpInterceptor from '@/common/http.interceptor.js'; |
|||
|
|||
Vue.config.productionTip = false; |
|||
App.mpType = 'app' |
|||
|
|||
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({ |
|||
...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(); |
|||
@ -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> |
|||
@ -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', |
|||
}) |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue