提交 b1246c71 编写于 作者: L linju

分享功能

上级 9c97a81b
module.exports = {
"h5":{
"url":"https://static-76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e.bspapp.com"
},
"mp":{
"weixin":{
"id":"gh_33446d7f7a26"
}
},
"router":{
"needLogin":[ //配置需要路由拦截的页面地址,在打开这些页面之前会自动检查(不联网)uni_id_token的值是否存在/过期等
"/pages/ucenter/edit/edit",
......@@ -9,6 +17,7 @@ module.exports = {
},
"about":{
"appName":"base-app",
"logo":"/static/logo.png",
"company":"数字天堂(北京)网络技术有限公司",
"slogan":"为开发而生",
"agreements":[
......@@ -21,6 +30,6 @@ module.exports = {
"url":"https://uniapp.dcloud.io/"
}
],
"下载地址":""
"download":"https://m3w.cn/uniapp"
}
}
\ No newline at end of file
<template>
<view>
<canvas :id="cid" :canvas-id="cid" :style="{width: `${size}px`, height: `${size}px`}" />
</view>
</template>
<script>
import uQRCode from './uqrcode.js'
export default {
props: {
cid: {
type: String,
default(){
return Date.now()+Math.random()+'';
}
},
text: {
type: String,
required: true
},
size: {
type: Number,
default: uni.upx2px(200)
},
margin: {
type: Number,
default: 0
},
backgroundColor: {
type: String,
default: '#ffffff'
},
foregroundColor: {
type: String,
default: '#000000'
},
backgroundImage: {
type: String
},
logo: {
type: String
},
makeOnLoad: {
type: Boolean,
default: false
}
},
data() {
return {
}
},
mounted() {
if (this.makeOnLoad) {
this.make()
}
},
methods: {
async make() {
var options = {
canvasId: this.cid,
componentInstance: this,
text: this.text,
size: this.size,
margin: this.margin,
backgroundColor: this.backgroundImage ? 'rgba(255,255,255,0)' : this.backgroundColor,
foregroundColor: this.foregroundColor
}
var filePath = await this.makeSync(options)
if (this.backgroundImage) {
filePath = await this.drawBackgroundImageSync(filePath)
}
if (this.logo) {
filePath = await this.drawLogoSync(filePath)
}
this.makeComplete(filePath)
},
makeComplete(filePath) {
this.$emit('makeComplete', filePath)
},
drawBackgroundImage(options) {
var ctx = uni.createCanvasContext(this.cid, this)
ctx.drawImage(this.backgroundImage, 0, 0, this.size, this.size)
ctx.drawImage(options.filePath, 0, 0, this.size, this.size)
ctx.draw(false, () => {
uni.canvasToTempFilePath({
canvasId: this.cid,
success: res => {
options.success && options.success(res.tempFilePath)
},
fail: error => {
options.fail && options.fail(error)
}
}, this)
})
},
async drawBackgroundImageSync(filePath) {
return new Promise((resolve, reject) => {
this.drawBackgroundImage({
filePath: filePath,
success: res => {
resolve(res)
},
fail: error => {
reject(error)
}
})
})
},
fillRoundRect(ctx, r, x, y, w, h) {
ctx.save()
ctx.translate(x, y)
ctx.beginPath()
ctx.arc(w - r, h - r, r, 0, Math.PI / 2)
ctx.lineTo(r, h)
ctx.arc(r, h - r, r, Math.PI / 2, Math.PI)
ctx.lineTo(0, r)
ctx.arc(r, r, r, Math.PI, Math.PI * 3 / 2)
ctx.lineTo(w - r, 0)
ctx.arc(w - r, r, r, Math.PI * 3 / 2, Math.PI * 2)
ctx.lineTo(w, h - r)
ctx.closePath()
ctx.setFillStyle('#ffffff')
ctx.fill()
ctx.restore()
},
drawLogo(options) {
var ctx = uni.createCanvasContext(this.cid, this)
ctx.drawImage(options.filePath, 0, 0, this.size, this.size)
var logoSize = this.size / 4
var logoX = this.size / 2 - logoSize / 2
var logoY = logoX
var borderSize = logoSize + 10
var borderX = this.size / 2 - borderSize / 2
var borderY = borderX
var borderRadius = 5
this.fillRoundRect(ctx, borderRadius, borderX, borderY, borderSize, borderSize)
ctx.drawImage(this.logo, logoX, logoY, logoSize, logoSize)
ctx.draw(false, () => {
uni.canvasToTempFilePath({
canvasId: this.cid,
success: res => {
options.success && options.success(res.tempFilePath)
},
fail: error => {
options.fail && options.fail(error)
}
}, this)
})
},
async drawLogoSync(filePath) {
return new Promise((resolve, reject) => {
this.drawLogo({
filePath: filePath,
success: res => {
resolve(res)
},
fail: error => {
reject(error)
}
})
})
},
async makeSync(options) {
return new Promise((resolve, reject) => {
uQRCode.make({
canvasId: options.canvasId,
componentInstance: options.componentInstance,
text: options.text,
size: options.size,
margin: options.margin,
backgroundColor: options.backgroundColor,
foregroundColor: options.foregroundColor,
success: res => {
resolve(res)
},
fail: error => {
reject(error)
}
})
})
}
}
}
</script>
//---------------------------------------------------------------------
// github https://github.com/Sansnn/uQRCode
//---------------------------------------------------------------------
let uQRCode = {};
(function() {
//---------------------------------------------------------------------
// QRCode for JavaScript
//
// Copyright (c) 2009 Kazuhiko Arase
//
// URL: http://www.d-project.com/
//
// Licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license.php
//
// The word "QR Code" is registered trademark of
// DENSO WAVE INCORPORATED
// http://www.denso-wave.com/qrcode/faqpatent-e.html
//
//---------------------------------------------------------------------
//---------------------------------------------------------------------
// QR8bitByte
//---------------------------------------------------------------------
function QR8bitByte(data) {
this.mode = QRMode.MODE_8BIT_BYTE;
this.data = data;
}
QR8bitByte.prototype = {
getLength: function(buffer) {
return this.data.length;
},
write: function(buffer) {
for (var i = 0; i < this.data.length; i++) {
// not JIS ...
buffer.put(this.data.charCodeAt(i), 8);
}
}
};
//---------------------------------------------------------------------
// QRCode
//---------------------------------------------------------------------
function QRCode(typeNumber, errorCorrectLevel) {
this.typeNumber = typeNumber;
this.errorCorrectLevel = errorCorrectLevel;
this.modules = null;
this.moduleCount = 0;
this.dataCache = null;
this.dataList = new Array();
}
QRCode.prototype = {
addData: function(data) {
var newData = new QR8bitByte(data);
this.dataList.push(newData);
this.dataCache = null;
},
isDark: function(row, col) {
if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
throw new Error(row + "," + col);
}
return this.modules[row][col];
},
getModuleCount: function() {
return this.moduleCount;
},
make: function() {
// Calculate automatically typeNumber if provided is < 1
if (this.typeNumber < 1) {
var typeNumber = 1;
for (typeNumber = 1; typeNumber < 40; typeNumber++) {
var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);
var buffer = new QRBitBuffer();
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
for (var i = 0; i < this.dataList.length; i++) {
var data = this.dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
data.write(buffer);
}
if (buffer.getLengthInBits() <= totalDataCount * 8)
break;
}
this.typeNumber = typeNumber;
}
this.makeImpl(false, this.getBestMaskPattern());
},
makeImpl: function(test, maskPattern) {
this.moduleCount = this.typeNumber * 4 + 17;
this.modules = new Array(this.moduleCount);
for (var row = 0; row < this.moduleCount; row++) {
this.modules[row] = new Array(this.moduleCount);
for (var col = 0; col < this.moduleCount; col++) {
this.modules[row][col] = null; //(col + row) % 3;
}
}
this.setupPositionProbePattern(0, 0);
this.setupPositionProbePattern(this.moduleCount - 7, 0);
this.setupPositionProbePattern(0, this.moduleCount - 7);
this.setupPositionAdjustPattern();
this.setupTimingPattern();
this.setupTypeInfo(test, maskPattern);
if (this.typeNumber >= 7) {
this.setupTypeNumber(test);
}
if (this.dataCache == null) {
this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
}
this.mapData(this.dataCache, maskPattern);
},
setupPositionProbePattern: function(row, col) {
for (var r = -1; r <= 7; r++) {
if (row + r <= -1 || this.moduleCount <= row + r) continue;
for (var c = -1; c <= 7; c++) {
if (col + c <= -1 || this.moduleCount <= col + c) continue;
if ((0 <= r && r <= 6 && (c == 0 || c == 6)) ||
(0 <= c && c <= 6 && (r == 0 || r == 6)) ||
(2 <= r && r <= 4 && 2 <= c && c <= 4)) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
},
getBestMaskPattern: function() {
var minLostPoint = 0;
var pattern = 0;
for (var i = 0; i < 8; i++) {
this.makeImpl(true, i);
var lostPoint = QRUtil.getLostPoint(this);
if (i == 0 || minLostPoint > lostPoint) {
minLostPoint = lostPoint;
pattern = i;
}
}
return pattern;
},
createMovieClip: function(target_mc, instance_name, depth) {
var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
var cs = 1;
this.make();
for (var row = 0; row < this.modules.length; row++) {
var y = row * cs;
for (var col = 0; col < this.modules[row].length; col++) {
var x = col * cs;
var dark = this.modules[row][col];
if (dark) {
qr_mc.beginFill(0, 100);
qr_mc.moveTo(x, y);
qr_mc.lineTo(x + cs, y);
qr_mc.lineTo(x + cs, y + cs);
qr_mc.lineTo(x, y + cs);
qr_mc.endFill();
}
}
}
return qr_mc;
},
setupTimingPattern: function() {
for (var r = 8; r < this.moduleCount - 8; r++) {
if (this.modules[r][6] != null) {
continue;
}
this.modules[r][6] = (r % 2 == 0);
}
for (var c = 8; c < this.moduleCount - 8; c++) {
if (this.modules[6][c] != null) {
continue;
}
this.modules[6][c] = (c % 2 == 0);
}
},
setupPositionAdjustPattern: function() {
var pos = QRUtil.getPatternPosition(this.typeNumber);
for (var i = 0; i < pos.length; i++) {
for (var j = 0; j < pos.length; j++) {
var row = pos[i];
var col = pos[j];
if (this.modules[row][col] != null) {
continue;
}
for (var r = -2; r <= 2; r++) {
for (var c = -2; c <= 2; c++) {
if (r == -2 || r == 2 || c == -2 || c == 2 ||
(r == 0 && c == 0)) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
}
}
},
setupTypeNumber: function(test) {
var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
for (var i = 0; i < 18; i++) {
var mod = (!test && ((bits >> i) & 1) == 1);
this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
}
for (var i = 0; i < 18; i++) {
var mod = (!test && ((bits >> i) & 1) == 1);
this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
}
},
setupTypeInfo: function(test, maskPattern) {
var data = (this.errorCorrectLevel << 3) | maskPattern;
var bits = QRUtil.getBCHTypeInfo(data);
// vertical
for (var i = 0; i < 15; i++) {
var mod = (!test && ((bits >> i) & 1) == 1);
if (i < 6) {
this.modules[i][8] = mod;
} else if (i < 8) {
this.modules[i + 1][8] = mod;
} else {
this.modules[this.moduleCount - 15 + i][8] = mod;
}
}
// horizontal
for (var i = 0; i < 15; i++) {
var mod = (!test && ((bits >> i) & 1) == 1);
if (i < 8) {
this.modules[8][this.moduleCount - i - 1] = mod;
} else if (i < 9) {
this.modules[8][15 - i - 1 + 1] = mod;
} else {
this.modules[8][15 - i - 1] = mod;
}
}
// fixed module
this.modules[this.moduleCount - 8][8] = (!test);
},
mapData: function(data, maskPattern) {
var inc = -1;
var row = this.moduleCount - 1;
var bitIndex = 7;
var byteIndex = 0;
for (var col = this.moduleCount - 1; col > 0; col -= 2) {
if (col == 6) col--;
while (true) {
for (var c = 0; c < 2; c++) {
if (this.modules[row][col - c] == null) {
var dark = false;
if (byteIndex < data.length) {
dark = (((data[byteIndex] >>> bitIndex) & 1) == 1);
}
var mask = QRUtil.getMask(maskPattern, row, col - c);
if (mask) {
dark = !dark;
}
this.modules[row][col - c] = dark;
bitIndex--;
if (bitIndex == -1) {
byteIndex++;
bitIndex = 7;
}
}
}
row += inc;
if (row < 0 || this.moduleCount <= row) {
row -= inc;
inc = -inc;
break;
}
}
}
}
};
QRCode.PAD0 = 0xEC;
QRCode.PAD1 = 0x11;
QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {
var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
var buffer = new QRBitBuffer();
for (var i = 0; i < dataList.length; i++) {
var data = dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
data.write(buffer);
}
// calc num max data.
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
if (buffer.getLengthInBits() > totalDataCount * 8) {
throw new Error("code length overflow. (" +
buffer.getLengthInBits() +
">" +
totalDataCount * 8 +
")");
}
// end code
if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
buffer.put(0, 4);
}
// padding
while (buffer.getLengthInBits() % 8 != 0) {
buffer.putBit(false);
}
// padding
while (true) {
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCode.PAD0, 8);
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCode.PAD1, 8);
}
return QRCode.createBytes(buffer, rsBlocks);
}
QRCode.createBytes = function(buffer, rsBlocks) {
var offset = 0;
var maxDcCount = 0;
var maxEcCount = 0;
var dcdata = new Array(rsBlocks.length);
var ecdata = new Array(rsBlocks.length);
for (var r = 0; r < rsBlocks.length; r++) {
var dcCount = rsBlocks[r].dataCount;
var ecCount = rsBlocks[r].totalCount - dcCount;
maxDcCount = Math.max(maxDcCount, dcCount);
maxEcCount = Math.max(maxEcCount, ecCount);
dcdata[r] = new Array(dcCount);
for (var i = 0; i < dcdata[r].length; i++) {
dcdata[r][i] = 0xff & buffer.buffer[i + offset];
}
offset += dcCount;
var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
var modPoly = rawPoly.mod(rsPoly);
ecdata[r] = new Array(rsPoly.getLength() - 1);
for (var i = 0; i < ecdata[r].length; i++) {
var modIndex = i + modPoly.getLength() - ecdata[r].length;
ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
}
}
var totalCodeCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalCodeCount += rsBlocks[i].totalCount;
}
var data = new Array(totalCodeCount);
var index = 0;
for (var i = 0; i < maxDcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < dcdata[r].length) {
data[index++] = dcdata[r][i];
}
}
}
for (var i = 0; i < maxEcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < ecdata[r].length) {
data[index++] = ecdata[r][i];
}
}
}
return data;
}
//---------------------------------------------------------------------
// QRMode
//---------------------------------------------------------------------
var QRMode = {
MODE_NUMBER: 1 << 0,
MODE_ALPHA_NUM: 1 << 1,
MODE_8BIT_BYTE: 1 << 2,
MODE_KANJI: 1 << 3
};
//---------------------------------------------------------------------
// QRErrorCorrectLevel
//---------------------------------------------------------------------
var QRErrorCorrectLevel = {
L: 1,
M: 0,
Q: 3,
H: 2
};
//---------------------------------------------------------------------
// QRMaskPattern
//---------------------------------------------------------------------
var QRMaskPattern = {
PATTERN000: 0,
PATTERN001: 1,
PATTERN010: 2,
PATTERN011: 3,
PATTERN100: 4,
PATTERN101: 5,
PATTERN110: 6,
PATTERN111: 7
};
//---------------------------------------------------------------------
// QRUtil
//---------------------------------------------------------------------
var QRUtil = {
PATTERN_POSITION_TABLE: [
[],
[6, 18],
[6, 22],
[6, 26],
[6, 30],
[6, 34],
[6, 22, 38],
[6, 24, 42],
[6, 26, 46],
[6, 28, 50],
[6, 30, 54],
[6, 32, 58],
[6, 34, 62],
[6, 26, 46, 66],
[6, 26, 48, 70],
[6, 26, 50, 74],
[6, 30, 54, 78],
[6, 30, 56, 82],
[6, 30, 58, 86],
[6, 34, 62, 90],
[6, 28, 50, 72, 94],
[6, 26, 50, 74, 98],
[6, 30, 54, 78, 102],
[6, 28, 54, 80, 106],
[6, 32, 58, 84, 110],
[6, 30, 58, 86, 114],
[6, 34, 62, 90, 118],
[6, 26, 50, 74, 98, 122],
[6, 30, 54, 78, 102, 126],
[6, 26, 52, 78, 104, 130],
[6, 30, 56, 82, 108, 134],
[6, 34, 60, 86, 112, 138],
[6, 30, 58, 86, 114, 142],
[6, 34, 62, 90, 118, 146],
[6, 30, 54, 78, 102, 126, 150],
[6, 24, 50, 76, 102, 128, 154],
[6, 28, 54, 80, 106, 132, 158],
[6, 32, 58, 84, 110, 136, 162],
[6, 26, 54, 82, 110, 138, 166],
[6, 30, 58, 86, 114, 142, 170]
],
G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
getBCHTypeInfo: function(data) {
var d = data << 10;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)));
}
return ((data << 10) | d) ^ QRUtil.G15_MASK;
},
getBCHTypeNumber: function(data) {
var d = data << 12;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)));
}
return (data << 12) | d;
},
getBCHDigit: function(data) {
var digit = 0;
while (data != 0) {
digit++;
data >>>= 1;
}
return digit;
},
getPatternPosition: function(typeNumber) {
return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
},
getMask: function(maskPattern, i, j) {
switch (maskPattern) {
case QRMaskPattern.PATTERN000:
return (i + j) % 2 == 0;
case QRMaskPattern.PATTERN001:
return i % 2 == 0;
case QRMaskPattern.PATTERN010:
return j % 3 == 0;
case QRMaskPattern.PATTERN011:
return (i + j) % 3 == 0;
case QRMaskPattern.PATTERN100:
return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
case QRMaskPattern.PATTERN101:
return (i * j) % 2 + (i * j) % 3 == 0;
case QRMaskPattern.PATTERN110:
return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
case QRMaskPattern.PATTERN111:
return ((i * j) % 3 + (i + j) % 2) % 2 == 0;
default:
throw new Error("bad maskPattern:" + maskPattern);
}
},
getErrorCorrectPolynomial: function(errorCorrectLength) {
var a = new QRPolynomial([1], 0);
for (var i = 0; i < errorCorrectLength; i++) {
a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
}
return a;
},
getLengthInBits: function(mode, type) {
if (1 <= type && type < 10) {
// 1 - 9
switch (mode) {
case QRMode.MODE_NUMBER:
return 10;
case QRMode.MODE_ALPHA_NUM:
return 9;
case QRMode.MODE_8BIT_BYTE:
return 8;
case QRMode.MODE_KANJI:
return 8;
default:
throw new Error("mode:" + mode);
}
} else if (type < 27) {
// 10 - 26
switch (mode) {
case QRMode.MODE_NUMBER:
return 12;
case QRMode.MODE_ALPHA_NUM:
return 11;
case QRMode.MODE_8BIT_BYTE:
return 16;
case QRMode.MODE_KANJI:
return 10;
default:
throw new Error("mode:" + mode);
}
} else if (type < 41) {
// 27 - 40
switch (mode) {
case QRMode.MODE_NUMBER:
return 14;
case QRMode.MODE_ALPHA_NUM:
return 13;
case QRMode.MODE_8BIT_BYTE:
return 16;
case QRMode.MODE_KANJI:
return 12;
default:
throw new Error("mode:" + mode);
}
} else {
throw new Error("type:" + type);
}
},
getLostPoint: function(qrCode) {
var moduleCount = qrCode.getModuleCount();
var lostPoint = 0;
// LEVEL1
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount; col++) {
var sameCount = 0;
var dark = qrCode.isDark(row, col);
for (var r = -1; r <= 1; r++) {
if (row + r < 0 || moduleCount <= row + r) {
continue;
}
for (var c = -1; c <= 1; c++) {
if (col + c < 0 || moduleCount <= col + c) {
continue;
}
if (r == 0 && c == 0) {
continue;
}
if (dark == qrCode.isDark(row + r, col + c)) {
sameCount++;
}
}
}
if (sameCount > 5) {
lostPoint += (3 + sameCount - 5);
}
}
}
// LEVEL2
for (var row = 0; row < moduleCount - 1; row++) {
for (var col = 0; col < moduleCount - 1; col++) {
var count = 0;
if (qrCode.isDark(row, col)) count++;
if (qrCode.isDark(row + 1, col)) count++;
if (qrCode.isDark(row, col + 1)) count++;
if (qrCode.isDark(row + 1, col + 1)) count++;
if (count == 0 || count == 4) {
lostPoint += 3;
}
}
}
// LEVEL3
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount - 6; col++) {
if (qrCode.isDark(row, col) &&
!qrCode.isDark(row, col + 1) &&
qrCode.isDark(row, col + 2) &&
qrCode.isDark(row, col + 3) &&
qrCode.isDark(row, col + 4) &&
!qrCode.isDark(row, col + 5) &&
qrCode.isDark(row, col + 6)) {
lostPoint += 40;
}
}
}
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount - 6; row++) {
if (qrCode.isDark(row, col) &&
!qrCode.isDark(row + 1, col) &&
qrCode.isDark(row + 2, col) &&
qrCode.isDark(row + 3, col) &&
qrCode.isDark(row + 4, col) &&
!qrCode.isDark(row + 5, col) &&
qrCode.isDark(row + 6, col)) {
lostPoint += 40;
}
}
}
// LEVEL4
var darkCount = 0;
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount; row++) {
if (qrCode.isDark(row, col)) {
darkCount++;
}
}
}
var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
lostPoint += ratio * 10;
return lostPoint;
}
};
//---------------------------------------------------------------------
// QRMath
//---------------------------------------------------------------------
var QRMath = {
glog: function(n) {
if (n < 1) {
throw new Error("glog(" + n + ")");
}
return QRMath.LOG_TABLE[n];
},
gexp: function(n) {
while (n < 0) {
n += 255;
}
while (n >= 256) {
n -= 255;
}
return QRMath.EXP_TABLE[n];
},
EXP_TABLE: new Array(256),
LOG_TABLE: new Array(256)
};
for (var i = 0; i < 8; i++) {
QRMath.EXP_TABLE[i] = 1 << i;
}
for (var i = 8; i < 256; i++) {
QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^
QRMath.EXP_TABLE[i - 5] ^
QRMath.EXP_TABLE[i - 6] ^
QRMath.EXP_TABLE[i - 8];
}
for (var i = 0; i < 255; i++) {
QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
}
//---------------------------------------------------------------------
// QRPolynomial
//---------------------------------------------------------------------
function QRPolynomial(num, shift) {
if (num.length == undefined) {
throw new Error(num.length + "/" + shift);
}
var offset = 0;
while (offset < num.length && num[offset] == 0) {
offset++;
}
this.num = new Array(num.length - offset + shift);
for (var i = 0; i < num.length - offset; i++) {
this.num[i] = num[i + offset];
}
}
QRPolynomial.prototype = {
get: function(index) {
return this.num[index];
},
getLength: function() {
return this.num.length;
},
multiply: function(e) {
var num = new Array(this.getLength() + e.getLength() - 1);
for (var i = 0; i < this.getLength(); i++) {
for (var j = 0; j < e.getLength(); j++) {
num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
}
}
return new QRPolynomial(num, 0);
},
mod: function(e) {
if (this.getLength() - e.getLength() < 0) {
return this;
}
var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0));
var num = new Array(this.getLength());
for (var i = 0; i < this.getLength(); i++) {
num[i] = this.get(i);
}
for (var i = 0; i < e.getLength(); i++) {
num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
}
// recursive call
return new QRPolynomial(num, 0).mod(e);
}
};
//---------------------------------------------------------------------
// QRRSBlock
//---------------------------------------------------------------------
function QRRSBlock(totalCount, dataCount) {
this.totalCount = totalCount;
this.dataCount = dataCount;
}
QRRSBlock.RS_BLOCK_TABLE = [
// L
// M
// Q
// H
// 1
[1, 26, 19],
[1, 26, 16],
[1, 26, 13],
[1, 26, 9],
// 2
[1, 44, 34],
[1, 44, 28],
[1, 44, 22],
[1, 44, 16],
// 3
[1, 70, 55],
[1, 70, 44],
[2, 35, 17],
[2, 35, 13],
// 4
[1, 100, 80],
[2, 50, 32],
[2, 50, 24],
[4, 25, 9],
// 5
[1, 134, 108],
[2, 67, 43],
[2, 33, 15, 2, 34, 16],
[2, 33, 11, 2, 34, 12],
// 6
[2, 86, 68],
[4, 43, 27],
[4, 43, 19],
[4, 43, 15],
// 7
[2, 98, 78],
[4, 49, 31],
[2, 32, 14, 4, 33, 15],
[4, 39, 13, 1, 40, 14],
// 8
[2, 121, 97],
[2, 60, 38, 2, 61, 39],
[4, 40, 18, 2, 41, 19],
[4, 40, 14, 2, 41, 15],
// 9
[2, 146, 116],
[3, 58, 36, 2, 59, 37],
[4, 36, 16, 4, 37, 17],
[4, 36, 12, 4, 37, 13],
// 10
[2, 86, 68, 2, 87, 69],
[4, 69, 43, 1, 70, 44],
[6, 43, 19, 2, 44, 20],
[6, 43, 15, 2, 44, 16],
// 11
[4, 101, 81],
[1, 80, 50, 4, 81, 51],
[4, 50, 22, 4, 51, 23],
[3, 36, 12, 8, 37, 13],
// 12
[2, 116, 92, 2, 117, 93],
[6, 58, 36, 2, 59, 37],
[4, 46, 20, 6, 47, 21],
[7, 42, 14, 4, 43, 15],
// 13
[4, 133, 107],
[8, 59, 37, 1, 60, 38],
[8, 44, 20, 4, 45, 21],
[12, 33, 11, 4, 34, 12],
// 14
[3, 145, 115, 1, 146, 116],
[4, 64, 40, 5, 65, 41],
[11, 36, 16, 5, 37, 17],
[11, 36, 12, 5, 37, 13],
// 15
[5, 109, 87, 1, 110, 88],
[5, 65, 41, 5, 66, 42],
[5, 54, 24, 7, 55, 25],
[11, 36, 12],
// 16
[5, 122, 98, 1, 123, 99],
[7, 73, 45, 3, 74, 46],
[15, 43, 19, 2, 44, 20],
[3, 45, 15, 13, 46, 16],
// 17
[1, 135, 107, 5, 136, 108],
[10, 74, 46, 1, 75, 47],
[1, 50, 22, 15, 51, 23],
[2, 42, 14, 17, 43, 15],
// 18
[5, 150, 120, 1, 151, 121],
[9, 69, 43, 4, 70, 44],
[17, 50, 22, 1, 51, 23],
[2, 42, 14, 19, 43, 15],
// 19
[3, 141, 113, 4, 142, 114],
[3, 70, 44, 11, 71, 45],
[17, 47, 21, 4, 48, 22],
[9, 39, 13, 16, 40, 14],
// 20
[3, 135, 107, 5, 136, 108],
[3, 67, 41, 13, 68, 42],
[15, 54, 24, 5, 55, 25],
[15, 43, 15, 10, 44, 16],
// 21
[4, 144, 116, 4, 145, 117],
[17, 68, 42],
[17, 50, 22, 6, 51, 23],
[19, 46, 16, 6, 47, 17],
// 22
[2, 139, 111, 7, 140, 112],
[17, 74, 46],
[7, 54, 24, 16, 55, 25],
[34, 37, 13],
// 23
[4, 151, 121, 5, 152, 122],
[4, 75, 47, 14, 76, 48],
[11, 54, 24, 14, 55, 25],
[16, 45, 15, 14, 46, 16],
// 24
[6, 147, 117, 4, 148, 118],
[6, 73, 45, 14, 74, 46],
[11, 54, 24, 16, 55, 25],
[30, 46, 16, 2, 47, 17],
// 25
[8, 132, 106, 4, 133, 107],
[8, 75, 47, 13, 76, 48],
[7, 54, 24, 22, 55, 25],
[22, 45, 15, 13, 46, 16],
// 26
[10, 142, 114, 2, 143, 115],
[19, 74, 46, 4, 75, 47],
[28, 50, 22, 6, 51, 23],
[33, 46, 16, 4, 47, 17],
// 27
[8, 152, 122, 4, 153, 123],
[22, 73, 45, 3, 74, 46],
[8, 53, 23, 26, 54, 24],
[12, 45, 15, 28, 46, 16],
// 28
[3, 147, 117, 10, 148, 118],
[3, 73, 45, 23, 74, 46],
[4, 54, 24, 31, 55, 25],
[11, 45, 15, 31, 46, 16],
// 29
[7, 146, 116, 7, 147, 117],
[21, 73, 45, 7, 74, 46],
[1, 53, 23, 37, 54, 24],
[19, 45, 15, 26, 46, 16],
// 30
[5, 145, 115, 10, 146, 116],
[19, 75, 47, 10, 76, 48],
[15, 54, 24, 25, 55, 25],
[23, 45, 15, 25, 46, 16],
// 31
[13, 145, 115, 3, 146, 116],
[2, 74, 46, 29, 75, 47],
[42, 54, 24, 1, 55, 25],
[23, 45, 15, 28, 46, 16],
// 32
[17, 145, 115],
[10, 74, 46, 23, 75, 47],
[10, 54, 24, 35, 55, 25],
[19, 45, 15, 35, 46, 16],
// 33
[17, 145, 115, 1, 146, 116],
[14, 74, 46, 21, 75, 47],
[29, 54, 24, 19, 55, 25],
[11, 45, 15, 46, 46, 16],
// 34
[13, 145, 115, 6, 146, 116],
[14, 74, 46, 23, 75, 47],
[44, 54, 24, 7, 55, 25],
[59, 46, 16, 1, 47, 17],
// 35
[12, 151, 121, 7, 152, 122],
[12, 75, 47, 26, 76, 48],
[39, 54, 24, 14, 55, 25],
[22, 45, 15, 41, 46, 16],
// 36
[6, 151, 121, 14, 152, 122],
[6, 75, 47, 34, 76, 48],
[46, 54, 24, 10, 55, 25],
[2, 45, 15, 64, 46, 16],
// 37
[17, 152, 122, 4, 153, 123],
[29, 74, 46, 14, 75, 47],
[49, 54, 24, 10, 55, 25],
[24, 45, 15, 46, 46, 16],
// 38
[4, 152, 122, 18, 153, 123],
[13, 74, 46, 32, 75, 47],
[48, 54, 24, 14, 55, 25],
[42, 45, 15, 32, 46, 16],
// 39
[20, 147, 117, 4, 148, 118],
[40, 75, 47, 7, 76, 48],
[43, 54, 24, 22, 55, 25],
[10, 45, 15, 67, 46, 16],
// 40
[19, 148, 118, 6, 149, 119],
[18, 75, 47, 31, 76, 48],
[34, 54, 24, 34, 55, 25],
[20, 45, 15, 61, 46, 16]
];
QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
if (rsBlock == undefined) {
throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
}
var length = rsBlock.length / 3;
var list = new Array();
for (var i = 0; i < length; i++) {
var count = rsBlock[i * 3 + 0];
var totalCount = rsBlock[i * 3 + 1];
var dataCount = rsBlock[i * 3 + 2];
for (var j = 0; j < count; j++) {
list.push(new QRRSBlock(totalCount, dataCount));
}
}
return list;
}
QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
switch (errorCorrectLevel) {
case QRErrorCorrectLevel.L:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
case QRErrorCorrectLevel.M:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
case QRErrorCorrectLevel.Q:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
case QRErrorCorrectLevel.H:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
default:
return undefined;
}
}
//---------------------------------------------------------------------
// QRBitBuffer
//---------------------------------------------------------------------
function QRBitBuffer() {
this.buffer = new Array();
this.length = 0;
}
QRBitBuffer.prototype = {
get: function(index) {
var bufIndex = Math.floor(index / 8);
return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1;
},
put: function(num, length) {
for (var i = 0; i < length; i++) {
this.putBit(((num >>> (length - i - 1)) & 1) == 1);
}
},
getLengthInBits: function() {
return this.length;
},
putBit: function(bit) {
var bufIndex = Math.floor(this.length / 8);
if (this.buffer.length <= bufIndex) {
this.buffer.push(0);
}
if (bit) {
this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
}
this.length++;
}
};
//---------------------------------------------------------------------
// Support Chinese
//---------------------------------------------------------------------
function utf16To8(text) {
var result = '';
var c;
for (var i = 0; i < text.length; i++) {
c = text.charCodeAt(i);
if (c >= 0x0001 && c <= 0x007F) {
result += text.charAt(i);
} else if (c > 0x07FF) {
result += String.fromCharCode(0xE0 | c >> 12 & 0x0F);
result += String.fromCharCode(0x80 | c >> 6 & 0x3F);
result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
} else {
result += String.fromCharCode(0xC0 | c >> 6 & 0x1F);
result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
}
}
return result;
}
uQRCode = {
errorCorrectLevel: QRErrorCorrectLevel,
defaults: {
size: 354,
margin: 0,
backgroundColor: '#ffffff',
foregroundColor: '#000000',
fileType: 'png', // 'jpg', 'png'
errorCorrectLevel: QRErrorCorrectLevel.H,
typeNumber: -1
},
make: function(options) {
return new Promise((reslove, reject) => {
var defaultOptions = {
canvasId: options.canvasId,
componentInstance: options.componentInstance,
text: options.text,
size: this.defaults.size,
margin: this.defaults.margin,
backgroundColor: this.defaults.backgroundColor,
foregroundColor: this.defaults.foregroundColor,
fileType: this.defaults.fileType,
errorCorrectLevel: this.defaults.errorCorrectLevel,
typeNumber: this.defaults.typeNumber
};
if (options) {
for (var i in options) {
defaultOptions[i] = options[i];
}
}
options = defaultOptions;
if (!options.canvasId) {
console.error('uQRCode: Please set canvasId!');
return;
}
function createCanvas() {
var qrcode = new QRCode(options.typeNumber, options.errorCorrectLevel);
qrcode.addData(utf16To8(options.text));
qrcode.make();
var ctx = uni.createCanvasContext(options.canvasId, options.componentInstance);
ctx.setFillStyle(options.backgroundColor);
ctx.fillRect(0, 0, options.size, options.size);
var tileW = (options.size - options.margin * 2) / qrcode.getModuleCount();
var tileH = tileW;
for (var row = 0; row < qrcode.getModuleCount(); row++) {
for (var col = 0; col < qrcode.getModuleCount(); col++) {
var style = qrcode.isDark(row, col) ? options.foregroundColor : options.backgroundColor;
ctx.setFillStyle(style);
var x = Math.round(col * tileW) + options.margin;
var y = Math.round(row * tileH) + options.margin;
var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW);
var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW);
ctx.fillRect(x, y, w, h);
}
}
setTimeout(function() {
ctx.draw(false, (function() {
setTimeout(function() {
uni.canvasToTempFilePath({
canvasId: options.canvasId,
fileType: options.fileType,
width: options.size,
height: options.size,
destWidth: options.size,
destHeight: options.size,
success: function(res) {
let resData; // 将统一为base64格式
let tempFilePath = res.tempFilePath; // H5为base64,其他为相对路径
// #ifdef H5
resData = tempFilePath;
options.success && options.success(resData);
reslove(resData);
// #endif
// #ifdef APP-PLUS
const path = plus.io.convertLocalFileSystemURL(tempFilePath) // 绝对路径
let fileReader = new plus.io.FileReader();
fileReader.readAsDataURL(path);
fileReader.onloadend = res => {
resData = res.target.result;
options.success && options.success(resData);
reslove(resData);
};
// #endif
// #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
uni.getFileSystemManager().readFile({
filePath: tempFilePath,
encoding: 'base64',
success: res => {
resData = 'data:image/png;base64,' + res.data;
options.success && options.success(resData);
reslove(resData);
}
})
// #endif
// #ifndef H5 || APP-PLUS || MP-WEIXIN || MP-QQ || MP-TOUTIAO
if (plus) {
const path = plus.io.convertLocalFileSystemURL(tempFilePath) // 绝对路径
let fileReader = new plus.io.FileReader();
fileReader.readAsDataURL(path);
fileReader.onloadend = res => {
resData = res.target.result;
options.success && options.success(resData);
reslove(resData);
};
} else {
uni.request({
url: tempFilePath,
method: 'GET',
responseType: 'arraybuffer',
success: res => {
resData = `data:image/png;base64,${uni.arrayBufferToBase64(res.data)}`; // 把arraybuffer转成base64
options.success && options.success(resData);
reslove(resData);
}
})
}
// #endif
},
fail: function(error) {
options.fail && options.fail(error);
reject(error);
},
complete: function(res) {
options.complete && options.complete(res);
}
}, options.componentInstance);
}, options.text.length + 100);
})());
}, 150);
}
createCanvas();
});
}
}
})()
export default uQRCode
......@@ -21,7 +21,6 @@ export default function request(name,params,callback=false,{showLoading=false,lo
uniCloud.callFunction({name,data: {action,params},
success(e){
// console.log(e);
if(showLoading || loadText) uni.hideLoading()
const {result:{data,code}} = e
console.log(data,code);
if (code === 0 ) {
......@@ -47,6 +46,9 @@ export default function request(name,params,callback=false,{showLoading=false,lo
})
}
fail(err)
},
complete() {
if(showLoading || loadText) uni.hideLoading()
}
})
})
......
......@@ -86,7 +86,8 @@
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
"usingComponents" : true,
"betterScopedSlots":true
},
"mp-alipay" : {
"usingComponents" : true
......
......@@ -76,7 +76,17 @@
}, {
"path": "pages/ucenter/about/about",
"style": {
"navigationBarTitleText": "关于"
"navigationBarTitleText": "关于"
// #ifdef APP-PLUS
,"app-plus": {
"titleNView": {
"buttons": [{
"type": "share"
}],
"type": "transparent"
}
}
// #endif
}
}, {
......@@ -179,6 +189,13 @@
},
"condition": {
"list": [
{
"path": "pages/list/list",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": true
}
},
{
"path": "uni_modules/uni-login-page/pages/index/index"
},
......
<template>
<!--
本页面模板教程:https://ext.dcloud.net.cn/plugin?id=2717
uni-list 文档:https://ext.dcloud.net.cn/plugin?id=24
uniCloud 文档:https://uniapp.dcloud.io/uniCloud/README
unicloud-db 组件文档:https://uniapp.dcloud.net.cn/uniCloud/unicloud-db-component
DB Schema 规范:https://uniapp.dcloud.net.cn/uniCloud/schema
-->
<view class="article">
<uni-nav-bar :statusBar="true" :border="false"></uni-nav-bar>
<unicloud-db v-slot:default="{data, loading, error, options}" :options="formData" :collection="collection" :field="field"
:getone="true" :where="where" :manual="true" ref="detail" foreignKey="opendb-news-articles.author" @load="loadData">
<template v-if="!loading && data">
<view class="article-title">{{title}}</view>
<uni-list :border="false">
<uni-list-item thumbSize="lg" :thumb="data.image">
<!-- 通过body插槽定义作者信息内容 -->
<view slot="body" class="header-content">
<view class="uni-title">{{data.author && data.author[0].username}}</view>
<view class="uni-note">更新于 <uni-dateformat :date="data.last_modify_date" format="yyyy-MM-dd" :threshold="[60000, 2592000000]" /> </view>
</view>
<view slot="footer" class="footer">
<button @click="followClick" class="footer-button">关注</button>
</view>
</uni-list-item>
</uni-list>
<view class="banner">
<!-- 文章开头,缩略图 -->
<image class="banner-img" :src="data.avatar" mode="widthFix"></image>
<!-- 文章摘要 -->
<view class="banner-title">
<text class="uni-ellipsis">{{data.excerpt}}</text>
</view>
</view>
<!-- 新闻详情:使用 uParse 解析富文本 -->
<view class="article-content">
<u-parse :content="data.content" :noData="options.noData"></u-parse>
</view>
</template>
</unicloud-db>
<uni-popup ref="sharePopup" type="bottom">
<uni-popup-share @select="selectShareItem"></uni-popup-share>
</uni-popup>
</view>
</template>
<script>
import uParse from '@/components/u-parse/parse.vue';
export default {
components: {
uParse
},
data() {
return {
// 当前显示 _id
id:"",
title:'',
// 数据表名
collection: 'opendb-news-articles,uni-id-users',
// 查询字段,多个字段用 , 分割
field: 'author{username, _id},_id,avatar,excerpt,last_modify_date, comment_count, like_count,title,content',
formData: {
noData: '<p style="text-align:center;color:#666">详情加载中...</p>'
},
}
},
computed:{
//拼接where条件
//查询条件 ,更多详见 :https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=jsquery
where(){
return `_id =="${this.id}"`
}
},
onLoad(event) {
//获取真实新闻id,通常 id 来自上一个页面
if(event.id){
this.id = event.id
}
//若上一页传递了标题过来,则设置导航栏标题
if(event.title){
this.title = event.title
uni.setNavigationBarTitle({
title:event.title
})
}
},
onNavigationBarButtonTap(event) {
if(event.type == 'share'){
this.shareClick();
}
},
onReady() {
// 开始加载数据,修改 where 条件后才开始去加载 clinetDB 的数据 ,需要等组件渲染完毕后才开始执行 loadData,所以不能再 onLoad 中执行
if(this.id){// ID 不为空,则发起查询
this.$refs.detail.loadData()
}else{
uni.showToast({
icon:'none',
title:'出错了,新闻ID为空'
})
}
},
methods: {
loadData(data){
//如果上一页未传递标题过来(如搜索直达详情),则从新闻详情中读取标题
if(this.title == '' && data[0].title){
this.title = data[0].title
uni.setNavigationBarTitle({
title:data[0].title
})
}
},
/**
* followClick
* 点击关注
*/
followClick(){
uni.showToast({
title: '点击关注',
icon: 'none'
});
},
/**
* 分享该文章
*/
shareClick(){
//#ifdef APP-PLUS
this.$refs.sharePopup.open();
//#endif
//#ifndef APP-PLUS || H5
uni.setClipboardData({
data: 'http://uniapp.dcloud.io/',
success: function () {
uni.showToast({
title: '已复制到剪切板',
icon: 'none'
});
}
});
//#endif
// #ifdef H5
let value = 'http://uniapp.dcloud.io/';
const textarea = document.createElement('textarea');
textarea.value = value;
textarea.readOnly = true;
document.body.appendChild(textarea);
textarea.select();
textarea.setSelectionRange(0, value.length);
document.execCommand('copy');
textarea.remove();
uni.showToast({
title: '已复制到剪切板',
icon: 'none'
});
// #endif
},
selectShareItem({item, index}, done){
//#ifdef APP-PLUS
if(item.name == 'more'){
// "复制链接"选项
uni.setClipboardData({
data: 'http://uniapp.dcloud.io/',
success: function () {
uni.showToast({
title: '已复制到剪切板',
icon: 'none'
});
}
});
} else {
uni.share({
provider: item.name,
scene: "WXSceneSession",
type: 0,
href: "http://uniapp.dcloud.io/",
title: "uni-app分享",
summary: "我正在使用HBuilderX开发uni-app,赶紧跟我一起来体验!",
imageUrl: "https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/d8590190-4f28-11eb-b680-7980c8a877b8.png",
success: function (res) {
console.log("success:" + JSON.stringify(res));
},
fail: function (err) {
console.log("fail:" + JSON.stringify(err));
}
});
}
//#endif
//#ifndef APP-PLUS
uni.showToast({
title: '仅app端支持分享',
icon: 'none'
});
//#endif
done();
}
}
}
</script>
<style scoped>
.header-content {
flex: 1;
display: flex;
flex-direction: column;
font-size: 14px;
}
/* 标题 */
.uni-title {
display: flex;
margin-bottom: 5px;
font-size: 14px;
font-weight: bold;
color: #3b4144;
}
/* 描述 额外文本 */
.uni-note {
color: #999;
font-size: 12px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
}
.footer {
display: flex;
align-items: center;
}
.footer-button {
display: flex;
align-items: center;
font-size: 12px;
height: 30px;
color: #fff;
background-color: #ff5a5f;
}
.banner {
position: relative;
margin: 0 15px;
height: 180px;
overflow: hidden;
}
.banner-img {
position: absolute;
width: 100%;
}
.banner-title {
display: flex;
align-items: center;
position: absolute;
padding: 0 15px;
width: 100%;
bottom: 0;
height: 30px;
font-size: 14px;
color: #fff;
background: rgba(0, 0, 0, 0.4);
overflow: hidden;
box-sizing: border-box;
}
.uni-ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.article-title {
padding: 20px 15px;
padding-bottom: 0;
}
.article-content {
padding: 15px;
font-size: 15px;
overflow: hidden;
}
<template>
<!--
本页面模板教程:https://ext.dcloud.net.cn/plugin?id=2717
uni-list 文档:https://ext.dcloud.net.cn/plugin?id=24
uniCloud 文档:https://uniapp.dcloud.io/uniCloud/README
unicloud-db 组件文档:https://uniapp.dcloud.net.cn/uniCloud/unicloud-db-component
DB Schema 规范:https://uniapp.dcloud.net.cn/uniCloud/schema
-->
<view class="article">
<uni-nav-bar :statusBar="true" :border="false"></uni-nav-bar>
<unicloud-db v-slot:default="{data, loading, error, options}" :options="formData" :collection="collection"
:field="field" :getone="true" :where="where" :manual="true" ref="detail"
foreignKey="opendb-news-articles.author" @load="loadData">
<template v-if="!loading && data">
<view class="article-title">{{title}}</view>
<uni-list :border="false">
<uni-list-item thumbSize="lg" :thumb="data.image">
<!-- 通过body插槽定义作者信息内容 -->
<view slot="body" class="header-content">
<view class="uni-title">{{data.author && data.author[0].username}}</view>
<view class="uni-note">更新于
<uni-dateformat :date="data.last_modify_date" format="yyyy-MM-dd"
:threshold="[60000, 2592000000]" />
</view>
</view>
<view slot="footer" class="footer">
<button @click="followClick" class="footer-button">关注</button>
</view>
</uni-list-item>
</uni-list>
<view class="banner">
<!-- 文章开头,缩略图 -->
<image class="banner-img" :src="data.avatar" mode="widthFix"></image>
<!-- 文章摘要 -->
<view class="banner-title">
<text class="uni-ellipsis">{{data.excerpt}}</text>
</view>
</view>
<!-- 新闻详情:使用 uParse 解析富文本 -->
<view class="article-content">
<u-parse :content="data.content" :noData="options.noData"></u-parse>
</view>
</template>
</unicloud-db>
</view>
</template>
<script>
import baseappConfig from '@/baseapp.config.js';
import uniShare from 'uni_modules/uni-share/js_sdk/uni-share.js';
import uParse from '@/components/u-parse/parse.vue';
export default {
components: {
uParse
},
data() {
return {
// 当前显示 _id
id: "",
title: '',
// 数据表名
collection: 'opendb-news-articles,uni-id-users',
// 查询字段,多个字段用 , 分割
field: 'author{username, _id},_id,avatar,excerpt,last_modify_date, comment_count, like_count,title,content',
formData: {
noData: '<p style="text-align:center;color:#666">详情加载中...</p>'
},
}
},
computed: {
//拼接where条件
//查询条件 ,更多详见 :https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=jsquery
where() {
return `_id =="${this.id}"`
}
},
onLoad(event) {
//获取真实新闻id,通常 id 来自上一个页面
if (event.id) {
this.id = event.id
}
//若上一页传递了标题过来,则设置导航栏标题
if (event.title) {
this.title = event.title
uni.setNavigationBarTitle({
title: event.title
})
}
},
onNavigationBarButtonTap(event) {
if (event.type == 'share') {
this.shareClick();
}
},
onReady() {
// 开始加载数据,修改 where 条件后才开始去加载 clinetDB 的数据 ,需要等组件渲染完毕后才开始执行 loadData,所以不能再 onLoad 中执行
if (this.id) { // ID 不为空,则发起查询
this.$refs.detail.loadData()
} else {
uni.showToast({
icon: 'none',
title: '出错了,新闻ID为空'
})
}
},
methods: {
loadData(data) {
//如果上一页未传递标题过来(如搜索直达详情),则从新闻详情中读取标题
if (this.title == '' && data[0].title) {
this.title = data[0].title
uni.setNavigationBarTitle({
title: data[0].title
})
}
},
/**
* followClick
* 点击关注
*/
followClick() {
uni.showToast({
title: '点击关注',
icon: 'none'
});
},
/**
* 分享该文章
*/
shareClick() {
let {
_id,
title,
excerpt,
avatar
} = this.$refs.detail.dataList
uniShare({
content: { //公共的分享类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图)
type: 0,
href: baseappConfig.h5.url + `/#/pages/list/detail?id=${_id}&title=${title}`,
title: this.title,
summary: excerpt,
imageUrl: avatar
},
menus: [{
"img": "/static/sharemenu/wechatfriend.png",
"text": "微信好友",
"share": {
"provider": "weixin",
"scene": "WXSceneSession"
}
},
{
"img": "/static/sharemenu/wechatmoments.png",
"text": "微信朋友圈",
"share": {
"provider": "weixin",
"scene": "WXSenceTimeline"
}
},
{
"img": "/static/sharemenu/mp_weixin.png",
"text": "微信小程序",
"share": {
provider: "weixin",
scene: "WXSceneSession",
type: 5,
miniProgram: {
id:baseappConfig.mp.weixin.id,
path:`/pages/list/detail?id=${_id}&title=${title}`,
webUrl:baseappConfig.h5.url + `/#/pages/list/detail?id=${_id}&title=${title}`,
type:0
},
}
},
{
"img": "/static/sharemenu/weibo.png",
"text": "微博",
"share": {
"provider": "sinaweibo"
}
},
{
"img": "/static/sharemenu/qq.png",
"text": "QQ",
"share": {
"provider": "qq"
}
},
{
"img": "/static/sharemenu/copyurl.png",
"text": "复制",
"share": "copyurl"
},
{
"img": "/static/sharemenu/more.png",
"text": "更多",
"share": "shareSystem"
}
],
cancelText: "取消分享",
}, e => { //callback
console.log(e);
})
},
}
}
</script>
<style scoped>
.header-content {
flex: 1;
display: flex;
flex-direction: column;
font-size: 14px;
}
/* 标题 */
.uni-title {
display: flex;
margin-bottom: 5px;
font-size: 14px;
font-weight: bold;
color: #3b4144;
}
/* 描述 额外文本 */
.uni-note {
color: #999;
font-size: 12px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
}
.footer {
display: flex;
align-items: center;
}
.footer-button {
display: flex;
align-items: center;
font-size: 12px;
height: 30px;
color: #fff;
background-color: #ff5a5f;
}
.banner {
position: relative;
margin: 0 15px;
height: 180px;
overflow: hidden;
}
.banner-img {
position: absolute;
width: 100%;
}
.banner-title {
display: flex;
align-items: center;
position: absolute;
padding: 0 15px;
width: 100%;
bottom: 0;
height: 30px;
font-size: 14px;
color: #fff;
background: rgba(0, 0, 0, 0.4);
overflow: hidden;
box-sizing: border-box;
}
.uni-ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.article-title {
padding: 20px 15px;
padding-bottom: 0;
}
.article-content {
padding: 15px;
font-size: 15px;
overflow: hidden;
}
</style>
......@@ -17,7 +17,7 @@
<script>
// import permision from '@/js_sdk/wa-permission/permission.js';
import uniShare from 'uni_modules/uni-share/js_sdk/main.js';
import uniShare from 'uni_modules/uni-share/js_sdk/uni-share.js';
export default {
data() {
return {
......@@ -86,7 +86,60 @@
},
methods: {
showShare(){
uniShare()
uniShare({
menus:[
{
"img": "/static/sharemenu/wechatfriend.png",
"text": "微信好友",
"share": {
"provider": "weixin",
"scene": "WXSceneSession"
}
},
{
"img": "/static/sharemenu/wechatmoments.png",
"text": "微信朋友圈",
"share": {
"provider": "weixin",
"scene": "WXSceneSession"
}
},
{
"img": "/static/sharemenu/weibo.png",
"text": "微博",
"share": {
"provider": "sinaweibo"
}
},
{
"img": "/static/sharemenu/qq.png",
"text": "QQ",
"share": {
"provider": "qq"
}
},
{
"img": "/static/sharemenu/copyurl.png",
"text": "复制",
"share": "copyurl"
},
{
"img": "/static/sharemenu/more.png",
"text": "更多",
"share": "shareSystem"
}
],
content:{
type: 0,
href: "https://uniapp.dcloud.io/api/plugins/share?id=share",
title: "主标题",
summary: "分享内容的摘要",
imageUrl: "https://uniapp.dcloud.io/api/plugins/share?id=share",
},
cancelText:"取消分享",
},e=>{ //callback
console.log(e);
})
},
clickItem(e){
console.log(e);
......
<template>
<view class="about">
<view class="logo">
<image class="logoImg" src="@/static/logo.png"></image>
<view class="box">
<image class="logoImg" :src="about.logo"></image>
<text class="tip appName">{{about.appName}}</text>
<text class="tip" style="font-size:24upx;">Version {{version}}</text>
<!--Sansnn-uQRCode组件来源,插件市场:https://ext.dcloud.net.cn/plugin?id=1287 微调后-->
<Sansnn-uQRCode :text="about.download" :makeOnLoad="true" class="qrcode"></Sansnn-uQRCode>
</view>
<view class="copyright">
<template v-for="(agreement,index) in about.agreements">
......@@ -17,6 +19,7 @@
</template>
<script>
import baseappConfig from '@/baseapp.config.js';
import uniShare from 'uni_modules/uni-share/js_sdk/uni-share.js';
export default {
onLoad() {
// #ifdef APP-PLUS
......@@ -34,6 +37,62 @@ import baseappConfig from '@/baseapp.config.js';
this.about = baseappConfig.about
this.year = (new Date).getFullYear()
},
onNavigationBarButtonTap() {
let {download,appName,slogan,logo} = this.about
uniShare({
content: { //公共的分享类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图)
type: 0,
href: download,
title: appName,
summary: slogan,
imageUrl: logo
},
menus: [{
"img": "/static/sharemenu/wechatfriend.png",
"text": "微信好友",
"share": {
"provider": "weixin",
"scene": "WXSceneSession"
}
},
{
"img": "/static/sharemenu/wechatmoments.png",
"text": "微信朋友圈",
"share": {
"provider": "weixin",
"scene": "WXSenceTimeline"
}
},
{
"img": "/static/sharemenu/weibo.png",
"text": "微博",
"share": {
"provider": "sinaweibo"
}
},
{
"img": "/static/sharemenu/qq.png",
"text": "QQ",
"share": {
"provider": "qq"
}
},
{
"img": "/static/sharemenu/copyurl.png",
"text": "复制",
"share": "copyurl"
},
{
"img": "/static/sharemenu/more.png",
"text": "更多",
"share": "shareSystem"
}
],
cancelText: "取消分享",
}, e => { //callback
console.log(e);
})
},
methods:{
navigateTo({url,title}){
uni.navigateTo({
......@@ -51,11 +110,8 @@ import baseappConfig from '@/baseapp.config.js';
width: 750upx;
flex-direction: column;
}
.logo {
width: 750upx;
position: fixed;
left:0;
top:100px;
.box {
margin-top: 100px;
flex-direction: column;
justify-content: center;
align-items: center;
......@@ -72,6 +128,9 @@ import baseappConfig from '@/baseapp.config.js';
font-size:42rpx;
font-weight: 500;
}
.qrcode{
margin-top: 50px;
}
.copyright {
width: 750upx;
font-size:32rpx;
......
<template>
<view class="content">
<!-- 功能列表 -->
<uni-list>
<uni-list-item v-for="(item,index) in agreeList" :key="index" :title="item.title"
:clickable="true" @click="itemClick(item)" :showSwitch="item.showSwitch" :switchChecked="item.isChecked"
:link="!item.showSwitch"
></uni-list-item>
</uni-list>
<!-- 退出按钮 -->
<view class="bottom-back" @click="clickLogout">
<text class="bottom-back-text" v-if="userInfo">退出登录</text>
<text class="bottom-back-text" v-else>登录</text>
</view>
</view>
</template>
<script>
import {isOn,setting} from './dc-push/push.js';
import {mapMutations,mapGetters} from 'vuex';
export default {
data() {
return {
agreeList: [{
title: '个人资料',
event:'toEdit'
},
{
title: '修改密码',
event:'changePwd'
},
// {
// title: '注销用户',
// event: ''
// },
//#ifdef APP-PLUS
{
title: '推送功能',
name: 'push',
event: 'openSetting',
isChecked: false,
showSwitch: true
},
// {
// title: '清理缓存',
// event: ''
// },
//#endif
]
}
},
computed:{
...mapGetters({
'userInfo':'user/info'
})
},
onLoad() {
this.initSoterAuthentication();
},
onShow() {
this.checkPush();
},
methods: {
...mapMutations({
logout: 'user/logout'
}),
toEdit(){
uni.navigateTo({
url: '/uni_modules/uni-id-users/pages/uni-id-users/edit'
});
},
changePwd(){
uni.navigateTo({
url:'/uni_modules/uni-login-page/pages/pwd-retrieve/pwd-retrieve?phoneNumber='+ (this.userInfo&&this.userInfo.phone?this.userInfo.phone:'') +'&phoneArea=+86',
fail:err=> {
console.log(err);
}
});
},
checkPush(){
// 手机端获取推送是否开启
//#ifdef APP-PLUS
let pushIsOn = isOn();
this.agreeList.forEach(item => {
item.name == 'push' ? (item.isChecked = pushIsOn) : '';
})
//#endif
},
/**
* 添加生物认证选项
*/
initSoterAuthentication() {
// #ifdef APP-PLUS || MP-WEIXIN
let checkAuthModeList = [{
title: '指纹解锁',
name: 'fingerPrint',
event: 'startSoterAuthentication'
}, {
title: '人脸解锁',
name: 'facial',
event: 'startSoterAuthentication'
}];
uni.checkIsSupportSoterAuthentication({
success: (res) => {
res.supportMode.forEach(item => {
this.agreeList.push(checkAuthModeList.find(mode => mode.name == item));
})
},
fail: (err) => {
reject(err);
}
})
// #endif
},
/**
* 开始生物认证
*/
startSoterAuthentication(item) {
// 检查是否开启认证
this.checkIsSoterEnrolledInDevice(item)
.then(()=>{
// 开始认证
uni.startSoterAuthentication({
requestAuthModes: [item.name],
challenge: '123456', // 微信端挑战因子
authContent: `请用${item.title}`,
success:(res)=> {
if(res.errCode == 0){
/**
* 验证成功后开启自己的业务逻辑
*
* app端以此为依据 验证成功
*
* 微信小程序需要再次通过后台验证resultJSON与resultJSONSignature获取最终结果
*/
return uni.showToast({
title: `${item.title}成功`,
icon: 'none'
});
}
uni.showToast({
title: '认证失败请重试',
icon: 'none'
});
},
fail:(err)=> {
console.log(`认证失败:${err.errCode}`);
uni.showToast({
title: `认证失败`,
icon: 'none'
});
}
})
})
},
checkIsSoterEnrolledInDevice(mode){
return new Promise((resolve, reject)=>{
uni.checkIsSoterEnrolledInDevice({
checkAuthMode:mode.name,
success: (res) => {
if(res.isEnrolled){
return resolve(res);
}
uni.showToast({
title: `设备未开启${mode.title}`,
icon: 'none'
});
reject(res);
},
fail: (err) => {
uni.showToast({
title: `${mode.title}失败`,
icon: 'none'
});
reject(err);
}
})
})
},
clickLogout() {
if(this.userInfo){
uni.showModal({
title: '提示',
content: '是否退出登录',
cancelText: '取消',
confirmText: '确定',
success: res => {
if(res.confirm){
this.logout();
uni.navigateBack();
}
},
fail: () => {},
complete: () => {}
});
}else{
uni.navigateTo({
url: '/uni_modules/uni-login-page/pages/index/index'
});
}
},
itemClick(item) {
console.log(item);
if (item.event) {
this[item.event](item);
}
},
/**
* 打开设置页面
*/
openSetting() {
setting();
}
}
}
</script>
<style>
/* #ifndef APP-NVUE */
page {
flex: 1;
width: 100%;
height: 100%;
}
uni-button:after{
border: none;
border-radius: 0;
}
/* #endif */
.content {
/* #ifndef APP-NVUE */
display: flex;
width: 750rpx;
height: 100vh;
/* #endif */
flex-direction: column;
flex: 1;
background-color: #E5E5E5;
}
.bottom-back {
width: 750rpx;
height: 120rpx;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
/* #ifndef APP-NVUE */
border: none;
/* #endif */
border-width: 0;
border-radius: 0;
background-color: #FFFFFF;
}
.bottom-back-text {
font-size: 40rpx;
color: #999999;
}
</style>
......@@ -2,7 +2,7 @@
<view class="content">
<!-- 功能列表 -->
<uni-list :border="false" class="mb10" v-for="(sublist,index) in agreeList">
<uni-list-item :border="false" class="mb1" v-for="(item,index) in sublist" :key="index" :title="item.title"
<uni-list-item :border="false" class="mb1" v-for="(item,i) in sublist" :key="i" :title="item.title"
:clickable="true" @click="itemClick(item)" :showSwitch="item.showSwitch" :switchChecked="item.isChecked"
:link="!item.showSwitch"></uni-list-item>
</uni-list>
......@@ -216,7 +216,18 @@
uni.showLoading({
title: '清除中',
mask: true
});
});
/*
任何临时存储或删除不直接影响程序运行逻辑(清除缓存必定造成业务逻辑的变化,如:打开页面的图片不从缓存中读取而从网络请求)的内容都可以视为缓存。主要有storage、和file写入。
缓存分为三部分
原生层(如:webview、x5播放器的、第三方sdk的、地图组件等)
前端框架(重启就会自动清除)
开发者自己的逻辑(如:
本示例的 检测更新功能下载了apk安装包,
其他逻辑需要根据开发者自己的业务设计
比如:有聊天功能的应用,聊天记录是否视为缓存,还是单独提供清除聊天记录的功能由开发者自己设计
*/
uni.getSavedFileList({
success:res=>{
if (res.fileList.length > 0) {
......@@ -224,11 +235,19 @@
filePath: res.fileList[0].filePath,
complete:res=>{
console.log(res);
uni.hideLoading()
uni.hideLoading()
uni.showToast({
title: '清除成功',
icon: 'none'
});
}
});
}else{
uni.hideLoading()
uni.showToast({
title: '清除成功',
icon: 'none'
});
}
},
complete:e=>{
......
var nvMask,nvImageMenu;
export default {
show(list,callback){
show({list,cancelText},callback){
if(!list){
list = [{
"img":"/static/sharemenu/wechatfriend.png",
"text":"图标文字"
}]
}
//以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心
var screenWidth = plus.screen.resolutionWidth
//以360px宽度屏幕为例,上下左右边距及2排按钮边距留25像素,图标宽度55像素,同行图标间的间距在360宽的屏幕是30px,但需要动态计算,以此原则计算4列图标分别的left位置
//图标下的按钮文字距离图标5像素,文字大小12像素
//底部取消按钮高度固定为44px
//TODO 未处理横屏和pad,这些情况6个图标应该一排即可
var margin = 25,
iconWidth = 55,
var margin = 20,
iconWidth = 60,
icontextSpace = 5,
textHeight = 12
var left1 = margin / 360 * screenWidth
......@@ -46,7 +44,7 @@ export default {
nvImageMenu = new plus.nativeObj.View("nvImageMenu", { //创建底部图标菜单
bottom: '0px',
left: '0px',
height: (iconWidth + textHeight + 2 * margin)*(parseInt(list.length/4)+1) +44+'px',//'264px',
height: (iconWidth + textHeight + 2 * margin)*Math.ceil(list.length/4) +44+'px',//'264px',
width: '100%',
backgroundColor: 'rgb(255,255,255)'
});
......@@ -90,8 +88,7 @@ export default {
},
{
tag: 'font',
id: 'sharecancel',//底部取消按钮的文字
text: '取消分享',
text: cancelText,//底部取消按钮的文字
textStyles: {
size: '14px'
},
......@@ -141,9 +138,10 @@ export default {
iClickIndex = iCol + 4
}
// console.log("点击按钮的序号: " + iClickIndex);
if (iClickIndex >= 0 && iClickIndex <= 5) { //处理具体的点击逻辑,此处也可以自行定义逻辑。如果增减了按钮,此处也需要跟着修改
callback(iClickIndex)
}
// if (iClickIndex >= 0 && iClickIndex <= 5) { //处理具体的点击逻辑,此处也可以自行定义逻辑。如果增减了按钮,此处也需要跟着修改
// }
callback(iClickIndex)
this.hide()
}
})
/* nvImageMenu.addEventListener("touchstart", function(e) {
......
......@@ -47,7 +47,7 @@ page {
}
.phone-input-box {
height: 85rpx;
height: 45px;
background-color: #f9f9f9;
border-radius: 6rpx;
flex-direction: row;
......
......@@ -15,44 +15,44 @@
config: {
"weixin": {
"text": "微信登陆",
"logo": "../../static/login/img/weixin.png",
"logo": "../../static/login/weixin.png",
"isChecked":true
},
"apple": {
"text": "苹果登陆",
"logo": "../../static/login/img/apple.png",
"logo": "../../static/login/apple.png",
"isChecked":true
},
"univerify": {
"text": "一键登陆",
"logo": "../../static/login/img/univerify.png",
"logo": "../../static/login/univerify.png",
"isChecked":true
},
"qq": {
"text": "QQ登陆",
"logo": "../../static/login/img/qq.png",
"logo": "../../static/login/qq.png",
"isChecked":false //暂未提供该登陆方式的接口示例
},
"xiaomi": {
"text": "小米登陆",
"logo": "../../static/login/img/qq.png",
"logo": "../../static/login/qq.png",
"isChecked":false //暂未提供该登陆方式的接口示例
},
"sinaweibo": {
"text": "微博登录",
"logo": "../../static/login/img/sinaweibo.png",
"logo": "../../static/login/weibo.png",
"isChecked":false //暂未提供该登陆方式的接口示例
}
},
servicesList:[
{
"text": "账号登陆",
"logo": "../../static/login/img/username.png",
"logo": "../../static/login/db.png",
"path":"/uni_modules/uni-login-page/pages/pwd-login/pwd-login"
},
{
"text": "短信登陆",
"logo": "../../static/login/img/smsCode.png",
"logo": "../../static/login/smsCode.png",
"path":"/uni_modules/uni-login-page/pages/index/index"
}
],
......@@ -208,7 +208,7 @@
console.log('delta:'+delta);
uni.navigateBack({delta})
}
})
},{showLoading:true})
},
async getUserInfo(e){
return new Promise((resolve, reject)=>{
......@@ -246,7 +246,7 @@
.logo {
width: 60rpx;
height: 60rpx;
height: 60rpx;
}
.login-title {
......
......@@ -14,7 +14,7 @@
<template slot="left">
<!-- 当前仅支持中国大陆手机号 -->
<!-- <picker mode="selector" :range="phoneArea" @change="selectPhoneArea"> -->
<text class="phone-area" @click="selectPhoneArea">{{currenPhoneArea}}</text>
<!-- <text class="phone-area" @click="selectPhoneArea">{{currenPhoneArea}}</text> -->
<!-- </picker> -->
</template>
</uni-easyinput>
......@@ -150,5 +150,5 @@ import baseappConfig from '@/baseapp.config.js';
/* #ifndef APP-NVUE */
border-right: 1rpx solid #d7d9d8;
/* #endif */
}
}
</style>
{
"name": "user-center",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"uni-captcha": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha",
"uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"uni-id": "file:../../../../uni-id/uniCloud/cloudfunctions/common/uni-id"
}
},
"../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha": {
"version": "0.1.0",
"license": "Apache-2.0"
},
"../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center": {
"version": "0.0.1",
"license": "Apache-2.0"
},
"../../../../uni-id/uniCloud/cloudfunctions/common/uni-id": {
"version": "3.0.12",
"license": "Apache-2.0",
"dependencies": {
"uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
}
},
"../../../../uni-id/uniCloud/cloudfunctions/common/uni-id/node_modules/uni-config-center": {
"resolved": "../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"link": true
},
"node_modules/uni-captcha": {
"resolved": "../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha",
"link": true
},
"node_modules/uni-config-center": {
"resolved": "../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"link": true
},
"node_modules/uni-id": {
"resolved": "../../../../uni-id/uniCloud/cloudfunctions/common/uni-id",
"link": true
}
},
"dependencies": {
"uni-captcha": {
"version": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha"
},
"uni-config-center": {
"version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
},
"uni-id": {
"version": "file:../../../../uni-id/uniCloud/cloudfunctions/common/uni-id",
"requires": {
"uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
},
"dependencies": {
"uni-config-center": {
"version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
}
}
}
}
}
{
"name": "user",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"uni-captcha": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha",
"uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"uni-id": "file:../../../../uni-id/uniCloud/cloudfunctions/common/uni-id"
}
},
"../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha": {
"version": "0.1.0",
"license": "Apache-2.0"
},
"../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center": {
"version": "0.0.1",
"license": "Apache-2.0"
},
"../../../../uni-id/uniCloud/cloudfunctions/common/uni-id": {
"version": "3.0.12",
"license": "Apache-2.0",
"dependencies": {
"uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
}
},
"../../../../uni-id/uniCloud/cloudfunctions/common/uni-id/node_modules/uni-config-center": {
"resolved": "../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"link": true
},
"node_modules/uni-captcha": {
"resolved": "../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha",
"link": true
},
"node_modules/uni-config-center": {
"resolved": "../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"link": true
},
"node_modules/uni-id": {
"resolved": "../../../../uni-id/uniCloud/cloudfunctions/common/uni-id",
"link": true
}
},
"dependencies": {
"uni-captcha": {
"version": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha"
},
"uni-config-center": {
"version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
},
"uni-id": {
"version": "file:../../../../uni-id/uniCloud/cloudfunctions/common/uni-id",
"requires": {
"uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
},
"dependencies": {
"uni-config-center": {
"version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
}
}
}
}
}
{
"id": "quick-login",
"displayName": "quick-login",
"version": "1.0.0",
"description": "quick-login",
"keywords": [
"quick-login"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"category": [
"uniCloud",
"云端一体页面模板"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "",
"data": "",
"permissions": ""
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "u",
"aliyun": "u"
},
"client": {
"App": {
"app-vue": "u",
"app-nvue": "u"
},
"H5-mobile": {
"Safari": "u",
"Android Browser": "u",
"微信浏览器(Android)": "u",
"QQ浏览器(Android)": "u"
},
"H5-pc": {
"Chrome": "u",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
},
"小程序": {
"微信": "u",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}
\ No newline at end of file
# uni-quick-login
\ No newline at end of file
{
"name": "user-center",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"uni-captcha": {
"version": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha"
},
"uni-config-center": {
"version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
},
"uni-id": {
"version": "file:../../../../uni-id/uniCloud/cloudfunctions/common/uni-id",
"requires": {
"uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
},
"dependencies": {
"uni-config-center": {
"version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
}
}
}
}
}
{
"name": "user",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"uni-captcha": {
"version": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha"
},
"uni-config-center": {
"version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
},
"uni-id": {
"version": "file:../../../../uni-id/uniCloud/cloudfunctions/common/uni-id",
"requires": {
"uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
},
"dependencies": {
"uni-config-center": {
"version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
}
}
}
}
}
import uniImageMenu from 'uni_modules/uni-image-menu/js_sdk/uni-image-menu.js';
let old_menus = [{
"img": "/static/sharemenu/wechatfriend.png",
"text": "微信好友",
"share":{
"provider":"weixin",
"scene":"WXSceneSession"
}
},
{
"img": "/static/sharemenu/wechatmoments.png",
"text": "微信朋友圈",
"share":{
"provider":"weixin",
"scene":"WXSceneSession"
}
},
{
"img": "/static/sharemenu/weibo.png",
"text": "微博",
"share":{
"provider":"sinaweibo"
}
},
{
"img": "/static/sharemenu/qq.png",
"text": "QQ",
"share":{
"provider":"qq"
}
},
{
"img": "/static/sharemenu/copyurl.png",
"text": "复制",
"share":false
},
{
"img": "/static/sharemenu/more.png",
"text": "更多",
"share":"more"
}
]
let menus = []
plus.oauth.getServices(services=>{ //只显示有服务的项目
let servicesList = services.map(e=>e.id)
console.log(servicesList);
old_menus.forEach(item=>{
console.log(item.share.provider);
if(servicesList.includes(item.share.provider)){
menus.push(item)
}
})
},err=>{
uni.showModal({
title: '获取服务供应商失败:' +JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
let shareContent = {
type: 0,
href: "https://uniapp.dcloud.io/api/plugins/share?id=share",
title: "主标题",
summary: "分享内容的摘要",
imageUrl: "https://uniapp.dcloud.io/api/plugins/share?id=share",
}
export default (callback) => {
uniImageMenu.show(menus,e=>{
console.log(e);
if(e<4){
uni.share({
...menus[e].share,
...shareContent,
success: function(res) {
console.log("success:" + JSON.stringify(res));
},
fail: function(err) {
console.log("fail:" + JSON.stringify(err));
},
complete() {
uniImageMenu.hide()
}
})
}
})
}
import uniImageMenu from 'uni_modules/uni-image-menu/js_sdk/uni-image-menu.js';
export default async (param,callback) => {
var menus = []
plus.oauth.getServices(services => { //只显示有服务的项目
let servicesList = services.map(e => e.id)
console.log(servicesList);
param.menus.forEach(item => {
if (servicesList.includes(item.share.provider) || typeof(item.share) == 'string') {
menus.push(item)
}
})
console.log(menus);
uniImageMenu.show({list:menus,cancelText:param.cancelText}, e => {
console.log(e);
if (typeof(menus[e]['share']) == 'string') {
eval(menus[e]['share']+'()')
} else {
console.log(9527,{
...param.content,
...menus[e].share,
});
uni.share({
...param.content,
...menus[e].share,
success: function(res) {
console.log("success:" + JSON.stringify(res));
},
fail: function(err) {
console.log("fail:" + JSON.stringify(err));
},
complete(e) {
uniImageMenu.hide()
callback(e)
}
})
}
})
}, err => {
uni.showModal({
title: '获取服务供应商失败:' + JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
function copyurl() {
uni.setClipboardData({
data: param.content.href,
success: function () {
console.log('success');
uni.hideToast()//关闭自带的toast
uni.showToast({
title: '复制成功',
icon: 'none'
});
},
fail: (err) => {
uni.showModal({
content: JSON.stringify(err),
showCancel: false
});
}
});
}
// 使用系统分享发送分享消息
function shareSystem() {
plus.share.sendWithSystem({
type: 'text',
content: param.content.title + param.content.summary || '',
href: param.content.href,
}, function(e) {
console.log('分享成功');
callback(e)
}, function(e) {
console.log('分享失败:' + JSON.stringify(e));
callback(e)
});
}
}
# uni-share
\ No newline at end of file
# uni-share
例子
import uniShare from 'uni_modules/uni-share/js_sdk/uni-share.js';
uniShare({
menus:[
{
"img": "/static/sharemenu/wechatfriend.png",
"text": "微信好友",
"share": {
"provider": "weixin",
"scene": "WXSceneSession"
}
},
{
"img": "/static/sharemenu/wechatmoments.png",
"text": "微信朋友圈",
"share": {
"provider": "weixin",
"scene": "WXSceneSession"
}
},
{
"img": "/static/sharemenu/weibo.png",
"text": "微博",
"share": {
"provider": "sinaweibo"
}
},
{
"img": "/static/sharemenu/qq.png",
"text": "QQ",
"share": {
"provider": "qq"
}
},
{
"img": "/static/sharemenu/copyurl.png",
"text": "复制",
"share": "copyurl"
},
{
"img": "/static/sharemenu/more.png",
"text": "更多",
"share": "shareSystem"
}
],
cancelText:"取消分享",
content:{
type: 0,
href: "https://uniapp.dcloud.io/api/plugins/share?id=share",
title: "主标题",
summary: "分享内容的摘要",
imageUrl: "https://uniapp.dcloud.io/api/plugins/share?id=share",
}
},e=>{ //callback
console.log(e);
})
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册