Commit d83864e6 by wangcx1997

提交台粮道

parent 1f58acec
unpackage
<script>
import Vue from 'vue'
import {
getInvitaCode
} from '@/config/api.js'
export default {
onLaunch: function() {
console.log('App Launch')
const IMG_BASE_URL = "https://huarenv1.oss-cn-beijing.aliyuncs.com/huaren_icon/"
getInvitaCode('', {
suc: (res) => {
Vue.prototype.invateCode = res.data.code
}
})
uni.getSystemInfo({
success: function(e) {
//屏幕高度
Vue.prototype.ScreenHeight = uni.getSystemInfoSync().screenHeight;
// #ifndef MP
Vue.prototype.StatusBar = e.statusBarHeight;
if (e.platform == 'android') {
Vue.prototype.CustomBar = e.statusBarHeight + 50;
} else {
Vue.prototype.CustomBar = e.statusBarHeight + 45;
};
// #endif
// #ifdef MP-WEIXIN
Vue.prototype.StatusBar = e.statusBarHeight;
let custom = wx.getMenuButtonBoundingClientRect();
Vue.prototype.Custom = custom;
Vue.prototype.CustomBar = custom.bottom + custom.top - e.statusBarHeight;
// #endif
// #ifdef MP-ALIPAY
Vue.prototype.StatusBar = e.statusBarHeight;
Vue.prototype.CustomBar = e.statusBarHeight + e.titleBarHeight;
// #endif
}
})
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
/*每个页面公共css */
body {
background-color: #f1f1f1;
}
view {
box-sizing: border-box;
}
.status_bar {
height: var(--status-bar-height);
width: 100%;
}
/*单行*/
.singline {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;/*要显示的行数*/
overflow: hidden;
}
/*选项卡 插件v-tab 主要设置它的位置top*/
.tabs {
position: fixed;
/* #ifdef H5 */
top: 44px;
/* #endif */
/* #ifndef H5 */
top: 0;
/* #endif */
left: 0;
display: flex;
align-items: center;
width: 100%;
height: 100rpx;
box-sizing: border-box;
background-color: #fff;
box-shadow: 0px 0px 10rpx rgba(0, 0, 0, 0.1);
border-radius: 0px 0px 10rpx 10rpx;
z-index: 3;
}
.container-tabs__list {
height: 100%;
}
.container-tabs__swiper {
height: 100%;
}
/*分页*/
.loading-more {
align-items: center;
justify-content: center;
padding-top: 10px;
padding-bottom: 10px;
text-align: center;
}
.loading-more-text {
font-size: 28rpx;
color: #999;
}
</style>
<style lang="less">
/*每个页面公共css */
@import url("./static/style/cx-style.less");
/*自定义状态栏高度*/
.status-bar {
height: var(--status-bar-height);
width: 100%;
background-color: white;
}
/* https://www.jianshu.com/p/93d7104be420 、
去除自带的边框
*/
button {
background-color: white;
}
button::after {
border: none;
border-radius: 0;
}
button.theme {
width: calc(100% - 70rpx);
margin: 50rpx 35rpx 0 35rpx;
height: 88rpx;
line-height: 88rpx;
color: white;
font-size: 30rpx;
background-color: #21D183;
border-radius: 88rpx;
}
button.theme[disabled] {
color: white;
background-color: #DCDCDC;
}
uni-button.theme::after {
border: none;
}
</style>
\ No newline at end of file
export function adaptor(ctx) {
return Object.assign(ctx, {
setStrokeStyle(val) {
ctx.strokeStyle = val;
},
setLineWidth(val) {
ctx.lineWidth = val;
},
setLineCap(val) {
ctx.lineCap = val;
},
setFillStyle(val) {
ctx.fillStyle = val;
},
setFontSize(val) {
ctx.font = String(val);
},
setGlobalAlpha(val) {
ctx.globalAlpha = val;
},
setLineJoin(val) {
ctx.lineJoin = val;
},
setTextAlign(val) {
ctx.textAlign = val;
},
setMiterLimit(val) {
ctx.miterLimit = val;
},
setShadow(offsetX, offsetY, blur, color) {
ctx.shadowOffsetX = offsetX;
ctx.shadowOffsetY = offsetY;
ctx.shadowBlur = blur;
ctx.shadowColor = color;
},
setTextBaseline(val) {
ctx.textBaseline = val;
},
createCircularGradient() {},
draw() {},
});
}
/* eslint-disable */
export const GD = {
isGradient(bg) {
if (bg && (bg.startsWith('linear') || bg.startsWith('radial'))) {
return true;
}
return false;
},
doGradient(bg, width, height, ctx) {
if (bg.startsWith('linear')) {
linearEffect(width, height, bg, ctx);
} else if (bg.startsWith('radial')) {
radialEffect(width, height, bg, ctx);
}
},
}
function analizeGrad(string) {
const colorPercents = string.substring(0, string.length - 1).split("%,");
const colors = [];
const percents = [];
for (let colorPercent of colorPercents) {
colors.push(colorPercent.substring(0, colorPercent.lastIndexOf(" ")).trim());
percents.push(colorPercent.substring(colorPercent.lastIndexOf(" "), colorPercent.length) / 100);
}
return {
colors: colors,
percents: percents
};
}
function radialEffect(width, height, bg, ctx) {
const colorPer = analizeGrad(bg.match(/radial-gradient\((.+)\)/)[1]);
const grd = ctx.createCircularGradient(0, 0, width < height ? height / 2 : width / 2);
for (let i = 0; i < colorPer.colors.length; i++) {
grd.addColorStop(colorPer.percents[i], colorPer.colors[i]);
}
ctx.setFillStyle(grd);
}
function analizeLinear(bg, width, height) {
const direction = bg.match(/([-]?\d{1,3})deg/);
const dir = direction && direction[1] ? parseFloat(direction[1]) : 0;
let coordinate;
switch (dir) {
case 0:
coordinate = [0, -height / 2, 0, height / 2];
break;
case 90:
coordinate = [width / 2, 0, -width / 2, 0];
break;
case -90:
coordinate = [-width / 2, 0, width / 2, 0];
break;
case 180:
coordinate = [0, height / 2, 0, -height / 2];
break;
case -180:
coordinate = [0, -height / 2, 0, height / 2];
break;
default:
let x1 = 0;
let y1 = 0;
let x2 = 0;
let y2 = 0;
if (direction[1] > 0 && direction[1] < 90) {
x1 = (width / 2) - ((width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (
90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
} else if (direction[1] > -180 && direction[1] < -90) {
x1 = -(width / 2) + ((width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (
90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
} else if (direction[1] > 90 && direction[1] < 180) {
x1 = (width / 2) + (-(width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (
90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
} else {
x1 = -(width / 2) - (-(width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 *
(90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
}
coordinate = [x1, y1, x2, y2];
break;
}
return coordinate;
}
function linearEffect(width, height, bg, ctx) {
const param = analizeLinear(bg, width, height);
const grd = ctx.createLinearGradient(param[0], param[1], param[2], param[3]);
const content = bg.match(/linear-gradient\((.+)\)/)[1];
const colorPer = analizeGrad(content.substring(content.indexOf(',') + 1));
for (let i = 0; i < colorPer.colors.length; i++) {
grd.addColorStop(colorPer.percents[i], colorPer.colors[i]);
}
ctx.setFillStyle(grd);
}
<template>
<canvas v-if="use2dCanvas" :id="canvasId" type="2d" :style="style"></canvas>
<canvas v-else :canvas-id="canvasId" :style="style" :id="canvasId" :width="boardWidth * dpr" :height="boardHeight * dpr"></canvas>
</template>
<script>
import { toPx, base64ToPath, compareVersion} from './utils';
import { Draw } from './draw';
import { adaptor } from './canvas';
export default {
// version: '1.5.9.2',
name: 'l-painter',
props: {
board: Object,
fileType: {
type: String,
default: 'png'
},
width: [Number, String],
height: [Number, String],
pixelRatio: Number,
customStyle: String,
isRenderImage: Boolean,
isBase64ToPath: Boolean,
isH5PathToBase64: Boolean,
sleep: {
type: Number,
default: 1000/30
},
type: {
type: String,
default: '2d',
}
},
data() {
return {
// #ifndef MP-WEIXIN || MP-QQ
canvasId: `l-painter_${this._uid}`,
// #endif
// #ifdef MP-WEIXIN || MP-QQ
canvasId: `l-painter`,
// #endif
// #ifdef MP-WEIXIN
use2dCanvas: true,
// #endif
// #ifndef MP-WEIXIN
use2dCanvas: false,
// #endif
draw: null,
ctx: null
};
},
computed: {
newboard() {
return this.board && JSON.parse(JSON.stringify(this.board))
},
style() {
return `width:${this.boardWidth}px; height: ${this.boardHeight}px; ${this.customStyle}`;
},
dpr() {
return this.pixelRatio || uni.getSystemInfoSync().pixelRatio;
},
boardWidth() {
const { width = 200 } = this.board || {};
return toPx(this.width || width);
},
boardHeight() {
const { height = 200 } = this.board || {};
return toPx(this.height || height);
}
},
mounted() {
// #ifdef MP-WEIXIN
const {SDKVersion} = wx.getSystemInfoSync()
this.use2dCanvas = this.type === '2d' && compareVersion(SDKVersion, '2.9.2') >= 0;
// #endif
this.$watch('newboard', async (val, old) => {
if (JSON.stringify(val) === '{}' || !val) return;
const {width: w, height: h} = val || {};
const {width: ow, height: oh} = old || {};
if(w !== ow || h !== oh) {
this.inited = false;
}
this.render();
}, {
deep: true,
immediate: true,
})
},
methods: {
async render(args = {}, single = false) {
const ctx = await this.getContext()
const { use2dCanvas, boardWidth, boardHeight, board, canvas, isBase64ToPath, isH5PathToBase64, sleep } = this;
if (use2dCanvas && !canvas) {
return Promise.reject(new Error('render: fail canvas has not been created'));
}
if(!this.boundary) {
this.boundary = {
top: 0,
left: 0,
width: boardWidth,
height: boardHeight,
sleep
}
}
if(!single) {
ctx.clearRect(0, 0, boardWidth, boardHeight);
}
if(!this.draw) {
this.draw = new Draw(ctx, canvas, use2dCanvas, isH5PathToBase64, this.boundary);
}
if(JSON.stringify(args) != '{}' || board && JSON.stringify(board) != '{}') {
await this.draw.drawBoard(JSON.stringify(args) != '{}' ? args : board);
}
await new Promise(resolve => this.$nextTick(resolve))
if (!use2dCanvas && !single) {
await this.canvasDraw(ctx);
}
this.$emit('done')
if(this.isRenderImage && !single) {
this.canvasToTempFilePath()
.then(async res => {
if(/^data:image\/(\w+);base64/.test(res.tempFilePath) && isBase64ToPath) {
const img = await base64ToPath(res.tempFilePath)
this.$emit('success', img)
} else {
this.$emit('success', res.tempFilePath)
}
})
.catch(err => {
this.$emit('fail', err)
new Error(JSON.stringify(err))
console.error(111, JSON.stringify(err))
})
}
return Promise.resolve({ctx, draw: this.draw});
},
async custom(cb) {
const {ctx, draw} = await this.render({}, true)
ctx.save()
await cb(ctx, draw)
ctx.restore()
return Promise.resolve(true);
},
async single(args = {}) {
await this.render(args, true)
return Promise.resolve(true);
},
canvasDraw(flag = false) {
const {ctx} = this
return new Promise(resolve => {
ctx.draw(flag, () => {
resolve(true);
});
});
},
async getContext() {
if(this.ctx && this.inited) {
return Promise.resolve(this.ctx)
};
const { type, use2dCanvas, dpr, boardWidth, boardHeight } = this;
const _getContext = () => {
return new Promise(resolve => {
uni.createSelectorQuery()
.in(this)
.select('#' + this.canvasId)
.boundingClientRect()
.exec(res => {
if(res) {
const ctx = uni.createCanvasContext(this.canvasId, this);
if (!this.inited) {
this.inited = true;
this.use2dCanvas = false;
this.canvas = res
}
// #ifdef MP-ALIPAY
ctx.scale(dpr, dpr);
// #endif
this.ctx = ctx
resolve(ctx);
}
})
})
}
// #ifndef MP-WEIXIN
return _getContext()
// #endif
if(!use2dCanvas) {
return _getContext()
}
return new Promise(resolve => {
uni.createSelectorQuery()
.in(this)
.select('#l-painter')
.node()
.exec(res => {
const canvas = res[0].node;
if(!canvas) {
this.use2dCanvas = false;
return this.getContext()
}
const ctx = canvas.getContext(type);
if (!this.inited) {
this.inited = true;
canvas.width = boardWidth * dpr;
canvas.height = boardHeight * dpr;
this.use2dCanvas = true;
this.canvas = canvas
ctx.scale(dpr, dpr);
}
this.ctx = adaptor(ctx)
resolve(adaptor(ctx));
});
});
},
canvasToTempFilePath(args = {}) {
const {use2dCanvas, canvasId} = this
return new Promise((resolve, reject) => {
let { top = 0, left = 0, width, height } = this.boundary || this
let destWidth = width * this.dpr
let destHeight = height * this.dpr
// #ifdef MP-ALIPAY
width = width * this.dpr
height = height * this.dpr
// #endif
const copyArgs = {
x: left,
y: top,
width,
height,
destWidth,
destHeight,
canvasId,
fileType: args.fileType || this.fileType,
quality: args.quality || 1,
success: resolve,
fail: reject
}
if (use2dCanvas) {
delete copyArgs.canvasId
copyArgs.canvas = this.canvas
}
uni.canvasToTempFilePath(copyArgs, this)
})
}
}
};
</script>
<style></style>
// 请去下载覆盖:https://gitee.com/liangei/lime-painter/blob/master/qrcode.js
\ No newline at end of file
export function adaptor(ctx) {
return Object.assign(ctx, {
setStrokeStyle(val) {
ctx.strokeStyle = val;
},
setLineWidth(val) {
ctx.lineWidth = val;
},
setLineCap(val) {
ctx.lineCap = val;
},
setFillStyle(val) {
ctx.fillStyle = val;
},
setFontSize(val) {
ctx.font = String(val);
},
setGlobalAlpha(val) {
ctx.globalAlpha = val;
},
setLineJoin(val) {
ctx.lineJoin = val;
},
setTextAlign(val) {
ctx.textAlign = val;
},
setMiterLimit(val) {
ctx.miterLimit = val;
},
setShadow(offsetX, offsetY, blur, color) {
ctx.shadowOffsetX = offsetX;
ctx.shadowOffsetY = offsetY;
ctx.shadowBlur = blur;
ctx.shadowColor = color;
},
setTextBaseline(val) {
ctx.textBaseline = val;
},
createCircularGradient() {},
draw() {},
});
}
/* eslint-disable */
export const GD = {
isGradient(bg) {
if (bg && (bg.startsWith('linear') || bg.startsWith('radial'))) {
return true;
}
return false;
},
doGradient(bg, width, height, ctx) {
if (bg.startsWith('linear')) {
linearEffect(width, height, bg, ctx);
} else if (bg.startsWith('radial')) {
radialEffect(width, height, bg, ctx);
}
},
}
function analizeGrad(string) {
const colorPercents = string.substring(0, string.length - 1).split("%,");
const colors = [];
const percents = [];
for (let colorPercent of colorPercents) {
colors.push(colorPercent.substring(0, colorPercent.lastIndexOf(" ")).trim());
percents.push(colorPercent.substring(colorPercent.lastIndexOf(" "), colorPercent.length) / 100);
}
return {
colors: colors,
percents: percents
};
}
function radialEffect(width, height, bg, ctx) {
const colorPer = analizeGrad(bg.match(/radial-gradient\((.+)\)/)[1]);
const grd = ctx.createCircularGradient(0, 0, width < height ? height / 2 : width / 2);
for (let i = 0; i < colorPer.colors.length; i++) {
grd.addColorStop(colorPer.percents[i], colorPer.colors[i]);
}
ctx.setFillStyle(grd);
}
function analizeLinear(bg, width, height) {
const direction = bg.match(/([-]?\d{1,3})deg/);
const dir = direction && direction[1] ? parseFloat(direction[1]) : 0;
let coordinate;
switch (dir) {
case 0:
coordinate = [0, -height / 2, 0, height / 2];
break;
case 90:
coordinate = [width / 2, 0, -width / 2, 0];
break;
case -90:
coordinate = [-width / 2, 0, width / 2, 0];
break;
case 180:
coordinate = [0, height / 2, 0, -height / 2];
break;
case -180:
coordinate = [0, -height / 2, 0, height / 2];
break;
default:
let x1 = 0;
let y1 = 0;
let x2 = 0;
let y2 = 0;
if (direction[1] > 0 && direction[1] < 90) {
x1 = (width / 2) - ((width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (
90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
} else if (direction[1] > -180 && direction[1] < -90) {
x1 = -(width / 2) + ((width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (
90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
} else if (direction[1] > 90 && direction[1] < 180) {
x1 = (width / 2) + (-(width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (
90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
} else {
x1 = -(width / 2) - (-(width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 *
(90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
}
coordinate = [x1, y1, x2, y2];
break;
}
return coordinate;
}
function linearEffect(width, height, bg, ctx) {
const param = analizeLinear(bg, width, height);
const grd = ctx.createLinearGradient(param[0], param[1], param[2], param[3]);
const content = bg.match(/linear-gradient\((.+)\)/)[1];
const colorPer = analizeGrad(content.substring(content.indexOf(',') + 1));
for (let i = 0; i < colorPer.colors.length; i++) {
grd.addColorStop(colorPer.percents[i], colorPer.colors[i]);
}
ctx.setFillStyle(grd);
}
<template>
<canvas v-if="use2dCanvas" :id="canvasId" type="2d" :style="style"></canvas>
<canvas v-else :canvas-id="canvasId" :style="style" :id="canvasId" :width="boardWidth * dpr" :height="boardHeight * dpr"></canvas>
</template>
<script>
import { toPx, base64ToPath, compareVersion} from './utils';
import { Draw } from './draw';
import { adaptor } from './canvas';
export default {
// version: '1.5.9.2',
name: 'l-painter',
props: {
board: Object,
fileType: {
type: String,
default: 'png'
},
width: [Number, String],
height: [Number, String],
pixelRatio: Number,
customStyle: String,
isRenderImage: Boolean,
isBase64ToPath: Boolean,
isH5PathToBase64: Boolean,
sleep: {
type: Number,
default: 1000/30
},
type: {
type: String,
default: '2d',
}
},
data() {
return {
// #ifndef MP-WEIXIN || MP-QQ
canvasId: `l-painter_${this._uid}`,
// #endif
// #ifdef MP-WEIXIN || MP-QQ
canvasId: `l-painter`,
// #endif
// #ifdef MP-WEIXIN
use2dCanvas: true,
// #endif
// #ifndef MP-WEIXIN
use2dCanvas: false,
// #endif
draw: null,
ctx: null
};
},
computed: {
newboard() {
return this.board && JSON.parse(JSON.stringify(this.board))
},
style() {
return `width:${this.boardWidth}px; height: ${this.boardHeight}px; ${this.customStyle}`;
},
dpr() {
return this.pixelRatio || uni.getSystemInfoSync().pixelRatio;
},
boardWidth() {
const { width = 200 } = this.board || {};
return toPx(this.width || width);
},
boardHeight() {
const { height = 200 } = this.board || {};
return toPx(this.height || height);
}
},
mounted() {
// #ifdef MP-WEIXIN
const {SDKVersion} = wx.getSystemInfoSync()
this.use2dCanvas = this.type === '2d' && compareVersion(SDKVersion, '2.9.2') >= 0;
// #endif
this.$watch('newboard', async (val, old) => {
if (JSON.stringify(val) === '{}' || !val) return;
const {width: w, height: h} = val || {};
const {width: ow, height: oh} = old || {};
if(w !== ow || h !== oh) {
this.inited = false;
}
this.render();
}, {
deep: true,
immediate: true,
})
},
methods: {
async render(args = {}, single = false) {
const ctx = await this.getContext()
const { use2dCanvas, boardWidth, boardHeight, board, canvas, isBase64ToPath, isH5PathToBase64, sleep } = this;
if (use2dCanvas && !canvas) {
return Promise.reject(new Error('render: fail canvas has not been created'));
}
if(!this.boundary) {
this.boundary = {
top: 0,
left: 0,
width: boardWidth,
height: boardHeight,
sleep
}
}
if(!single) {
ctx.clearRect(0, 0, boardWidth, boardHeight);
}
if(!this.draw) {
this.draw = new Draw(ctx, canvas, use2dCanvas, isH5PathToBase64, this.boundary);
}
if(JSON.stringify(args) != '{}' || board && JSON.stringify(board) != '{}') {
await this.draw.drawBoard(JSON.stringify(args) != '{}' ? args : board);
}
await new Promise(resolve => this.$nextTick(resolve))
if (!use2dCanvas && !single) {
await this.canvasDraw(ctx);
}
this.$emit('done')
if(this.isRenderImage && !single) {
this.canvasToTempFilePath()
.then(async res => {
if(/^data:image\/(\w+);base64/.test(res.tempFilePath) && isBase64ToPath) {
const img = await base64ToPath(res.tempFilePath)
this.$emit('success', img)
} else {
this.$emit('success', res.tempFilePath)
}
})
.catch(err => {
this.$emit('fail', err)
new Error(JSON.stringify(err))
console.error(JSON.stringify(err))
})
}
return Promise.resolve({ctx, draw: this.draw});
},
async custom(cb) {
const {ctx, draw} = await this.render({}, true)
ctx.save()
await cb(ctx, draw)
ctx.restore()
return Promise.resolve(true);
},
async single(args = {}) {
await this.render(args, true)
return Promise.resolve(true);
},
canvasDraw(flag = false) {
const {ctx} = this
return new Promise(resolve => {
ctx.draw(flag, () => {
resolve(true);
});
});
},
async getContext() {
if(this.ctx && this.inited) {
return Promise.resolve(this.ctx)
};
const { type, use2dCanvas, dpr, boardWidth, boardHeight } = this;
const _getContext = () => {
return new Promise(resolve => {
uni.createSelectorQuery()
.in(this)
.select('#' + this.canvasId)
.boundingClientRect()
.exec(res => {
if(res) {
const ctx = uni.createCanvasContext(this.canvasId, this);
if (!this.inited) {
this.inited = true;
this.use2dCanvas = false;
this.canvas = res
}
// #ifdef MP-ALIPAY
ctx.scale(dpr, dpr);
// #endif
this.ctx = ctx
resolve(ctx);
}
})
})
}
// #ifndef MP-WEIXIN
return _getContext()
// #endif
if(!use2dCanvas) {
return _getContext()
}
return new Promise(resolve => {
uni.createSelectorQuery()
.in(this)
.select('#l-painter')
.node()
.exec(res => {
const canvas = res[0].node;
if(!canvas) {
this.use2dCanvas = false;
return this.getContext()
}
const ctx = canvas.getContext(type);
if (!this.inited) {
this.inited = true;
canvas.width = boardWidth * dpr;
canvas.height = boardHeight * dpr;
this.use2dCanvas = true;
this.canvas = canvas
ctx.scale(dpr, dpr);
}
this.ctx = adaptor(ctx)
resolve(adaptor(ctx));
});
});
},
canvasToTempFilePath(args = {}) {
const {use2dCanvas, canvasId} = this
return new Promise((resolve, reject) => {
let { top = 0, left = 0, width, height } = this.boundary || this
let destWidth = width * this.dpr
let destHeight = height * this.dpr
// #ifdef MP-ALIPAY
width = width * this.dpr
height = height * this.dpr
// #endif
const copyArgs = {
x: left,
y: top,
width,
height,
destWidth,
destHeight,
canvasId,
fileType: args.fileType || this.fileType,
quality: args.quality || 1,
success: resolve,
fail: reject
}
if (use2dCanvas) {
delete copyArgs.canvasId
copyArgs.canvas = this.canvas
}
uni.canvasToTempFilePath(copyArgs, this)
})
}
}
};
</script>
<style></style>
export default {
'contact': '\ue100',
'person': '\ue101',
'personadd': '\ue102',
'contact-filled': '\ue130',
'person-filled': '\ue131',
'personadd-filled': '\ue132',
'phone': '\ue200',
'email': '\ue201',
'chatbubble': '\ue202',
'chatboxes': '\ue203',
'phone-filled': '\ue230',
'email-filled': '\ue231',
'chatbubble-filled': '\ue232',
'chatboxes-filled': '\ue233',
'weibo': '\ue260',
'weixin': '\ue261',
'pengyouquan': '\ue262',
'chat': '\ue263',
'qq': '\ue264',
'videocam': '\ue300',
'camera': '\ue301',
'mic': '\ue302',
'location': '\ue303',
'mic-filled': '\ue332',
'speech': '\ue332',
'location-filled': '\ue333',
'micoff': '\ue360',
'image': '\ue363',
'map': '\ue364',
'compose': '\ue400',
'trash': '\ue401',
'upload': '\ue402',
'download': '\ue403',
'close': '\ue404',
'redo': '\ue405',
'undo': '\ue406',
'refresh': '\ue407',
'star': '\ue408',
'plus': '\ue409',
'minus': '\ue410',
'circle': '\ue411',
'checkbox': '\ue411',
'close-filled': '\ue434',
'clear': '\ue434',
'refresh-filled': '\ue437',
'star-filled': '\ue438',
'plus-filled': '\ue439',
'minus-filled': '\ue440',
'circle-filled': '\ue441',
'checkbox-filled': '\ue442',
'closeempty': '\ue460',
'refreshempty': '\ue461',
'reload': '\ue462',
'starhalf': '\ue463',
'spinner': '\ue464',
'spinner-cycle': '\ue465',
'search': '\ue466',
'plusempty': '\ue468',
'forward': '\ue470',
'back': '\ue471',
'left-nav': '\ue471',
'checkmarkempty': '\ue472',
'home': '\ue500',
'navigate': '\ue501',
'gear': '\ue502',
'paperplane': '\ue503',
'info': '\ue504',
'help': '\ue505',
'locked': '\ue506',
'more': '\ue507',
'flag': '\ue508',
'home-filled': '\ue530',
'gear-filled': '\ue532',
'info-filled': '\ue534',
'help-filled': '\ue535',
'more-filled': '\ue537',
'settings': '\ue560',
'list': '\ue562',
'bars': '\ue563',
'loop': '\ue565',
'paperclip': '\ue567',
'eye': '\ue568',
'arrowup': '\ue580',
'arrowdown': '\ue581',
'arrowleft': '\ue582',
'arrowright': '\ue583',
'arrowthinup': '\ue584',
'arrowthindown': '\ue585',
'arrowthinleft': '\ue586',
'arrowthinright': '\ue587',
'pulldown': '\ue588',
'closefill': '\ue589',
'sound': '\ue590',
'scan': '\ue612'
}
<template>
<view class="uni-navbar">
<view :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }" :style="{ 'background-color': backgroundColor }"
class="uni-navbar__content">
<uni-status-bar v-if="statusBar" />
<view :style="{ color: color,backgroundColor: backgroundColor }" class="uni-navbar__header uni-navbar__content_view">
<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left uni-navbar__content_view">
<view class="uni-navbar__content_view" v-if="leftIcon.length">
<uni-icons :color="color" :type="leftIcon" size="24" />
</view>
<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length }" class="uni-navbar-btn-text uni-navbar__content_view"
v-if="leftText.length">
<text :style="{ color: color, fontSize: '14px' }">{{ leftText }}</text>
</view>
<slot name="left" />
</view>
<view class="uni-navbar__header-container uni-navbar__content_view">
<view class="uni-navbar__header-container-inner uni-navbar__content_view" v-if="title.length">
<text class="uni-nav-bar-text" :style="{color: color }">{{ title }}</text>
</view>
<!-- 标题插槽 -->
<slot />
</view>
<view :class="title.length ? 'uni-navbar__header-btns-right' : ''" @tap="onClickRight" class="uni-navbar__header-btns uni-navbar__content_view">
<view class="uni-navbar__content_view" v-if="rightIcon.length">
<uni-icons :color="color" :type="rightIcon" size="24" />
</view>
<!-- 优先显示图标 -->
<view class="uni-navbar-btn-text uni-navbar__content_view" v-if="rightText.length && !rightIcon.length">
<text class="uni-nav-bar-right-text">{{ rightText }}</text>
</view>
<slot name="right" />
</view>
</view>
</view>
<view class="uni-navbar__placeholder" v-if="fixed">
<uni-status-bar v-if="statusBar" />
<view class="uni-navbar__placeholder-view" />
</view>
</view>
</template>
<script>
import uniStatusBar from "../uni-status-bar/uni-status-bar.vue";
import uniIcons from "../uni-icons/uni-icons.vue";
export default {
name: "UniNavBar",
components: {
uniStatusBar,
uniIcons
},
props: {
title: {
type: String,
default: ""
},
leftText: {
type: String,
default: ""
},
rightText: {
type: String,
default: ""
},
leftIcon: {
type: String,
default: ""
},
rightIcon: {
type: String,
default: ""
},
fixed: {
type: [Boolean, String],
default: false
},
color: {
type: String,
default: "#000000"
},
backgroundColor: {
type: String,
default: "#FFFFFF"
},
statusBar: {
type: [Boolean, String],
default: false
},
shadow: {
type: [String, Boolean],
default: false
},
border: {
type: [String, Boolean],
default: true
}
},
mounted() {
if(uni.report && this.title !== '') {
uni.report('title', this.title)
}
},
methods: {
onClickLeft() {
this.$emit("clickLeft");
},
onClickRight() {
this.$emit("clickRight");
}
}
};
</script>
<style lang="scss" scoped>
$nav-height: 44px;
.uni-nav-bar-text {
/* #ifdef APP-PLUS */
font-size: 34rpx;
/* #endif */
/* #ifndef APP-PLUS */
font-size: $uni-font-size-lg;
/* #endif */
}
.uni-nav-bar-right-text {
font-size: $uni-font-size-base;
}
.uni-navbar {
width: 750rpx;
}
.uni-navbar__content {
position: relative;
width: 750rpx;
background-color: $uni-bg-color;
overflow: hidden;
}
.uni-navbar__content_view {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
align-items: center;
flex-direction: row;
// background-color: #FFFFFF;
}
.uni-navbar__header {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
width: 750rpx;
height: $nav-height;
line-height: $nav-height;
font-size: 16px;
// background-color: #ffffff;
}
.uni-navbar__header-btns {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-wrap: nowrap;
width: 120rpx;
padding: 0 6px;
justify-content: center;
align-items: center;
}
.uni-navbar__header-btns-left {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
width: 150rpx;
justify-content: flex-start;
}
.uni-navbar__header-btns-right {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
width: 150rpx;
padding-right: 30rpx;
justify-content: flex-end;
}
.uni-navbar__header-container {
flex: 1;
}
.uni-navbar__header-container-inner {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
align-items: center;
justify-content: center;
font-size: $uni-font-size-base;
}
.uni-navbar__placeholder-view {
height: $nav-height;
}
.uni-navbar--fixed {
position: fixed;
z-index: 998;
}
.uni-navbar--shadow {
/* #ifndef APP-NVUE */
box-shadow: 0 1px 6px #ccc;
/* #endif */
}
.uni-navbar--border {
border-bottom-width: 1rpx;
border-bottom-style: solid;
border-bottom-color: $uni-border-color;
}
</style>
export default {
created() {
if (this.type === 'message') {
// 不显示遮罩
this.maskShow = false
// 获取子组件对象
this.childrenMsg = null
}
},
methods: {
customOpen() {
if (this.childrenMsg) {
this.childrenMsg.open()
}
},
customClose() {
if (this.childrenMsg) {
this.childrenMsg.close()
}
}
}
}
import message from './message.js';
// 定义 type 类型:弹出类型:top/bottom/center
const config = {
// 顶部弹出
top:'top',
// 底部弹出
bottom:'bottom',
// 居中弹出
center:'center',
// 消息提示
message:'top',
// 对话框
dialog:'center',
// 分享
share:'bottom',
}
export default {
data(){
return {
config:config
}
},
mixins: [message],
}
<template>
<view class="uni-popup-select">
<view class="uni-select-title">
<text class="uni-select-title-text">选择支付方式</text>
<view class="close" @click="close">
<image src="/static/ic_black_close.png"></image>
</view>
</view>
<view class="uni-select-content">
<view class="row" @click="changePay(1)">
<view class="pay-type">
<image mode="aspectFill" src="/static/plays@3x.png"></image>
<label>支付宝支付</label>
</view>
<image class="choose" :src="payType == 1 ? '/static/Selecti.png' : '/static/ic_now.png'"></image>
</view>
<view class="row" @click="changePay(2)">
<view class="pay-type">
<image mode="aspectFill" src="/static/WChat@3x.png"></image>
<label>微信支付</label>
</view>
<image class="choose" :src="payType == 2 ? '/static/Selecti.png' : '/static/ic_now.png'"></image>
</view>
<view class="row" @click="changePay(3)" v-if="fromType == 1">
<view class="pay-type">
<image mode="aspectFill" src="/static/banlance.png"></image>
<label>余额支付</label>
</view>
<image class="choose" :src="payType == 3 ? '/static/Selecti.png' : '/static/ic_now.png'"></image>
</view>
<view class="row">
<button @click="sure">确认支付</button>
</view>
</view>
</view>
</template>
<script>
import util from '@/utils/util.js'
import {
balancePay,
createAliPayOrder,
wxPayCreateOrder
} from '@/utils/api.js'
export default {
props: {
payAmount: {
type: Number
},
combineOrderNo: {
type: String
},
fromType: { //1购买物品 2申请代理 3购买tz
type: Number
},
},
name: 'UniPopupPay',
inject: ['popup'],
data() {
return {
payType: 1
}
},
methods: {
// 修改支付方式
changePay(type) {
this.payType = type
},
// 关闭窗口
close() {
this.popup.close()
},
// 确认支付
sure() {
var params = {}
if (this.payType == 1) { //支付宝支付 需要传
params['amount'] = this.payAmount
params["tradeNo"] = this.combineOrderNo
params["type"] = this.fromType
}
if (this.payType == 2) { //微信支付 需要传
params['totalFee'] = this.payAmount
params["outTradeNo"] = this.combineOrderNo
params["type"] = this.fromType
}
if (this.payType == 3) { //余额支付 需要传
params['combineOrderNo'] = this.combineOrderNo
params['payAmount'] = this.payAmount
params["payType"] = this.payType
}
if (this.payType == 1) {
console.log('支付包参赛')
console.log(params)
// 支付宝支付
createAliPayOrder(params, {
suc: res => {
uni.requestPayment({
provider: 'alipay',
orderInfo: res.data,
success: res => {
this.$emit('ok')
this.close()
},
fail: err => {
util.printLog(err)
}
})
}
})
} else if (this.payType == 2) {
console.log('微信参赛')
console.log(params)
// 微信支付
wxPayCreateOrder(params, {
suc: res => {
uni.requestPayment({
provider: 'wxpay',
orderInfo: res.result,
success: res => {
this.$emit('ok')
this.close()
},
fail: err => {
util.printLog(err)
}
})
}
})
}else if (this.payType == 3) {
console.log('余额参赛')
console.log(params)
// 余额支付
balancePay(params, {
suc: res => {
this.$emit('ok')
this.close()
}
})
}
}
}
}
</script>
<style scoped>
.uni-popup-select {
background-color: #fff;
}
.uni-select-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
height: 50px;
position: relative;
border-bottom: 1rpx solid #E8E8E8;
}
.uni-select-title-text {
font-size: 34rpx;
font-weight: bold;
color: #020202;
text-align: center;
}
.uni-select-title .close {
position: absolute;
right: 30rpx;
top: 32rpx;
}
.close image {
width: 30rpx;
height: 30rpx;
}
.uni-select-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.row {
display: flex;
flex-direction: row;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #F2F2F2;
}
.row .left {
flex: 1;
font-size: 26rpx;
color: #020202;
}
.left view:last-child {
font-size: 22rpx;
color: #AAAAAA;
}
.row .pay-type {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
font-size: 26rpx;
color: #020202;
}
.pay-type image {
width: 33rpx;
height: 33rpx;
margin-right: 10rpx;
}
.row .choose {
width: 30rpx;
height: 30rpx;
}
.row button {
width: 100vw;
height: 80rpx;
line-height: 88rpx;
color: white;
font-size: 30rpx;
background-color: #ff4229;
border-radius: 88rpx;
}
</style>
<template>
<view class="uni-popup-share">
<view class="uni-share-title"><text class="uni-share-title-text">{{title}}</text></view>
<view class="uni-share-content">
<view class="uni-share-content-box">
<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
<text class="uni-share-text">{{item.text}}</text>
</view>
</view>
</view>
<view class="uni-share-button-box">
<button class="uni-share-button" @click="close">取消</button>
</view>
</view>
</template>
<script>
export default {
name: 'UniPopupShare',
props: {
title: {
type: String,
default: '分享到'
}
},
inject: ['popup'],
data() {
return {
imgBaseUrl: null,
bottomData: [{
text: '微信',
icon: 'https://huarenv1.oss-cn-beijing.aliyuncs.com/huaren_icon/WeChatdl.png',
name: 'wx'
},
{
text: '朋友圈',
icon: 'https://huarenv1.oss-cn-beijing.aliyuncs.com/huaren_icon/friend.png',
name: 'wx'
}
]
}
},
created() {
this.imgBaseUrl = this.$api.IMG_BASE_URL
},
methods: {
/**
* 选择内容
*/
select(item, index) {
this.$emit('select', {
item,
index
}, () => {
this.popup.close()
})
},
/**
* 关闭窗口
*/
close() {
this.popup.close()
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup-share {
background-color: #fff;
}
.uni-share-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
height: 40px;
}
.uni-share-title-text {
font-size: 14px;
color: #666;
}
.uni-share-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 10px;
}
.uni-share-content-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
flex-wrap: wrap;
width: 360px;
}
.uni-share-content-item {
width: 90px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
padding: 10px 0;
align-items: center;
}
.uni-share-content-item:active {
background-color: #f5f5f5;
}
.uni-share-image {
width: 30px;
height: 30px;
}
.uni-share-text {
margin-top: 10px;
font-size: 14px;
color: #3B4144;
}
.uni-share-button-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: 10px 15px;
}
.uni-share-button {
flex: 1;
border-radius: 50px;
color: #666;
font-size: 16px;
}
.uni-share-button::after {
border-radius: 50px;
}
</style>
<template>
<view v-if="showPopup" class="uni-popup" :class="[popupstyle]" @touchmove.stop.prevent="clear">
<uni-transition v-if="maskShow" :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="showTrans"
@click="onTap" />
<uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
<view class="uni-popup__wrapper-box" @click.stop="clear">
<slot />
</view>
</uni-transition>
</view>
</template>
<script>
import uniTransition from '../uni-transition/uni-transition.vue'
import popup from './popup.js'
/**
* PopUp 弹出层
* @description 弹出层组件,为了解决遮罩弹层的问题
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [top|center|bottom] 弹出方式
* @value top 顶部弹出
* @value center 中间弹出
* @value bottom 底部弹出
* @value message 消息提示
* @value dialog 对话框
* @value share 底部分享示例
* @property {Boolean} animation = [ture|false] 是否开启动画
* @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
* @event {Function} change 打开关闭弹窗触发,e={show: false}
*/
export default {
name: 'UniPopup',
components: {
uniTransition
},
props: {
// 开启动画
animation: {
type: Boolean,
default: true
},
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
// message: 消息提示 ; dialog : 对话框
type: {
type: String,
default: 'center'
},
// maskClick
maskClick: {
type: Boolean,
default: true
}
},
provide() {
return {
popup: this
}
},
mixins: [popup],
watch: {
/**
* 监听type类型
*/
type: {
handler: function(newVal) {
this[this.config[newVal]]()
},
immediate: true
},
/**
* 监听遮罩是否可点击
* @param {Object} val
*/
maskClick(val) {
this.mkclick = val
}
},
data() {
return {
duration: 300,
ani: [],
showPopup: false,
showTrans: false,
maskClass: {
'position': 'fixed',
'bottom': 0,
'top': 0,
'left': 0,
'right': 0,
'backgroundColor': 'rgba(0, 0, 0, 0.4)'
},
transClass: {
'position': 'fixed',
'left': 0,
'right': 0,
},
maskShow: true,
mkclick: true,
popupstyle: 'top'
}
},
created() {
this.mkclick = this.maskClick
if (this.animation) {
this.duration = 300
} else {
this.duration = 0
}
},
methods: {
clear(e) {
// TODO nvue 取消冒泡
e.stopPropagation()
},
open() {
this.showPopup = true
this.$nextTick(() => {
new Promise(resolve => {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.showTrans = true
// fixed by mehaotian 兼容 app 端
this.$nextTick(() => {
resolve();
})
}, 50);
}).then(res => {
// 自定义打开事件
clearTimeout(this.msgtimer)
this.msgtimer = setTimeout(() => {
this.customOpen && this.customOpen()
}, 100)
this.$emit('change', {
show: true,
type: this.type
})
})
})
},
close(type) {
this.showTrans = false
this.$nextTick(() => {
this.$emit('change', {
show: false,
type: this.type
})
clearTimeout(this.timer)
// 自定义关闭事件
this.customOpen && this.customClose()
this.timer = setTimeout(() => {
this.showPopup = false
}, 300)
})
},
onTap() {
if (!this.mkclick) return
this.close()
},
/**
* 顶部弹出样式处理
*/
top() {
this.popupstyle = 'top'
this.ani = ['slide-top']
this.transClass = {
'position': 'fixed',
'left': 0,
'right': 0,
}
},
/**
* 底部弹出样式处理
*/
bottom() {
this.popupstyle = 'bottom'
this.ani = ['slide-bottom']
this.transClass = {
'position': 'fixed',
'left': 0,
'right': 0,
'bottom': 0
}
},
/**
* 中间弹出样式处理
*/
center() {
this.popupstyle = 'center'
this.ani = ['zoom-out', 'fade']
this.transClass = {
'position': 'fixed',
/* #ifndef APP-NVUE */
'display': 'flex',
'flexDirection': 'column',
/* #endif */
'bottom': 0,
'left': 0,
'right': 0,
'top': 0,
'justifyContent': 'center',
'alignItems': 'center'
}
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup {
position: fixed;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-popup__mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: $uni-bg-color-mask;
opacity: 0;
}
.mask-ani {
transition-property: opacity;
transition-duration: 0.2s;
}
.uni-top-mask {
opacity: 1;
}
.uni-bottom-mask {
opacity: 1;
}
.uni-center-mask {
opacity: 1;
}
.uni-popup__wrapper {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: absolute;
}
.top {
/* #ifdef H5 */
top: var(--window-top);
/* #endif */
/* #ifndef H5 */
top: 0;
/* #endif */
}
.bottom {
bottom: 0;
}
.uni-popup__wrapper-box {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: relative;
/* iphonex 等安全区设置,底部安全区适配 */
/* #ifndef APP-NVUE */
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
/* #endif */
}
.content-ani {
// transition: transform 0.3s;
transition-property: transform, opacity;
transition-duration: 0.2s;
}
.uni-top-content {
transform: translateY(0);
}
.uni-bottom-content {
transform: translateY(0);
}
.uni-center-content {
transform: scale(1);
opacity: 1;
}
</style>
<template>
<view :style="{ height: statusBarHeight }" class="uni-status-bar">
<slot />
</view>
</template>
<script>
var statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px'
export default {
name: 'UniStatusBar',
data() {
return {
statusBarHeight: statusBarHeight
}
}
}
</script>
<style lang="scss" scoped>
.uni-status-bar {
width: 750rpx;
height: 20px;
background-color: white;
// height: var(--status-bar-height);
}
</style>
<template>
<view v-if="isShow" ref="ani" class="uni-transition" :class="[ani.in]" :style="'transform:' +transform+';'+stylesObject"
@click="change">
<slot></slot>
</view>
</template>
<script>
// #ifdef APP-NVUE
const animation = uni.requireNativePlugin('animation');
// #endif
/**
* Transition 过渡动画
* @description 简单过渡动画组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=985
* @property {Boolean} show = [false|true] 控制组件显示或隐藏
* @property {Array} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
* @value fade 渐隐渐出过渡
* @value slide-top 由上至下过渡
* @value slide-right 由右至左过渡
* @value slide-bottom 由下至上过渡
* @value slide-left 由左至右过渡
* @value zoom-in 由小到大过渡
* @value zoom-out 由大到小过渡
* @property {Number} duration 过渡动画持续时间
* @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
*/
export default {
name: 'uniTransition',
props: {
show: {
type: Boolean,
default: false
},
modeClass: {
type: Array,
default () {
return []
}
},
duration: {
type: Number,
default: 300
},
styles: {
type: Object,
default () {
return {}
}
}
},
data() {
return {
isShow: false,
transform: '',
ani: { in: '',
active: ''
}
};
},
watch: {
show: {
handler(newVal) {
if (newVal) {
this.open()
} else {
this.close()
}
},
immediate: true
}
},
computed: {
stylesObject() {
let styles = {
...this.styles,
'transition-duration': this.duration / 1000 + 's'
}
let transfrom = ''
for (let i in styles) {
let line = this.toLine(i)
transfrom += line + ':' + styles[i] + ';'
}
return transfrom
}
},
created() {
// this.timer = null
// this.nextTick = (time = 50) => new Promise(resolve => {
// clearTimeout(this.timer)
// this.timer = setTimeout(resolve, time)
// return this.timer
// });
},
methods: {
change() {
this.$emit('click', {
detail: this.isShow
})
},
open() {
clearTimeout(this.timer)
this.isShow = true
this.transform = ''
this.ani.in = ''
for (let i in this.getTranfrom(false)) {
if (i === 'opacity') {
this.ani.in = 'fade-in'
} else {
this.transform += `${this.getTranfrom(false)[i]} `
}
}
this.$nextTick(() => {
setTimeout(() => {
this._animation(true)
}, 50)
})
},
close(type) {
clearTimeout(this.timer)
this._animation(false)
},
_animation(type) {
let styles = this.getTranfrom(type)
// #ifdef APP-NVUE
if(!this.$refs['ani']) return
animation.transition(this.$refs['ani'].ref, {
styles,
duration: this.duration, //ms
timingFunction: 'ease',
needLayout: false,
delay: 0 //ms
}, () => {
if (!type) {
this.isShow = false
}
this.$emit('change', {
detail: this.isShow
})
})
// #endif
// #ifndef APP-NVUE
this.transform = ''
for (let i in styles) {
if (i === 'opacity') {
this.ani.in = `fade-${type?'out':'in'}`
} else {
this.transform += `${styles[i]} `
}
}
this.timer = setTimeout(() => {
if (!type) {
this.isShow = false
}
this.$emit('change', {
detail: this.isShow
})
}, this.duration)
// #endif
},
getTranfrom(type) {
let styles = {
transform: ''
}
this.modeClass.forEach((mode) => {
switch (mode) {
case 'fade':
styles.opacity = type ? 1 : 0
break;
case 'slide-top':
styles.transform += `translateY(${type?'0':'-100%'}) `
break;
case 'slide-right':
styles.transform += `translateX(${type?'0':'100%'}) `
break;
case 'slide-bottom':
styles.transform += `translateY(${type?'0':'100%'}) `
break;
case 'slide-left':
styles.transform += `translateX(${type?'0':'-100%'}) `
break;
case 'zoom-in':
styles.transform += `scale(${type?1:0.8}) `
break;
case 'zoom-out':
styles.transform += `scale(${type?1:1.2}) `
break;
}
})
return styles
},
_modeClassArr(type) {
let mode = this.modeClass
if (typeof(mode) !== "string") {
let modestr = ''
mode.forEach((item) => {
modestr += (item + '-' + type + ',')
})
return modestr.substr(0, modestr.length - 1)
} else {
return mode + '-' + type
}
},
// getEl(el) {
// console.log(el || el.ref || null);
// return el || el.ref || null
// },
toLine(name) {
return name.replace(/([A-Z])/g, "-$1").toLowerCase();
}
}
}
</script>
<style>
.uni-transition {
transition-timing-function: ease;
transition-duration: 0.3s;
transition-property: transform, opacity;
}
.fade-in {
opacity: 0;
}
.fade-active {
opacity: 1;
}
.slide-top-in {
/* transition-property: transform, opacity; */
transform: translateY(-100%);
}
.slide-top-active {
transform: translateY(0);
/* opacity: 1; */
}
.slide-right-in {
transform: translateX(100%);
}
.slide-right-active {
transform: translateX(0);
}
.slide-bottom-in {
transform: translateY(100%);
}
.slide-bottom-active {
transform: translateY(0);
}
.slide-left-in {
transform: translateX(-100%);
}
.slide-left-active {
transform: translateX(0);
opacity: 1;
}
.zoom-in-in {
transform: scale(0.8);
}
.zoom-out-active {
transform: scale(1);
}
.zoom-out-in {
transform: scale(1.2);
}
</style>
## 插件说明
> 这是 `v-tabs` 插件的升级版本,参数上有很大变动,支持 `H5` `小程序` `手机端`,如果是在之前的插件上升级的话,请注意参数的变更,触发的事件没有变更。
## 使用说明
### 1、最基本用法
- 视图文件
```html
<v-tabs v-model="current" :tabs="tabs" @change="changeTab"></v-tabs>
```
- 脚本文件
```js
export default {
data() {
return {
current: 0,
tabs: ['军事', '国内', '新闻新闻', '军事', '国内', '新闻', '军事', '国内', '新闻']
}
},
methods: {
changeTab(index) {
console.log('当前选中的项:' + index)
}
}
}
```
### 2、平铺整个屏幕
- 视图文件
```html
<v-tabs v-model="activeTab" :scroll="false" :tabs="['全部', '进行中', '已完成']"></v-tabs>
```
- 脚本文件
```js
export default {
data() {
return {
activeTab: 0
}
}
}
```
### 3、胶囊用法
- 视图文件
```html
<v-tabs v-model="current" :tabs="tabs" :pills="true" line-height="0" activeColor="#fff" @change="changeTab"></v-tabs>
```
- 脚本文件
```js
data() {
return {
current: 2,
tabs: [
'军事',
'国内',
'新闻新闻',
'军事',
'国内',
'新闻',
'军事',
'国内',
'新闻',
],
},
methods: {
changeTab(index) {
console.log('当前选中索引:' + index)
}
}
}
```
## 文档说明
### 1、属性说明
| 参数 | 类型 | 默认值 | 说明 |
| :---------------: | :-----: | :-------: | :----------------------------------------: |
| value | Number | 0 | 必传(双向绑定的值) |
| color | String | '#333' | 默认文字颜色 |
| activeColor | String | '#2979ff' | 选中文字的颜色 |
| fontSize | String | '28rpx' | 默认文字大小(rpx 或 px) |
| bold | Boolean | true | 是否加粗选中项 |
| scroll | Boolean | true | 是否显示滚动条,平铺设置 false |
| height | String | '70rpx' | tab 高度(rpx 或 px) |
| lineHeight | String | '10rpx' | 滑块高度(rpx 或 px) |
| lineColor | String | '#2979ff' | 滑块的颜色 |
| lineScale | Number | 0.5 | 滑块宽度缩放值 |
| lineRadius | String | '10rpx' | 滑块圆角宽度(rpx 或 px) |
| pills | Boolean | false | 是否开启胶囊 |
| pillsColor | String | '#2979ff' | 胶囊背景颜色(rpx 或 px) |
| pillsBorderRadius | String | '10rpx' | 胶囊圆角宽度(rpx 或 px) |
| field | String | '' | 如果 tabs 子项是对象,输入需要展示的键名 |
| bgColor | String | '#fff' | 背景色,支持 linear-gradient 渐变 |
| padding | String | '0' | 整个 tab padding 属性 |
| fixed | Boolean | false | 是否固定在顶部 |
| paddingItem | String | '0 22rpx' | 选项的边距(设置上下不生效,需要设置高度) |
### 2、事件说明
| 名称 | 参数 | 说明 |
| :----: | :---: | :--------------------------------: |
| change | index | 改变选中项触发, index 选中项的下标 |
## 更新日志
### 2020-09-24
1. 修复 `v-tabs` 第一次可能出现第一个标签显示不完整的情况
2. 修改了 `pages/tabs/order` 示例文件
### 2020-09-21
1. 修复添加 `fixed` 属性后,滚动条无效
2. 修复选项很少的情况下,下划线计算计算错误
3. 新增 `paddingItem` 属性,设置选项左右边距(上下边距需要设置 `height` 属性,或者设置 `padding` 属性)
**写在最后:**
欢迎各位老铁反馈 bug ,本人后端 PHP 一枚,只是应为感兴趣前端,自己琢磨,自己搞。如果你在使用的过程中有什么不合理,需要优化的,都可以在下面评论(或加我 QQ: 1207791534),本人看见后回复、修正,感谢。
### 2020-09-17
1. 紧急修复 bug,横向滑动不了的情况
### 2020-09-16
1. 新增 `fixed` 属性,是否固定在顶部,示例地址:`pages/tabs/tabs-static`
2. 优化之前的页面结构
**注意:**
1. 使用 `padding` 属性的时候,尽量不要左右边距,会导致下划线位置不对
2. 如果不绑定 `v-model` 会导致 `change` 事件改变的时候,下划线不跟随问题
### 2020-09-09
1. 修复 `width` 错误,dom 加载的时候没有及时获取到 `data` 属性导致的。
### 2020-08-29
1. 优化异步改变 `tabs` 后,下划线不初始化问题
2. `github` 地址上有图 2 的源码,需要的自行下载,页面路径:`pages/tabs/order`
### 2020-08-20
1. 优化 `节点查询``选中渲染`
2. 优化支付宝中 `createSelectorQuery()` 的影响
### 2020-08-19
1. 优化 `change` 事件触发机制
### 2020-08-16
1. 修改默认高度为 `70rpx`
2. 新增属性 `bgColor`,可设置背景颜色,默认 `#fff`
3. 新增整个 `tab``padding` 属性,默认 `0`
### 2020-08-13
1. 全新的 `v-tabs 2.0`
2. 支持 `H5` `小程序` `APP`
3. 属性高度可配置
## 预览
![v-tabs 2.0.1.gif](https://tva1.sinaimg.cn/large/007S8ZIlgy1ghsv40mj76g30ai0i2tsd.gif)
![v-tabs 2.0.2.gif](https://img-cdn-aliyun.dcloud.net.cn/stream/plugin_screens/42f3a920-a674-11ea-8a24-ffee00625e2e_1.png?v=1597912963)
<template>
<view :id="elId" class="v-tabs">
<scroll-view
id="scrollContainer"
:scroll-x="scroll"
:scroll-left="scroll ? scrollLeft : 0"
:scroll-with-animation="scroll"
:style="{ position: fixed ? 'fixed' : 'relative', zIndex: 1993 }"
>
<view
class="v-tabs__container"
:style="{
display: scroll ? 'inline-flex' : 'flex',
whiteSpace: scroll ? 'nowrap' : 'normal',
background: bgColor,
height,
padding
}"
>
<view
class="v-tabs__container-item"
v-for="(v, i) in tabs"
:key="i"
:style="{
color: current == i ? activeColor : color,
fontSize: current == i ? fontSize : fontSize,
fontWeight: bold && current == i ? 'bold' : '',
justifyContent: !scroll ? 'center' : '',
flex: scroll ? '' : 1,
padding: paddingItem
}"
@click="change(i)"
>
{{ field ? v[field] : v }}
</view>
<view
v-if="!pills"
class="v-tabs__container-line"
:style="{
background: lineColor,
width: lineWidth + 'px',
height: lineHeight,
borderRadius: lineRadius,
left: lineLeft + 'px',
transform: `translateX(-${lineWidth / 2}px)`
}"
></view>
<view
v-else
class="v-tabs__container-pills"
:style="{
background: pillsColor,
borderRadius: pillsBorderRadius,
left: pillsLeft + 'px',
width: currentWidth + 'px',
height
}"
></view>
</view>
</scroll-view>
<view
class="v-tabs__placeholder"
:style="{
height: fixed ? height : '0',
padding
}"
></view>
</view>
</template>
<script>
/**
* v-tabs
* @property {Number} value 选中的下标
* @property {Array} tabs tabs 列表
* @property {String} bgColor = '#fff' 背景颜色
* @property {String} color = '#333' 默认颜色
* @property {String} activeColor = '#2979ff' 选中文字颜色
* @property {String} fontSize = '28rpx' 默认文字大小
* @property {String} activeFontSize = '28rpx' 选中文字大小
* @property {Boolean} bold = [true | false] 选中文字是否加粗
* @property {Boolean} scroll = [true | false] 是否滚动
* @property {String} height = '60rpx' tab 的高度
* @property {String} lineHeight = '10rpx' 下划线的高度
* @property {String} lineColor = '#2979ff' 下划线的颜色
* @property {Number} lineScale = 0.5 下划线的宽度缩放比例
* @property {String} lineRadius = '10rpx' 下划线圆角
* @property {Boolean} pills = [true | false] 是否胶囊样式
* @property {String} pillsColor = '#2979ff' 胶囊背景色
* @property {String} pillsBorderRadius = '10rpx' 胶囊圆角大小
* @property {String} field 如果是对象,显示的键名
* @property {Boolean} fixed = [true | false] 是否固定
* @property {String} paddingItem = '0 22rpx' 选项的边距
*
* @event {Function(current)} change 改变标签触发
*/
export default {
props: {
value: {
type: Number,
default: 0
},
tabs: {
type: Array,
default() {
return []
}
},
bgColor: {
type: String,
default: '#fff'
},
padding: {
type: String,
default: '0'
},
color: {
type: String,
default: '#333'
},
activeColor: {
type: String,
default: '#2979ff'
},
fontSize: {
type: String,
default: '28rpx'
},
activeFontSize: {
type: String,
default: '32rpx'
},
bold: {
type: Boolean,
default: true
},
scroll: {
type: Boolean,
default: true
},
height: {
type: String,
default: '70rpx'
},
lineColor: {
type: String,
default: '#2979ff'
},
lineHeight: {
type: String,
default: '10rpx'
},
lineScale: {
type: Number,
default: 0.5
},
lineRadius: {
type: String,
default: '10rpx'
},
pills: {
type: Boolean,
deafult: false
},
pillsColor: {
type: String,
default: '#2979ff'
},
pillsBorderRadius: {
type: String,
default: '10rpx'
},
field: {
type: String,
default: ''
},
fixed: {
type: Boolean,
default: false
},
paddingItem: {
type: String,
default: '0 22rpx'
}
},
data() {
return {
elId: '',
lineWidth: 30,
currentWidth: 0, // 当前选项的宽度
lineLeft: 0, // 滑块距离左侧的位置
pillsLeft: 0, // 胶囊距离左侧的位置
scrollLeft: 0, // 距离左边的位置
containerWidth: 0, // 容器的宽度
current: 0 // 当前选中项
}
},
watch: {
value(newVal) {
this.current = newVal
this.$nextTick(() => {
this.getTabItemWidth()
})
},
current(newVal) {
this.$emit('input', newVal)
},
tabs(newVal) {
this.$nextTick(() => {
this.getTabItemWidth()
})
}
},
methods: {
// 产生随机字符串
randomString(len) {
len = len || 32
let $chars =
'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678' /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
let maxPos = $chars.length
let pwd = ''
for (let i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos))
}
return pwd
},
// 切换事件
change(index) {
if (this.current !== index) {
this.current = index
this.$emit('change', index)
}
},
// 获取左移动位置
getTabItemWidth() {
let query = uni
.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(this)
// #endif
// 获取容器的宽度
query
.select(`#scrollContainer`)
.boundingClientRect((data) => {
if (!this.containerWidth && data) {
this.containerWidth = data.width
}
})
.exec()
// 获取所有的 tab-item 的宽度
query
.selectAll('.v-tabs__container-item')
.boundingClientRect((data) => {
if (!data) {
return
}
let lineLeft = 0
let currentWidth = 0
if (data) {
for (let i = 0; i < data.length; i++) {
if (i < this.current) {
lineLeft += data[i].width
} else if (i == this.current) {
currentWidth = data[i].width
} else {
break
}
}
}
// 当前滑块的宽度
this.currentWidth = currentWidth
// 缩放后的滑块宽度
this.lineWidth = currentWidth * this.lineScale * 1
// 滑块作移动的位置
this.lineLeft = lineLeft + currentWidth / 2
// 胶囊距离左侧的位置
this.pillsLeft = lineLeft
// 计算滚动的距离左侧的位置
if (this.scroll) {
this.scrollLeft = this.lineLeft - this.containerWidth / 2
}
})
.exec()
}
},
mounted() {
this.elId = 'xfjpeter_' + this.randomString()
this.current = this.value
this.$nextTick(() => {
this.getTabItemWidth()
})
}
}
</script>
<style lang="scss" scoped>
.v-tabs {
width: 100%;
box-sizing: border-box;
overflow: hidden;
::-webkit-scrollbar {
display: none;
}
&__container {
min-width: 100%;
position: relative;
display: inline-flex;
align-items: center;
white-space: nowrap;
overflow: hidden;
&-item {
display: flex;
align-items: center;
height: 100%;
position: relative;
z-index: 10;
// padding: 0 11px;
transition: all 0.3s;
white-space: nowrap;
}
&-line {
position: absolute;
bottom: 0;
transition: all 0.3s linear;
}
&-pills {
position: absolute;
transition: all 0.3s linear;
z-index: 9;
}
}
}
</style>
This diff is collapsed. Click to expand it.
// uni框架的方法封装
const main = {
// 显示消息提示窗
showToast: (title = '', duration = 1500, icon = 'none') => {
uni.showToast({
icon: icon,
title: title,
duration: duration
})
},
// 隐藏消息提示窗
hideToast: () => {
uni.hideToast()
},
// 显示loadding提示窗 需主动调用 hideLoading 才能关闭提示框
showLoading: (title = '') => {
uni.showLoading({
title: title
})
},
// 隐藏loadding提示窗
hideLoading: (duration = 0) => {
setTimeout(function () {
uni.hideLoading()
}, duration)
},
// 显示模态提示框
showModal: (content = '', title = '提示', showCancel = true, confirmText = '确定', cancelText = '取消', confirmColor = '#50A8FC', cancelColor = '#9b9b9b') => {
if (content && content instanceof Object) {
let data = content
title = data.title || title
showCancel = data.showCancel || showCancel
confirmText = data.confirmText || confirmText
cancelText = data.cancelText || cancelText
confirmColor = data.confirmColor || confirmColor
cancelColor = data.cancelColor || cancelColor
content = data.content || ''
}
var promise = new Promise(function (resolve, reject) {
uni.showModal({
title: title, // 标题
content: content, // 内容
showCancel: showCancel, // 是否显示取消按钮
confirmText: confirmText, // 确认按钮文字
cancelText: cancelText, // 取消按钮文字
confirmColor: confirmColor, // 确认按钮颜色
cancelColor: cancelColor, // 取消按钮颜色
success: function (res) {
if (res.confirm) {
resolve(true)
} else if (res.cancel) {
resolve(false)
}
}
})
})
return promise
},
// 显示从底部弹出的操作菜单
showActionSheet: (itemList = [], itemColor = '#333333') => {
var promise = new Promise(function (resolve, reject) {
uni.showActionSheet({
itemList: itemList, // 菜单列表
itemColor: itemColor, // 选项文字
success (res) {
resolve(res.tapIndex)
},
fail (res) {
resolve(false)
}
})
})
return promise
},
// 动态设置当前页面的标题
setNavigationBarTitle: (title = '') => {
uni.setNavigationBarTitle({
title: title
})
},
//将页面滚动到目标位置
pageScrollTo: (scrollTop, selector, duration = 300) => {
uni.pageScrollTo({
scrollTop: scrollTop,
selector: selector, // 选择器(id、class)
duration: duration
})
},
//获取当前位置(经度、纬度)
getLocation: (type = 'wgs84') => {
var promise = new Promise((resolve, reject) => {
uni.getLocation({
type: type,
success: res => {
resolve(res)
},
fail: err => {
reject(err)
}
})
})
return promise
},
// 复制文本内容
setClipboardData: (data, msg = '') => {
uni.setClipboardData({
data: data, // 复制的文本
success: function () {
if (msg) {
main.showToast(msg, 1000)
}
}
})
},
// 支付
requestPayment: (type, orderInfo) => {
var promise = new Promise (function (resolve, reject) {
uni.requestPayment({
provider: type,
orderInfo: orderInfo,
success: (res) => {
resolve (res)
},
fail: (err) => {
// console.log('err', err)
}
})
})
return promise
},
// 登录
uniLogin: (type) => {
var promise = new Promise (function (resolve, reject) {
uni.login({
provider: type,
success: (res) => {
resolve(res)
},
fail: (err) => {
reject(err)
}
})
})
return promise
}
}
export default main
\ No newline at end of file
// 配置路由
const path = {
// 跳转到非tabBar的子页面
navigateTo (url) {
uni.navigateTo({
url: url
})
},
// 跳转到tabBar页面
switchTab (url) {
uni.switchTab({
url: url
})
},
// 重定向跳转
redirectTo (url) {
uni.redirectTo({
url: url
})
},
// 关闭所有页面,跳转一个新页面
reLaunch (url) {
uni.reLaunch({
url: url
})
},
// 返回上一个页面
navigateBack (count) {
uni.navigateBack({
delta: count
})
},
// 预加载页面,打开时速度更快
preloadPage (url) {
uni.preloadPage({
url: url
})
}
}
export default path
// 缓存封装
const store = {
// 存缓存
setStorage: (key, data) => {
uni.setStorage({
key: key,
data: data
})
},
// 存缓存(同步)
setStorageSync: (key, data) => {
try {
uni.setStorageSync(key, data)
} catch (e) {
// error
}
},
// 取缓存 (异步)
getStorage(key) {
var promise = new Promise((resolve, reject) => {
uni.getStorage({
key: key,
success (res) {
resolve(res.data)
},
fail (err) {
},
complete (res) {
}
})
})
return promise
},
// 取缓存(同步)
getStorageSync(key) {
return uni.getStorageSync(key)
},
// 移除缓存(异步)
removeStorage(key) {
uni.removeStorage({
key: key
})
},
// 移除缓存(同步)
removeStorageSync(key) {
uni.removeStorageSync(key)
},
// 清空缓存(异步)
clearStorage: () => {
uni.clearStorage()
},
//清空缓存(同步)
clearStorageSync: () => {
uni.clearStorageSync()
}
}
export default store
\ No newline at end of file
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [hour, minute].map(formatNumber).join(':')
}
const formatDate = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('-')
}
const showIntervalTime = (currentTime, nowTime) => {
var time = Math.floor((nowTime - currentTime) / 1000)
var str = ''
if (time < 60) {
str = '1分钟'
} else if (time > 60 && time < 3600) {
str = Math.ceil(time / 60) + '分钟'
} else if (time > 3600 && time < 3600 * 24) {
str = Math.ceil(time / 3600) + '小时'
} else {
str = Math.ceil(time / (3600 * 24)) + '天'
}
return str
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
const getDistance = (la1, lo1, la2, lo2) => {
var La1 = la1 * Math.PI / 180.0
var La2 = la2 * Math.PI / 180.0
var La3 = La1 - La2
var Lb3 = lo1 * Math.PI / 180.0 - lo2 * Math.PI / 180.0
var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(La3 / 2), 2) + Math.cos(La1) * Math.cos(La2) * Math.pow(Math.sin(
Lb3 / 2), 2)))
s = s * 6378.137
s = Math.round(s * 10000) / 10000
s = s > 1 ? s.toFixed(2) + 'km' : (s * 1000).toFixed(0) + 'm'
return s
}
const hidePhone = (phone) => {
if (phone) {
return phone.substring(0, 3) + '****' + phone.substring(7)
} else {
return ''
}
}
//从存储去获取用户信息
const getUsersInfoByStore = () => {
var obj = {}
if (uni.getStorageSync('user')) {
let userInfoStr = uni.getStorageSync('user')
obj = JSON.parse(userInfoStr)
}
return obj
}
// 搜索历史
const getSearchHistory = () => {
let history = []
let historyStr = uni.getStorageSync('search')
if (historyStr) {
history = historyStr.split(',')
}
return history
}
// 设置搜索历史
const addSearchHistory = (word) => {
let history = getSearchHistory()
if (history.indexOf(word) != -1) {
history.splice(history.indexOf(word), 1)
}
history.unshift(word)
uni.setStorageSync('search', history.join(','))
}
// 清空搜索历史
const clearSearchHistory = () => {
uni.setStorageSync('search', '')
}
// 微信分享 朋友圈/好友
const wetchatShare = (scene, href, title, summary, imageUrl) => {
//如果没图片就用logo图
var imgUrl = (imageUrl.length > 0) ? imageUrl : 'https://yun-kuang.oss-cn-hangzhou.aliyuncs.com/upload/test/ic_logo_1603180073960.png';
uni.share({
provider: "weixin",
scene: scene,
type: 0,
href: href,
title: title,
summary: summary,
imageUrl: imgUrl,//decodeURIComponent(imageUrl),//还是显示不了
success: function(res) {
uni.showToast({
title: '分享成功',
icon: 'none'
})
},
fail: function(err) {
console.log("fail:" + JSON.stringify(err));
uni.showToast({
title: '分享失败',
icon: 'none'
})
}
});
}
//转rgb
//https://blog.csdn.net/mossbaoo/article/details/93484635
const colorRgb = (oldColor,rgb) => {
// 16进制颜色值的正则
var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
// 把颜色值变成小写
var color = oldColor.toLowerCase();
if (reg.test(color)) {
// 如果只有三位的值,需变成六位,如:#fff => #ffffff
if (color.length === 4) {
var colorNew = "#";
for (var i = 1; i < 4; i += 1) {
colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1));
}
color = colorNew;
}
// 处理六位的颜色值,转为RGB
var colorChange = [];
for (var i = 1; i < 7; i += 2) {
colorChange.push(parseInt("0x" + color.slice(i, i + 2)));
}
return "RGB(" + colorChange.join(",") + "," + rgb +")";
} else {
return color;
}
}
module.exports = {
formatTime: formatTime,
formatDate: formatDate,
showIntervalTime: showIntervalTime,
getDistance: getDistance,
hidePhone: hidePhone,
getSearchHistory: getSearchHistory,
addSearchHistory: addSearchHistory,
clearSearchHistory: clearSearchHistory,
getUsersInfoByStore: getUsersInfoByStore,
wetchatShare: wetchatShare,
colorRgb:colorRgb,
printLog: function(msg) {
console.log(msg)
},
showLoading: function() {
uni.showLoading({
title: '加载中'
})
},
closeLoading: function() {
uni.hideLoading()
},
showToast: function(msg) {
uni.showToast({
title: msg,
icon: 'none'
})
},
isLogin: function() {
return uni.getStorageSync('token')
},
goLogin: function() {
uni.removeStorageSync('token')
uni.removeStorageSync('user')
uni.reLaunch({
url: '/pages/index/login'
})
},
//是否安装微信
isInstallWetchat: function() {
var isInstall = false;
// 判断第三方程序(微信) 是否安装
if(plus.runtime.isApplicationExist({pname:'com.hexagon.sandstone',action:'weixin://'})){
console.log("微信应用已安装");
isInstall = true;
}else{
console.log("微信应用未安装");
isInstall = false;
}
return isInstall;
}
}
function AMapWX(a){this.key=a.key,this.requestConfig={key:a.key,s:"rsx",platform:"WXJS",appname:a.key,sdkversion:"1.2.0",logversion:"2.0"}}AMapWX.prototype.getWxLocation=function(a,b){wx.getLocation({type:"gcj02",success:function(a){var c=a.longitude+","+a.latitude;wx.setStorage({key:"userLocation",data:c}),b(c)},fail:function(c){wx.getStorage({key:"userLocation",success:function(a){a.data&&b(a.data)}}),a.fail({errCode:"0",errMsg:c.errMsg||""})}})},AMapWX.prototype.getRegeo=function(a){function c(c){var d=b.requestConfig;wx.request({url:"https://restapi.amap.com/v3/geocode/regeo",data:{key:b.key,location:c,extensions:"all",s:d.s,platform:d.platform,appname:b.key,sdkversion:d.sdkversion,logversion:d.logversion},method:"GET",header:{"content-type":"application/json"},success:function(b){var d,e,f,g,h,i,j,k,l;b.data.status&&"1"==b.data.status?(d=b.data.regeocode,e=d.addressComponent,f=[],g="",d&&d.roads[0]&&d.roads[0].name&&(g=d.roads[0].name+"附近"),h=c.split(",")[0],i=c.split(",")[1],d.pois&&d.pois[0]&&(g=d.pois[0].name+"附近",j=d.pois[0].location,j&&(h=parseFloat(j.split(",")[0]),i=parseFloat(j.split(",")[1]))),e.provice&&f.push(e.provice),e.city&&f.push(e.city),e.district&&f.push(e.district),e.streetNumber&&e.streetNumber.street&&e.streetNumber.number?(f.push(e.streetNumber.street),f.push(e.streetNumber.number)):(k="",d&&d.roads[0]&&d.roads[0].name&&(k=d.roads[0].name),f.push(k)),f=f.join(""),l=[{iconPath:a.iconPath,width:a.iconWidth,height:a.iconHeight,name:f,desc:g,longitude:h,latitude:i,id:0,regeocodeData:d}],a.success(l)):a.fail({errCode:b.data.infocode,errMsg:b.data.info})},fail:function(b){a.fail({errCode:"0",errMsg:b.errMsg||""})}})}var b=this;a.location?c(a.location):b.getWxLocation(a,function(a){c(a)})},AMapWX.prototype.getWeather=function(a){function d(d){var e="base";a.type&&"forecast"==a.type&&(e="all"),wx.request({url:"https://restapi.amap.com/v3/weather/weatherInfo",data:{key:b.key,city:d,extensions:e,s:c.s,platform:c.platform,appname:b.key,sdkversion:c.sdkversion,logversion:c.logversion},method:"GET",header:{"content-type":"application/json"},success:function(b){function c(a){var b={city:{text:"城市",data:a.city},weather:{text:"天气",data:a.weather},temperature:{text:"温度",data:a.temperature},winddirection:{text:"风向",data:a.winddirection+"风"},windpower:{text:"风力",data:a.windpower+"级"},humidity:{text:"湿度",data:a.humidity+"%"}};return b}var d,e;b.data.status&&"1"==b.data.status?b.data.lives?(d=b.data.lives,d&&d.length>0&&(d=d[0],e=c(d),e["liveData"]=d,a.success(e))):b.data.forecasts&&b.data.forecasts[0]&&a.success({forecast:b.data.forecasts[0]}):a.fail({errCode:b.data.infocode,errMsg:b.data.info})},fail:function(b){a.fail({errCode:"0",errMsg:b.errMsg||""})}})}function e(e){wx.request({url:"https://restapi.amap.com/v3/geocode/regeo",data:{key:b.key,location:e,extensions:"all",s:c.s,platform:c.platform,appname:b.key,sdkversion:c.sdkversion,logversion:c.logversion},method:"GET",header:{"content-type":"application/json"},success:function(b){var c,e;b.data.status&&"1"==b.data.status?(e=b.data.regeocode,e.addressComponent?c=e.addressComponent.adcode:e.aois&&e.aois.length>0&&(c=e.aois[0].adcode),d(c)):a.fail({errCode:b.data.infocode,errMsg:b.data.info})},fail:function(b){a.fail({errCode:"0",errMsg:b.errMsg||""})}})}var b=this,c=b.requestConfig;a.city?d(a.city):b.getWxLocation(a,function(a){e(a)})},AMapWX.prototype.getPoiAround=function(a){function d(d){var e={key:b.key,location:d,s:c.s,platform:c.platform,appname:b.key,sdkversion:c.sdkversion,logversion:c.logversion};a.querytypes&&(e["types"]=a.querytypes),a.querykeywords&&(e["keywords"]=a.querykeywords),wx.request({url:"https://restapi.amap.com/v3/place/around",data:e,method:"GET",header:{"content-type":"application/json"},success:function(b){var c,d,e,f;if(b.data.status&&"1"==b.data.status){if(b=b.data,b&&b.pois){for(c=[],d=0;d<b.pois.length;d++)e=0==d?a.iconPathSelected:a.iconPath,c.push({latitude:parseFloat(b.pois[d].location.split(",")[1]),longitude:parseFloat(b.pois[d].location.split(",")[0]),iconPath:e,width:22,height:32,id:d,name:b.pois[d].name,address:b.pois[d].address});f={markers:c,poisData:b.pois},a.success(f)}}else a.fail({errCode:b.data.infocode,errMsg:b.data.info})},fail:function(b){a.fail({errCode:"0",errMsg:b.errMsg||""})}})}var b=this,c=b.requestConfig;a.location?d(a.location):b.getWxLocation(a,function(a){d(a)})},AMapWX.prototype.getStaticmap=function(a){function f(b){c.push("location="+b),a.zoom&&c.push("zoom="+a.zoom),a.size&&c.push("size="+a.size),a.scale&&c.push("scale="+a.scale),a.markers&&c.push("markers="+a.markers),a.labels&&c.push("labels="+a.labels),a.paths&&c.push("paths="+a.paths),a.traffic&&c.push("traffic="+a.traffic);var e=d+c.join("&");a.success({url:e})}var e,b=this,c=[],d="https://restapi.amap.com/v3/staticmap?";c.push("key="+b.key),e=b.requestConfig,c.push("s="+e.s),c.push("platform="+e.platform),c.push("appname="+e.appname),c.push("sdkversion="+e.sdkversion),c.push("logversion="+e.logversion),a.location?f(a.location):b.getWxLocation(a,function(a){f(a)})},AMapWX.prototype.getInputtips=function(a){var b=this,c=b.requestConfig,d={key:b.key,s:c.s,platform:c.platform,appname:b.key,sdkversion:c.sdkversion,logversion:c.logversion};a.location&&(d["location"]=a.location),a.keywords&&(d["keywords"]=a.keywords),a.type&&(d["type"]=a.type),a.city&&(d["city"]=a.city),a.citylimit&&(d["citylimit"]=a.citylimit),wx.request({url:"https://restapi.amap.com/v3/assistant/inputtips",data:d,method:"GET",header:{"content-type":"application/json"},success:function(b){b&&b.data&&b.data.tips&&a.success({tips:b.data.tips})},fail:function(b){a.fail({errCode:"0",errMsg:b.errMsg||""})}})},AMapWX.prototype.getDrivingRoute=function(a){var b=this,c=b.requestConfig,d={key:b.key,s:c.s,platform:c.platform,appname:b.key,sdkversion:c.sdkversion,logversion:c.logversion};a.origin&&(d["origin"]=a.origin),a.destination&&(d["destination"]=a.destination),a.strategy&&(d["strategy"]=a.strategy),a.waypoints&&(d["waypoints"]=a.waypoints),a.avoidpolygons&&(d["avoidpolygons"]=a.avoidpolygons),a.avoidroad&&(d["avoidroad"]=a.avoidroad),wx.request({url:"https://restapi.amap.com/v3/direction/driving",data:d,method:"GET",header:{"content-type":"application/json"},success:function(b){b&&b.data&&b.data.route&&a.success({paths:b.data.route.paths,taxi_cost:b.data.route.taxi_cost||""})},fail:function(b){a.fail({errCode:"0",errMsg:b.errMsg||""})}})},AMapWX.prototype.getWalkingRoute=function(a){var b=this,c=b.requestConfig,d={key:b.key,s:c.s,platform:c.platform,appname:b.key,sdkversion:c.sdkversion,logversion:c.logversion};a.origin&&(d["origin"]=a.origin),a.destination&&(d["destination"]=a.destination),wx.request({url:"https://restapi.amap.com/v3/direction/walking",data:d,method:"GET",header:{"content-type":"application/json"},success:function(b){b&&b.data&&b.data.route&&a.success({paths:b.data.route.paths})},fail:function(b){a.fail({errCode:"0",errMsg:b.errMsg||""})}})},AMapWX.prototype.getTransitRoute=function(a){var b=this,c=b.requestConfig,d={key:b.key,s:c.s,platform:c.platform,appname:b.key,sdkversion:c.sdkversion,logversion:c.logversion};a.origin&&(d["origin"]=a.origin),a.destination&&(d["destination"]=a.destination),a.strategy&&(d["strategy"]=a.strategy),a.city&&(d["city"]=a.city),a.cityd&&(d["cityd"]=a.cityd),wx.request({url:"https://restapi.amap.com/v3/direction/transit/integrated",data:d,method:"GET",header:{"content-type":"application/json"},success:function(b){if(b&&b.data&&b.data.route){var c=b.data.route;a.success({distance:c.distance||"",taxi_cost:c.taxi_cost||"",transits:c.transits})}},fail:function(b){a.fail({errCode:"0",errMsg:b.errMsg||""})}})},AMapWX.prototype.getRidingRoute=function(a){var b=this,c=b.requestConfig,d={key:b.key,s:c.s,platform:c.platform,appname:b.key,sdkversion:c.sdkversion,logversion:c.logversion};a.origin&&(d["origin"]=a.origin),a.destination&&(d["destination"]=a.destination),wx.request({url:"https://restapi.amap.com/v4/direction/bicycling",data:d,method:"GET",header:{"content-type":"application/json"},success:function(b){b&&b.data&&b.data.data&&a.success({paths:b.data.data.paths})},fail:function(b){a.fail({errCode:"0",errMsg:b.errMsg||""})}})},module.exports.AMapWX=AMapWX;
\ No newline at end of file
import Vue from 'vue'
import App from './App'
import path from './config/router.js'
import store from './config/store.js'
import main from './config/main.js'
import api from './config/api.js'
Vue.config.productionTip = false
Vue.prototype.$path = path
Vue.prototype.$store = store
Vue.prototype.$main = main
Vue.prototype.$api = api
App.mpType = 'app'
// Vue.util.productionTip = false
const app = new Vue({
...App,
path,
store,
main,
api
})
app.$mount()
{
"name" : "华仁优选",
"appid" : "__UNI__E592995",
"description" : "华仁优选",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
"usingComponents" : true,
"nvueCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* 模块配置 */
"modules" : {
"Payment" : {},
"OAuth" : {},
"Share" : {},
"Maps" : {}
},
/* 应用发布信息 */
"distribute" : {
/* android打包配置 */
"android" : {
"permissions" : [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios打包配置 */
"ios" : {
"privacyDescription" : {
"NSLocationWhenInUseUsageDescription" : "华仁访问您的位置,仅仅显示你当前的位置,从而更快得到你附近咨讯和供应商品数据,该信息数据不会上传到服务器",
"NSLocationAlwaysUsageDescription" : "华仁访问您的位置,仅仅显示你当前的位置,从而更快得到你附近咨讯和供应商品数据,该信息数据不会上传到服务器",
"NSLocationAlwaysAndWhenInUseUsageDescription" : "华仁访问您的位置,仅仅显示你当前的位置,从而更快得到你附近咨讯和供应商品数据,该信息数据不会上传到服务器"
}
},
/* SDK配置 */
"sdkConfigs" : {
"ad" : {},
"payment" : {
"alipay" : {
"__platform__" : [ "android" ]
},
"weixin" : {
"__platform__" : [ "android" ],
"appid" : "wx5ffb0a232bf3fc9b",
"UniversalLinks" : "https://tr5z78.xinstall.top/tolink/"
}
},
"oauth" : {
"weixin" : {
"appid" : "wx5ffb0a232bf3fc9b",
"appsecret" : "ffb9665edfbbdeeebba04c01e5272a9d",
"UniversalLinks" : "https://tr5z78.xinstall.top/tolink/"
}
},
"share" : {
"weixin" : {
"appid" : "wx5ffb0a232bf3fc9b",
"UniversalLinks" : "https://tr5z78.xinstall.top/tolink/"
}
},
"maps" : {
"amap" : {
"appkey_ios" : "67250069dd9762ec0b12b6b49a2150f9",
"appkey_android" : "892e741ef93a9552647aec2826f038c0"
}
},
"geolocation" : {}
},
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
},
"splashscreen" : {
"androidStyle" : "common"
}
}
},
/* 快应用特有相关 */
"quickapp" : {},
/* 小程序特有相关 */
"mp-weixin" : {
"appid" : "wx5990f741872f4974",
"setting" : {
"urlCheck" : false,
"es6" : true,
"minified" : false
},
"optimization" : {
"subPackages" : true
},
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "你的位置信息将用于小程序位置接口的效果展示"
}
}
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"mp-qq" : {
"uniStatistics" : {
"enable" : false
}
},
"h5" : {
"title" : "华仁优选",
"domain" : "http://hr.jsonpro.cn"
}
}
{
"pages": [
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path" : "pages/index/home",
"style" :
{
"navigationBarTitleText": "台粮道",
"enablePullDownRefresh": false
}
},
{
"path": "pages/index/goodsDetail",
"style": {
"navigationBarTitleText": "商品详情",
"app-plus": {
"titleNView": {
"type": "transparent"
}
}
}
},
{
"path": "pages/my/index",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"navigationBarBackgroundColor": "#FFFFFF",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/myWallet",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"navigationBarTextStyle": "white",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/cashOut",
"style": {
"navigationBarTitleText": "提现",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/cashOutRecord",
"style": {
"navigationBarTitleText": "提现记录",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/coupon",
"style": {
"navigationBarTitleText": "优惠券",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/manageAdress",
"style": {
"navigationBarTitleText": "管理收货地址",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/creatAdress",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/balanceRecord",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/signForDetail",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/setting",
"style": {
"navigationBarTitleText": "设置",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/aboutUs",
"style": {
"navigationBarTitleText": "关于我们",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/myCollection",
"style": {
"navigationBarTitleText": "我的收藏",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/inviteFriend",
"style": {
"navigationBarTitleText": "邀请好友",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/myOrder",
"style": {
"navigationBarTitleText": "我的订单",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/orderDetail",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/index/login",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/index/bind",
"style": {
"navigationBarTitleText": "绑定手机"
}
},
{
"path": "pages/my/feedback",
"style": {
"navigationBarTitleText": "意见反馈",
"enablePullDownRefresh": false
}
},
{
"path": "pages/index/detail",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/index/webView",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/my/myTeam",
"style" :
{
"navigationBarTitleText": "我的团队",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/my/setUserInfo",
"style" :
{
"navigationBarTitleText": "个人资料",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/shopping/index",
"style" :
{
"navigationStyle": "custom",
"navigationBarTitleText": "",
// "onReachBottomDistance": 80,
"enablePullDownRefresh": true
}
},
{
"path" : "pages/shopping/shopCar",
"style" :
{
"navigationBarTitleText": "购物车",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/shopping/confirmOrder",
"style" :
{
"navigationBarTitleText": "确认订单",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/shopping/orderSettle",
"style" :
{
"navigationBarTitleText": "确认订单",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/shopping/payResult",
"style" :
{
"navigationBarTitleText": "支付结果",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/index/more",
"style" :
{
"navigationBarTitleText": "更多",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/my/manger",
"style" :
{
"navigationBarTitleText": "",
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/my/rollOut",
"style" :
{
"navigationBarTitleText": "转出到余额",
"enablePullDownRefresh": false
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#FFF",
"backgroundColor": "#F8F8F8"
},
"condition": {
//模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [{
"name": "", //模式名称
"path": "", //启动页面,必选
"query": "" //启动参数,在页面的onLoad函数里面得到
}]
},
"easycom": {
"autoscan": true,
"custom": {
"l-(.*)": "@/components/$1/index.vue"
}
}
}
<template>
<view class="white-content">
<view class="content">
<view class="input-row">
<label>手机号</label>
<input v-model="phone" type="digit" maxlength="11" placeholder="请输入手机号码" @blur="handleBlur" />
</view>
<view class="input-row">
<label>验证码</label>
<input v-model="smsCode" type="digit" maxlength="6" placeholder="请输入验证码" />
<button @click="getSmsCode" :disabled="!phone || phone.length < 11 || time < 60">{{codeTip}}</button>
</view>
</view>
<button class="theme" :disabled="!phone || phone.length < 11 || !smsCode || smsCode.length < 6 " @click="gobind">绑定</button>
</view>
</template>
<script>
import util from '@/config/util.js'
import {
checkCode,
bindWx
} from '@/config/api.js'
export default {
data() {
return {
phone: null,
smsCode: null,
codeTip: '获取验证码',
time: 60,
userInfo: null
};
},
onLoad(options) {
Object.assign(this, this.$options.data())
if (options.data) {
this.userInfo = JSON.parse(options.data)
} else {
util.showToast('数据缺失,请重试!')
uni.navigateBack({
delta: 1
})
}
},
methods: {
getSmsCode() {
var that = this
if (that.time != 60) {
return
}
var params = {
phone: that.phone
}
checkCode(params, {
suc: (res) => {
util.showToast('验证码发送成功');
that.startCountDown()
}
})
},
startCountDown() {
var that = this
var id = setInterval(function() {
var time = that.time
var str = ''
if (time > 0) {
time--
str = time + 's'
} else {
time = 60
str = '获取验证码'
}
that.time = time
that.codeTip = str
if (time == 60) {
clearInterval(id)
}
}, 1000)
},
//提交
gobind() {
if (!this.phoneStatus) this.$main.showToast('手机号格式有误,请重新输入')
var that = this
var params = {
phone: that.phone,
code: that.smsCode,
bindType: 2,
openId: that.userInfo.openId,
nickName: that.userInfo.nickName,
avatar: that.userInfo.avatar
}
bindWx(params, {
suc: res => {
util.showToast('登录成功')
var data = res.data;
uni.setStorageSync('token', data.token)
uni.setStorageSync('user', that.userInfo)
setTimeout(() => {
that.$path.reLaunch('/pages/index/home')
}, 1000)
}
})
},
//登录成功操作
loginSuccess(res) {
},
// 正则验证
getRegExp(value) {
let regExp =
/^1[3-9]\d{9}$/
if (regExp.test(value)) {
this.phoneStatus = true
} else {
this.phoneStatus = false
}
},
// 手机号输入框失焦事件
handleBlur (e) {
this.getRegExp(this.phone)
}
}
}
</script>
<style>
.white-content {
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
background: white;
}
.logo {
width: 380rpx;
height: 120rpx;
margin-top: 170rpx;
}
.content {
width: calc(100% - 140rpx);
margin: 24rpx 70rpx 0 70rpx;
}
.input-row {
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
margin-top: 27rpx;
border-bottom: 2rpx solid #f2f2f2;
}
.input-row image {
width: 40rpx;
height: 40rpx;
}
.input-row label {
width: 120rpx;
font-size: 26rpx;
font-weight: bold;
color: #020202;
}
.input-row image:last-child {
height: 30rpx;
}
.input-row input {
flex: 1;
padding: 40rpx 26rpx;
height: auto;
font-size: 26rpx;
}
.input-row button {
padding: 0 24rpx;
min-width: 142rpx;
height: 50rpx;
line-height: 50rpx;
font-size: 20rpx;
color: #ff3c39;;
border-radius: 40rpx;
border: 1rpx solid #ff3c39;;
}
.input-row button[disabled] {
border: 1rpx solid #F2F2F2;
}
.agreement {
width: 100vw;
position: absolute;
left: 0;
display: flex;
flex-direction: column;
align-items: center;
color: #AAAAAA;
font-size: 24rpx;
}
.agreement text {
color: #007AFF;
}
.input-tip {
display: flex;
color: #999999;
font-size: 24rpx;
margin-top: 10rpx;
}
</style>
<template>
<view class="cx-detail">
<!-- <view class="title" v-if="name">
{{name}}
</view> -->
<view class="detail" ref="detail" id="detail" v-html="detail"></view>
</view>
</template>
<script>
import {
contractDetail,
medicalWikiSecondDetail,
agreementDetail
} from '@/config/api.js'
export default {
data() {
return {
invateCode: this.invateCode,
type: null,
id: null,
name: null,
status: null,
detail: null,
imgSrc: ''
}
},
onLoad (options) {
Object.assign(this, this.$options.data())
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
})
if (options.id) this.id = options.id
if (options.detail) this.detail = options.detail
if (options.status) this.status = options.status
if (options.title) {
this.$main.setNavigationBarTitle(options.title)
} else {
this.$main.setNavigationBarTitle('详情')
}
if (options.type) {
this.type = options.type
this.getApiagreementTips()
}
},
// 分享给朋友
onShareAppMessage (res) {
return {
title: '快来注册吧',
path: '/pages/index/home?invateCode=' + this.invateCode
}
},
// 分享朋友圈
onShareTimeline () {
return {
title: '快来注册吧',
query: '/pages/index/home?invateCode=' + this.invateCode
}
},
methods: {
// 协议、说明详情
getApiagreementTips () {
let that = this
let params = {
type: that.type
}
agreementDetail(params, {
suc: (res) => {
that.detail = res.data.detailHtml
}
})
}
}
}
</script>
<style scoped lang="less">
.title {
padding: 20rpx;
box-sizing: border-box;
color: #020202;
font-size: 32rpx;
text-align: center;
font-weight:bold;
background-color: #FFF;
}
.detail {
white-space: pre-wrap;
}
</style>
<template>
<view class="cx-login">
<view class="top-box">
<view class="view-bg">
</view>
<view class="wx-login-box">
<image class="icon" :src="imgBaseUrl + 'WeChatdl.png'" webp="true" lazy-load="true" :style="{'margin-bottom': authType ? '60rpx;' : '0'}"></image>
<button v-if="authType" class="button" style="background-color: #2EA9EA;" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">授权手机号</button>
<button v-else class="button" open-type="getUserInfo" @click="getWxLogin()">微信授权登录</button>
</view>
<view class="bottom-box">
<!-- <view class="text-box">
<p class="text">登录即表明同意</p>
<p class="agreement" @click="btnPath('./detail?type=4&status=2')">《台粮道用户协议》</p>
<p class="text"></p>
<p class="agreement" @click="btnPath('./detail?type=4&status=3')">《隐私政策》</p>
</view> -->
<p class="support">POWERED BY&copy;六方网络</p>
</view>
</view>
</view>
</template>
<script>
import util from '@/config/util.js'
import {
getId,
wxLogin,
bindWx,
personal,
checkCode
} from '@/config/api.js'
export default {
data() {
return {
imgBaseUrl: null,
userInfo: null,
openId: null,
codeText: '获取验证码',
passText: 'password',
invateCode: '',
phone: '',
jsonData: {},
authType: 0
}
},
onLoad() {
Object.assign(this, this.$options.data())
this.imgBaseUrl = this.$api.IMG_BASE_URL
if (this.$store.getStorageSync('invateCode')) {
this.invateCode = this.$store.getStorageSync('invateCode')
}
},
methods: {
// 获取验证码
getApiCode() {
setTimeout(() => {
if (!this.phoneValue) return this.$main.showToast('手机号不能为空!')
if (!this.phoneStatus) return this.$main.showToast('您输入的手机号有误,请重新输入')
let that = this
let num = 60
let params = {
phone: that.phoneValue
}
checkCode(params, {
suc: (res) => {
that.$main.showToast('验证码已发送')
let timeSmap = setInterval(function() {
num--
that.codeText = num + 's后重新获取'
if (!num) {
clearInterval(timeSmap)
that.codeText = '获取验证码'
}
}, 1000)
},
err: (err) => {
}
})
}, 50)
},
// 获取手机号
getPhoneNumber (e) {
this.getWxLogin(e.detail.encryptedData, e.detail.iv)
},
// 绑定微信
apiBind (data) {
console.log(1111, this.invateCode)
let that = this
let params = {
phone: data.phone,
bindType: 2,
openId: data.openId,
nickName: data.nickName,
avatar: data.avatar
}
if (that.invateCode) params.invitationCode = that.invateCode
bindWx(params, {
suc: (res) => {
that.$main.showToast('登录成功', 1000)
let token = res.data.tokenHead + ' ' + res.data.token
if (this.$store.getStorageSync('invateCode')) {
this.$store.removeStorageSync('invateCode')
}
uni.setStorageSync('token', token)
let userInfo = {
avatar: data.avatar,
phone: data.phone,
nickName: data.nickName
}
uni.setStorageSync('user', userInfo)
setTimeout(() => {
that.$path.reLaunch('/pages/index/home')
}, 1000)
}
})
},
// 微信登录
getWxLogin (data, iv) {
let that = this
wx.login({
success (res) {
if (that.authType) {
let params = {
jsCode: res.code,
encryptedData: data,
iv: iv
}
if (that.invateCode) params.invitationCode = that.invateCode
getId(params, {
suc: (ress) => {
let token = ress.data.tokenHead + ' ' + ress.data.token
that.$store.setStorageSync('token', token)
that.$main.showToast('登录成功', 1000)
setTimeout(() => {
that.$path.reLaunch('/pages/index/home')
}, 1000)
},
erc: (err) => {
if (err.data.code === 15000) {
that.phone = err.data.data.phone
that.jsonData.phone = that.phone
// let jsonData = {
// phone: that.phone,
// openId: err.data.data.openId,
// nickName: ress.userInfo.nickName,
// avatar: ress.userInfo.avatarUrl
// }
that.apiBind(that.jsonData)
}
}
})
} else {
wx.getUserInfo({
success: function(ress) {
that.$main.showLoading('登陆中')
let params = {
jsCode: res.code,
encryptedData: ress.encryptedData,
iv: ress.iv
}
if (that.invateCode) params.invitationCode = that.invateCode
getId(params, {
suc: (reslove) => {
that.$main.hideLoading()
let token = reslove.data.tokenHead + ' ' + reslove.data.token
that.$store.setStorageSync('token', token)
if (that.$store.getStorageSync('invateCode')) {
that.$store.removeStorageSync('invateCode')
}
that.$main.showToast('登录成功', 1000)
setTimeout(() => {
that.$path.reLaunch('/pages/index/home')
}, 1000)
},
erc: err => {
if (err.data.code === 15000) {
that.jsonData = {
openId: err.data.data.openid,
nickName: ress.userInfo.nickName,
avatar: ress.userInfo.avatarUrl
}
that.authType = 1
that.$forceUpdate()
// let jsonData = {
// phone: that.phone,
// openId: err.data.data.openId,
// nickName: ress.userInfo.nickName,
// avatar: ress.userInfo.avatarUrl
// }
// that.apiBind(jsonData)
}
}
})
},
fail: function(err) {
that.$main.hideLoading()
}
})
}
},
fail: (err) => {
}
})
},
// 获取个人信息
getApiUserInfo (status) {
let that = this
let params = ''
personal(params, {
suc: (res) => {
let data = res.data
if (status) {
uni.getUserInfo({
provider: 'weixin',
success: function (info) {
that.userInfo = {
nickName: info.userInfo.nickName,
avatar: info.userInfo.avatarUrl
}
data.nickName = info.userInfo.nickName
data.avatar = info.userInfo.avatarUrl
that.$store.setStorageSync('user', data)
}
})
} else {
that.$store.setStorageSync('user', data)
}
}
})
},
// 路由 - 跳转子页面
btnPath(url) {
this.$path.navigateTo(url)
}
}
}
</script>
<style>
</style>
<template>
<view class="cx-more">
<view class="imgs-box" v-if="type == 1">
<image class="img" v-for="(item, index) in imgList" :key="index" :src="item.pic" @click="btnPreviewImage(index, imgList)" mode="aspectFill"></image>
</view>
<view class="new-box" v-if="type == 2">
<view class="list" v-for="(item, index) in newsList" :key="index">
<p class="left">{{item.title}} | {{item.subTitle}}</p>
<p class="date">{{item.createDate.split(' ')[0]}}</p>
</view>
</view>
</view>
</template>
<script>
import {
tlImages,
tlNews
} from '@/config/api.js'
export default {
data() {
return {
invateCode: this.invateCode,
type: 0,
imgList: [],
newsList: [],
page: 1,
total: 0
}
},
onLoad (options) {
Object.assign(this, this.$options.data())
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
})
this.type = options.type
this.getApiIndexData()
},
// 分享给朋友
onShareAppMessage (res) {
return {
title: '快来注册吧',
path: '/pages/index/home?invateCode=' + this.invateCode
}
},
// 分享朋友圈
onShareTimeline () {
return {
title: '快来注册吧',
query: '/pages/index/home?invateCode=' + this.invateCode
}
},
// 触底刷新
onReachBottom () {
if (!this.total) return
this.page++
if (this.type == 1) {
if (this.total === this.imgList.length) return
this.imgList = []
} else if (this.type == 2){
if (this.total === this.newsList.length) return
this.newsList = []
}
this.getApiIndexData()
},
methods: {
// 请求主数据
getApiIndexData () {
if (this.type == 1) {
let that = this
let params = {
pageNum: that.page,
pageSize: 30
}
tlImages(params, {
suc: (res) => {
that.total = res.data.total
if (res.data.pageNum === 1) that.imgList = []
that.imgList = that.imgList.concat(res.data.list)
}
})
} else {
let that = this
let params = {
pageNum: that.page,
pageSize: 30
}
tlNews(params, {
suc: (res) => {
that.total = res.data.total
if (res.data.pageNum === 1) that.newsList = []
that.newsList = that.newsList.concat(res.data.list)
}
})
}
},
// 查看大图
btnPreviewImage (index, imgs) {
let arr = []
for (let i = 0; i < imgs.length; i++) {
arr.push(imgs[i].pic)
}
uni.previewImage({
current: index,
urls: arr
})
},
}
}
</script>
<style>
</style>
<template>
<view class="cx-web-view">
<web-view :src="src"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
src: ''
}
},
onLoad (options) {
Object.assign(this, this.$options.data())
this.src = options.src
},
methods: {
}
}
</script>
<style>
</style>
<template>
<view class="cx-about-us">
<view class="logo-box">
<image class="logo" :src="imgBaseUrl + 'logowe.png'" webp="true" lazy-load="true"></image>
</view>
<view class="edition-info">{{mobileInfo}}</view>
<view class="option-box">
<view class="options">
<p class="title">邮箱</p>
<view class="right">
<p class="text">632598226@qq.com</p>
<image class="icon" :src="imgBaseUrl + 'page.png'" webp="true" lazy-load="true"></image>
</view>
</view>
<view class="options">
<p class="title">官方微信公众号</p>
<view class="right">
<p class="text">jsksjd</p>
<image class="icon" :src="imgBaseUrl + 'page.png'" webp="true" lazy-load="true"></image>
</view>
</view>
<view class="options">
<p class="title">官方微博</p>
<view class="right">
<p class="text">jsksjd</p>
<image class="icon" :src="imgBaseUrl + 'page.png'" webp="true" lazy-load="true"></image>
</view>
</view>
<view class="options">
<p class="title">官网技术支持</p>
<view class="right">
<p class="text">泉州六方网络有限公司</p>
<image class="icon" :src="imgBaseUrl + 'page.png'" webp="true" lazy-load="true"></image>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
Ok: false,
imgBaseUrl: null,
invateCode: this.invateCode,
mobileInfo: ''
}
},
onLoad () {
Object.assign(this, this.$options.data())
this.imgBaseUrl = this.$api.IMG_BASE_URL
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
})
this.getSystemInfo()
},
// 分享给朋友
onShareAppMessage (res) {
return {
title: '快来注册吧',
path: '/pages/index/home?invateCode=' + this.invateCode
}
},
// 分享朋友圈
onShareTimeline () {
return {
title: '快来注册吧',
query: '/pages/index/home?invateCode=' + this.invateCode
}
},
methods: {
// 获取系统信息
getSystemInfo () {
uni.getSystemInfo({
success: res => {
let system = res.platform == 'ios' ? 'ios版本' : '安卓版本'
let edition = res.system.substr(res.system.indexOf(' '))
this.mobileInfo = system + edition
}
})
}
}
}
</script>
<style>
</style>
<template>
<view class="cx-balance-record">
<uni-nav-bar left-icon="back" title="余额明细" right-text=" " :fixed="true" :statusBar="true" :border="false" @clickLeft="btnBack(1)">
</uni-nav-bar>
<view class="tips-box">
<p>总支出:¥{{outcome}} &nbsp;&nbsp; 总收入:¥{{income}}</p>
<p @click="btnPath('/pages/index/detail?type=6')">说明</p>
</view>
<view class="record-box">
<view class="options" v-for="(item, index) in list" :key="index">
<view class="left-box">
<p class="title" v-if="item.type === 1">购买商品</p>
<p class="title" v-else-if="item.type === 2">下级升级获得</p>
<p class="title" v-else-if="item.type === 3">提现</p>
<p class="title" v-else-if="item.type === 5">佣金管理奖</p>
<p class="title" v-else-if="item.type === 6">直推佣金</p>
<p class="title" v-else-if="item.type === 7">间推佣金</p>
<p class="title" v-else-if="item.type === 8">管理奖转入</p>
<p class="title" v-else-if="item.type === 9">管理奖转出</p>
<view class="count red" v-if="item.changeType === 2">-{{item.changeAmount}}</view>
<view class="count black" v-else>+{{item.changeAmount}}</view>
</view>
<p class="time">{{item.createDate}}</p>
</view>
</view>
</view>
</template>
<script>
import {
balanceRecord
} from '@/config/api.js'
export default {
data() {
return {
invateCode: this.invateCode,
imgBaseUrl: null,
list: [],
income: 0,
outcome: 0,
page: 1,
total: 0
}
},
onLoad () {
Object.assign(this, this.$options.data())
this.imgBaseUrl = this.$api.IMG_BASE_URL
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
})
this.getApiIndexData()
},
// 分享给朋友
onShareAppMessage (res) {
return {
title: '快来注册吧',
path: '/pages/index/home?invateCode=' + this.invateCode
}
},
// 分享朋友圈
onShareTimeline () {
return {
title: '快来注册吧',
query: '/pages/index/home?invateCode=' + this.invateCode
}
},
methods: {
// 获取主数据
getApiIndexData () {
let that = this
let params = {
pageNum: that.page,
pageSize: 15
}
balanceRecord(params, {
suc: (res) => {
that.total = res.data.detailList.total
if (res.data.detailList.pageNum === 1) that.list = []
that.list = that.list.concat(res.data.detailList.list)
that.outcome = res.data.allExpenditure
that.income = res.data.allIncome
}
})
},
// 路由 - 跳转子页面
btnPath (url) {
this.$path.navigateTo(url)
},
// 路由 - 回退
btnBack (count) {
this.$path.navigateBack(1)
}
},
// 触底刷新
onReachBottom () {
if (!this.total) return
if (this.total === this.list.length) return
this.page++
this.getApiIndexData()
}
}
</script>
<style scoped lang="less">
.record-box {
height: calc(100vh - 88rpx - 82rpx - var(--status-bar-height));
}
</style>
<template>
<view class="cx-cash-out">
<view class="top-tips">提现需要扣除手续费3%,到账时间以实际到账时间为准</view>
<view class="option-box">
<view class="options">
<p class="title">当前余额</p>
<p class="text">{{balance.balance}}</p>
</view>
<view class="options">
<p class="title">收款人</p>
<input class="input" type="text" v-model="nameValue" placeholder="请输入收款人姓名" />
</view>
<view class="options">
<view class="title">收款方式</view>
<view class="right">
<view class="list" @click="type = 0">
<view class="border">
<view class="point" v-if="type === 0"></view>
</view>
<p class="text">支付宝</p>
</view>
<view class="list" @click="type = 1">
<view class="border">
<view class="point" v-if="type === 1"></view>
</view>
<p class="text">微信</p>
</view>
</view>
</view>
<view class="options">
<p class="title">提现金额</p>
<input class="input" type="digit" v-model="moneyValue" placeholder="请输入提现金额" @input="handleInput" />
</view>
<view class="options">
<p class="title">实际到账金额</p>
<p class="text">{{actualAmount}}</p>
</view>
</view>
<view class="btn" @click="chooseImage()">上传收款码</view>
<view class="btn" style="margin-top: 30rpx;" @click="btnSure()">确认提现,48小时内到账</view>
</view>
</template>
<script>
import {
cashOut,
ossPolicy,
myWallet,
} from '@/config/api.js'
export default {
data() {
return {
invateCode: this.invateCode,
type: 0,
balance: '',
nameValue: '',
moneyValue: '',
actualAmount: '',
imgURL: '',
openRequest: true // 按钮保护
}
},
onLoad () {
Object.assign(this, this.$options.data())
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
})
this.getApiMoney()
},
// 分享给朋友
onShareAppMessage (res) {
return {
title: '快来注册吧',
path: '/pages/index/home?invateCode=' + this.invateCode
}
},
// 分享朋友圈
onShareTimeline () {
return {
title: '快来注册吧',
query: '/pages/index/home?invateCode=' + this.invateCode
}
},
methods: {
// 获取余额
getApiMoney () {
let that = this
myWallet('', {
suc: (res) => {
that.balance = res.data
}
})
},
// 提现按钮
btnSure () {
if (!this.openRequest) return
this.openRequest = false
if (!this.nameValue) {
this.openRequest = true
return this.$main.showToast('请输入收款人姓名!')
}
if (!this.moneyValue || this.moneyValue <= 0) {
this.openRequest = true
return this.$main.showToast('请输入提现金额!')
}
if (!this.imgURL) {
this.openRequest = true
return this.$main.showToast('请先上传收款码')
}
this.getApiCashOut()
},
// 选择图片操作
async chooseImage () {
let that = this
await uni.chooseImage({
count: 1,
success: res => {
for (let i = 0; i < res.tempFiles.length; i++) {
if (res.tempFiles[i].size > 2097152) return that.$main.showToast('您上传的图片过大,请重新上传')
that.getUpload(res.tempFiles[i].path)
}
},
fail: err => {
that.openRequest = true
}
})
},
// 上传
getUpload (data) {
let that = this
ossPolicy('', {
suc: (res) => {
let tiemr = new Date()
let address = res.data.dir + '/'
let str = data.substr(data.lastIndexOf('.'))
let nameStr = address + tiemr.getTime() + str
uni.uploadFile({
url: res.data.host,
filePath: data,
fileType: 'image',
name: 'file',
formData: {
name: nameStr,
key: nameStr,
policy: res.data.policy,
OSSAccessKeyId: res.data.accessKeyId,
success_action_status: '200',
signature: res.data.signature
},
success: ress => {
if (ress.statusCode == '200'){
// console.log(111, res.data.host + '/' + nameStr)
that.$main.showToast('上传成功')
let path = res.data.host + '/' + nameStr
that.imgURL = path
} else {
that.$main.showToast('上传失败,请重试')
}
}
})
}
})
},
// 提现接口
getApiCashOut () {
let that = this
let params = {
name: that.nameValue,
method: that.type,
amount: that.moneyValue,
withdrawalQrCode: that.imgURL
}
cashOut(params, {
suc: (res) => {
that.openRequest = true
that.$main.showToast('提现成功')
that.moneyValue = ''
that.nameValue = ''
that.imgURL = ''
that.actualAmount = ''
},
erc: (err) => {
that.openRequest = true
}
})
},
// 提现金额输入框事件
handleInput (e) {
if (!this.balance.balance || this.balance.balance === 0) {
this.$main.showToast('余额不足')
return this.actualAmount = ''
}
if (!e.detail.value) return this.actualAmount = ''
let value = e.detail.value
let count = value * 0.03
this.actualAmount = value - count
},
// 判断提现金额
getApiJudgAmount (value, id, type) {
let that = this
let params = {
withdrawalAmount: value,
userId: id,
userType: type
}
judgAmount(params, {
suc: (res) => {
that.openCashout = false
}
})
},
// 路由 - 跳转子页面
btnPath (url) {
this.$path.navigateTo(url)
},
// 路由 - 回退
btnBack (count) {
this.$path.navigateBack(count)
},
// 提现金额输入框失焦
handleBlur (e) {
setTimeout(() => {
// if (e.mp.detail.value > this.balance) return this.$main.showToast('提现金额超过可用金额!')
if (e.mp.detail.value) this.getApiJudgAmount(e.mp.detail.value, this.$store.getStorageSync('user').memberId, 1)
}, 50)
}
}
}
</script>
<style>
</style>
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment