初始项目
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
.lotus-address-picker {
|
||||
font-size: 26rpx;
|
||||
padding-top: 30rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
line-height: normal;
|
||||
padding-right: 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.lotus-address-picker-box {
|
||||
/*display: -webkit-box;
|
||||
display: -webkit-flex;*/
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
justify-content: flex-start;
|
||||
padding-top: 10rpx;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
.lotus-address-picker-box-item {
|
||||
height: 600upx;
|
||||
overflow-y: auto;
|
||||
width: 33.333%;
|
||||
padding-left: 20rpx;
|
||||
padding-right: 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.lotus-address-picker2 {
|
||||
color: #e93b3d;
|
||||
position: relative;
|
||||
}
|
||||
.lotus-address-picker2:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 65%;
|
||||
transform: translateY(-35%) rotate(-45deg);
|
||||
width: 20rpx;
|
||||
height: 10rpx;
|
||||
border-left-width: 4rpx;
|
||||
border-bottom-width: 4rpx;
|
||||
border-left-style: solid;
|
||||
border-bottom-style: solid;
|
||||
border-left-color: #e93b3d;
|
||||
border-bottom-color: #e93b3d;
|
||||
}
|
||||
.lotus-address-mask {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 999;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.lotus-address-box {
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.lotus-address-action {
|
||||
font-size: 30rpx;
|
||||
/*display: -webkit-box;
|
||||
display: -webkit-flex;*/
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
justify-content: space-between;
|
||||
padding: 25rpx 30rpx;
|
||||
position: relative;
|
||||
}
|
||||
.lotus-address-action:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-top: 1px solid #eee;
|
||||
color: #eee;
|
||||
transform-origin: 0 0;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.lotus-address-action:before {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-bottom: 1px solid #eee;
|
||||
color: #eee;
|
||||
transform-origin: 0 100%;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.lotus-address-action-cancel {
|
||||
color: #969696;
|
||||
}
|
||||
.lotus-address-action-affirm {
|
||||
color: #e93b3d;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<!--地址picker-->
|
||||
<view :status="checkStatus" v-if="lotusAddressData.visible" class="lotus-address-mask">
|
||||
<view class="lotus-address-box">
|
||||
<view class="lotus-address-action">
|
||||
<text @tap="cancelPicker" class="lotus-address-action-cancel">取消</text>
|
||||
<text @tap="chosedVal" class="lotus-address-action-affirm">确认</text>
|
||||
</view>
|
||||
<view class="lotus-address-picker-box">
|
||||
<!--省-->
|
||||
<scroll-view scroll-y :scroll-into-view="'pid'+pChoseIndex" class="lotus-address-picker-box-item">
|
||||
<view @tap="clickPicker(0,pIndex,pItem);" :id="'pid'+pIndex" :class="pIndex === pChoseIndex?'lotus-address-picker lotus-address-picker2':'lotus-address-picker'" v-for="(pItem,pIndex) in province" :key="pIndex">{{pItem}}</view>
|
||||
</scroll-view>
|
||||
<!--市-->
|
||||
<scroll-view scroll-y :scroll-into-view="'cid'+cChoseIndex" class="lotus-address-picker-box-item">
|
||||
<view @tap="clickPicker(1,cIndex,cItem);" :id="'cid'+cIndex" :class="cIndex === cChoseIndex?'lotus-address-picker lotus-address-picker2':'lotus-address-picker'" v-for="(cItem,cIndex) in city" :key="cIndex">{{cItem}}</view>
|
||||
</scroll-view>
|
||||
<!--区-->
|
||||
<scroll-view scroll-y :scroll-into-view="'tid'+tChoseIndex" class="lotus-address-picker-box-item">
|
||||
<view @tap="clickPicker(2,tIndex,tItem);" :id="'tid'+tIndex" :class="tIndex === tChoseIndex?'lotus-address-picker lotus-address-picker2':'lotus-address-picker'" v-for="(tItem,tIndex) in town" :key="tIndex">{{tItem}}</view>
|
||||
</scroll-view>
|
||||
<!--区END-->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!--地址picker END-->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {lotusAddressJson} from "./Winglau14-lotusAddress.js";
|
||||
export default {
|
||||
props:['lotusAddressData'],
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
province:[],
|
||||
city:[],
|
||||
town:[],
|
||||
provinceName:'',
|
||||
cityName:'',
|
||||
townName:'',
|
||||
type:0,//0新增1编辑
|
||||
pChoseIndex:-1,
|
||||
cChoseIndex:-1,
|
||||
tChoseIndex:-1,
|
||||
};
|
||||
},
|
||||
methods:{
|
||||
//取消
|
||||
cancelPicker(){
|
||||
const provinceCode = this.getTarId(this.provinceName);
|
||||
const cityCode = this.getTarId(this.cityName);
|
||||
const townCode = this.getTarId(this.townName);
|
||||
this.$emit("choseVal",{
|
||||
provice:this.provinceName,
|
||||
provinceCode,
|
||||
city:this.cityName,
|
||||
cityCode,
|
||||
town:this.townName,
|
||||
townCode,
|
||||
isChose:0,
|
||||
visible:false
|
||||
});
|
||||
},
|
||||
//获取最后选择的省市区的值
|
||||
chosedVal() {
|
||||
this.type = 1;
|
||||
const provinceCode = this.getTarId(this.provinceName);
|
||||
const cityCode = this.getTarId(this.cityName);
|
||||
const townCode = this.getTarId(this.townName);
|
||||
this.$emit("choseVal",{
|
||||
provice:this.provinceName,
|
||||
provinceCode,
|
||||
city:this.cityName,
|
||||
cityCode,
|
||||
town:this.townName,
|
||||
townCode,
|
||||
isChose:1,
|
||||
visible:false
|
||||
});
|
||||
},
|
||||
//获取省市区value
|
||||
getTarId(name,type){
|
||||
let id = 0;
|
||||
const _this = this;
|
||||
lotusAddressJson.map((item,index)=>{
|
||||
if(item.name === name){
|
||||
id = item.value;
|
||||
}
|
||||
});
|
||||
return id;
|
||||
},
|
||||
//获取市数据
|
||||
getCityArr(parentId){
|
||||
let city = [];
|
||||
|
||||
lotusAddressJson.map((item,index)=>{
|
||||
if(item.parent === parentId){
|
||||
city.push(item.name);
|
||||
}
|
||||
});
|
||||
return city;
|
||||
},
|
||||
//获取区数据
|
||||
getTownArr(parentId){
|
||||
let town = [];
|
||||
lotusAddressJson.map((item,index)=>{
|
||||
if(index>34&&item.parent === parentId){
|
||||
town.push(item.name);
|
||||
}
|
||||
});
|
||||
return town;
|
||||
},
|
||||
//初始化数据
|
||||
initFn(){
|
||||
console.log(1);
|
||||
lotusAddressJson.map((item,index)=>{
|
||||
if(index<=34){
|
||||
this.province.push(item.name);
|
||||
}
|
||||
});
|
||||
//已选择省市区,高亮显示对应选择省市区
|
||||
const p = this._props.lotusAddressData.provinceName;
|
||||
const c = this._props.lotusAddressData.cityName;
|
||||
const t = this._props.lotusAddressData.townName;
|
||||
if(p){
|
||||
this.pChoseIndex = this.getTarIndex(this.province,p);
|
||||
}
|
||||
if(p&&c){
|
||||
const pid = this.getTarId(p);
|
||||
this.city = this.getCityArr(pid);
|
||||
this.cChoseIndex = this.getTarIndex(this.city,c);
|
||||
}
|
||||
if(p&&c&&t){
|
||||
const cid= this.getTarId(c);
|
||||
this.town = this.getTownArr(cid);
|
||||
this.tChoseIndex = this.getTarIndex(this.town,t);
|
||||
}
|
||||
},
|
||||
//获取已选省市区
|
||||
getChosedData(){
|
||||
const pid = this.getTarId(this.provinceName,'provice');
|
||||
this.city = this.getCityArr(pid);
|
||||
const cid= this.getTarId(this.cityName,'city');
|
||||
this.town = this.getTownArr(cid);
|
||||
//已选省市区获取对应index
|
||||
if(this.provinceName){
|
||||
this.pChoseIndex = this.getTarIndex(this.province,this.provinceName);
|
||||
}
|
||||
if(this.cityName){
|
||||
this.cChoseIndex = this.getTarIndex(this.city,this.cityName);
|
||||
}
|
||||
if(this.townName){
|
||||
this.tChoseIndex = this.getTarIndex(this.town,this.townName);
|
||||
}
|
||||
},
|
||||
//选择省市区交互
|
||||
clickPicker(type,index,name){
|
||||
//省
|
||||
if(type === 0){
|
||||
this.pChoseIndex = index;
|
||||
this.provinceName = name;
|
||||
this.cChoseIndex = -1;
|
||||
this.tChoseIndex = -1;
|
||||
this.cityName = '';
|
||||
this.townName = '';
|
||||
}
|
||||
//市
|
||||
if(type ===1){
|
||||
this.cChoseIndex = index;
|
||||
this.cityName = name;
|
||||
this.tChoseIndex = -1;
|
||||
this.townName = '';
|
||||
}
|
||||
//区
|
||||
if(type === 2){
|
||||
this.tChoseIndex = index;
|
||||
this.townName = name;
|
||||
}
|
||||
//获取省市区数据
|
||||
this.getChosedData();
|
||||
},
|
||||
//获取已选省市区index
|
||||
getTarIndex(arr,tarName){
|
||||
let cIndex = 0;
|
||||
arr.map((item,index)=>{
|
||||
if(item === tarName){
|
||||
cIndex = index;
|
||||
}
|
||||
});
|
||||
return cIndex;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.provinceName = this._props.lotusAddressData.provinceName;
|
||||
this.cityName = this._props.lotusAddressData.cityName;
|
||||
this.townName = this._props.lotusAddressData.townName;
|
||||
},
|
||||
computed:{
|
||||
checkStatus(){
|
||||
let t = null;
|
||||
const _this = this;
|
||||
if(!_this.visible){
|
||||
_this.initFn();
|
||||
_this.visible = _this._props.lotusAddressData.visible;
|
||||
t = _this.visible;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import "./Winglau14-lotusAddress.css";
|
||||
</style>
|
||||
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<view class="box">
|
||||
<view class="boxContent">
|
||||
<view class="boxContent2">
|
||||
<view class="before" :style="{top: (100-percent)+'%'}"></view>
|
||||
<view class="jd" :style="{background: bg}"></view>
|
||||
<view class="after" :style="{top: (100-percent)+'%'}"></view>
|
||||
</view>
|
||||
<view class="percent">{{percent}}%</view>
|
||||
</view>
|
||||
<view class="atitle">{{titleOne}}</view>
|
||||
<view class="atitle">{{titleTwo}}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "circle-percent",
|
||||
props: {
|
||||
titleOne:{
|
||||
type:String,
|
||||
default: '发卡'
|
||||
},
|
||||
titleTwo:{
|
||||
type:String,
|
||||
default: '21'
|
||||
},
|
||||
bg: {
|
||||
type:String,
|
||||
default: 'red'
|
||||
},
|
||||
percent: {
|
||||
type:String,
|
||||
default: "0"
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.box{
|
||||
box-sizing: border-box;
|
||||
width: 33%;
|
||||
text-align:center;
|
||||
margin: 20upx 0;
|
||||
.boxContent{
|
||||
position: relative;
|
||||
width: 160upx;
|
||||
height: 160upx;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
border: 4upx solid #d9d9d9;
|
||||
overflow: hidden;
|
||||
.boxContent2{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
border: 4upx solid #fff;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
.before,
|
||||
.after{
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
background-color: rgba(255, 255, 255, .4);
|
||||
border-radius: 45%;
|
||||
transform: translate(-50%, -100%) rotate(0);
|
||||
animation: rotate 6s linear infinite;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.after {
|
||||
border-radius: 44%;
|
||||
background-color: rgba(255, 255, 255, .9);
|
||||
transform: translate(-50%, -100%) rotate(0);
|
||||
animation: rotate 10s linear -5s infinite;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
50% {
|
||||
transform: translate(-50%, -103%) rotate(180deg);
|
||||
} 100% {
|
||||
transform: translate(-50%, -100%) rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.jd{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
bottom:0;
|
||||
}
|
||||
}
|
||||
|
||||
.percent{
|
||||
font-size: 36upx;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 52upx;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
z-index: 90;
|
||||
}
|
||||
}
|
||||
.atitle{
|
||||
margin-top: 0upx;
|
||||
font-size: 20upx;
|
||||
color: $uni-text-color-grey;
|
||||
font-size: $uni-font-size-base;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<view class="coupon-item">
|
||||
<view class="coupon-money">
|
||||
<view class="nick" ></view>
|
||||
<view class="layof" :style="{color:theme}">¥{{item.amount}}</view>
|
||||
<view class="end_time">{{item.endTime | formatCreateTime}}前使用</view>
|
||||
<view >
|
||||
<view class="demand">满{{ item.minPoint }} 减 {{ item.amount }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="get-btn" v-if="!types" :style="{color:color, borderColor:color, background:solid}" @click="acceptCoupon(item)" >立即领取</view>
|
||||
<navigator class="get-btn" v-if="types" :style="{color:color, borderColor:color, background:solid}" :url='item.url' @click="acceptCoupon(item)">立即使用</navigator>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Api from '@/common/api';
|
||||
import mallplusCopyright from '@/components/mall-copyright/mallplusCopyright.vue';
|
||||
import { formatDate } from '@/common/date';
|
||||
|
||||
export default {
|
||||
components:{
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
props:{
|
||||
item:{
|
||||
type: Object
|
||||
},
|
||||
types:{
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
theme:{
|
||||
type: String,
|
||||
default: '#ff9000'
|
||||
},
|
||||
solid:{
|
||||
type: String,
|
||||
default: '#ffffff'
|
||||
},
|
||||
color:{
|
||||
type: String,
|
||||
default: '#ff9000'
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
formatCreateTime(time) {
|
||||
let date = new Date(time);
|
||||
return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async acceptCoupon(item){
|
||||
uni.showLoading({
|
||||
title: '请稍后'
|
||||
});
|
||||
|
||||
let params = { couponId: item.id };
|
||||
let data = await Api.apiCall('post', Api.index.acceptCoupon, params);
|
||||
console.log(data);
|
||||
if (data) {
|
||||
this.$api.msg(data);
|
||||
}
|
||||
uni.hideLoading();
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
.coupon-item {
|
||||
width:100%; height:auto; display:table; border-radius:10upx; padding:0 20upx; margin-top:22upx; border:1px solid #eeeeee; position:relative;
|
||||
.coupon-money {
|
||||
width:465upx; height:auto; display:table; float:left; padding:26upx 0; border-style:none dotted none none; border-color:#eeeeee;
|
||||
|
||||
.nick { width:100%; height:50upx; line-height:30upx; font-size:$font-sm; color:$font-color-999; }
|
||||
.tit { width:100%; height:50upx; line-height:50upx; font-size:$font-sm; color:$font-color-999; }
|
||||
.demand { width:100%; height:30upx; line-height:30upx; font-size:$font-sm; color:$font-color-999; }
|
||||
|
||||
.layof { width:100%; height:48upx; line-height:30upx; font-size:44upx; color:#ff9000; font-weight:bold; }
|
||||
.end_time { width:100%; height:30upx; line-height:30upx; font-size:$font-sm; color:$font-color-999; }
|
||||
}
|
||||
.get-btn { width:146upx; height:52upx; line-height:50upx; position:absolute; top:50%; right:26upx; margin-top:-26upx; text-align:center; border-radius:60upx; color:#ff9000; border:1px solid #ff9000; font-size:$font-sm; float:right; }
|
||||
}
|
||||
.coupon-item:after { width:40upx; height:20upx; position:absolute; left:460upx; top:-1px; border-radius:0 0 40upx 40upx; content:""; display:block; background:$bgcolor_white; border:1px solid #eeeeee; border-top:0px; }
|
||||
.coupon-item:before { width:40upx; height:20upx; position:absolute; left:460upx; bottom:-1px; border-radius:40upx 40upx 0 0; content:""; display:block; background:$bgcolor_white; border:1px solid #eeeeee; border-bottom:0px; }
|
||||
</style>
|
||||
85
mallplusui-uniapp-app/components/drag-ball/ball.js
Normal file
85
mallplusui-uniapp-app/components/drag-ball/ball.js
Normal file
@@ -0,0 +1,85 @@
|
||||
import value from './ball.js';
|
||||
|
||||
var list = []
|
||||
|
||||
var boundary = [[],[]]
|
||||
|
||||
function getDistance( x_1, y_1, x_2, y_2){
|
||||
|
||||
let x = (x_2 - x_1)*2;
|
||||
let y = (y_2 - y_1)*2;
|
||||
|
||||
let s = Math.pow((x * x + y * y), 0.5);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
function sustained(that){
|
||||
|
||||
let data = value.list;
|
||||
let index_1 = 0;
|
||||
let index_2 = 0;
|
||||
|
||||
setInterval(function(){
|
||||
|
||||
for (let number = 0; number < data.length; number++) {
|
||||
|
||||
data[number].y = data[number].y+( data[number].floating[1] ? 0.05 : -0.05) ;
|
||||
data[number].floating[0] < 15 ? data[number].floating[0] = data[number].floating[0]+1 : data[number].floating[0] = 1 ;
|
||||
data[number].floating[0] == 1 ? data[number].floating[1] = !data[number].floating[1] : data[number].floating[1];
|
||||
value.mapping(that);
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
|
||||
index_1 = getDistance(data[i].x,data[i].y,data[number].x,data[number].y);
|
||||
index_2 = (data[i].radius*2) + (data[number].radius*2);
|
||||
|
||||
if(i != number){
|
||||
|
||||
if( index_1 < index_2){
|
||||
|
||||
data[i].x = data[i].x+(-(data[number].x-data[i].x)/100) ;
|
||||
data[i].y = data[i].y+(-(data[number].y-data[i].y)/100) ;
|
||||
|
||||
(data[i].x-data[i].radius) < 0 ? data[i].x = data[i].radius : data[i].x;
|
||||
(data[i].y-data[i].radius) < 0 ? data[i].y = data[i].radius : data[i].y;
|
||||
|
||||
(data[i].x+data[i].radius) > value.boundary[0] ? data[i].x = (value.boundary[0]-data[i].radius) : data[i].x;
|
||||
(data[i].y+data[i].radius) > value.boundary[1] ? data[i].y = (value.boundary[1]-data[i].radius) : data[i].y;
|
||||
|
||||
value.mapping(that);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
},100);
|
||||
}
|
||||
|
||||
function mapping(_this){
|
||||
let data = value.list
|
||||
let context = uni.createCanvasContext('canvas',_this);
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
|
||||
context.beginPath();
|
||||
context.arc(data[i].x, data[i].y, data[i].radius, 0, 2 * Math.PI, true);
|
||||
context.setFillStyle(data[i].color[data[i].colse ? 1 : 0]);
|
||||
context.fill();
|
||||
|
||||
context.setFillStyle('#FFFFFF');
|
||||
context.setFontSize(data[i].size);
|
||||
if(data[i].labelName.length < 6){
|
||||
context.fillText(data[i].labelName,(data[i].x - (data[i].size*(0.5*data[i].labelName.length))), (data[i].y + data[i].size*(0.5)))
|
||||
}else{
|
||||
context.fillText(data[i].labelName.substring(0, 3),(data[i].x - (data[i].size*(0.5*(data[i].labelName.substring(0, 3)).length))),
|
||||
((data[i].y + data[i].size*(0.5))-data[i].size*(0.8)))
|
||||
context.fillText(data[i].labelName.substring(3, 6),(data[i].x - (data[i].size*(0.5*(data[i].labelName.substring(3, 6)).length))),
|
||||
((data[i].y + data[i].size*(0.5))+data[i].size*(0.8)))
|
||||
}
|
||||
}
|
||||
context.draw();
|
||||
}
|
||||
|
||||
export default {mapping,list,sustained,boundary}
|
||||
21
mallplusui-uniapp-app/components/drag-ball/drag-ball.js
Normal file
21
mallplusui-uniapp-app/components/drag-ball/drag-ball.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import value from '../../componets/drag-ball/drag-ball.js';
|
||||
|
||||
var list = [{x:100,y:50,radius:25},{x:200,y:50,radius:25},{x:300,y:50,radius:25}]
|
||||
|
||||
function mapping(_this){
|
||||
|
||||
let data = value.list
|
||||
|
||||
let context = uni.createCanvasContext('canvas',_this);
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
context.beginPath();
|
||||
context.arc(data[i].x, data[i].y, data[i].radius, 0, 2 * Math.PI, true);
|
||||
context.setFillStyle('#AAAAAA');
|
||||
context.fill();
|
||||
}
|
||||
|
||||
context.draw();
|
||||
}
|
||||
|
||||
export default {mapping,list}
|
||||
135
mallplusui-uniapp-app/components/drag-ball/drag-ball.vue
Normal file
135
mallplusui-uniapp-app/components/drag-ball/drag-ball.vue
Normal file
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<canvas
|
||||
:canvas-id="id"
|
||||
id="canvas"
|
||||
@touchstart="touchstart"
|
||||
@touchend="touchend"
|
||||
></canvas>
|
||||
<!-- @touchmove.prevent="touchmove" -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dragBall from './ball.js';
|
||||
|
||||
var data = [];
|
||||
|
||||
function getDistance( x_1, y_1, x_2, y_2){
|
||||
|
||||
let x = (x_2 - x_1)*2;
|
||||
let y = (y_2 - y_1)*2;
|
||||
|
||||
let s = Math.pow((x * x + y * y), 0.5);
|
||||
|
||||
return s;
|
||||
}
|
||||
export default {
|
||||
props:{
|
||||
onInit: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
colse:{
|
||||
type:Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
index:'false',
|
||||
touchstarte_x:0,
|
||||
touchstarte_y:0,
|
||||
id:'canvas',
|
||||
number: 0
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
// colse(index) {
|
||||
// !index ? index : this.trim();
|
||||
// }
|
||||
this.trim();
|
||||
},
|
||||
watch: {
|
||||
onInit() {
|
||||
this.trim();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
trim(){
|
||||
dragBall.boundary[0] = 320; //高
|
||||
dragBall.boundary[1] = 500; // 宽
|
||||
// var query = uni.createSelectorQuery();
|
||||
// query.select('#canvas').boundingClientRect()
|
||||
// query.exec((res) => {
|
||||
// dragBall.boundary[0]=res[0].width
|
||||
// dragBall.boundary[1]=res[0].height;
|
||||
// })
|
||||
dragBall.list = this.onInit;
|
||||
dragBall.mapping(this);
|
||||
data = dragBall.list;
|
||||
dragBall.sustained(this);},
|
||||
touchstart(e){
|
||||
this.touchstarte_x = e.mp.touches[0].x;
|
||||
this.touchstarte_y = e.mp.touches[0].y;
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if( getDistance(data[i].x,data[i].y,this.touchstarte_x,this.touchstarte_y) < (data[i].radius*2)){
|
||||
this.index = i;
|
||||
|
||||
if(this.number < 8){
|
||||
data[i].colse =!data[i].colse;
|
||||
data[i].colse ? this.number +=1 : this.number -=1;
|
||||
} else {
|
||||
if(data[i].colse){
|
||||
data[i].colse =!data[i].colse;
|
||||
this.number -=1;
|
||||
}
|
||||
}
|
||||
this.$emit('click_',i)
|
||||
dragBall.mapping(this);
|
||||
// this.touchstarte_x = this.touchstarte_x-data[i].x;
|
||||
// this.touchstarte_y = this.touchstarte_y-data[i].y;
|
||||
}
|
||||
}
|
||||
},
|
||||
// touchmove(e){
|
||||
// if(this.index != 'false'){
|
||||
//
|
||||
// let index_1,index_2;
|
||||
// let tag = e.touches[0];
|
||||
//
|
||||
// data[this.index].x = tag.x-this.touchstarte_x ;
|
||||
// data[this.index].y = tag.y-this.touchstarte_y ;
|
||||
//
|
||||
// for (let i = 0; i < data.length; i++) {
|
||||
//
|
||||
// index_1 = getDistance(data[i].x,data[i].y,data[this.index].x,data[this.index].y);
|
||||
// index_2 = (data[i].radius*2) + (data[this.index].radius*2);
|
||||
// if(i!= this.index){
|
||||
//
|
||||
// if( index_1 > index_2){
|
||||
// dragBall.mapping(this);
|
||||
// }else{
|
||||
// data[i].x = data[i].x+(-(data[this.index].x-data[i].x)/10) ;
|
||||
// data[i].y = data[i].y+(-(data[this.index].y-data[i].y)/10) ;
|
||||
//
|
||||
// (data[i].x-data[i].radius) < 0 ? data[i].x = data[i].radius : data[i].x;
|
||||
// (data[i].y-data[i].radius) < 0 ? data[i].y = data[i].radius : data[i].y;
|
||||
//
|
||||
//
|
||||
// (data[i].x+data[i].radius) > dragBall.boundary[0] ? data[i].x = (dragBall.boundary[0]-data[i].radius) : data[i].x;
|
||||
// (data[i].y+data[i].radius) > dragBall.boundary[1] ? data[i].y = (dragBall.boundary[1]-data[i].radius) : data[i].y;
|
||||
//
|
||||
// dragBall.mapping(this);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
touchend(){this.index = 'false';}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page{width: 100%;height: 100%;}
|
||||
canvas {width: 100%;height: 90%;}
|
||||
</style>
|
||||
52
mallplusui-uniapp-app/components/empty.vue
Normal file
52
mallplusui-uniapp-app/components/empty.vue
Normal file
File diff suppressed because one or more lines are too long
453
mallplusui-uniapp-app/components/eonfox/eonfox.js
Normal file
453
mallplusui-uniapp-app/components/eonfox/eonfox.js
Normal file
@@ -0,0 +1,453 @@
|
||||
var eonfox = function(config){
|
||||
if( config ){
|
||||
if( config.debug ){
|
||||
eonfox.prototype.debug = true;
|
||||
}
|
||||
if( config.application ){
|
||||
eonfox.prototype.application = config.application;
|
||||
}
|
||||
if( config.api_server_url ){
|
||||
eonfox.prototype.api_server_url = config.api_server_url;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
eonfox.prototype = {
|
||||
|
||||
constructor : eonfox,
|
||||
|
||||
//是否开启调试模式
|
||||
debug : false,
|
||||
|
||||
|
||||
//文件服务器URL
|
||||
file_server_url : 'http://img.eonfox.cc/',
|
||||
|
||||
//接口地址 应用ID
|
||||
api_server_url : 'http://server.test.eapie.com/',
|
||||
application : "test",
|
||||
|
||||
//会话名称
|
||||
session_name : 'Eonfox_API_Engine_Session',
|
||||
|
||||
/*
|
||||
转换时间格式
|
||||
*/
|
||||
switchingTime: function(timestamp) {
|
||||
var date = new Date(timestamp * 1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
|
||||
var Y = date.getFullYear() + '-';
|
||||
var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
|
||||
var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
|
||||
var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
|
||||
var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
|
||||
var s = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
|
||||
return Y + M + D + h + m + s;
|
||||
},
|
||||
|
||||
|
||||
//提交的有效等待时间
|
||||
submit_sleep_expire_time : 30,
|
||||
|
||||
|
||||
//请求任务
|
||||
submit_task : null,
|
||||
|
||||
/**
|
||||
* 提交队列
|
||||
*/
|
||||
submit_queue : [],
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 提交登记
|
||||
*/
|
||||
submit_register : function( config ){
|
||||
config.time = ((new Date()).getTime()/1000);//赋值是 时间戳 (秒),用于有效时间
|
||||
eonfox.prototype.submit_queue.push(config);
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 运行提交
|
||||
*/
|
||||
submit_run : function(){
|
||||
if( eonfox.prototype.submit_queue.length < 1 ){
|
||||
return false;//没有执行的提交
|
||||
}
|
||||
if( eonfox.prototype.submit_queue[0].runtime ){
|
||||
return false;//正在执行
|
||||
}
|
||||
|
||||
//检查是否已经失效
|
||||
if( (eonfox.prototype.submit_queue[0].time + eonfox.prototype.submit_sleep_expire_time) < ((new Date()).getTime()/1000) ){
|
||||
//已经过了有效期
|
||||
//删除第一个元素
|
||||
eonfox.prototype.submit_queue.shift();
|
||||
//再次提交
|
||||
return eonfox.prototype.submit_run();
|
||||
}
|
||||
|
||||
eonfox.prototype.submit_queue[0].runtime = true;
|
||||
var config = eonfox.prototype.submit_queue[0];
|
||||
|
||||
//从本地缓存中同步获取指定 key 对应的内容。
|
||||
var token = eonfox.prototype.token(function(e){
|
||||
config.error(e);
|
||||
});
|
||||
|
||||
if( !(function(){try{ return token['session_right_token'];}catch(e){return false;}}()) ){
|
||||
config.right_data.session = "start";
|
||||
config.right_data.application = this.application;
|
||||
}else{
|
||||
config.right_data.token = token['session_right_token'];
|
||||
config.left_data.token = token['session_left_token'];
|
||||
config.left_data.session = "start";
|
||||
config.left_data.application = this.application;
|
||||
}
|
||||
|
||||
var request = {
|
||||
url : config.url,
|
||||
method : "POST",
|
||||
dataType : "json",
|
||||
responseType : "text",
|
||||
header: {"Content-Type":"application/x-www-form-urlencoded"},//跨域,防止请求options
|
||||
complete : function(){
|
||||
//当请求完成之后调用这个函数,无论成功或失败。执行时间比success晚
|
||||
//删除第一个元素
|
||||
eonfox.prototype.submit_queue.shift();
|
||||
//再次提交
|
||||
eonfox.prototype.submit_run();
|
||||
},
|
||||
success : function(){},
|
||||
fail : function(err){
|
||||
config.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
//右令牌
|
||||
var right_token_post = function(){
|
||||
request.data = config.right_data;
|
||||
request.success = function(success_data_all){
|
||||
//这里要注意,这里是包含了 data
|
||||
if(typeof success_data_all != 'object'){
|
||||
success_data_all = (function(){try{ return JSON.parse(success_data_all);}catch(e){return false;}}());
|
||||
}
|
||||
var success_data = success_data_all.data? success_data_all.data : null;
|
||||
if(typeof success_data != 'object'){
|
||||
console.warn("应用接口响应异常");
|
||||
return config.callback(false, success_data_all);
|
||||
}
|
||||
|
||||
//如果存在请求令牌,直接返回数据
|
||||
if( (function(){try{ return success_data['token'];}catch(e){return false;}}()) ){
|
||||
//储存令牌
|
||||
eonfox.prototype.storage_token(success_data);
|
||||
//返回到回调函数
|
||||
return config.callback(success_data, success_data_all);
|
||||
}else{
|
||||
//否则说明没有这个会话,再进行左令牌查询
|
||||
return left_token_post();
|
||||
}
|
||||
};
|
||||
if( eonfox.prototype.debug ){
|
||||
console.log("post():右令牌提交:", request);
|
||||
}
|
||||
|
||||
eonfox.prototype.submit_task = uni.request(request);
|
||||
};
|
||||
|
||||
|
||||
//左令牌
|
||||
var left_token_post = function(){
|
||||
request.data = config.left_data;
|
||||
request.success = function(success_data_all){
|
||||
//这里要注意,这里是包含了 data
|
||||
if(typeof success_data_all != 'object'){
|
||||
success_data_all = (function(){try{ return JSON.parse(success_data_all);}catch(e){return false;}}());
|
||||
}
|
||||
var success_data = success_data_all.data? success_data_all.data : null;
|
||||
if(typeof success_data != 'object'){
|
||||
console.warn("应用接口响应异常");
|
||||
return config.callback(false, success_data_all);
|
||||
}
|
||||
|
||||
//如果没有报错
|
||||
if( (function(){try{ return success_data['token'];}catch(e){return false;}}()) ){
|
||||
//储存令牌
|
||||
eonfox.prototype.storage_token(success_data);
|
||||
}
|
||||
|
||||
//返回到回调函数
|
||||
return config.callback(success_data, success_data_all);
|
||||
};
|
||||
|
||||
if( eonfox.prototype.debug ){
|
||||
console.log("post():左令牌提交:", request);
|
||||
}
|
||||
|
||||
eonfox.prototype.submit_task = uni.request(request);
|
||||
};
|
||||
|
||||
|
||||
return right_token_post();
|
||||
},
|
||||
/**
|
||||
* 获取左token
|
||||
* 如果没用传入回调函数,那么则直接返回当前左令牌,但是有可能会出现左令牌失效
|
||||
* 正常操作是,传入一个回调函数,左令牌始终是保持最新的。
|
||||
*
|
||||
* @param {Function} #fn
|
||||
*/
|
||||
websocketToken : function(fn){
|
||||
if(typeof fn != "function"){
|
||||
var storage_token = eonfox.prototype.token();
|
||||
if( (function(){try{ return storage_token['session_websocket_token'];}catch(e){return false;}}()) ){
|
||||
return storage_token['session_websocket_token'];
|
||||
}else{
|
||||
return '';
|
||||
}
|
||||
}else{
|
||||
eonfox.prototype.submit({
|
||||
callback: function(){
|
||||
//从本地缓存中同步获取指定 key 对应的内容。
|
||||
var websocket_token = "";
|
||||
var websocket_token = eonfox.prototype.token();
|
||||
if( (function(){try{ return storage_token['session_websocket_token'];}catch(e){return false;}}()) ){
|
||||
websocket_token = storage_token['session_websocket_token'];
|
||||
}
|
||||
fn(websocket_token);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
/* 中断请求任务 */
|
||||
abort : function(){
|
||||
//清理等待的请求
|
||||
eonfox.prototype.submit_queue = [];
|
||||
//中断请求任务
|
||||
if( eonfox.prototype.submit_task.abort ){
|
||||
eonfox.prototype.submit_task.abort();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
/* 提交请求
|
||||
* 暂时只支持 POST
|
||||
* {
|
||||
* url : this.api_server_url,默认接口地址
|
||||
* data : {},
|
||||
* callback : 回调函数 第一个是单个 data,第二个是 全部的返回数据
|
||||
* error : 错误回调函数
|
||||
* }
|
||||
*
|
||||
*/
|
||||
submit : function(config){
|
||||
if( eonfox.prototype.debug ){
|
||||
console.log("submit()传入参数:", config);
|
||||
}
|
||||
|
||||
//回调函数
|
||||
if( !config.callback || config.callback.constructor != Function ){
|
||||
config.callback = function(){};
|
||||
}
|
||||
if( !config.error || config.error.constructor != Function ){
|
||||
config.error = function(){};
|
||||
}
|
||||
|
||||
//路由
|
||||
if(typeof config.url == 'undefined' || typeof config.url != 'string'){
|
||||
config.url = this.api_server_url;
|
||||
}
|
||||
|
||||
config.right_data = {};
|
||||
config.left_data = {};
|
||||
//请求字符串
|
||||
if( config.request ){
|
||||
//如果是对象,则先转换为字符串
|
||||
if(typeof config.request == "object"){
|
||||
config.request = JSON.stringify(config.request)
|
||||
}
|
||||
if(typeof config.request == "string"){
|
||||
config.right_data.data = config.request;
|
||||
config.left_data.data = config.request;
|
||||
}
|
||||
}
|
||||
|
||||
//用户传入的data数据
|
||||
if( config.data && typeof config.data == "object" ){
|
||||
for(var i in config.data){
|
||||
config.right_data[i] = config.data[i];
|
||||
config.left_data[i] = config.data[i];
|
||||
}
|
||||
}
|
||||
|
||||
if( eonfox.prototype.debug ){
|
||||
console.log("post():right_data、left_data:", config.right_data, config.left_data);
|
||||
}
|
||||
|
||||
/*//是否强制提交
|
||||
config.recursion = config.recursion? true : false;
|
||||
//大于0,说明存在队列
|
||||
if( this.submit_queue.length > 0 ){
|
||||
//判断是否强制提交
|
||||
if( config.recursion ){
|
||||
//去登记注册
|
||||
eonfox.prototype.submit_register(config);
|
||||
}else{
|
||||
//否则返回错误信息
|
||||
console.warn("应用接口提交队列个数:", this.submit_queue.length);
|
||||
return config.error("应用接口出现重复提交,前方正在提交队列个数:", this.submit_queue.length);
|
||||
}
|
||||
}else{
|
||||
//去登记注册
|
||||
eonfox.prototype.submit_register(config);
|
||||
} */
|
||||
|
||||
//去登记注册
|
||||
eonfox.prototype.submit_register(config);
|
||||
//并且调用执行
|
||||
eonfox.prototype.submit_run();
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 储存token
|
||||
*
|
||||
* @param {Object} data
|
||||
*/
|
||||
storage_token : function(data){
|
||||
if( !data ){
|
||||
return false;
|
||||
}
|
||||
|
||||
var token_data = null;
|
||||
var exist_right_token = false;
|
||||
var exist_left_token = false;
|
||||
|
||||
exist_right_token = (function(){try{ return data['token']['session_right_token'];}catch(e){return false;}}());
|
||||
exist_left_token = (function(){try{ return data['token']['session_left_token'];}catch(e){return false;}}());
|
||||
if(exist_right_token && exist_left_token){
|
||||
token_data = data['token'];
|
||||
}else{
|
||||
//有可能是顶级关联对象
|
||||
exist_right_token = (function(){try{ return data['session_right_token'];}catch(e){return false;}}());
|
||||
exist_left_token = (function(){try{ return data['session_left_token'];}catch(e){return false;}}());
|
||||
if(exist_right_token && exist_left_token){
|
||||
token_data = data;
|
||||
}
|
||||
}
|
||||
|
||||
if(!token_data){
|
||||
return false;
|
||||
}
|
||||
|
||||
//从本地缓存中同步获取指定 key 对应的内容。
|
||||
var storage_token = eonfox.prototype.token();
|
||||
if( (function(){try{ return storage_token['session_right_token'];}catch(e){return false;}}()) &&
|
||||
(function(){try{ return storage_token['session_left_token'];}catch(e){return false;}}()) ){
|
||||
|
||||
if(storage_token['session_right_token'] == token_data['session_right_token'] ||
|
||||
storage_token['session_left_token'] == token_data['session_left_token'] ){
|
||||
if( eonfox.prototype.debug ){
|
||||
console.log("需要对比旧token中的当前时间戳,为true则不需要更新token", storage_token['session_now_time'], token_data['session_now_time'], parseInt(storage_token['session_now_time']) > parseInt(token_data['session_now_time']));
|
||||
}
|
||||
if( parseInt(storage_token['session_now_time']) > parseInt(token_data['session_now_time']) ){
|
||||
if( eonfox.prototype.debug ){
|
||||
console.log("并发异步,不需要更新token" );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//console.log( uni.setStorageSync );
|
||||
|
||||
try {
|
||||
uni.setStorageSync(this.session_name +":"+ this.application, JSON.stringify(token_data));
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取token
|
||||
*
|
||||
* @param {Function} error_function
|
||||
*/
|
||||
token : function(error_function){
|
||||
//异步可能存在覆盖的问题,所以对比已存在的token,如果右左有一个相同则比较当前时间,即最大的当前时间是最新的。
|
||||
var storage_token = false;
|
||||
try {
|
||||
storage_token = uni.getStorageSync(this.session_name +":"+ this.application);
|
||||
if( storage_token ){
|
||||
storage_token = (function(){try{ return JSON.parse(storage_token);}catch(e){return false;}}());
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
if(error_function){
|
||||
error_function(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return storage_token;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 获取左token
|
||||
* 如果没用传入回调函数,那么则直接返回当前左令牌,但是有可能会出现左令牌失效
|
||||
* 正常操作是,传入一个回调函数,左令牌始终是保持最新的。
|
||||
*
|
||||
* @param {Function} #fn
|
||||
*/
|
||||
left_token : function(fn){
|
||||
if(typeof fn != "function"){
|
||||
var storage_token = eonfox.prototype.token();
|
||||
if( (function(){try{ return storage_token['session_left_token'];}catch(e){return false;}}()) ){
|
||||
return storage_token['session_left_token'];
|
||||
}else{
|
||||
return '';
|
||||
}
|
||||
}else{
|
||||
eonfox.prototype.submit({
|
||||
callback: function(){
|
||||
//从本地缓存中同步获取指定 key 对应的内容。
|
||||
var left_token = "";
|
||||
var storage_token = eonfox.prototype.token();
|
||||
if( (function(){try{ return storage_token['session_left_token'];}catch(e){return false;}}()) ){
|
||||
left_token = storage_token['session_left_token'];
|
||||
}
|
||||
fn(left_token);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
},
|
||||
/* 获取 websocket 数据 */
|
||||
websocket_data : function(res){
|
||||
console.log(res);
|
||||
if( !res.data ){
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return JSON.parse( res.data );
|
||||
}
|
||||
|
||||
};
|
||||
export default eonfox;
|
||||
285
mallplusui-uniapp-app/components/eonfox/fns.js
Normal file
285
mallplusui-uniapp-app/components/eonfox/fns.js
Normal file
@@ -0,0 +1,285 @@
|
||||
var fns = {
|
||||
//--------------
|
||||
//api接口验证
|
||||
checkError: function(data, ids, error){
|
||||
if(typeof(error)!='function'){
|
||||
error=function(){
|
||||
}
|
||||
}
|
||||
if(data.errno){
|
||||
error(data.errno, data.error);
|
||||
return false;
|
||||
}
|
||||
if(!data.data){
|
||||
error(1, "未知错误");
|
||||
return false;
|
||||
}
|
||||
if(ids){
|
||||
if(typeof ids =='object'){
|
||||
for( var i in ids){
|
||||
if(typeof ids[i] != "undefined"){
|
||||
var id = ids[i];
|
||||
if( data.data[id] && data.data[id].errno ){
|
||||
error(data.data[id].errno, data.data[id].error);
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
error(1, "“"+ids[i]+"”目标,未知错误");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}else if(typeof ids =='string' || typeof ids == 'number'){
|
||||
if(typeof data.data[ids] != "undefined" ){
|
||||
if( data.data[ids].errno ){
|
||||
error(data.data[ids].errno, data.data[ids].error);
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
error(1, "“"+ids+"”目标,未知错误");
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
error(1, "“"+ids+"”目标,未知错误");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var data_list = {};
|
||||
|
||||
if(data.data){
|
||||
for(var i in data.data){
|
||||
if(typeof data.data[i].data != "undefined"){
|
||||
data_list[i] = data.data[i].data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return data_list;
|
||||
},
|
||||
//数据处理 ceil向上取整
|
||||
number_pre:function(number,pre){
|
||||
switch(pre){
|
||||
case 'ceil':
|
||||
return Math.ceil(number)
|
||||
break;
|
||||
}
|
||||
},
|
||||
//保留两位小数
|
||||
number_floor_2:function(number){
|
||||
var number = number * 100;
|
||||
number = Math.floor(number)
|
||||
number = number/100;
|
||||
return number.toFixed(2);
|
||||
},
|
||||
//错误信息处理
|
||||
err:function(title,data,_json,fun){
|
||||
|
||||
if(data){
|
||||
if(_json){
|
||||
data=JSON.stringify(data)
|
||||
}
|
||||
console.log(title+' :',data)
|
||||
uni.showToast({
|
||||
title:title+' : '+data,
|
||||
icon:'none',
|
||||
duration:1500,
|
||||
success() {
|
||||
if(fun){
|
||||
fun();
|
||||
}
|
||||
}
|
||||
})
|
||||
}else{
|
||||
console.log(title)
|
||||
uni.showToast({
|
||||
title:title,
|
||||
icon:'none',
|
||||
duration:1500,
|
||||
success() {
|
||||
if(fun){
|
||||
fun();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
//成功信息处理
|
||||
success(title,fun){
|
||||
if(fun){
|
||||
fun();
|
||||
}
|
||||
uni.hideLoading();
|
||||
/* uni.showToast({
|
||||
title:title,
|
||||
icon:'success',
|
||||
success() {
|
||||
if(fun){
|
||||
fun();
|
||||
}
|
||||
}
|
||||
}) */
|
||||
},
|
||||
//敬请期待
|
||||
waiting:function(){
|
||||
uni.showToast({
|
||||
title:'敬请期待',
|
||||
icon:'none'
|
||||
})
|
||||
},
|
||||
//授权验证
|
||||
oauth_:function(){
|
||||
uni.setStorage({
|
||||
key:'oauth',
|
||||
data:true
|
||||
})
|
||||
},
|
||||
noauth:function(){
|
||||
uni.setStorage({
|
||||
key:'oauth',
|
||||
data:false
|
||||
})
|
||||
},
|
||||
//绑定验证
|
||||
unionid:function(){
|
||||
uni.setStorage({
|
||||
key:'unionid',
|
||||
data:true
|
||||
})
|
||||
},
|
||||
nunionid:function(){
|
||||
uni.setStorage({
|
||||
key:'unionid',
|
||||
data:false
|
||||
})
|
||||
},
|
||||
//绑定
|
||||
bind:function(){
|
||||
console.log('oauth');
|
||||
uni.getStorage({
|
||||
key:'oauth',
|
||||
success(re) {
|
||||
console.log('oauth',re);
|
||||
}
|
||||
})
|
||||
},
|
||||
//获取指定url参数
|
||||
getUrlQuery:function (urlStr) {
|
||||
// var urlStr = location.search.substr(1) ? location.search.substr(1) : "";
|
||||
var urlArr = [];
|
||||
for(var i = 0; i < urlStr.split("&").length; i++) {
|
||||
urlArr.push(urlStr.split("&")[i].split("=")[0] ? urlStr.split("&")[i].split("=")[0] : "");
|
||||
urlArr.push(urlStr.split("&")[i].split("=")[1] ? urlStr.split("&")[i].split("=")[1] : "onlyKey")
|
||||
}
|
||||
if(urlStr == "") {
|
||||
return;
|
||||
} else {
|
||||
var urlObj = {}
|
||||
for(var i = 0; i < urlArr.length; i += 2) {
|
||||
if(urlArr[i] != "") {
|
||||
urlObj[urlArr[i]] = decodeURIComponent(urlArr[i + 1]);
|
||||
}
|
||||
}
|
||||
return urlObj;
|
||||
}
|
||||
}
|
||||
,
|
||||
// url参数解析
|
||||
getUrlkey:function(url) {
|
||||
var params = {};
|
||||
var urls = url.split("?"); console.log('1_分割url:', urls)
|
||||
var arr = urls[1].split("&"); console.log('2_分割urls[1]:', arr)
|
||||
for (var i = 0, l = arr.length; i < l; i++) {
|
||||
var a = arr[i].split("="); console.log('3_遍历 arr 并分割后赋值给a:', a[0], a[1])
|
||||
params[a[0]] = a[1]; console.log('4_a给params对象赋值:', params)
|
||||
} console.log('5_结果:', params)
|
||||
return params;
|
||||
}
|
||||
,
|
||||
toast(tit,url,time){
|
||||
if(!time){
|
||||
time=1500
|
||||
}
|
||||
uni.showToast({
|
||||
title:tit,
|
||||
success() {
|
||||
setTimeout(function(){
|
||||
uni.reLaunch({
|
||||
url:url
|
||||
})
|
||||
},time)
|
||||
}
|
||||
})
|
||||
},
|
||||
setSystemInfoSync(){
|
||||
uni.getStorage({
|
||||
key:'SystemInfoSync',
|
||||
fail(err) {
|
||||
console.log('设置缓存');
|
||||
try {
|
||||
console.log('star');
|
||||
const res = uni.getSystemInfoSync();
|
||||
console.log('config'+JSON.stringify(res));
|
||||
uni.setStorage({
|
||||
key:'SystemInfoSync',
|
||||
data:res
|
||||
})
|
||||
console.log('ok');
|
||||
} catch (e) {
|
||||
console.log('catch+'+JSON.stringify(e));
|
||||
// error
|
||||
}
|
||||
},
|
||||
|
||||
})
|
||||
},
|
||||
getCompare(Version,newVersion,fun){
|
||||
if(Version==newVersion){
|
||||
console.log('没有更新');
|
||||
return
|
||||
}
|
||||
console.log('接收到参数');
|
||||
uni.getStorage({
|
||||
key:'SystemInfoSync',
|
||||
success(res) {
|
||||
console.log('缓存:'+JSON.stringify(res));
|
||||
if(res.data){
|
||||
var SystemInfoSync=res.data;
|
||||
console.log('json:'+JSON.stringify(SystemInfoSync));
|
||||
console.log('设备:'+SystemInfoSync.platform);
|
||||
if(SystemInfoSync.platform=='android'){
|
||||
console.log('设备:安卓');
|
||||
fun();
|
||||
}
|
||||
}else{
|
||||
return this.setSystemInfo();
|
||||
}
|
||||
},
|
||||
fail(err) {
|
||||
console.log('缓存获取失败'+JSON.stringify(err));
|
||||
const res = uni.getSystemInfoSync();
|
||||
console.log('config'+JSON.stringify(res));
|
||||
uni.setStorage({
|
||||
key:'SystemInfoSync',
|
||||
data:res,
|
||||
success() {
|
||||
if(res.platform=='android'){
|
||||
console.log('设备:安卓');
|
||||
fun();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
complete() {
|
||||
console.log('获取缓存');
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
}
|
||||
//------------------------
|
||||
};
|
||||
|
||||
export default fns;
|
||||
39
mallplusui-uniapp-app/components/eonfox/grouporder.js
Normal file
39
mallplusui-uniapp-app/components/eonfox/grouporder.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import eonfox from '@/components/eonfox/eonfox.js';
|
||||
var ef=new eonfox()
|
||||
import f from '@/components/eonfox/fns.js';
|
||||
var pay= {
|
||||
shoppingCar:function(groupId,method,pass,fun){
|
||||
ef.submit({
|
||||
request:{
|
||||
s:['SHOPGROUPGOODSSELFPAY',[{id:groupId,pay_method:method,pay_password:pass}]]
|
||||
},
|
||||
callback:function(data){
|
||||
const dataList=(data=f.checkError(data,'s',function(errno,error){
|
||||
f.err(error)
|
||||
|
||||
}))
|
||||
console.log('da...',dataList)
|
||||
if(dataList.s==true){
|
||||
fun()
|
||||
}
|
||||
|
||||
// var dataList=data.s
|
||||
// if(dataList.data){
|
||||
// if(dataList.data==true){
|
||||
// f.err('支付成功')
|
||||
// }else{
|
||||
// f.err('支付失败')
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
console.log('支付结果');
|
||||
},
|
||||
error(err){
|
||||
f.err('',err,1)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
export default pay;
|
||||
12
mallplusui-uniapp-app/components/eonfox/merchant.js
Normal file
12
mallplusui-uniapp-app/components/eonfox/merchant.js
Normal file
@@ -0,0 +1,12 @@
|
||||
/* 商家模块 */
|
||||
var merchant = function(){};
|
||||
merchant.prototype = {
|
||||
|
||||
constructor : merchant,
|
||||
|
||||
//收银员的订单列表是否需要刷新
|
||||
cashierOrderListRefresh : false
|
||||
|
||||
};
|
||||
|
||||
export default merchant;
|
||||
72
mallplusui-uniapp-app/components/eonfox/order.js
Normal file
72
mallplusui-uniapp-app/components/eonfox/order.js
Normal file
@@ -0,0 +1,72 @@
|
||||
import eonfox from '@/components/eonfox/eonfox.js';
|
||||
var ef = new eonfox();
|
||||
|
||||
var order = {
|
||||
|
||||
/* 检查支付状态
|
||||
order_id 要检查的订单ID
|
||||
frequency 检查的次数,当等于0时,则返回回调
|
||||
callback 回调。成功时:callback.success 失败时:callback.fail
|
||||
因为有 frequency 次数,所以每次进来 -1 。如果不等于0,那么要继续递归
|
||||
|
||||
order.checkPayState({
|
||||
order_id: order_id,
|
||||
frequency: 3,
|
||||
success:function(){
|
||||
|
||||
},
|
||||
fail:function(){
|
||||
|
||||
}
|
||||
})
|
||||
*/
|
||||
checkPayState : function(data){
|
||||
var _this = this;
|
||||
if(typeof data.success != 'function') data.success = function(){};
|
||||
if(typeof data.fail != 'function') data.fail = function(){};
|
||||
if( typeof data.frequency != 'number') data.frequency = 3;
|
||||
|
||||
if( !data.frequency || !data.order_id ){
|
||||
return data.fail('参数不正确', data);
|
||||
}
|
||||
|
||||
|
||||
//如果不等于0,那么要继续递归
|
||||
data.frequency --;
|
||||
|
||||
//开始查询状态 0表示未支付;1表示支付成功。
|
||||
ef.submit({
|
||||
request:{
|
||||
s:['APPLICATIONORDERSELFPAYSTATE',[{order_id: data.order_id}]]
|
||||
},
|
||||
callback: function(r){
|
||||
console.log('order.checkPayState:::',r);
|
||||
// console.log('支付查询回调成功',r.data.s.data) ;return r.data.s.data;
|
||||
if( !r.errno && !r.data.s.errno && r.data.s.data){
|
||||
console.log('支付成功');
|
||||
//获取成功,无错误信息时
|
||||
return data.success();
|
||||
} else {
|
||||
console.log('支付状态查询失败或者未支付');
|
||||
if( !data.frequency ){
|
||||
return data.fail();
|
||||
}else{
|
||||
setTimeout(function() {
|
||||
return _this.checkPayState(data);
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
},
|
||||
error(err){
|
||||
data.fail(err);
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
export default order;
|
||||
70
mallplusui-uniapp-app/components/eonfox/pay.js
Normal file
70
mallplusui-uniapp-app/components/eonfox/pay.js
Normal file
@@ -0,0 +1,70 @@
|
||||
import eonfox from '@/components/eonfox/eonfox.js';
|
||||
var ef=new eonfox()
|
||||
import f from '@/components/eonfox/fns.js';
|
||||
var pay= {
|
||||
set_password:function(pass,pass_confirm,fun){
|
||||
ef.submit({
|
||||
request:{
|
||||
set_pass:['setpass',[{password:pass}]]
|
||||
},
|
||||
callback:function(data){
|
||||
if(data=f.checkError(data,'set_pass',function(errno,error){
|
||||
f.err(error)
|
||||
})){
|
||||
fun()
|
||||
}else{
|
||||
f.err('设置失败')
|
||||
}
|
||||
console.log('支付结果');
|
||||
},
|
||||
error(err){
|
||||
f.err('',err,1)
|
||||
}
|
||||
})
|
||||
},
|
||||
shoppingCar:function(id,method,pass,fun){
|
||||
ef.submit({
|
||||
request:{
|
||||
s:['SHOPORDERSELFPAYMENT',[{order_id:id,pay_method:method,pay_password:pass}]]
|
||||
},
|
||||
callback:function(data){
|
||||
const dataList=(data=f.checkError(data,'s',function(errno,error){
|
||||
f.err(error)
|
||||
|
||||
}))
|
||||
console.log('da...',dataList)
|
||||
if(dataList.s.order_id){
|
||||
|
||||
f.err('支付成功')
|
||||
return ok
|
||||
}
|
||||
|
||||
console.log('支付结果');
|
||||
},
|
||||
error(err){
|
||||
f.err('',err,1)
|
||||
}
|
||||
})
|
||||
},
|
||||
//取消订单
|
||||
cancel_order:function(id,fun){
|
||||
ef.submit({
|
||||
request:{
|
||||
cancel_order:['SHOPORDERSELFCANCEL',[{id:id}]]
|
||||
},
|
||||
callback:function(data){
|
||||
if(data=f.checkError(data,'cancel_order',function(errno,error){
|
||||
f.err(error)
|
||||
})){
|
||||
fun()
|
||||
}else{
|
||||
f.err('订单取消失败')
|
||||
}
|
||||
},
|
||||
error(err){
|
||||
f.err('',err,1)
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
export default pay;
|
||||
61
mallplusui-uniapp-app/components/eonfox/polling.js
Normal file
61
mallplusui-uniapp-app/components/eonfox/polling.js
Normal file
@@ -0,0 +1,61 @@
|
||||
var polling = {
|
||||
|
||||
//定时器ID
|
||||
_interval_id : null,
|
||||
_switch : false,
|
||||
|
||||
//关闭
|
||||
close : function(){
|
||||
clearInterval(this._interval_id);
|
||||
this._interval_id = null;
|
||||
},
|
||||
|
||||
//暂停
|
||||
stop : function(){
|
||||
this._switch = false;
|
||||
},
|
||||
|
||||
//启动
|
||||
start : function(){
|
||||
this._switch = true;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 开启
|
||||
*
|
||||
* @param {Time} ms 毫秒数
|
||||
* @param {Function} fn 回调函数
|
||||
*/
|
||||
run : function(ms, fn){
|
||||
if( !ms || typeof ms != 'number'){
|
||||
ms = 3000;//默认3秒
|
||||
}
|
||||
if(!fn || typeof fn != 'function'){
|
||||
fn = function(){};
|
||||
}
|
||||
|
||||
var _this = this;
|
||||
//如果已经存在,则要关闭轮询
|
||||
if( _this._interval_id ){
|
||||
_this.start();
|
||||
return true;
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
_this._switch = true;
|
||||
_this._interval_id = setInterval(function(){
|
||||
if( !_this._switch ){
|
||||
return false;
|
||||
}
|
||||
|
||||
i ++;
|
||||
fn(i);
|
||||
}, ms);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default polling;
|
||||
1123
mallplusui-uniapp-app/components/eonfox/qqmap-wx-jssdk.js
Normal file
1123
mallplusui-uniapp-app/components/eonfox/qqmap-wx-jssdk.js
Normal file
File diff suppressed because it is too large
Load Diff
3
mallplusui-uniapp-app/components/eonfox/version.js
Normal file
3
mallplusui-uniapp-app/components/eonfox/version.js
Normal file
@@ -0,0 +1,3 @@
|
||||
// 版本控制文件
|
||||
var version='0.0.12';
|
||||
export default version;
|
||||
541
mallplusui-uniapp-app/components/eonfox/websocket.js
Normal file
541
mallplusui-uniapp-app/components/eonfox/websocket.js
Normal file
@@ -0,0 +1,541 @@
|
||||
import eonfoxObject from '@/components/eonfox/eonfox.js';
|
||||
var eonfox = new eonfoxObject();
|
||||
var websocket_app = false;
|
||||
//#ifdef APP-PLUS
|
||||
websocket_app = true;
|
||||
//#endif
|
||||
|
||||
var websocket = function(config){};
|
||||
websocket.prototype = {
|
||||
|
||||
// url :'wss://developer.eapie.eonfox.com:9997',//测试版
|
||||
url :'wss://eapie.eonfox.com:9999',//正式版
|
||||
connect_type : 0,//连接类型。0是安卓,1是非安卓
|
||||
debug: false,//是否调试
|
||||
close_type : 0,//1是手动关闭,不会再尝试连接
|
||||
token:'',//websocket令牌
|
||||
open:false,//打开状态
|
||||
client_id:'',//连接ID
|
||||
server_time: 0,//websocket 服务器时间
|
||||
messages:[],//接受的websocket消息的集合
|
||||
message_max_number:10,//最大消息个数
|
||||
messages_change:function(){},//变动时执行的函数
|
||||
|
||||
heartbeat_interval_id: null,//心跳检测的定时器ID
|
||||
heartbeat_ms: 15000,//心跳检测毫秒
|
||||
heartbeat_messages:[],//心跳检测的信息集合
|
||||
heartbeat_message_max_number:10,//最大消息个数
|
||||
heartbeat_messages_change:function(){},//变动时执行的函数
|
||||
|
||||
|
||||
connect_parameter: null,//连接websocket的参数
|
||||
|
||||
|
||||
/* 调试信息 */
|
||||
debug_message:function(message, fn){
|
||||
if( !websocket.prototype.debug ){
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(message);
|
||||
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
});
|
||||
|
||||
if(typeof fn == 'function'){
|
||||
fn();
|
||||
}
|
||||
},
|
||||
|
||||
/* 获取 websocket 数据 */
|
||||
get_data : function(res){
|
||||
if( !res.data ){
|
||||
return false;
|
||||
}
|
||||
return JSON.parse( res.data );
|
||||
},
|
||||
|
||||
|
||||
|
||||
/* 设置心跳检测的信息集合 */
|
||||
set_heartbeat_messages: function(message){
|
||||
if( this.heartbeat_messages.length >= this.heartbeat_message_max_number ){
|
||||
this.heartbeat_messages.pop();//删除最后一个元素
|
||||
}
|
||||
|
||||
//往前面添加
|
||||
this.heartbeat_messages.unshift(message);
|
||||
if(typeof websocket.prototype.heartbeat_messages_change == 'function') websocket.prototype.heartbeat_messages_change();
|
||||
},
|
||||
|
||||
|
||||
/* 设置心跳检测的信息集合 */
|
||||
set_messages: function(message){
|
||||
if( this.messages.length >= this.message_max_number ){
|
||||
this.messages.pop();//删除最后一个元素
|
||||
}
|
||||
|
||||
//往前面添加
|
||||
this.messages.unshift(message);
|
||||
if(typeof websocket.prototype.messages_change == 'function') websocket.prototype.messages_change();
|
||||
},
|
||||
|
||||
messages_change_function: function(fn){
|
||||
websocket.prototype.messages_change = fn;
|
||||
},
|
||||
|
||||
heartbeat_messages_change_function: function(fn){
|
||||
websocket.prototype.heartbeat_messages_change = fn;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 获取左 websocket_token
|
||||
* 如果没用传入回调函数,那么则直接返回当前左令牌,但是有可能会出现左令牌失效
|
||||
* 正常操作是,传入一个回调函数,左令牌始终是保持最新的。
|
||||
*
|
||||
* @param {Function} #fn
|
||||
*/
|
||||
session_websocket_token : function(fn){
|
||||
if(typeof fn != "function"){
|
||||
var storage_token = eonfox.token();
|
||||
if( (function(){try{ return storage_token['session_websocket_token'];}catch(e){return false;}}()) ){
|
||||
return storage_token['session_websocket_token'];
|
||||
}else{
|
||||
return '';
|
||||
}
|
||||
}else{
|
||||
eonfox.submit({
|
||||
callback: function(){
|
||||
//从本地缓存中同步获取指定 key 对应的内容。
|
||||
var websocket_token = "";
|
||||
var storage_token = eonfox.token();
|
||||
if( (function(){try{ return storage_token['session_websocket_token'];}catch(e){return false;}}()) ){
|
||||
websocket_token = storage_token['session_websocket_token'];
|
||||
}
|
||||
fn(websocket_token);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* 获取 websocket 令牌
|
||||
* 传入一个回调函数
|
||||
*/
|
||||
get_token : function(fn){
|
||||
var websocket_token = websocket.prototype.session_websocket_token();
|
||||
if( websocket_token ){
|
||||
console.log('get_websocket_token 已存在', websocket_token);
|
||||
fn(websocket_token);
|
||||
}else{
|
||||
console.log('get_websocket_token 不存在,异步获取');
|
||||
websocket.prototype.session_websocket_token(function(websocket_token){
|
||||
fn(websocket_token);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
/* 连接 websocket */
|
||||
connect: function(connectParameter){
|
||||
websocket.prototype.connect_type = 1;//连接类型。0是安卓,1是非安卓
|
||||
websocket.prototype.not_android_connect(connectParameter);
|
||||
// if( websocket_app && plus.os.name == 'Android'){
|
||||
// websocket.prototype.connect_type = 0;//连接类型。0是安卓,1是非安卓
|
||||
// websocket.prototype.android_connect(connectParameter);
|
||||
// }else{
|
||||
// websocket.prototype.connect_type = 1;//连接类型。0是安卓,1是非安卓
|
||||
// websocket.prototype.not_android_connect(connectParameter);
|
||||
// }
|
||||
},
|
||||
|
||||
//安卓程序
|
||||
android_connect: function(connectParameter){},
|
||||
|
||||
|
||||
//非安卓程序
|
||||
//data.onSocketOpen
|
||||
not_android_connect: function(connectParameter){
|
||||
var _this = this;
|
||||
websocket.prototype.debug_message('websocket.connect 连接 websocket');
|
||||
websocket.prototype.connect_parameter = connectParameter;
|
||||
websocket.prototype.get_token(function(token){
|
||||
if( !token ){
|
||||
//这里弹出错误消息
|
||||
websocket.prototype.debug_message('websocket.connect 连接失败!没有获取到 websocket token');
|
||||
}
|
||||
|
||||
//链接
|
||||
uni.connectSocket({
|
||||
url: websocket.prototype.url,
|
||||
success(){
|
||||
_this.set_messages({
|
||||
state:true,
|
||||
content:'连接webscoket成功',
|
||||
});
|
||||
websocket.prototype.token = token;
|
||||
websocket.prototype.debug_message(' uni.connectSocket 连接webscoket成功!token:'+token);
|
||||
},
|
||||
fail(){
|
||||
_this.set_messages({
|
||||
state:false,
|
||||
content:'连接webscoket失败',
|
||||
});
|
||||
|
||||
websocket.prototype.debug_message(' uni.connectSocket 连接webscoket失败!token:'+token);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//WebSocket连接打开监听
|
||||
uni.onSocketOpen(function () {
|
||||
websocket.prototype.close_type = 0;
|
||||
websocket.prototype.open = true;
|
||||
websocket.prototype.debug_message('uni.onSocketOpen WebSocket连接已经打开监听!');
|
||||
if(connectParameter && typeof connectParameter.onSocketOpen == 'function'){
|
||||
connectParameter.onSocketOpen();
|
||||
}
|
||||
});
|
||||
|
||||
uni.onSocketClose(function (res) {
|
||||
websocket.prototype.token = '';
|
||||
websocket.prototype.open = false;
|
||||
websocket.prototype.client_id = '';
|
||||
//关闭心跳检测
|
||||
if( websocket.prototype.heartbeat_interval_id ){
|
||||
clearInterval( websocket.prototype.heartbeat_interval_id );
|
||||
}
|
||||
|
||||
if(connectParameter && typeof connectParameter.onSocketClose == 'function'){
|
||||
connectParameter.onSocketClose(res);
|
||||
}
|
||||
|
||||
//开启心跳检测
|
||||
if( websocket.prototype.close_type == 0){
|
||||
websocket.prototype.debug_message('uni.onSocketClose 非手动关闭,开启心跳守护');
|
||||
setTimeout(function(){
|
||||
websocket.prototype.connect(connectParameter);
|
||||
}, websocket.prototype.heartbeat_ms);
|
||||
|
||||
}
|
||||
websocket.prototype.debug_message('uni.onSocketClose WebSocket 已关闭!');
|
||||
});
|
||||
|
||||
//收到服务器内容
|
||||
uni.onSocketMessage(function (res) {
|
||||
console.log('onSocketMessage!!!!!!!!');
|
||||
//给一个超时器
|
||||
setTimeout(function(){
|
||||
console.log('setTimeout!!!!!!!!');
|
||||
websocket.prototype.debug_message('onSocketMessage 获取 websocket 数据:' + JSON.stringify(res));
|
||||
var websocket_token = eonfox.websocketToken();
|
||||
var r = websocket.prototype.get_data(res);
|
||||
//websocket 检查连接ID值(旧-新)
|
||||
if( (r.data && r.data.client_id && websocket.prototype.client_id != r.data.client_id) ||
|
||||
(r.data && r.data.server_time && websocket.prototype.server_time != r.data.server_time) ||
|
||||
(websocket.prototype.token != websocket_token) ){
|
||||
if(r.data && r.data.client_id && websocket.prototype.client_id != r.data.client_id){
|
||||
websocket.prototype.debug_message('websocket 连接ID 不一致',function(){
|
||||
console.log('websocket.prototype.client_id != r.data.client_id', websocket.prototype.client_id, r.data.client_id);
|
||||
});
|
||||
}
|
||||
if(r.data && r.data.server_time && websocket.prototype.server_time != r.data.server_time){
|
||||
websocket.prototype.debug_message('websocket 服务器时间 不一致',function(){
|
||||
console.log('websocket.prototype.server_time != r.data.server_time', websocket.prototype.server_time, r.data.server_time);
|
||||
});
|
||||
}
|
||||
if(websocket.prototype.token != websocket_token){
|
||||
websocket.prototype.debug_message('websocket_token 不一致',function(){
|
||||
console.log('websocket.prototype.token != websocket_token', websocket.prototype.token, websocket_token);
|
||||
});
|
||||
}
|
||||
return websocket.prototype.init( r.data.client_id, r.data.server_time, websocket_token, connectParameter, function(){
|
||||
if(typeof connectParameter.onSocketMessage == 'function'){
|
||||
connectParameter.onSocketMessage(res);
|
||||
}
|
||||
});//初始化
|
||||
}else{
|
||||
if(connectParameter && typeof connectParameter.onSocketMessage == 'function'){
|
||||
connectParameter.onSocketMessage(res);
|
||||
}
|
||||
}
|
||||
|
||||
}, 0);
|
||||
|
||||
});
|
||||
|
||||
uni.onSocketError(function (res) {
|
||||
//开启心跳检测
|
||||
setTimeout(function(){
|
||||
websocket.prototype.connect(connectParameter);
|
||||
}, websocket.prototype.heartbeat_ms);
|
||||
if(connectParameter && typeof connectParameter.onSocketError == 'function'){
|
||||
connectParameter.onSocketError(res);
|
||||
}
|
||||
_this.set_messages({
|
||||
state:false,
|
||||
content:'连接webscoket失败',
|
||||
error: res
|
||||
});
|
||||
|
||||
websocket.prototype.debug_message('uni.onSocketError WebSocket连接打开失败,请检查!error:'+res);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
||||
/* 初始化 */
|
||||
init : function( client_id, server_time, token, connectParameter, callback){
|
||||
var errorData = {
|
||||
open : websocket.prototype.open,
|
||||
token : websocket.prototype.token,
|
||||
client_id : client_id
|
||||
};
|
||||
|
||||
if( !websocket.prototype.open || !client_id ){
|
||||
_this.set_messages({
|
||||
state:false,
|
||||
content:'websocket 初始化失败',
|
||||
error: ''
|
||||
});
|
||||
websocket.prototype.debug_message('websocket 初始化失败!');
|
||||
};
|
||||
|
||||
eonfox.submit({
|
||||
request: {
|
||||
s: ['SESSIONWEBSOCKETSELFCLIENT', [{
|
||||
client_id: client_id, //连接id
|
||||
server_time: server_time // 服务器时间
|
||||
}]]
|
||||
},
|
||||
callback: function(){
|
||||
//必须是在初始化成功之后 才更新连接ID值
|
||||
websocket.prototype.client_id = client_id;
|
||||
websocket.prototype.server_time = server_time;
|
||||
//再次重置 websoket 令牌
|
||||
websocket.prototype.token = token;
|
||||
//开启心跳检测
|
||||
if( websocket.prototype.heartbeat_interval_id ){
|
||||
clearInterval( websocket.prototype.heartbeat_interval_id );
|
||||
}
|
||||
websocket.prototype.heartbeat_interval_id = setInterval(function(){
|
||||
websocket.prototype.debug_message('websocket init 心跳检测');
|
||||
websocket.prototype.heartbeat(function(errorData){
|
||||
websocket.prototype.debug_message('websocket init 心跳检测失败', function(){
|
||||
console.log('websocket_init 心跳检测失败返回值:', errorData);
|
||||
});
|
||||
clearInterval( websocket.prototype.heartbeat_interval_id );
|
||||
websocket.prototype.connect(connectParameter);
|
||||
});
|
||||
}, websocket.prototype.heartbeat_ms);
|
||||
|
||||
if(typeof connectParameter.initSuccess != 'function') connectParameter.initSuccess = function(){};
|
||||
connectParameter.initSuccess();
|
||||
websocket.prototype.debug_message('websocket init 初始化成功');
|
||||
websocket.prototype.set_heartbeat_messages({
|
||||
state:true,
|
||||
content:'websocket init 初始化成功!'
|
||||
});
|
||||
if(typeof callback != 'function') callback = function(){};
|
||||
callback();
|
||||
},
|
||||
error : function(errorData){
|
||||
websocket.prototype.debug_message('websocket init 初始化错误');
|
||||
websocket.prototype.set_heartbeat_messages({
|
||||
state:false,
|
||||
content:'websocket init 初始化错误!',
|
||||
error:errorData
|
||||
});
|
||||
return connectParameter.initError(errorData);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/* 发送心跳 */
|
||||
heartbeat: function(errorFunction){
|
||||
var errorData = {
|
||||
open : websocket.prototype.open,
|
||||
token : websocket.prototype.token,
|
||||
client_id : websocket.prototype.client_id
|
||||
};
|
||||
if( !websocket.prototype.open || !websocket.prototype.token ){
|
||||
if(typeof errorFunction != 'function') errorFunction = function(){};
|
||||
websocket.prototype.debug_message('websocket heartbeat 初始化失败!');
|
||||
websocket.prototype.set_heartbeat_messages({
|
||||
state:false,
|
||||
content:'websocket 初始化失败!'
|
||||
});
|
||||
return errorFunction(errorData);
|
||||
};
|
||||
|
||||
var heartbeat = JSON.stringify({
|
||||
module:'heartbeat',
|
||||
application: eonfox.application,
|
||||
token: websocket.prototype.token
|
||||
});
|
||||
|
||||
uni.sendSocketMessage({
|
||||
data: heartbeat,
|
||||
success: function(res){
|
||||
websocket.prototype.debug_message('websocket heartbeat 保持心跳成功!');
|
||||
websocket.prototype.set_heartbeat_messages({
|
||||
state:true,
|
||||
content:'websocket heartbeat 保持心跳成功!'
|
||||
});
|
||||
},
|
||||
fail: function(data){
|
||||
websocket.prototype.debug_message('websocket heartbeat 保持心跳失败!');
|
||||
websocket.prototype.set_heartbeat_messages({
|
||||
state:false,
|
||||
content:'websocket heartbeat 保持心跳失败!',
|
||||
error: data
|
||||
});
|
||||
return errorFunction(errorData);
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
//重启 websocket
|
||||
restart : function(){
|
||||
websocket.prototype.close();
|
||||
//重启
|
||||
websocket.prototype.connect(websocket.prototype.connect_parameter);
|
||||
websocket.prototype.debug_message('重启 websocket');
|
||||
},
|
||||
|
||||
//关闭
|
||||
close : function(){
|
||||
//关闭
|
||||
if( websocket.prototype.open ){
|
||||
//连接类型。0是安卓,1是非安卓
|
||||
if( websocket.prototype.connect_type == 1 ){
|
||||
uni.closeSocket();
|
||||
}else{
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
websocket.prototype.close_type = 1;
|
||||
websocket.prototype.token = '';
|
||||
websocket.prototype.open = false;
|
||||
websocket.prototype.client_id = '';
|
||||
//关闭心跳检测
|
||||
if( websocket.prototype.heartbeat_interval_id ){
|
||||
clearInterval( websocket.prototype.heartbeat_interval_id );
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
/* 用户向用户推送 */
|
||||
user_push : function(user_id, message, errorFunction){
|
||||
var data = {
|
||||
open : websocket.prototype.open,
|
||||
token : websocket.prototype.token
|
||||
}
|
||||
if( !websocket.prototype.open || !websocket.prototype.token ){
|
||||
if(typeof errorFunction != 'function') errorFunction = function(){};
|
||||
return errorFunction(data);
|
||||
}
|
||||
var user_push = JSON.stringify({
|
||||
module:'user_push',
|
||||
application: eonfox.application,
|
||||
token: websocket.prototype.token,
|
||||
user_id:user_id,
|
||||
message: message,
|
||||
});
|
||||
|
||||
uni.sendSocketMessage({
|
||||
data: user_push,
|
||||
success: function(res){
|
||||
websocket.prototype.debug_message('websocket 消息推送成功!', function(){
|
||||
console.log('user_push', res)
|
||||
});
|
||||
websocket.prototype.set_messages({
|
||||
state:true,
|
||||
content:'websocket user_push 消息推送成功!',
|
||||
});
|
||||
},
|
||||
fail: function(faildata){
|
||||
websocket.prototype.debug_message('websocket 消息推送失败!', function(){
|
||||
console.log('user_push', faildata)
|
||||
});
|
||||
websocket.prototype.set_messages({
|
||||
state:false,
|
||||
content:'websocket user_push 消息推送失败!',
|
||||
error:faildata
|
||||
});
|
||||
|
||||
return errorFunction(errorData);
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/* 用户向后台推送 */
|
||||
admin_push : function(message, errorFunction){
|
||||
var data = {
|
||||
open : websocket.prototype.open,
|
||||
token : websocket.prototype.token
|
||||
}
|
||||
if( !websocket.prototype.open || !websocket.prototype.token ){
|
||||
if(typeof errorFunction != 'function') errorFunction = function(){};
|
||||
return errorFunction(data);
|
||||
}
|
||||
var admin_push = JSON.stringify({
|
||||
module:'admin_push',
|
||||
application: eonfox.application,
|
||||
token: websocket.prototype.token,
|
||||
message: message,
|
||||
});
|
||||
|
||||
uni.sendSocketMessage({
|
||||
data: admin_push,
|
||||
success: function(res){
|
||||
websocket.prototype.debug_message('websocket 消息推送成功!', function(){
|
||||
console.log('admin_push', res)
|
||||
});
|
||||
websocket.prototype.set_messages({
|
||||
state:true,
|
||||
content:'websocket admin_push 消息推送成功!',
|
||||
});
|
||||
|
||||
},
|
||||
fail: function(faildata){
|
||||
websocket.prototype.debug_message('websocket 消息推送失败!', function(){
|
||||
console.log('admin_push', faildata)
|
||||
});
|
||||
websocket.prototype.set_messages({
|
||||
state:false,
|
||||
content:'websocket admin_push 消息推送失败!',
|
||||
error:faildata
|
||||
});
|
||||
|
||||
return errorFunction(errorData);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
export default websocket;
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<!-- '<audio/>' 组件不再维护,建议使用能力更强的 'uni.createInnerAudioContext' 接口 有时间再改-->
|
||||
<!--增加audio标签支持-->
|
||||
<audio
|
||||
:id="node.attr.id"
|
||||
:class="node.classStr"
|
||||
:style="node.styleStr"
|
||||
:src="node.attr.src"
|
||||
:loop="node.attr.loop"
|
||||
:poster="node.attr.poster"
|
||||
:name="node.attr.name"
|
||||
:author="node.attr.author"
|
||||
controls></audio>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'wxParseAudio',
|
||||
props: {
|
||||
node: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<view class="">
|
||||
<!-- #ifdef MP -->
|
||||
<image
|
||||
:lazy-load="node.attr.lazyLoad"
|
||||
:data-src="node.attr.src"
|
||||
:src="node.attr.src"
|
||||
@tap="wxParseImgTap"
|
||||
mode="widthFix"
|
||||
class="nodeclassStr"
|
||||
/>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP -->
|
||||
<image
|
||||
:lazy-load="node.attr.lazyLoad"
|
||||
:data-src="node.attr.src"
|
||||
:src="node.attr.src"
|
||||
@tap="wxParseImgTap"
|
||||
:mode="node.attr.mode"
|
||||
:class="node.classStr"
|
||||
:style="newStyleStr || node.styleStr"
|
||||
@load="wxParseImgLoad"
|
||||
/>
|
||||
<!-- #endif -->
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'wxParseImg',
|
||||
data() {
|
||||
return {
|
||||
newStyleStr: '',
|
||||
preview: true
|
||||
};
|
||||
},
|
||||
inject: ['parseWidth'],
|
||||
mounted() {},
|
||||
props: {
|
||||
node: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
wxParseImgTap(e) {
|
||||
if (!this.preview) return;
|
||||
const { src } = e.currentTarget.dataset;
|
||||
if (!src) return;
|
||||
let parent = this.$parent;
|
||||
while (!parent.preview || typeof parent.preview !== 'function') {
|
||||
// TODO 遍历获取父节点执行方法
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.preview(src, e);
|
||||
},
|
||||
// 图片视觉宽高计算函数区
|
||||
wxParseImgLoad(e) {
|
||||
const { src } = e.currentTarget.dataset;
|
||||
if (!src) return;
|
||||
let { width, height } = e.mp.detail;
|
||||
|
||||
const recal = this.wxAutoImageCal(width, height);
|
||||
|
||||
const { imageheight, imageWidth } = recal;
|
||||
const { padding, mode } = this.node.attr;//删除padding
|
||||
// const { mode } = this.node.attr;
|
||||
|
||||
const { styleStr } = this.node;
|
||||
// console.log(styleStr)
|
||||
const imageHeightStyle = mode === 'widthFix' ? '' : `height: ${imageheight}px`;
|
||||
// console.log(imageHeightStyle)
|
||||
this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px; padding: 0 ${+padding}px;`;//删除padding
|
||||
// this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px;`;
|
||||
// console.log(this.newStyleStr);
|
||||
},
|
||||
// 计算视觉优先的图片宽高
|
||||
wxAutoImageCal(originalWidth, originalHeight) {
|
||||
// 获取图片的原始长宽
|
||||
const windowWidth = this.parseWidth.value;
|
||||
const results = {};
|
||||
|
||||
if (originalWidth < 60 || originalHeight < 60) {
|
||||
const { src } = this.node.attr;
|
||||
let parent = this.$parent;
|
||||
while (!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.removeImageUrl(src);
|
||||
this.preview = false;
|
||||
}
|
||||
|
||||
// 判断按照那种方式进行缩放
|
||||
if (originalWidth > windowWidth) {
|
||||
// 在图片width大于手机屏幕width时候
|
||||
results.imageWidth = windowWidth;
|
||||
results.imageheight = windowWidth * (originalHeight / originalWidth);
|
||||
} else {
|
||||
// 否则展示原来的数据
|
||||
results.imageWidth = originalWidth;
|
||||
results.imageheight = originalHeight;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.nodeclassStr{
|
||||
max-width: 100%;
|
||||
float:left;
|
||||
width: 750rpx;
|
||||
padding: 0 0px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<rich-text :nodes="nodes" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'wxParseTable',
|
||||
props: {
|
||||
node: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
},
|
||||
inject: ['parseSelect'],
|
||||
data() {
|
||||
return {
|
||||
nodes:[]
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.nodes=this.loadNode([this.node]);
|
||||
},
|
||||
methods: {
|
||||
loadNode(node) {
|
||||
let obj = [];
|
||||
for (let children of node) {
|
||||
if (children.node=='element') {
|
||||
let t = {
|
||||
name:children.tag,
|
||||
attrs: {
|
||||
class: children.classStr,
|
||||
// style: children.styleStr,
|
||||
},
|
||||
children: children.nodes?this.loadNode(children.nodes):[]
|
||||
}
|
||||
|
||||
obj.push(t)
|
||||
} else if(children.node=='text'){
|
||||
obj.push({
|
||||
type: 'text',
|
||||
text: children.text
|
||||
})
|
||||
}
|
||||
}
|
||||
return obj
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
@import url("../parse.css");
|
||||
</style>
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<wx-parse-template :node="node" />
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node"/>
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// #ifdef APP-PLUS | H5
|
||||
import wxParseTemplate from './wxParseTemplate0';
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
import wxParseTemplate from './wxParseTemplate1';
|
||||
// #endif
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
// #ifdef APP-PLUS | H5
|
||||
name: 'wxParseTemplate',
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
name: 'wxParseTemplate0',
|
||||
// #endif
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;// TODO currentTarget才有dataset
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {// TODO 遍历获取父节点执行方法
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<wx-parse-template :node="node" />
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate2';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate1',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<wx-parse-template :node="node" />
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text' ">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate11';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate10',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text' ">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate11',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<wx-parse-template :node="node" />
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text'">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate3';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate2',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<wx-parse-template :node="node" />
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text' ">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate4';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate3',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<wx-parse-template :node="node" />
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text' ">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate5';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate4',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<wx-parse-template :node="node" />
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text' ">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate6';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate5',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<wx-parse-template :node="node" />
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text' ">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate7';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate6',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<wx-parse-template :node="node" />
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text' ">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate8';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate7',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<wx-parse-template :node="node" />
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text' ">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate9';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate8',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<!--判断是否是标签节点-->
|
||||
<block v-if="node.node == 'element'">
|
||||
<!--button类型-->
|
||||
<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
|
||||
<wx-parse-template :node="node" />
|
||||
</button>
|
||||
|
||||
<!--a类型-->
|
||||
<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--li类型-->
|
||||
<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!--table类型-->
|
||||
<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
|
||||
|
||||
<!--br类型-->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="node.tag == 'br'">\n</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="node.tag == 'br'">
|
||||
<!-- #endif -->
|
||||
|
||||
<!--video类型-->
|
||||
<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
|
||||
|
||||
<!--audio类型-->
|
||||
<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
|
||||
|
||||
<!--img类型-->
|
||||
<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
|
||||
|
||||
<!--其他标签-->
|
||||
<view v-else :class="node.classStr" :style="node.styleStr">
|
||||
<block v-for="(node, index) of node.nodes" :key="index">
|
||||
<wx-parse-template :node="node" />
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!--判断是否是文本节点-->
|
||||
<block v-else-if="node.node == 'text' ">{{node.text}}</block>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wxParseTemplate from './wxParseTemplate10';
|
||||
import wxParseImg from './wxParseImg';
|
||||
import wxParseVideo from './wxParseVideo';
|
||||
import wxParseAudio from './wxParseAudio';
|
||||
import wxParseTable from './wxParseTable';
|
||||
|
||||
export default {
|
||||
name: 'wxParseTemplate9',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate,
|
||||
wxParseImg,
|
||||
wxParseVideo,
|
||||
wxParseAudio,
|
||||
wxParseTable
|
||||
},
|
||||
methods: {
|
||||
wxParseATap(attr,e) {
|
||||
const {
|
||||
href
|
||||
} = e.currentTarget.dataset;
|
||||
if (!href) return;
|
||||
let parent = this.$parent;
|
||||
while(!parent.preview || typeof parent.preview !== 'function') {
|
||||
parent = parent.$parent;
|
||||
}
|
||||
parent.navigate(href, e, attr);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<!--增加video标签支持,并循环添加-->
|
||||
<view :class="node.classStr" :style="node.styleStr">
|
||||
<video :class="node.classStr" :style="node.styleStr" class="video-video" :src="node.attr.src"></video>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'wxParseVideo',
|
||||
props: {
|
||||
node: {},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
262
mallplusui-uniapp-app/components/gaoyia-parse/libs/html2json.js
Normal file
262
mallplusui-uniapp-app/components/gaoyia-parse/libs/html2json.js
Normal file
@@ -0,0 +1,262 @@
|
||||
/**
|
||||
* html2Json 改造来自: https://github.com/Jxck/html2json
|
||||
*
|
||||
*
|
||||
* author: Di (微信小程序开发工程师)
|
||||
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
|
||||
* 垂直微信小程序开发交流社区
|
||||
*
|
||||
* github地址: https://github.com/icindy/wxParse
|
||||
*
|
||||
* for: 微信小程序富文本解析
|
||||
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
|
||||
*/
|
||||
|
||||
import wxDiscode from './wxDiscode';
|
||||
import HTMLParser from './htmlparser';
|
||||
|
||||
function makeMap(str) {
|
||||
const obj = {};
|
||||
const items = str.split(',');
|
||||
for (let i = 0; i < items.length; i += 1) obj[items[i]] = true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Block Elements - HTML 5
|
||||
const block = makeMap('br,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video');
|
||||
|
||||
// Inline Elements - HTML 5
|
||||
const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var');
|
||||
|
||||
// Elements that you can, intentionally, leave open
|
||||
// (and which close themselves)
|
||||
const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');
|
||||
|
||||
function removeDOCTYPE(html) {
|
||||
const isDocument = /<body.*>([^]*)<\/body>/.test(html);
|
||||
return isDocument ? RegExp.$1 : html;
|
||||
}
|
||||
|
||||
function trimHtml(html) {
|
||||
return html
|
||||
.replace(/<!--.*?-->/gi, '')
|
||||
.replace(/\/\*.*?\*\//gi, '')
|
||||
.replace(/[ ]+</gi, '<')
|
||||
.replace(/<script[^]*<\/script>/gi, '')
|
||||
.replace(/<style[^]*<\/style>/gi, '');
|
||||
}
|
||||
|
||||
function getScreenInfo() {
|
||||
const screen = {};
|
||||
wx.getSystemInfo({
|
||||
success: (res) => {
|
||||
screen.width = res.windowWidth;
|
||||
screen.height = res.windowHeight;
|
||||
},
|
||||
});
|
||||
return screen;
|
||||
}
|
||||
|
||||
function html2json(html, customHandler, imageProp, host) {
|
||||
// 处理字符串
|
||||
html = removeDOCTYPE(html);
|
||||
html = trimHtml(html);
|
||||
html = wxDiscode.strDiscode(html);
|
||||
// 生成node节点
|
||||
const bufArray = [];
|
||||
const results = {
|
||||
nodes: [],
|
||||
imageUrls: [],
|
||||
};
|
||||
|
||||
const screen = getScreenInfo();
|
||||
function Node(tag) {
|
||||
this.node = 'element';
|
||||
this.tag = tag;
|
||||
|
||||
this.$screen = screen;
|
||||
}
|
||||
|
||||
HTMLParser(html, {
|
||||
start(tag, attrs, unary) {
|
||||
// node for this element
|
||||
const node = new Node(tag);
|
||||
|
||||
if (bufArray.length !== 0) {
|
||||
const parent = bufArray[0];
|
||||
if (parent.nodes === undefined) {
|
||||
parent.nodes = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (block[tag]) {
|
||||
node.tagType = 'block';
|
||||
} else if (inline[tag]) {
|
||||
node.tagType = 'inline';
|
||||
} else if (closeSelf[tag]) {
|
||||
node.tagType = 'closeSelf';
|
||||
}
|
||||
|
||||
node.attr = attrs.reduce((pre, attr) => {
|
||||
const { name } = attr;
|
||||
let { value } = attr;
|
||||
if (name === 'class') {
|
||||
node.classStr = value;
|
||||
}
|
||||
// has multi attibutes
|
||||
// make it array of attribute
|
||||
if (name === 'style') {
|
||||
node.styleStr = value;
|
||||
}
|
||||
if (value.match(/ /)) {
|
||||
value = value.split(' ');
|
||||
}
|
||||
|
||||
// if attr already exists
|
||||
// merge it
|
||||
if (pre[name]) {
|
||||
if (Array.isArray(pre[name])) {
|
||||
// already array, push to last
|
||||
pre[name].push(value);
|
||||
} else {
|
||||
// single value, make it array
|
||||
pre[name] = [pre[name], value];
|
||||
}
|
||||
} else {
|
||||
// not exist, put it
|
||||
pre[name] = value;
|
||||
}
|
||||
|
||||
return pre;
|
||||
}, {});
|
||||
|
||||
// 优化样式相关属性
|
||||
if (node.classStr) {
|
||||
node.classStr += ` ${node.tag}`;
|
||||
} else {
|
||||
node.classStr = node.tag;
|
||||
}
|
||||
if (node.tagType === 'inline') {
|
||||
node.classStr += ' inline';
|
||||
}
|
||||
|
||||
// 对img添加额外数据
|
||||
if (node.tag === 'img') {
|
||||
let imgUrl = node.attr.src;
|
||||
imgUrl = wxDiscode.urlToHttpUrl(imgUrl, imageProp.domain);
|
||||
Object.assign(node.attr, imageProp, {
|
||||
src: imgUrl || '',
|
||||
});
|
||||
if (imgUrl) {
|
||||
results.imageUrls.push(imgUrl);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理a标签属性
|
||||
if (node.tag === 'a') {
|
||||
node.attr.href = node.attr.href || '';
|
||||
}
|
||||
|
||||
// 处理font标签样式属性
|
||||
if (node.tag === 'font') {
|
||||
const fontSize = [
|
||||
'x-small',
|
||||
'small',
|
||||
'medium',
|
||||
'large',
|
||||
'x-large',
|
||||
'xx-large',
|
||||
'-webkit-xxx-large',
|
||||
];
|
||||
const styleAttrs = {
|
||||
color: 'color',
|
||||
face: 'font-family',
|
||||
size: 'font-size',
|
||||
};
|
||||
if (!node.styleStr) node.styleStr = '';
|
||||
Object.keys(styleAttrs).forEach((key) => {
|
||||
if (node.attr[key]) {
|
||||
const value = key === 'size' ? fontSize[node.attr[key] - 1] : node.attr[key];
|
||||
node.styleStr += `${styleAttrs[key]}: ${value};`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 临时记录source资源
|
||||
if (node.tag === 'source') {
|
||||
results.source = node.attr.src;
|
||||
}
|
||||
|
||||
if (customHandler.start) {
|
||||
customHandler.start(node, results);
|
||||
}
|
||||
|
||||
if (unary) {
|
||||
// if this tag doesn't have end tag
|
||||
// like <img src="hoge.png"/>
|
||||
// add to parents
|
||||
const parent = bufArray[0] || results;
|
||||
if (parent.nodes === undefined) {
|
||||
parent.nodes = [];
|
||||
}
|
||||
parent.nodes.push(node);
|
||||
} else {
|
||||
bufArray.unshift(node);
|
||||
}
|
||||
},
|
||||
end(tag) {
|
||||
// merge into parent tag
|
||||
const node = bufArray.shift();
|
||||
if (node.tag !== tag) {
|
||||
console.error('invalid state: mismatch end tag');
|
||||
}
|
||||
|
||||
// 当有缓存source资源时于于video补上src资源
|
||||
if (node.tag === 'video' && results.source) {
|
||||
node.attr.src = results.source;
|
||||
delete results.source;
|
||||
}
|
||||
|
||||
if (customHandler.end) {
|
||||
customHandler.end(node, results);
|
||||
}
|
||||
|
||||
if (bufArray.length === 0) {
|
||||
results.nodes.push(node);
|
||||
} else {
|
||||
const parent = bufArray[0];
|
||||
if (!parent.nodes) {
|
||||
parent.nodes = [];
|
||||
}
|
||||
parent.nodes.push(node);
|
||||
}
|
||||
},
|
||||
chars(text) {
|
||||
// if (!text.trim()){
|
||||
// return;
|
||||
// }
|
||||
const node = {
|
||||
node: 'text',
|
||||
text,
|
||||
};
|
||||
|
||||
if (customHandler.chars) {
|
||||
customHandler.chars(node, results);
|
||||
}
|
||||
|
||||
if (bufArray.length === 0) {
|
||||
results.nodes.push(node);
|
||||
} else {
|
||||
const parent = bufArray[0];
|
||||
if (parent.nodes === undefined) {
|
||||
parent.nodes = [];
|
||||
}
|
||||
parent.nodes.push(node);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
export default html2json;
|
||||
156
mallplusui-uniapp-app/components/gaoyia-parse/libs/htmlparser.js
Normal file
156
mallplusui-uniapp-app/components/gaoyia-parse/libs/htmlparser.js
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
*
|
||||
* htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser
|
||||
*
|
||||
* author: Di (微信小程序开发工程师)
|
||||
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
|
||||
* 垂直微信小程序开发交流社区
|
||||
*
|
||||
* github地址: https://github.com/icindy/wxParse
|
||||
*
|
||||
* for: 微信小程序富文本解析
|
||||
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
|
||||
*/
|
||||
// Regular Expressions for parsing tags and attributes
|
||||
|
||||
const startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z0-9_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
|
||||
const endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
|
||||
const attr = /([a-zA-Z0-9_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
|
||||
|
||||
function makeMap(str) {
|
||||
const obj = {};
|
||||
const items = str.split(',');
|
||||
for (let i = 0; i < items.length; i += 1) obj[items[i]] = true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Empty Elements - HTML 5
|
||||
const empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr');
|
||||
|
||||
// Block Elements - HTML 5
|
||||
const block = makeMap('address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video');
|
||||
|
||||
// Inline Elements - HTML 5
|
||||
const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var');
|
||||
|
||||
// Elements that you can, intentionally, leave open
|
||||
// (and which close themselves)
|
||||
const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');
|
||||
|
||||
// Attributes that have their values filled in disabled="disabled"
|
||||
const fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected');
|
||||
|
||||
function HTMLParser(html, handler) {
|
||||
let index;
|
||||
let chars;
|
||||
let match;
|
||||
let last = html;
|
||||
const stack = [];
|
||||
|
||||
stack.last = () => stack[stack.length - 1];
|
||||
|
||||
function parseEndTag(tag, tagName) {
|
||||
// If no tag name is provided, clean shop
|
||||
let pos;
|
||||
if (!tagName) {
|
||||
pos = 0;
|
||||
} else {
|
||||
// Find the closest opened tag of the same type
|
||||
tagName = tagName.toLowerCase();
|
||||
for (pos = stack.length - 1; pos >= 0; pos -= 1) {
|
||||
if (stack[pos] === tagName) break;
|
||||
}
|
||||
}
|
||||
if (pos >= 0) {
|
||||
// Close all the open elements, up the stack
|
||||
for (let i = stack.length - 1; i >= pos; i -= 1) {
|
||||
if (handler.end) handler.end(stack[i]);
|
||||
}
|
||||
|
||||
// Remove the open elements from the stack
|
||||
stack.length = pos;
|
||||
}
|
||||
}
|
||||
|
||||
function parseStartTag(tag, tagName, rest, unary) {
|
||||
tagName = tagName.toLowerCase();
|
||||
|
||||
if (block[tagName]) {
|
||||
while (stack.last() && inline[stack.last()]) {
|
||||
parseEndTag('', stack.last());
|
||||
}
|
||||
}
|
||||
|
||||
if (closeSelf[tagName] && stack.last() === tagName) {
|
||||
parseEndTag('', tagName);
|
||||
}
|
||||
|
||||
unary = empty[tagName] || !!unary;
|
||||
|
||||
if (!unary) stack.push(tagName);
|
||||
|
||||
if (handler.start) {
|
||||
const attrs = [];
|
||||
|
||||
rest.replace(attr, function genAttr(matches, name) {
|
||||
const value = arguments[2] || arguments[3] || arguments[4] || (fillAttrs[name] ? name : '');
|
||||
|
||||
attrs.push({
|
||||
name,
|
||||
value,
|
||||
escaped: value.replace(/(^|[^\\])"/g, '$1\\"'), // "
|
||||
});
|
||||
});
|
||||
|
||||
if (handler.start) {
|
||||
handler.start(tagName, attrs, unary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (html) {
|
||||
chars = true;
|
||||
|
||||
if (html.indexOf('</') === 0) {
|
||||
match = html.match(endTag);
|
||||
|
||||
if (match) {
|
||||
html = html.substring(match[0].length);
|
||||
match[0].replace(endTag, parseEndTag);
|
||||
chars = false;
|
||||
}
|
||||
|
||||
// start tag
|
||||
} else if (html.indexOf('<') === 0) {
|
||||
match = html.match(startTag);
|
||||
|
||||
if (match) {
|
||||
html = html.substring(match[0].length);
|
||||
match[0].replace(startTag, parseStartTag);
|
||||
chars = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (chars) {
|
||||
index = html.indexOf('<');
|
||||
let text = '';
|
||||
while (index === 0) {
|
||||
text += '<';
|
||||
html = html.substring(1);
|
||||
index = html.indexOf('<');
|
||||
}
|
||||
text += index < 0 ? html : html.substring(0, index);
|
||||
html = index < 0 ? '' : html.substring(index);
|
||||
|
||||
if (handler.chars) handler.chars(text);
|
||||
}
|
||||
|
||||
if (html === last) throw new Error(`Parse Error: ${html}`);
|
||||
last = html;
|
||||
}
|
||||
|
||||
// Clean up any remaining tags
|
||||
parseEndTag();
|
||||
}
|
||||
|
||||
export default HTMLParser;
|
||||
195
mallplusui-uniapp-app/components/gaoyia-parse/libs/wxDiscode.js
Normal file
195
mallplusui-uniapp-app/components/gaoyia-parse/libs/wxDiscode.js
Normal file
@@ -0,0 +1,195 @@
|
||||
// HTML 支持的数学符号
|
||||
function strNumDiscode(str) {
|
||||
str = str.replace(/∀/g, '∀');
|
||||
str = str.replace(/∂/g, '∂');
|
||||
str = str.replace(/∃/g, '∃');
|
||||
str = str.replace(/∅/g, '∅');
|
||||
str = str.replace(/∇/g, '∇');
|
||||
str = str.replace(/∈/g, '∈');
|
||||
str = str.replace(/∉/g, '∉');
|
||||
str = str.replace(/∋/g, '∋');
|
||||
str = str.replace(/∏/g, '∏');
|
||||
str = str.replace(/∑/g, '∑');
|
||||
str = str.replace(/−/g, '−');
|
||||
str = str.replace(/∗/g, '∗');
|
||||
str = str.replace(/√/g, '√');
|
||||
str = str.replace(/∝/g, '∝');
|
||||
str = str.replace(/∞/g, '∞');
|
||||
str = str.replace(/∠/g, '∠');
|
||||
str = str.replace(/∧/g, '∧');
|
||||
str = str.replace(/∨/g, '∨');
|
||||
str = str.replace(/∩/g, '∩');
|
||||
str = str.replace(/∪/g, '∪');
|
||||
str = str.replace(/∫/g, '∫');
|
||||
str = str.replace(/∴/g, '∴');
|
||||
str = str.replace(/∼/g, '∼');
|
||||
str = str.replace(/≅/g, '≅');
|
||||
str = str.replace(/≈/g, '≈');
|
||||
str = str.replace(/≠/g, '≠');
|
||||
str = str.replace(/≤/g, '≤');
|
||||
str = str.replace(/≥/g, '≥');
|
||||
str = str.replace(/⊂/g, '⊂');
|
||||
str = str.replace(/⊃/g, '⊃');
|
||||
str = str.replace(/⊄/g, '⊄');
|
||||
str = str.replace(/⊆/g, '⊆');
|
||||
str = str.replace(/⊇/g, '⊇');
|
||||
str = str.replace(/⊕/g, '⊕');
|
||||
str = str.replace(/⊗/g, '⊗');
|
||||
str = str.replace(/⊥/g, '⊥');
|
||||
str = str.replace(/⋅/g, '⋅');
|
||||
return str;
|
||||
}
|
||||
|
||||
// HTML 支持的希腊字母
|
||||
function strGreeceDiscode(str) {
|
||||
str = str.replace(/Α/g, 'Α');
|
||||
str = str.replace(/Β/g, 'Β');
|
||||
str = str.replace(/Γ/g, 'Γ');
|
||||
str = str.replace(/Δ/g, 'Δ');
|
||||
str = str.replace(/Ε/g, 'Ε');
|
||||
str = str.replace(/Ζ/g, 'Ζ');
|
||||
str = str.replace(/Η/g, 'Η');
|
||||
str = str.replace(/Θ/g, 'Θ');
|
||||
str = str.replace(/Ι/g, 'Ι');
|
||||
str = str.replace(/Κ/g, 'Κ');
|
||||
str = str.replace(/Λ/g, 'Λ');
|
||||
str = str.replace(/Μ/g, 'Μ');
|
||||
str = str.replace(/Ν/g, 'Ν');
|
||||
str = str.replace(/Ξ/g, 'Ν');
|
||||
str = str.replace(/Ο/g, 'Ο');
|
||||
str = str.replace(/Π/g, 'Π');
|
||||
str = str.replace(/Ρ/g, 'Ρ');
|
||||
str = str.replace(/Σ/g, 'Σ');
|
||||
str = str.replace(/Τ/g, 'Τ');
|
||||
str = str.replace(/Υ/g, 'Υ');
|
||||
str = str.replace(/Φ/g, 'Φ');
|
||||
str = str.replace(/Χ/g, 'Χ');
|
||||
str = str.replace(/Ψ/g, 'Ψ');
|
||||
str = str.replace(/Ω/g, 'Ω');
|
||||
|
||||
str = str.replace(/α/g, 'α');
|
||||
str = str.replace(/β/g, 'β');
|
||||
str = str.replace(/γ/g, 'γ');
|
||||
str = str.replace(/δ/g, 'δ');
|
||||
str = str.replace(/ε/g, 'ε');
|
||||
str = str.replace(/ζ/g, 'ζ');
|
||||
str = str.replace(/η/g, 'η');
|
||||
str = str.replace(/θ/g, 'θ');
|
||||
str = str.replace(/ι/g, 'ι');
|
||||
str = str.replace(/κ/g, 'κ');
|
||||
str = str.replace(/λ/g, 'λ');
|
||||
str = str.replace(/μ/g, 'μ');
|
||||
str = str.replace(/ν/g, 'ν');
|
||||
str = str.replace(/ξ/g, 'ξ');
|
||||
str = str.replace(/ο/g, 'ο');
|
||||
str = str.replace(/π/g, 'π');
|
||||
str = str.replace(/ρ/g, 'ρ');
|
||||
str = str.replace(/ς/g, 'ς');
|
||||
str = str.replace(/σ/g, 'σ');
|
||||
str = str.replace(/τ/g, 'τ');
|
||||
str = str.replace(/υ/g, 'υ');
|
||||
str = str.replace(/φ/g, 'φ');
|
||||
str = str.replace(/χ/g, 'χ');
|
||||
str = str.replace(/ψ/g, 'ψ');
|
||||
str = str.replace(/ω/g, 'ω');
|
||||
str = str.replace(/ϑ/g, 'ϑ');
|
||||
str = str.replace(/ϒ/g, 'ϒ');
|
||||
str = str.replace(/ϖ/g, 'ϖ');
|
||||
str = str.replace(/·/g, '·');
|
||||
return str;
|
||||
}
|
||||
|
||||
function strcharacterDiscode(str) {
|
||||
// 加入常用解析
|
||||
|
||||
str = str.replace(/ /g, "<span class='spaceshow'> </span>");
|
||||
str = str.replace(/ /g, ' ');
|
||||
str = str.replace(/ /g, ' ');
|
||||
str = str.replace(/"/g, "'");
|
||||
str = str.replace(/&/g, '&');
|
||||
str = str.replace(/</g, '<');
|
||||
str = str.replace(/>/g, '>');
|
||||
str = str.replace(/•/g, '•');
|
||||
return str;
|
||||
}
|
||||
|
||||
// HTML 支持的其他实体
|
||||
function strOtherDiscode(str) {
|
||||
str = str.replace(/Œ/g, 'Œ');
|
||||
str = str.replace(/œ/g, 'œ');
|
||||
str = str.replace(/Š/g, 'Š');
|
||||
str = str.replace(/š/g, 'š');
|
||||
str = str.replace(/Ÿ/g, 'Ÿ');
|
||||
str = str.replace(/ƒ/g, 'ƒ');
|
||||
str = str.replace(/ˆ/g, 'ˆ');
|
||||
str = str.replace(/˜/g, '˜');
|
||||
str = str.replace(/ /g, '');
|
||||
str = str.replace(/ /g, '');
|
||||
str = str.replace(/ /g, '');
|
||||
str = str.replace(/‌/g, '');
|
||||
str = str.replace(/‍/g, '');
|
||||
str = str.replace(/‎/g, '');
|
||||
str = str.replace(/‏/g, '');
|
||||
str = str.replace(/–/g, '–');
|
||||
str = str.replace(/—/g, '—');
|
||||
str = str.replace(/‘/g, '‘');
|
||||
str = str.replace(/’/g, '’');
|
||||
str = str.replace(/‚/g, '‚');
|
||||
str = str.replace(/“/g, '“');
|
||||
str = str.replace(/”/g, '”');
|
||||
str = str.replace(/„/g, '„');
|
||||
str = str.replace(/†/g, '†');
|
||||
str = str.replace(/‡/g, '‡');
|
||||
str = str.replace(/•/g, '•');
|
||||
str = str.replace(/…/g, '…');
|
||||
str = str.replace(/‰/g, '‰');
|
||||
str = str.replace(/′/g, '′');
|
||||
str = str.replace(/″/g, '″');
|
||||
str = str.replace(/‹/g, '‹');
|
||||
str = str.replace(/›/g, '›');
|
||||
str = str.replace(/‾/g, '‾');
|
||||
str = str.replace(/€/g, '€');
|
||||
str = str.replace(/™/g, '™');
|
||||
|
||||
str = str.replace(/←/g, '←');
|
||||
str = str.replace(/↑/g, '↑');
|
||||
str = str.replace(/→/g, '→');
|
||||
str = str.replace(/↓/g, '↓');
|
||||
str = str.replace(/↔/g, '↔');
|
||||
str = str.replace(/↵/g, '↵');
|
||||
str = str.replace(/⌈/g, '⌈');
|
||||
str = str.replace(/⌉/g, '⌉');
|
||||
|
||||
str = str.replace(/⌊/g, '⌊');
|
||||
str = str.replace(/⌋/g, '⌋');
|
||||
str = str.replace(/◊/g, '◊');
|
||||
str = str.replace(/♠/g, '♠');
|
||||
str = str.replace(/♣/g, '♣');
|
||||
str = str.replace(/♥/g, '♥');
|
||||
|
||||
str = str.replace(/♦/g, '♦');
|
||||
str = str.replace(/'/g, "'");
|
||||
return str;
|
||||
}
|
||||
|
||||
function strDiscode(str) {
|
||||
str = strNumDiscode(str);
|
||||
str = strGreeceDiscode(str);
|
||||
str = strcharacterDiscode(str);
|
||||
str = strOtherDiscode(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
function urlToHttpUrl(url, domain) {
|
||||
if (/^\/\//.test(url)) {
|
||||
return `https:${url}`;
|
||||
} else if (/^\//.test(url)) {
|
||||
return `https://${domain}${url}`;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
export default {
|
||||
strDiscode,
|
||||
urlToHttpUrl,
|
||||
};
|
||||
248
mallplusui-uniapp-app/components/gaoyia-parse/parse.css
Normal file
248
mallplusui-uniapp-app/components/gaoyia-parse/parse.css
Normal file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* author: Di (微信小程序开发工程师)
|
||||
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
|
||||
* 垂直微信小程序开发交流社区
|
||||
*
|
||||
* github地址: https://github.com/icindy/wxParse
|
||||
*
|
||||
* for: 微信小程序富文本解析
|
||||
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
|
||||
*/
|
||||
/**
|
||||
* 请在全局下引入该文件,@import '/static/wxParse.css';
|
||||
*/
|
||||
.wxParse {
|
||||
user-select:none;
|
||||
width: 100%;
|
||||
font-family: Helvetica, "PingFangSC", 'Microsoft Yahei', '微软雅黑', Arial, sans-serif;
|
||||
color: #333;
|
||||
line-height: 1.5;
|
||||
font-size: 1em;
|
||||
text-align:justify;/* //左右两端对齐 */
|
||||
}
|
||||
.wxParse view ,.wxParse uni-view{
|
||||
word-break: break-word;
|
||||
}
|
||||
.wxParse .p {
|
||||
padding-bottom: 0;
|
||||
clear: both;
|
||||
/* letter-spacing: 0;//字间距 */
|
||||
}
|
||||
.wxParse .inline {
|
||||
display: inline;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.wxParse .div {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.wxParse .h1{
|
||||
font-size: 2em;
|
||||
line-height: 1.2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
.wxParse .h2{
|
||||
font-size: 1.5em;
|
||||
margin: 0.83em 0;
|
||||
}
|
||||
.wxParse .h3{
|
||||
font-size: 1.17em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
.wxParse .h4{
|
||||
margin: 1.33em 0;
|
||||
}
|
||||
.wxParse .h5{
|
||||
font-size: 0.83em;
|
||||
margin: 1.67em 0;
|
||||
}
|
||||
.wxParse .h6{
|
||||
font-size: 0.83em;
|
||||
margin: 1.67em 0;
|
||||
}
|
||||
|
||||
.wxParse .h1,
|
||||
.wxParse .h2,
|
||||
.wxParse .h3,
|
||||
.wxParse .h4,
|
||||
.wxParse .h5,
|
||||
.wxParse .h6,
|
||||
.wxParse .b,
|
||||
.wxParse .strong{
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.wxParse .i,
|
||||
.wxParse .cite,
|
||||
.wxParse .em,
|
||||
.wxParse .var,
|
||||
.wxParse .address {
|
||||
font-style: italic;
|
||||
}
|
||||
.wxParse .spaceshow{
|
||||
white-space: pre;
|
||||
}
|
||||
.wxParse .pre,
|
||||
.wxParse .tt,
|
||||
.wxParse .code,
|
||||
.wxParse .kbd,
|
||||
.wxParse .samp {
|
||||
font-family: monospace;
|
||||
}
|
||||
.wxParse .pre {
|
||||
overflow: auto;
|
||||
background: #f5f5f5;
|
||||
padding: 16upx;
|
||||
white-space: pre;
|
||||
margin: 1em 0upx;
|
||||
font-size: 24upx;
|
||||
}
|
||||
.wxParse .code {
|
||||
overflow: auto;
|
||||
padding: 16upx;
|
||||
white-space: pre;
|
||||
margin: 1em 0upx;
|
||||
background: #f5f5f5;
|
||||
font-size: 24upx;
|
||||
}
|
||||
|
||||
.wxParse .big {
|
||||
font-size: 1.17em;
|
||||
}
|
||||
|
||||
.wxParse .small,
|
||||
.wxParse .sub,
|
||||
.wxParse .sup {
|
||||
font-size: 0.83em;
|
||||
}
|
||||
|
||||
.wxParse .sub {
|
||||
vertical-align: sub;
|
||||
}
|
||||
.wxParse .sup {
|
||||
vertical-align: super;
|
||||
}
|
||||
|
||||
.wxParse .s,
|
||||
.wxParse .strike,
|
||||
.wxParse .del {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.wxParse .strong,
|
||||
.wxParse .s {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.wxParse .a {
|
||||
color: deepskyblue;
|
||||
}
|
||||
|
||||
.wxParse .video {
|
||||
text-align: center;
|
||||
margin: 22upx 0;
|
||||
}
|
||||
|
||||
.wxParse .video-video {
|
||||
width: 100%;
|
||||
}
|
||||
.wxParse .uni-image{
|
||||
max-width: 100%;
|
||||
}
|
||||
.wxParse .img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
margin-bottom: 0em;/* //与p标签底部padding同时修改 */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.wxParse .blockquote {
|
||||
margin: 10upx 0;
|
||||
padding: 22upx 0 22upx 22upx;
|
||||
font-family: Courier, Calibri, "宋体";
|
||||
background: #f5f5f5;
|
||||
border-left: 6upx solid #dbdbdb;
|
||||
}
|
||||
.wxParse .blockquote .p {
|
||||
margin: 0;
|
||||
}
|
||||
.wxParse .ul, .wxParse .ol {
|
||||
display: block;
|
||||
margin: 1em 0;
|
||||
padding-left: 2em;
|
||||
}
|
||||
.wxParse .ol {
|
||||
list-style-type: disc;
|
||||
}
|
||||
.wxParse .ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
.wxParse .ol>weixin-parse-template,.wxParse .ul>weixin-parse-template {
|
||||
display: list-item;
|
||||
align-items: baseline;
|
||||
text-align: match-parent;
|
||||
}
|
||||
|
||||
.wxParse .ol>.li,.wxParse .ul>.li {
|
||||
display: list-item;
|
||||
align-items: baseline;
|
||||
text-align: match-parent;
|
||||
}
|
||||
.wxParse .ul .ul, .wxParse .ol .ul {
|
||||
list-style-type: circle;
|
||||
}
|
||||
.wxParse .ol .ol .ul, .wxParse .ol .ul .ul, .wxParse .ul .ol .ul, .wxParse .ul .ul .ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
.wxParse .u {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.wxParse .hide {
|
||||
display: none;
|
||||
}
|
||||
.wxParse .del {
|
||||
display: inline;
|
||||
}
|
||||
.wxParse .figure {
|
||||
overflow: hidden;
|
||||
}
|
||||
.wxParse .table .table{
|
||||
border-collapse:collapse;
|
||||
box-sizing: border-box;
|
||||
/* 内边框 */
|
||||
border: 1px solid #dadada;
|
||||
width: 100%;
|
||||
}
|
||||
.wxParse .tbody{
|
||||
border-collapse:collapse;
|
||||
box-sizing: border-box;
|
||||
/* 内边框 */
|
||||
border: 1px solid #dadada;
|
||||
}
|
||||
.wxParse .thead, .wxParse .tfoot, .wxParse .th{
|
||||
border-collapse:collapse;
|
||||
box-sizing: border-box;
|
||||
background: #ececec;
|
||||
font-weight: 40;
|
||||
}
|
||||
.wxParse .tr {
|
||||
border-collapse:collapse;
|
||||
box-sizing: border-box;
|
||||
/* border: 2px solid #F0AD4E; */
|
||||
overflow:auto;
|
||||
}
|
||||
.wxParse .th,
|
||||
.wxParse .td{
|
||||
border-collapse:collapse;
|
||||
box-sizing: border-box;
|
||||
border: 2upx solid #dadada;
|
||||
overflow:auto;
|
||||
}
|
||||
.wxParse .audio, .wxParse .uni-audio-default{
|
||||
display: block;
|
||||
}
|
||||
223
mallplusui-uniapp-app/components/gaoyia-parse/parse.vue
Normal file
223
mallplusui-uniapp-app/components/gaoyia-parse/parse.vue
Normal file
@@ -0,0 +1,223 @@
|
||||
<!--**
|
||||
* forked from:https://github.com/F-loat/mpvue-wxParse
|
||||
*
|
||||
* github地址: https://github.com/dcloudio/uParse
|
||||
*
|
||||
* for: uni-app框架下 富文本解析
|
||||
*
|
||||
* 优化 by gaoyia@qq.com https://github.com/gaoyia/parse
|
||||
*/-->
|
||||
|
||||
<template>
|
||||
|
||||
<!--基础元素-->
|
||||
<div class="wxParse" :class="className" :style="'user-select:' + userSelect">
|
||||
<block v-for="(node, index) of nodes" :key="index" v-if="!loading">
|
||||
<wxParseTemplate :node="node" />
|
||||
</block>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HtmlToJson from './libs/html2json';
|
||||
import wxParseTemplate from './components/wxParseTemplate0';
|
||||
|
||||
export default {
|
||||
name: 'wxParse',
|
||||
props: {
|
||||
// user-select:none;
|
||||
userSelect: {
|
||||
type: String,
|
||||
default: 'text' //none |text| all | element
|
||||
},
|
||||
imgOptions: {
|
||||
type: [Object, Boolean],
|
||||
default: function() {
|
||||
return {
|
||||
loop: false,
|
||||
indicator: 'number',
|
||||
longPressActions: false
|
||||
// longPressActions: {
|
||||
// itemList: ['发送给朋友', '保存图片', '收藏'],
|
||||
// success: function (res) {
|
||||
// console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
|
||||
// },
|
||||
// fail: function (res) {
|
||||
// console.log(res.errMsg);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
noData: {
|
||||
type: String,
|
||||
default: '<div style="color: red;">数据不能为空</div>'
|
||||
},
|
||||
startHandler: {
|
||||
type: Function,
|
||||
default () {
|
||||
return node => {
|
||||
node.attr.class = null;
|
||||
node.attr.style = null;
|
||||
};
|
||||
}
|
||||
},
|
||||
endHandler: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
charsHandler: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
imageProp: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {
|
||||
mode: 'aspectFit',
|
||||
padding: 0,
|
||||
lazyLoad: false,
|
||||
domain: ''
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
wxParseTemplate
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nodes: {},
|
||||
imageUrls: [],
|
||||
wxParseWidth: {
|
||||
value: 0
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
mounted() {
|
||||
let that = this
|
||||
this.getWidth().then(function(data) {
|
||||
that.wxParseWidth.value = data;
|
||||
})
|
||||
this.setHtml()
|
||||
},
|
||||
methods: {
|
||||
setHtml() {
|
||||
// this.getWidth().then((data) => {
|
||||
// this.wxParseWidth.value = data;
|
||||
// })
|
||||
let {
|
||||
content,
|
||||
noData,
|
||||
imageProp,
|
||||
startHandler,
|
||||
endHandler,
|
||||
charsHandler
|
||||
} = this;
|
||||
let parseData = content || noData;
|
||||
let customHandler = {
|
||||
start: startHandler,
|
||||
end: endHandler,
|
||||
chars: charsHandler
|
||||
};
|
||||
let results = HtmlToJson(parseData, customHandler, imageProp, this);
|
||||
this.imageUrls = results.imageUrls;
|
||||
// this.nodes = results.nodes;
|
||||
this.nodes = [];
|
||||
results.nodes.forEach((item) => {
|
||||
setTimeout(() => {
|
||||
this.nodes.push(item)
|
||||
}, 0);
|
||||
})
|
||||
},
|
||||
getWidth() {
|
||||
return new Promise((res, rej) => {
|
||||
// #ifndef MP-ALIPAY || MP-BAIDU
|
||||
uni.createSelectorQuery()
|
||||
.in(this)
|
||||
.select('.wxParse')
|
||||
.fields({
|
||||
size: true,
|
||||
scrollOffset: true
|
||||
},
|
||||
data => {
|
||||
res(data.width);
|
||||
}
|
||||
).exec();
|
||||
// #endif
|
||||
// #ifdef MP-BAIDU
|
||||
swan.createSelectorQuery().select('.wxParse').boundingClientRect(function(rect) {
|
||||
rect[0].width
|
||||
}).exec()
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
my.createSelectorQuery()
|
||||
.select('.wxParse')
|
||||
.boundingClientRect().exec((ret) => {
|
||||
res(ret[0].width);
|
||||
});
|
||||
// #endif
|
||||
});
|
||||
},
|
||||
navigate(href, $event, attr) {
|
||||
console.log(href, attr);
|
||||
this.$emit('navigate', href, $event);
|
||||
},
|
||||
preview(src, $event) {
|
||||
if (!this.imageUrls.length || typeof this.imgOptions === 'boolean') {
|
||||
|
||||
} else {
|
||||
uni.previewImage({
|
||||
current: src,
|
||||
urls: this.imageUrls,
|
||||
loop: this.imgOptions.loop,
|
||||
indicator: this.imgOptions.indicator,
|
||||
longPressActions: this.imgOptions.longPressActions
|
||||
});
|
||||
}
|
||||
this.$emit('preview', src, $event);
|
||||
},
|
||||
removeImageUrl(src) {
|
||||
const {
|
||||
imageUrls
|
||||
} = this;
|
||||
imageUrls.splice(imageUrls.indexOf(src), 1);
|
||||
}
|
||||
},
|
||||
// 父组件中提供
|
||||
provide() {
|
||||
return {
|
||||
parseWidth: this.wxParseWidth,
|
||||
parseSelect: this.userSelect
|
||||
// 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
content(){
|
||||
this.setHtml()
|
||||
}
|
||||
// content: {
|
||||
// handler: function(newVal, oldVal) {
|
||||
// if (newVal !== oldVal) {
|
||||
//
|
||||
// }
|
||||
// },
|
||||
// deep: true
|
||||
// }
|
||||
}
|
||||
};
|
||||
</script>
|
||||
50
mallplusui-uniapp-app/components/jihai-lable.vue
Normal file
50
mallplusui-uniapp-app/components/jihai-lable.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<view>
|
||||
<radio-group class="uni-list" @change="radioChange">
|
||||
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in type_list" :key="index">
|
||||
<view class="invoice-type-icon">
|
||||
<radio class="a-radio" :id="item.name" :value="item.value" :checked="item.checked" :disabled="item.disabled"></radio>
|
||||
</view>
|
||||
<view class="invoice-type-c">
|
||||
<label class="label-2-text" :for="item.name">
|
||||
<text>{{item.name}}</text>
|
||||
</label>
|
||||
</view>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
type_list: [
|
||||
{ value: '1', name: '仅退款', checked: true, disabled: false },
|
||||
{ value: '2', name: '退货退款', checked: false, disabled:false },
|
||||
],
|
||||
};
|
||||
},
|
||||
methods:{
|
||||
radioChange: function(evt) {
|
||||
this.type_list.forEach(item => {
|
||||
if (item.value === evt.target.value) {
|
||||
item.checked = true;
|
||||
this.aftersale_type = evt.target.value;
|
||||
}else{
|
||||
item.checked = false;
|
||||
}
|
||||
});
|
||||
if(this.type_list[0].checked){
|
||||
this.refund_input_noedit = true;
|
||||
}else{
|
||||
this.refund_input_noedit = false;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
BIN
mallplusui-uniapp-app/components/jshop/image/trumpet.png
Normal file
BIN
mallplusui-uniapp-app/components/jshop/image/trumpet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
mallplusui-uniapp-app/components/jshop/image/zoom.png
Normal file
BIN
mallplusui-uniapp-app/components/jshop/image/zoom.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
192
mallplusui-uniapp-app/components/jshop/jshop-adpop.vue
Normal file
192
mallplusui-uniapp-app/components/jshop/jshop-adpop.vue
Normal file
@@ -0,0 +1,192 @@
|
||||
<template>
|
||||
<!-- 单图 -->
|
||||
<view class="jshop-adpop" v-if="jdata.options.colorGroup && jdata.options.colorGroup.length > 0">
|
||||
<view class="adpop" v-if="closeAd">
|
||||
<view class="adpop-c">
|
||||
<view class="adpop-img">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view @click="navToTabPage(jdata.options.colorGroup[0].adLink)">
|
||||
<image class="ad-img" :src="jdata.options.colorGroup[0].adImg" mode="widthFix" ></image>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<image class="ad-img" :src="jdata.options.colorGroup[0].adImg" mode="widthFix" @click="navToTabPage(jdata.options.colorGroup[0].adLink)"></image>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<image class="close-btn" src="/static/image/close-pink.png" mode="" @click="closePop"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshopadpop",
|
||||
props: {
|
||||
jdata: {
|
||||
// type: Object,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
closeAd: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
// console.log(jdata)
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
|
||||
},
|
||||
methods: {
|
||||
closePop(){
|
||||
this.closeAd = false
|
||||
},
|
||||
navToTabPage(url) {
|
||||
uni.navigateTo({
|
||||
url: url
|
||||
});
|
||||
},
|
||||
showSliderInfo(type, val) {
|
||||
console.log(type);
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
if (type == 1) {
|
||||
if (val.indexOf('http') != -1) {
|
||||
// #ifdef H5
|
||||
window.location.href = val
|
||||
// #endif
|
||||
} else {
|
||||
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
|
||||
if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
|
||||
uni.switchTab({
|
||||
url: val
|
||||
});
|
||||
return;
|
||||
} else if(val.indexOf('/pages/coupon/coupon')>-1){
|
||||
var id = val.replace('/pages/coupon/coupon?id=',"");
|
||||
this.receiveCoupon(id)
|
||||
} else {
|
||||
this.$common.navigateTo(val);
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
} else if (type == 2) {
|
||||
// 商品详情
|
||||
this.goodsDetail(val)
|
||||
} else if (type == 3) {
|
||||
// 文章详情
|
||||
this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
|
||||
} else if (type == 4) {
|
||||
// 文章列表
|
||||
this.$common.navigateTo('/pages/article/list?cid=' + val)
|
||||
} else if (type == 5) {
|
||||
//智能表单
|
||||
this.$common.navigateTo('/pages/form/detail/form?id=' + val)
|
||||
}
|
||||
},
|
||||
//跳转到商品详情页面
|
||||
goodsDetail: function(id) {
|
||||
// let ins = encodeURIComponent('id='+id);
|
||||
let url = '/pages/goods/index/index?id=' + id;
|
||||
this.$common.navigateTo(url);
|
||||
},
|
||||
// 用户领取优惠券
|
||||
receiveCoupon(couponId) {
|
||||
let data = {
|
||||
promotion_id: couponId
|
||||
}
|
||||
this.$api.getCoupon(data, res => {
|
||||
if (res.status) {
|
||||
this.$common.successToShow(res.msg)
|
||||
} else {
|
||||
this.$common.errorToShow(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
// #ifdef MP-WEIXIN
|
||||
showSliderInfo2:function(e){
|
||||
let type = e.currentTarget.dataset.type;
|
||||
let val = e.currentTarget.dataset.val;
|
||||
console.log(type);
|
||||
console.log(val)
|
||||
console.log(type);
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
if (type == 1) {
|
||||
if (val.indexOf('http') != -1) {
|
||||
// #ifdef H5
|
||||
window.location.href = val
|
||||
// #endif
|
||||
} else {
|
||||
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
|
||||
if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
|
||||
uni.switchTab({
|
||||
url: val
|
||||
});
|
||||
return;
|
||||
} else if(val.indexOf('/pages/coupon/coupon')>-1){
|
||||
var id = val.replace('/pages/coupon/coupon?id=',"");
|
||||
this.receiveCoupon(id)
|
||||
} else {
|
||||
this.$common.navigateTo(val);
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
} else if (type == 2) {
|
||||
// 商品详情
|
||||
this.goodsDetail(val)
|
||||
} else if (type == 3) {
|
||||
// 文章详情
|
||||
this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
|
||||
} else if (type == 4) {
|
||||
// 文章列表
|
||||
this.$common.navigateTo('/pages/article/list?cid=' + val)
|
||||
} else if (type == 5) {
|
||||
//智能表单
|
||||
this.$common.navigateTo('/pages/form/detail/form?id=' + val)
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.adpop{
|
||||
position: fixed;
|
||||
background: rgba(0,0,0,.5);
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
z-index: 999;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.adpop-c{
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
width: 70%;
|
||||
text-align: center;
|
||||
}
|
||||
.adpop-img{
|
||||
width: 100%;
|
||||
max-height: 1000rpx;
|
||||
margin-bottom: 50rpx;
|
||||
}
|
||||
.ad-img{
|
||||
width: 100%;
|
||||
max-height: 1000rpx;
|
||||
}
|
||||
.close-btn{
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
</style>
|
||||
82
mallplusui-uniapp-app/components/jshop/jshop-article.vue
Normal file
82
mallplusui-uniapp-app/components/jshop/jshop-article.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<view class='index-article cell-group bottom-cell-group' v-if="jdata.options.colorGroup && count">
|
||||
<view class='cell-item'
|
||||
v-for="item in jdata.options.colorGroup"
|
||||
:key="item.id"
|
||||
@click="articleDetail(item.id)"
|
||||
>
|
||||
|
||||
<view class="cell-item-bd">
|
||||
<view class="article-title ">
|
||||
{{ item.title }}
|
||||
</view>
|
||||
<view class="article-time">
|
||||
{{ item.ctime }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="cell-title-img">
|
||||
<image :src="item.cover" mode="aspectFill"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshoparticle",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 查看文章详情
|
||||
articleDetail (articleId) {
|
||||
this.$common.navigateTo('/pages/article/index?id=' + articleId+'&id_type=1')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.index-article .cell-title-img{
|
||||
width: 160upx;
|
||||
height: 160upx;
|
||||
float: right;
|
||||
}
|
||||
.index-article .cell-title-img image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.index-article .cell-item-bd{
|
||||
padding-right: 0;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
}
|
||||
.index-article .article-title{
|
||||
font-size: 28upx;
|
||||
color: #333;
|
||||
width: 100%;
|
||||
min-height: 80upx;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
.index-article .article-time{
|
||||
font-size: 24upx;
|
||||
color: #999;
|
||||
display: inline-block;
|
||||
min-width: 220upx;
|
||||
min-height: 32upx;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<view class='index-article cell-group bottom-cell-group' v-if="jdata.options.colorGroup && count">
|
||||
<view class='cell-item'
|
||||
v-for="item in jdata.options.colorGroup"
|
||||
:key="item.id"
|
||||
@click="articleDetail(item.id)"
|
||||
>
|
||||
<view class="cell-item-bd">
|
||||
<view class="article-title ">
|
||||
{{ item.title }}
|
||||
</view>
|
||||
<view class="article-time">
|
||||
{{ item.ctime }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="cell-title-img">
|
||||
<image :src="item.cover" mode="aspectFill"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshoparticleclassify",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 查看文章详情
|
||||
articleDetail (articleId) {
|
||||
this.$common.navigateTo('/pages/article/index?id=' + articleId+'&id_type=1')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.index-article .cell-title-img{
|
||||
width: 160upx;
|
||||
height: 160upx;
|
||||
float: right;
|
||||
}
|
||||
.index-article .cell-title-img image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.index-article .cell-item-bd{
|
||||
padding-right: 0;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
}
|
||||
.index-article .article-title{
|
||||
font-size: 28upx;
|
||||
color: #333;
|
||||
width: 100%;
|
||||
min-height: 80upx;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
.index-article .article-time{
|
||||
font-size: 24upx;
|
||||
color: #999;
|
||||
display: inline-block;
|
||||
min-width: 220upx;
|
||||
min-height: 32upx;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
21
mallplusui-uniapp-app/components/jshop/jshop-blank.vue
Normal file
21
mallplusui-uniapp-app/components/jshop/jshop-blank.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<view class="blank" :style="{background:jdata.options.search_bg,height:jdata.options.udPadding*2+'rpx'}"></view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshopblank",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
27
mallplusui-uniapp-app/components/jshop/jshop-content.vue
Normal file
27
mallplusui-uniapp-app/components/jshop/jshop-content.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<u-parse :content="content" @preview="preview" @navigate="navigate" style="background-color: #fff;"/>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
//视频和文本解析组件
|
||||
import uParse from '@/components/gaoyia-parse/parse.vue'
|
||||
export default {
|
||||
name: 'jshop-content',
|
||||
components: {
|
||||
uParse
|
||||
},
|
||||
props: {
|
||||
content: {}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
preview(src, e) {
|
||||
// do something
|
||||
},
|
||||
navigate(href, e) {
|
||||
// do something
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
101
mallplusui-uniapp-app/components/jshop/jshop-coupon.vue
Normal file
101
mallplusui-uniapp-app/components/jshop/jshop-coupon.vue
Normal file
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<view class="coupon bottom-cell-group" v-if="count">
|
||||
<view class="coupon-item" v-for="item in jdata.options.colorGroup" :key="item.id" @click="receiveCoupon(item.id)">
|
||||
<view class="coupon-i-l">
|
||||
<view class="coupon-i-l-t">
|
||||
<image class="icon" src="/static/image/element-ic.png" mode=""></image>
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
<view class="coupon-i-l-b">
|
||||
{{ item.expression1 + item.expression2 }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="coupon-i-r">
|
||||
<image class="coupon-logo" src="/static/image/coupon-element.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshopcoupon",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 用户领取优惠券
|
||||
receiveCoupon(couponId) {
|
||||
let jdata = {
|
||||
promotion_id: couponId
|
||||
}
|
||||
this.$api.getCoupon(jdata, res => {
|
||||
if (res.status) {
|
||||
this.$common.successToShow(res.msg)
|
||||
} else {
|
||||
this.$common.errorToShow(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.coupon {
|
||||
padding: 0 26upx;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.coupon-item {
|
||||
padding: 20upx;
|
||||
margin-bottom: 20upx;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.coupon-i-l {
|
||||
width: 400upx;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.coupon-i-l-t {
|
||||
font-size: 32upx;
|
||||
position: relative;
|
||||
margin-bottom: 10upx;
|
||||
}
|
||||
|
||||
.coupon-i-l-t .icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.coupon-i-l-t text {
|
||||
margin-left: 60upx;
|
||||
}
|
||||
|
||||
.coupon-i-l-b {
|
||||
font-size: 24upx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.coupon-i-r {
|
||||
width: 258upx;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.coupon-logo {
|
||||
width: 130upx;
|
||||
height: 100upx;
|
||||
}
|
||||
|
||||
</style>
|
||||
604
mallplusui-uniapp-app/components/jshop/jshop-goods.vue
Normal file
604
mallplusui-uniapp-app/components/jshop/jshop-goods.vue
Normal file
@@ -0,0 +1,604 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
|
||||
<!-- 新品上市 -->
|
||||
<view class="f-header m-t" @click="navToTabPage('../../pagesA/product/list')">
|
||||
<image src="/static/temp/h1.png" ></image>
|
||||
<view class="tit-box">
|
||||
<text class="tit">新品上市</text>
|
||||
<text class="tit2">Guess You Like It</text>
|
||||
</view>
|
||||
<text class="yticon icon-you"></text>
|
||||
</view>
|
||||
|
||||
<view class="guess-section">
|
||||
<view v-for="(item, index) in jdata.options.colorGroup" :key="index" class="guess-item" @click="goodsDetail(item.id)">
|
||||
<view class="image-wrapper"><image :src="item.pic" mode="aspectFill"></image></view>
|
||||
<text class="title clamp">{{ item.title }}</text>
|
||||
<text class="price">¥{{ item.price }}</text>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {goods} from '@/config/mixins.js'
|
||||
export default {
|
||||
filters:{
|
||||
substr(val) {
|
||||
if (val.length == 0 || val == undefined) {
|
||||
return false;
|
||||
} else if (val.length > 13) {
|
||||
return val.substring(0, 13) + "...";
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
},
|
||||
mixins: [goods],
|
||||
name: "jshopgoods",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
navToTabPage(url) {
|
||||
uni.navigateTo({
|
||||
url: url
|
||||
});
|
||||
},
|
||||
//跳转到商品详情页面
|
||||
goodsDetail: function(id) {
|
||||
let url = '../../pagesA/product/product?id=' + id;
|
||||
|
||||
this.$common.navigateTo(url);
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.MP-search{
|
||||
background: #FFFFFF;height: 80upx;display: flex;justify-content: center;align-items: center;position: fixed;width: 100%;z-index: 999;
|
||||
}
|
||||
.MP-search-input{
|
||||
font-size: 28upx;background: #F5F5F5;height: 60upx;width: 90%;border-radius: 50upx;text-align: center;
|
||||
}
|
||||
.mp-search-box {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 30upx;
|
||||
z-index: 9999;
|
||||
width: 100%;
|
||||
padding: 0 80upx;
|
||||
.ser-input {
|
||||
flex: 1;
|
||||
height: 60upx;
|
||||
line-height: 60upx;
|
||||
text-align: center;
|
||||
font-size: 28upx;
|
||||
color: $font-color-base;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
page {
|
||||
.cate-section {
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
border-radius: 16upx 16upx 0 0;
|
||||
margin-top: -20upx;
|
||||
}
|
||||
.carousel-section {
|
||||
padding: 0;
|
||||
.titleNview-placing {
|
||||
padding-top: 0;
|
||||
height: 0;
|
||||
}
|
||||
.carousel {
|
||||
.carousel-item {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.swiper-dots {
|
||||
left: 45upx;
|
||||
bottom: 40upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
page {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.m-t {
|
||||
margin-top: 20upx;
|
||||
}
|
||||
/* 头部 轮播图 */
|
||||
.carousel-section {
|
||||
position: relative;
|
||||
padding-top: 10px;
|
||||
|
||||
.titleNview-placing {
|
||||
height: var(--status-bar-height);
|
||||
padding-top: 44px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.titleNview-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 426upx;
|
||||
transition: 0.4s;
|
||||
}
|
||||
}
|
||||
.carousel {
|
||||
width: 100%;
|
||||
height: 350upx;
|
||||
|
||||
.carousel-item {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 28upx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 10upx;
|
||||
}
|
||||
}
|
||||
.swiper-dots {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
left: 60upx;
|
||||
bottom: 15upx;
|
||||
width: 72upx;
|
||||
height: 36upx;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTk4MzlBNjE0NjU1MTFFOUExNjRFQ0I3RTQ0NEExQjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTk4MzlBNjA0NjU1MTFFOUExNjRFQ0I3RTQ0NEExQjMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6Q0E3RUNERkE0NjExMTFFOTg5NzI4MTM2Rjg0OUQwOEUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6Q0E3RUNERkI0NjExMTFFOTg5NzI4MTM2Rjg0OUQwOEUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4Gh5BPAAACTUlEQVR42uzcQW7jQAwFUdN306l1uWwNww5kqdsmm6/2MwtVCp8CosQtP9vg/2+/gY+DRAMBgqnjIp2PaCxCLLldpPARRIiFj1yBbMV+cHZh9PURRLQNhY8kgWyL/WDtwujjI8hoE8rKLqb5CDJaRMJHokC6yKgSCR9JAukmokIknCQJpLOIrJFwMsBJELFcKHwM9BFkLBMKFxNcBCHlQ+FhoocgpVwwnv0Xn30QBJGMC0QcaBVJiAMiec/dcwKuL4j1QMsVCXFAJE4s4NQA3K/8Y6DzO4g40P7UcmIBJxbEesCKWBDg8wWxHrAiFgT4fEGsB/CwIhYE+AeBAAdPLOcV8HRmWRDAiQVcO7GcV8CLM8uCAE4sQCDAlHcQ7x+ABQEEAggEEAggEEAggEAAgQACASAQQCCAQACBAAIBBAIIBBAIIBBAIABe4e9iAe/xd7EAJxYgEGDeO4j3EODp/cOCAE4sYMyJ5cwCHs4rCwI4sYBxJ5YzC84rCwKcXxArAuthQYDzC2JF0H49LAhwYUGsCFqvx5EF2T07dMaJBetx4cRyaqFtHJ8EIhK0i8OJBQxcECuCVutxJhCRoE0cZwMRyRcFefa/ffZBVPogePihhyCnbBhcfMFFEFM+DD4m+ghSlgmDkwlOgpAl4+BkkJMgZdk4+EgaSCcpVX7bmY9kgXQQU+1TgE0c+QJZUUz1b2T4SBbIKmJW+3iMj2SBVBWz+leVfCQLpIqYbp8b85EskIxyfIOfK5Sf+wiCRJEsllQ+oqEkQfBxmD8BBgA5hVjXyrBNUQAAAABJRU5ErkJggg==);
|
||||
background-size: 100% 100%;
|
||||
|
||||
.num {
|
||||
width: 36upx;
|
||||
height: 36upx;
|
||||
border-radius: 50px;
|
||||
font-size: 24upx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 36upx;
|
||||
}
|
||||
|
||||
.sign {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
line-height: 36upx;
|
||||
font-size: 12upx;
|
||||
color: #fff;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
/* 分类 */
|
||||
.cate-section {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
padding: 30upx 22upx;
|
||||
background: #fff;
|
||||
.cate-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
}
|
||||
/* 原图标颜色太深,不想改图了,所以加了透明度 */
|
||||
image {
|
||||
width: 88upx;
|
||||
height: 88upx;
|
||||
margin-bottom: 14upx;
|
||||
border-radius: 50%;
|
||||
opacity: 0.7;
|
||||
box-shadow: 4upx 4upx 20upx rgba(250, 67, 106, 0.3);
|
||||
}
|
||||
}
|
||||
.ad-1 {
|
||||
width: 100%;
|
||||
height: 210upx;
|
||||
padding: 10upx 0;
|
||||
background: #fff;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
/* 秒杀专区 */
|
||||
.seckill-section {
|
||||
padding: 0upx 20upx 20upx;
|
||||
background: #fff;
|
||||
.s-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 90upx;
|
||||
line-height: 1;
|
||||
.s-img {
|
||||
width: 140upx;
|
||||
height: 30upx;
|
||||
}
|
||||
.tip {
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
// margin: 0 20upx 0 40upx;
|
||||
}
|
||||
.timer {
|
||||
display: inline-block;
|
||||
width: 40upx;
|
||||
height: 36upx;
|
||||
text-align: center;
|
||||
line-height: 36upx;
|
||||
margin-right: 14upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: #fff;
|
||||
border-radius: 2px;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
.icon-you {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-light;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
.floor-list {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.scoll-wrapper {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.floor-item {
|
||||
width: 150upx;
|
||||
margin-right: 20upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.8;
|
||||
image {
|
||||
width: 150upx;
|
||||
height: 150upx;
|
||||
border-radius: 6upx;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.f-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 140upx;
|
||||
padding: 0upx 20upx;
|
||||
background: #fff;
|
||||
image {
|
||||
flex-shrink: 0;
|
||||
width: 80upx;
|
||||
height: 80upx;
|
||||
margin-right: 20upx;
|
||||
}
|
||||
.tit-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.tit {
|
||||
font-size: $font-lg + 2upx;
|
||||
color: #font-color-dark;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.tit2 {
|
||||
font-size: $font-sm;
|
||||
color: $font-color-light;
|
||||
}
|
||||
.icon-you {
|
||||
font-size: $font-lg + 2upx;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
/* 团购楼层 */
|
||||
.group-section {
|
||||
background: #fff;
|
||||
.g-swiper {
|
||||
height: 650upx;
|
||||
padding-bottom: 20upx;
|
||||
}
|
||||
.g-swiper-item {
|
||||
width: 100%;
|
||||
padding: 0 20upx;
|
||||
display: flex;
|
||||
}
|
||||
image {
|
||||
width: 100%;
|
||||
height: 460upx;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.g-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.left {
|
||||
flex: 1.2;
|
||||
// margin-right: 24upx;
|
||||
.t-box {
|
||||
padding-top: 20upx;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
flex: 0.8;
|
||||
flex-direction: column-reverse;
|
||||
.t-box {
|
||||
padding-bottom: 20upx;
|
||||
}
|
||||
}
|
||||
.t-box {
|
||||
height: 160upx;
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
.m-price {
|
||||
font-size: $font-sm + 2upx;
|
||||
text-decoration: line-through;
|
||||
color: $font-color-light;
|
||||
margin-left: 8upx;
|
||||
}
|
||||
.pro-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10upx;
|
||||
font-size: $font-sm;
|
||||
color: $font-base;
|
||||
padding-right: 10upx;
|
||||
}
|
||||
.progress-box {
|
||||
flex: 1;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
margin-right: 8upx;
|
||||
}
|
||||
}
|
||||
/* 分类推荐楼层 */
|
||||
.hot-floor {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20upx;
|
||||
.floor-img-box {
|
||||
width: 100%;
|
||||
height: 320upx;
|
||||
position: relative;
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(rgba(255, 255, 255, 0.06) 30%, #f8f8f8);
|
||||
}
|
||||
}
|
||||
.floor-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.floor-list {
|
||||
white-space: nowrap;
|
||||
padding: 20upx;
|
||||
padding-right: 50upx;
|
||||
border-radius: 6upx;
|
||||
margin-top: -140upx;
|
||||
margin-left: 30upx;
|
||||
background: #fff;
|
||||
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.scoll-wrapper {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.floor-item {
|
||||
width: 180upx;
|
||||
margin-right: 20upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.8;
|
||||
image {
|
||||
width: 180upx;
|
||||
height: 180upx;
|
||||
border-radius: 6upx;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
}
|
||||
.more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
width: 180upx;
|
||||
height: 180upx;
|
||||
border-radius: 6upx;
|
||||
background: #f3f3f3;
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
text:first-child {
|
||||
margin-bottom: 4upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 单条商品 */
|
||||
.goods-box-single {
|
||||
display: flex;
|
||||
padding: 20upx 0;
|
||||
.goods-img {
|
||||
display: block;
|
||||
width: 120upx;
|
||||
height: 120upx;
|
||||
}
|
||||
.right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 30upx 0 24upx;
|
||||
overflow: hidden;
|
||||
.title {
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1;
|
||||
}
|
||||
.attr-box {
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-light;
|
||||
padding: 10upx 12upx;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
&:before {
|
||||
content: '¥';
|
||||
font-size: $font-sm;
|
||||
margin: 0 2upx 0 8upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.price-box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: baseline;
|
||||
padding: 20upx 30upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-light;
|
||||
.num {
|
||||
margin: 0 8upx;
|
||||
color: $font-color-dark;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
&:before {
|
||||
content: '¥';
|
||||
font-size: $font-sm;
|
||||
margin: 0 2upx 0 8upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.action-box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: 100upx;
|
||||
position: relative;
|
||||
padding-right: 30upx;
|
||||
}
|
||||
.action-btn {
|
||||
width: 160upx;
|
||||
height: 60upx;
|
||||
margin: 0;
|
||||
margin-left: 24upx;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
line-height: 60upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
background: #fff;
|
||||
border-radius: 100px;
|
||||
&:after {
|
||||
border-radius: 100px;
|
||||
}
|
||||
&.recom {
|
||||
background: #fff9f9;
|
||||
color: $base-color;
|
||||
&:after {
|
||||
border-color: #f7bcc8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 猜你喜欢 */
|
||||
.guess-section {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0 30upx;
|
||||
background: #fff;
|
||||
.guess-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 48%;
|
||||
padding-bottom: 40upx;
|
||||
&:nth-child(2n + 1) {
|
||||
margin-right: 4%;
|
||||
}
|
||||
}
|
||||
.image-wrapper {
|
||||
width: 100%;
|
||||
height: 330upx;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
line-height: 80upx;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-lg;
|
||||
color: $uni-color-primary;
|
||||
line-height: 1;
|
||||
}
|
||||
.coupon_box {
|
||||
width:100%; height:auto; display:table; padding:6upx 26upx 26upx 26upx;
|
||||
}
|
||||
|
||||
.other_type {
|
||||
width:100%; height:90upx; padding-top:50upx;
|
||||
|
||||
.text { width:100%; border-top:1px solid #eeeeee; display:block; text-align:center; position:relative; }
|
||||
.text span { width:180upx; height:40upx; line-height:40upx; color:#999999; display:block; background:#ffffff; position:absolute; left:50%; top:50%; margin-left:-90upx; margin-top:-20upx; font-size:$font-base; }
|
||||
}
|
||||
}
|
||||
.getPosition{
|
||||
height: 100upx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 32upx;
|
||||
background-color: #FFF;
|
||||
}
|
||||
</style>
|
||||
132
mallplusui-uniapp-app/components/jshop/jshop-groupPurchase.vue
Normal file
132
mallplusui-uniapp-app/components/jshop/jshop-groupPurchase.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<!-- 团购秒杀 -->
|
||||
<view class="img-list bottom-cell-group group-buying" v-if="jdata.options.colorGroup && count">
|
||||
<view class='cell-item right-img'>
|
||||
<view class='cell-item-hd group-title'>
|
||||
{{jdata.params.title}}
|
||||
<!-- <view class='cell-hd-title'></view> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class='swiper-grids'>
|
||||
<scroll-view class='swiper-list' scroll-x="true">
|
||||
<view class="img-list-item" v-if="item.goods !== 'undefined' && item.goods" v-for="(item, key) in jdata.options.colorGroup"
|
||||
:key="key">
|
||||
<image class="img-list-item-l medium-img have-none" :src="item.goods.image_url" mode='aspectFill' @click="groupDetail(item.goods.id, item.goods.group_id)"></image>
|
||||
<view class="img-list-item-r medium-right">
|
||||
<view class="goods-name list-goods-name" @click="groupDetail(item.goods.id, item.goods.group_id)">{{item.goods.name}}</view>
|
||||
<view class="goods-item-c">
|
||||
<view class="goods-price red-price">¥{{item.goods.product.price}}</view>
|
||||
<view class="goods-buy">
|
||||
<view class="goods-salesvolume red-price" v-if="(item.goods.lasttime != '已经结束' || item.goods.lasttime != '即将开始') && item.goods.lasttime">剩余:<uni-countdown
|
||||
:show-day="false" :hour="item.goods.lasttime.hour" :minute="item.goods.lasttime.minute" :second="item.goods.lasttime.second"></uni-countdown>
|
||||
</view>
|
||||
<view class="goods-salesvolume red-price" v-if="item.goods.lasttime == '已经结束'">已结束</view>
|
||||
<view class="goods-salesvolume red-price" v-if="item.goods.lasttime == '即将开始'">即将开始</view>
|
||||
<image class="goods-cart" src="/static/image/ic-car.png" @click="groupDetail(item.goods.id, item.goods.group_id)"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniCountdown from "@/components/uni-countdown/uni-countdown.vue"
|
||||
import {
|
||||
goods
|
||||
} from '@/config/mixins.js'
|
||||
export default {
|
||||
mixins: [goods],
|
||||
components: {
|
||||
uniCountdown
|
||||
},
|
||||
name: "jshopgrouppurchase",
|
||||
props: {
|
||||
jdata: {
|
||||
// type: Array,
|
||||
required: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showSliderInfo(type, val) {
|
||||
if (type == 1) {
|
||||
if (val.indexOf('http') != -1) {
|
||||
// #ifdef H5
|
||||
window.location.href = val
|
||||
// #endif
|
||||
} else {
|
||||
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
|
||||
if (val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
|
||||
uni.switchTab({
|
||||
url: val
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
this.$common.navigateTo(val);
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
} else if (type == 2) {
|
||||
// 商品详情
|
||||
this.goodsDetail(val)
|
||||
} else if (type == 3) {
|
||||
// 文章详情
|
||||
this.$common.navigateTo('/pages/article/index?id=' + val +'&id_type=1')
|
||||
} else if (type == 4) {
|
||||
// 文章列表
|
||||
this.$common.navigateTo('/pages/article/list?cid=' + val)
|
||||
} else if (type == 5) {
|
||||
//智能表单
|
||||
this.$common.navigateTo('/pages/form/detail/form?id=' + val)
|
||||
}
|
||||
},
|
||||
//跳转到商品详情页面
|
||||
// goodsDetail: function(id) {
|
||||
// let url = '/pages/goods/index/index?id=' + id;
|
||||
// this.$common.navigateTo(url);
|
||||
// },
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.img-list,
|
||||
.img-grids {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.cell-item {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.group-buying .img-list-item {
|
||||
min-height: 236upx;
|
||||
padding: 20upx;
|
||||
margin-left: 26upx;
|
||||
margin-bottom: 26upx;
|
||||
display: inline-table;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.swiper-grids .img-list-item:last-child {
|
||||
margin-right: 26upx;
|
||||
}
|
||||
|
||||
/* .group-buying .goods-name{
|
||||
min-height: 74upx;
|
||||
} */
|
||||
.group-buying .group-title {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
189
mallplusui-uniapp-app/components/jshop/jshop-imgSingle.vue
Normal file
189
mallplusui-uniapp-app/components/jshop/jshop-imgSingle.vue
Normal file
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<!-- 单图 -->
|
||||
<view class="ad jshop-imgsingle" v-if="jdata.options.colorGroup && jdata.options.colorGroup.length > 0">
|
||||
<view class="" v-for="item in jdata.options.colorGroup" :key="item.id">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view @click="showSliderInfo2" :data-type="item.linkType" :data-val="item.linkValue">
|
||||
<image class="ad-img" :src="item.adImg" mode="widthFix" ></image>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<image class="ad-img" :src="item.adImg" mode="widthFix" @click="showSliderInfo(item.linkType, item.linkValue)"></image>
|
||||
<!-- #endif -->
|
||||
<view class="imgup-btn" v-if="item.buttonText != ''" @click="showSliderInfo(item.linkType, item.linkValue)">
|
||||
<button class="btn btn-fillet" :style="{background:item.buttonColor,color:item.textColor}">{{item.buttonText}}</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshopimgsingle",
|
||||
props: {
|
||||
jdata: {
|
||||
// type: Object,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
// console.log(jdata)
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
|
||||
},
|
||||
methods: {
|
||||
showSliderInfo(type, val) {
|
||||
console.log(type);
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
if (type == 1) {
|
||||
if (val.indexOf('http') != -1) {
|
||||
// #ifdef H5
|
||||
window.location.href = val
|
||||
// #endif
|
||||
} else {
|
||||
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
|
||||
if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
|
||||
uni.switchTab({
|
||||
url: val
|
||||
});
|
||||
return;
|
||||
} else if(val.indexOf('/pages/coupon/coupon')>-1){
|
||||
var id = val.replace('/pages/coupon/coupon?id=',"");
|
||||
this.receiveCoupon(id)
|
||||
} else {
|
||||
this.$common.navigateTo(val);
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
} else if (type == 2) {
|
||||
// 商品详情
|
||||
this.goodsDetail(val)
|
||||
} else if (type == 3) {
|
||||
// 文章详情
|
||||
this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
|
||||
} else if (type == 4) {
|
||||
// 文章列表
|
||||
this.$common.navigateTo('/pages/article/list?cid=' + val)
|
||||
} else if (type == 5) {
|
||||
//智能表单
|
||||
this.$common.navigateTo('/pages/form/detail/form?id=' + val)
|
||||
}
|
||||
},
|
||||
//跳转到商品详情页面
|
||||
goodsDetail: function(id) {
|
||||
// let ins = encodeURIComponent('id='+id);
|
||||
let url = '/pages/goods/index/index?id=' + id;
|
||||
this.$common.navigateTo(url);
|
||||
},
|
||||
// 用户领取优惠券
|
||||
receiveCoupon(couponId) {
|
||||
let data = {
|
||||
promotion_id: couponId
|
||||
}
|
||||
this.$api.getCoupon(data, res => {
|
||||
if (res.status) {
|
||||
this.$common.successToShow(res.msg)
|
||||
} else {
|
||||
this.$common.errorToShow(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
// #ifdef MP-WEIXIN
|
||||
showSliderInfo2:function(e){
|
||||
let type = e.currentTarget.dataset.type;
|
||||
let val = e.currentTarget.dataset.val;
|
||||
console.log(type);
|
||||
console.log(val)
|
||||
console.log(type);
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
if (type == 1) {
|
||||
if (val.indexOf('http') != -1) {
|
||||
// #ifdef H5
|
||||
window.location.href = val
|
||||
// #endif
|
||||
} else {
|
||||
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
|
||||
if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
|
||||
uni.switchTab({
|
||||
url: val
|
||||
});
|
||||
return;
|
||||
} else if(val.indexOf('/pages/coupon/coupon')>-1){
|
||||
var id = val.replace('/pages/coupon/coupon?id=',"");
|
||||
this.receiveCoupon(id)
|
||||
} else {
|
||||
this.$common.navigateTo(val);
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
} else if (type == 2) {
|
||||
// 商品详情
|
||||
this.goodsDetail(val)
|
||||
} else if (type == 3) {
|
||||
// 文章详情
|
||||
this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
|
||||
} else if (type == 4) {
|
||||
// 文章列表
|
||||
this.$common.navigateTo('/pages/article/list?cid=' + val)
|
||||
} else if (type == 5) {
|
||||
//智能表单
|
||||
this.$common.navigateTo('/pages/form/detail/form?id=' + val)
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* .ad {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ad-img{
|
||||
width: 100%;
|
||||
float: left;
|
||||
margin-bottom: 20upx;
|
||||
}
|
||||
.ad-img:last-child{
|
||||
margin-bottom: 0;
|
||||
} */
|
||||
.jshop-imgsingle.ad {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.jshop-imgsingle .ad-img {
|
||||
width: 100%;
|
||||
float: left;
|
||||
position: relative;
|
||||
z-index: 667;
|
||||
/* margin-bottom: 20upx; */
|
||||
}
|
||||
|
||||
.jshop-imgsingle .ad-img:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.jshop-imgsingle .imgup-btn {
|
||||
position: absolute;
|
||||
z-index: 668;
|
||||
bottom: 80upx;
|
||||
left: 40upx;
|
||||
}
|
||||
|
||||
.jshop-imgsingle .imgup-btn .btn {
|
||||
line-height: 2;
|
||||
font-size: 28upx;
|
||||
padding: 0 50upx;
|
||||
}
|
||||
</style>
|
||||
667
mallplusui-uniapp-app/components/jshop/jshop-imgSlide.vue
Normal file
667
mallplusui-uniapp-app/components/jshop/jshop-imgSlide.vue
Normal file
@@ -0,0 +1,667 @@
|
||||
<template>
|
||||
|
||||
<!-- 头部轮播 -->
|
||||
<!-- #ifdef MP -->
|
||||
<view class="carousel-section" style="margin-top: 80upx;">
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP -->
|
||||
<view class="carousel-section">
|
||||
<!-- #endif -->
|
||||
<!-- 标题栏和状态栏占位符 -->
|
||||
<view class="titleNview-placing"></view>
|
||||
<!-- 背景色区域 -->
|
||||
<view class="titleNview-background" :style="{ backgroundColor: titleNViewBackground }"></view>
|
||||
<swiper class="carousel" circular @change="swiperChange">
|
||||
<swiper-item v-for="(item, index) in jdata.options.colorGroup" :key="index" class="carousel-item" @click="navToTabPage(item.adLink)">
|
||||
<image :src="item.adImg" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<!-- 自定义swiper指示器 -->
|
||||
<view class="swiper-dots">
|
||||
<text class="num">{{ swiperCurrent + 1 }}</text>
|
||||
<text class="sign">/</text>
|
||||
<text class="num">{{ jdata.options.colorGroup.length }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshopimgSlide",
|
||||
props: {
|
||||
jdata: {
|
||||
// type: Object,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
swiperCurrent: 0,
|
||||
titleNViewBackground: '',
|
||||
swiperLength: 0,
|
||||
swiper: {
|
||||
indicatorDots: true,
|
||||
autoplay: true,
|
||||
interval: 2000,
|
||||
duration: 500,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
watch: {},
|
||||
methods: {
|
||||
navToTabPage(url) {
|
||||
uni.navigateTo({
|
||||
url: url
|
||||
});
|
||||
},
|
||||
//轮播图切换修改背景色
|
||||
swiperChange(e) {
|
||||
const index = e.detail.current;
|
||||
this.swiperCurrent = index;
|
||||
// this.titleNViewBackground = this.jdata.options.colorGroup[index].background;
|
||||
},
|
||||
// 广告点击查看详情
|
||||
showSliderInfo(type, val) {
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
if (type == 1) {
|
||||
if (val.indexOf('http') != -1) {
|
||||
// #ifdef H5
|
||||
window.location.href = val
|
||||
// #endif
|
||||
} else {
|
||||
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
|
||||
if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
|
||||
uni.switchTab({
|
||||
url: val
|
||||
});
|
||||
return;
|
||||
} else if (val.indexOf('/pages/coupon/coupon') > -1) {
|
||||
var id = val.replace('/pages/coupon/coupon?id=', "");
|
||||
this.receiveCoupon(id)
|
||||
} else {
|
||||
this.$common.navigateTo(val);
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
} else if (type == 2) {
|
||||
// 商品详情
|
||||
this.goodsDetail(val)
|
||||
} else if (type == 3) {
|
||||
// 文章详情
|
||||
this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
|
||||
} else if (type == 4) {
|
||||
// 文章列表
|
||||
this.$common.navigateTo('/pages/article/list?cid=' + val)
|
||||
} else if (type == 5) {
|
||||
//智能表单
|
||||
this.$common.navigateTo('/pages/form/detail/form?id=' + val)
|
||||
}
|
||||
},
|
||||
//跳转到商品详情页面
|
||||
goodsDetail: function(id) {
|
||||
let url = '/pages/goods/index/index?id=' + id;
|
||||
this.$common.navigateTo(url);
|
||||
},
|
||||
// 用户领取优惠券
|
||||
receiveCoupon(couponId) {
|
||||
let data = {
|
||||
promotion_id: couponId
|
||||
}
|
||||
this.$api.getCoupon(data, res => {
|
||||
if (res.status) {
|
||||
this.$common.successToShow(res.msg)
|
||||
} else {
|
||||
this.$common.errorToShow(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
.MP-search{
|
||||
background: #FFFFFF;height: 80upx;display: flex;justify-content: center;align-items: center;position: fixed;width: 100%;z-index: 999;
|
||||
}
|
||||
.MP-search-input{
|
||||
font-size: 28upx;background: #F5F5F5;height: 60upx;width: 90%;border-radius: 50upx;text-align: center;
|
||||
}
|
||||
.mp-search-box {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 30upx;
|
||||
z-index: 9999;
|
||||
width: 100%;
|
||||
padding: 0 80upx;
|
||||
.ser-input {
|
||||
flex: 1;
|
||||
height: 60upx;
|
||||
line-height: 60upx;
|
||||
text-align: center;
|
||||
font-size: 28upx;
|
||||
color: $font-color-base;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
page {
|
||||
.cate-section {
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
border-radius: 16upx 16upx 0 0;
|
||||
margin-top: -20upx;
|
||||
}
|
||||
.carousel-section {
|
||||
padding: 0;
|
||||
.titleNview-placing {
|
||||
padding-top: 0;
|
||||
height: 0;
|
||||
}
|
||||
.carousel {
|
||||
.carousel-item {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.swiper-dots {
|
||||
left: 45upx;
|
||||
bottom: 40upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
page {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.m-t {
|
||||
margin-top: 20upx;
|
||||
}
|
||||
/* 头部 轮播图 */
|
||||
.carousel-section {
|
||||
position: relative;
|
||||
padding-top: 10px;
|
||||
|
||||
.titleNview-placing {
|
||||
height: var(--status-bar-height);
|
||||
padding-top: 44px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.titleNview-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 426upx;
|
||||
transition: 0.4s;
|
||||
}
|
||||
}
|
||||
.carousel {
|
||||
width: 100%;
|
||||
height: 350upx;
|
||||
|
||||
.carousel-item {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 28upx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 10upx;
|
||||
}
|
||||
}
|
||||
.swiper-dots {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
left: 60upx;
|
||||
bottom: 15upx;
|
||||
width: 72upx;
|
||||
height: 36upx;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTk4MzlBNjE0NjU1MTFFOUExNjRFQ0I3RTQ0NEExQjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTk4MzlBNjA0NjU1MTFFOUExNjRFQ0I3RTQ0NEExQjMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6Q0E3RUNERkE0NjExMTFFOTg5NzI4MTM2Rjg0OUQwOEUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6Q0E3RUNERkI0NjExMTFFOTg5NzI4MTM2Rjg0OUQwOEUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4Gh5BPAAACTUlEQVR42uzcQW7jQAwFUdN306l1uWwNww5kqdsmm6/2MwtVCp8CosQtP9vg/2+/gY+DRAMBgqnjIp2PaCxCLLldpPARRIiFj1yBbMV+cHZh9PURRLQNhY8kgWyL/WDtwujjI8hoE8rKLqb5CDJaRMJHokC6yKgSCR9JAukmokIknCQJpLOIrJFwMsBJELFcKHwM9BFkLBMKFxNcBCHlQ+FhoocgpVwwnv0Xn30QBJGMC0QcaBVJiAMiec/dcwKuL4j1QMsVCXFAJE4s4NQA3K/8Y6DzO4g40P7UcmIBJxbEesCKWBDg8wWxHrAiFgT4fEGsB/CwIhYE+AeBAAdPLOcV8HRmWRDAiQVcO7GcV8CLM8uCAE4sQCDAlHcQ7x+ABQEEAggEEAggEEAggEAAgQACASAQQCCAQACBAAIBBAIIBBAIIBBAIABe4e9iAe/xd7EAJxYgEGDeO4j3EODp/cOCAE4sYMyJ5cwCHs4rCwI4sYBxJ5YzC84rCwKcXxArAuthQYDzC2JF0H49LAhwYUGsCFqvx5EF2T07dMaJBetx4cRyaqFtHJ8EIhK0i8OJBQxcECuCVutxJhCRoE0cZwMRyRcFefa/ffZBVPogePihhyCnbBhcfMFFEFM+DD4m+ghSlgmDkwlOgpAl4+BkkJMgZdk4+EgaSCcpVX7bmY9kgXQQU+1TgE0c+QJZUUz1b2T4SBbIKmJW+3iMj2SBVBWz+leVfCQLpIqYbp8b85EskIxyfIOfK5Sf+wiCRJEsllQ+oqEkQfBxmD8BBgA5hVjXyrBNUQAAAABJRU5ErkJggg==);
|
||||
background-size: 100% 100%;
|
||||
|
||||
.num {
|
||||
width: 36upx;
|
||||
height: 36upx;
|
||||
border-radius: 50px;
|
||||
font-size: 24upx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 36upx;
|
||||
}
|
||||
|
||||
.sign {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
line-height: 36upx;
|
||||
font-size: 12upx;
|
||||
color: #fff;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
/* 分类 */
|
||||
.cate-section {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
padding: 30upx 22upx;
|
||||
background: #fff;
|
||||
.cate-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
}
|
||||
/* 原图标颜色太深,不想改图了,所以加了透明度 */
|
||||
image {
|
||||
width: 88upx;
|
||||
height: 88upx;
|
||||
margin-bottom: 14upx;
|
||||
border-radius: 50%;
|
||||
opacity: 0.7;
|
||||
box-shadow: 4upx 4upx 20upx rgba(250, 67, 106, 0.3);
|
||||
}
|
||||
}
|
||||
.ad-1 {
|
||||
width: 100%;
|
||||
height: 210upx;
|
||||
padding: 10upx 0;
|
||||
background: #fff;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
/* 秒杀专区 */
|
||||
.seckill-section {
|
||||
padding: 0upx 20upx 20upx;
|
||||
background: #fff;
|
||||
.s-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 90upx;
|
||||
line-height: 1;
|
||||
.s-img {
|
||||
width: 140upx;
|
||||
height: 30upx;
|
||||
}
|
||||
.tip {
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
// margin: 0 20upx 0 40upx;
|
||||
}
|
||||
.timer {
|
||||
display: inline-block;
|
||||
width: 40upx;
|
||||
height: 36upx;
|
||||
text-align: center;
|
||||
line-height: 36upx;
|
||||
margin-right: 14upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: #fff;
|
||||
border-radius: 2px;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
.icon-you {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-light;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
.floor-list {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.scoll-wrapper {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.floor-item {
|
||||
width: 150upx;
|
||||
margin-right: 20upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.8;
|
||||
image {
|
||||
width: 150upx;
|
||||
height: 150upx;
|
||||
border-radius: 6upx;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.f-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 140upx;
|
||||
padding: 0upx 20upx;
|
||||
background: #fff;
|
||||
image {
|
||||
flex-shrink: 0;
|
||||
width: 80upx;
|
||||
height: 80upx;
|
||||
margin-right: 20upx;
|
||||
}
|
||||
.tit-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.tit {
|
||||
font-size: $font-lg + 2upx;
|
||||
color: #font-color-dark;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.tit2 {
|
||||
font-size: $font-sm;
|
||||
color: $font-color-light;
|
||||
}
|
||||
.icon-you {
|
||||
font-size: $font-lg + 2upx;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
/* 团购楼层 */
|
||||
.group-section {
|
||||
background: #fff;
|
||||
.g-swiper {
|
||||
height: 650upx;
|
||||
padding-bottom: 20upx;
|
||||
}
|
||||
.g-swiper-item {
|
||||
width: 100%;
|
||||
padding: 0 20upx;
|
||||
display: flex;
|
||||
}
|
||||
image {
|
||||
width: 100%;
|
||||
height: 460upx;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.g-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.left {
|
||||
flex: 1.2;
|
||||
// margin-right: 24upx;
|
||||
.t-box {
|
||||
padding-top: 20upx;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
flex: 0.8;
|
||||
flex-direction: column-reverse;
|
||||
.t-box {
|
||||
padding-bottom: 20upx;
|
||||
}
|
||||
}
|
||||
.t-box {
|
||||
height: 160upx;
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
.m-price {
|
||||
font-size: $font-sm + 2upx;
|
||||
text-decoration: line-through;
|
||||
color: $font-color-light;
|
||||
margin-left: 8upx;
|
||||
}
|
||||
.pro-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10upx;
|
||||
font-size: $font-sm;
|
||||
color: $font-base;
|
||||
padding-right: 10upx;
|
||||
}
|
||||
.progress-box {
|
||||
flex: 1;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
margin-right: 8upx;
|
||||
}
|
||||
}
|
||||
/* 分类推荐楼层 */
|
||||
.hot-floor {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20upx;
|
||||
.floor-img-box {
|
||||
width: 100%;
|
||||
height: 320upx;
|
||||
position: relative;
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(rgba(255, 255, 255, 0.06) 30%, #f8f8f8);
|
||||
}
|
||||
}
|
||||
.floor-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.floor-list {
|
||||
white-space: nowrap;
|
||||
padding: 20upx;
|
||||
padding-right: 50upx;
|
||||
border-radius: 6upx;
|
||||
margin-top: -140upx;
|
||||
margin-left: 30upx;
|
||||
background: #fff;
|
||||
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.scoll-wrapper {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.floor-item {
|
||||
width: 180upx;
|
||||
margin-right: 20upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.8;
|
||||
image {
|
||||
width: 180upx;
|
||||
height: 180upx;
|
||||
border-radius: 6upx;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
}
|
||||
.more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
width: 180upx;
|
||||
height: 180upx;
|
||||
border-radius: 6upx;
|
||||
background: #f3f3f3;
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
text:first-child {
|
||||
margin-bottom: 4upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 单条商品 */
|
||||
.goods-box-single {
|
||||
display: flex;
|
||||
padding: 20upx 0;
|
||||
.goods-img {
|
||||
display: block;
|
||||
width: 120upx;
|
||||
height: 120upx;
|
||||
}
|
||||
.right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 30upx 0 24upx;
|
||||
overflow: hidden;
|
||||
.title {
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1;
|
||||
}
|
||||
.attr-box {
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-light;
|
||||
padding: 10upx 12upx;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
&:before {
|
||||
content: '¥';
|
||||
font-size: $font-sm;
|
||||
margin: 0 2upx 0 8upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.price-box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: baseline;
|
||||
padding: 20upx 30upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-light;
|
||||
.num {
|
||||
margin: 0 8upx;
|
||||
color: $font-color-dark;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
&:before {
|
||||
content: '¥';
|
||||
font-size: $font-sm;
|
||||
margin: 0 2upx 0 8upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.action-box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: 100upx;
|
||||
position: relative;
|
||||
padding-right: 30upx;
|
||||
}
|
||||
.action-btn {
|
||||
width: 160upx;
|
||||
height: 60upx;
|
||||
margin: 0;
|
||||
margin-left: 24upx;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
line-height: 60upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
background: #fff;
|
||||
border-radius: 100px;
|
||||
&:after {
|
||||
border-radius: 100px;
|
||||
}
|
||||
&.recom {
|
||||
background: #fff9f9;
|
||||
color: $base-color;
|
||||
&:after {
|
||||
border-color: #f7bcc8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 猜你喜欢 */
|
||||
.guess-section {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0 30upx;
|
||||
background: #fff;
|
||||
.guess-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 48%;
|
||||
padding-bottom: 40upx;
|
||||
&:nth-child(2n + 1) {
|
||||
margin-right: 4%;
|
||||
}
|
||||
}
|
||||
.image-wrapper {
|
||||
width: 100%;
|
||||
height: 330upx;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
line-height: 80upx;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-lg;
|
||||
color: $uni-color-primary;
|
||||
line-height: 1;
|
||||
}
|
||||
.coupon_box {
|
||||
width:100%; height:auto; display:table; padding:6upx 26upx 26upx 26upx;
|
||||
}
|
||||
|
||||
.other_type {
|
||||
width:100%; height:90upx; padding-top:50upx;
|
||||
|
||||
.text { width:100%; border-top:1px solid #eeeeee; display:block; text-align:center; position:relative; }
|
||||
.text span { width:180upx; height:40upx; line-height:40upx; color:#999999; display:block; background:#ffffff; position:absolute; left:50%; top:50%; margin-left:-90upx; margin-top:-20upx; font-size:$font-base; }
|
||||
}
|
||||
}
|
||||
.getPosition{
|
||||
height: 100upx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 32upx;
|
||||
background-color: #FFF;
|
||||
}
|
||||
</style>
|
||||
|
||||
207
mallplusui-uniapp-app/components/jshop/jshop-imgWindow.vue
Normal file
207
mallplusui-uniapp-app/components/jshop/jshop-imgWindow.vue
Normal file
@@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<view class="imgwindow">
|
||||
<view class="imgwindow-list" v-if="jdata.id == '3' "
|
||||
v-bind:class="'row'+jdata.id" :style="{margin:-jdata.id+'px'}">
|
||||
<image v-for="(item, index) in jdata.options.colorGroup" :key="index" :src="item.adImg" mode="widthFix" @click="showSliderInfo(item.linkType, item.linkValue)"></image>
|
||||
</view>
|
||||
<view class="imgwindow-list" v-if="jdata.id == '4'" v-bind:class="'row'+jdata.id" :style="{margin:-jdata.id+'px'}">
|
||||
<view class="imgwindow-item" ref="imgwitem" :style="{height:height+'px',padding:jdata.id+'px'}" v-for="(item, index) in jdata.options.colorGroup"
|
||||
:key="index" v-if="index == 0">
|
||||
<image :src="item.adImg" mode="aspectFill" @click="showSliderInfo(item.linkType, item.linkValue)"></image>
|
||||
</view>
|
||||
<view class="imgwindow-item" ref="imgwitem" :style="{height:height1+'px',padding:jdata.id+'px'}" v-for="(item, index) in jdata.options.colorGroup"
|
||||
:key="index" v-if="index !== 0">
|
||||
<image :src="item.adImg" mode="aspectFill" @click="showSliderInfo(item.linkType, item.linkValue)"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshopimgwindow",
|
||||
props: {
|
||||
jdata: {
|
||||
// type: Object,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
height: '',
|
||||
height1: '',
|
||||
padding: '3'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE
|
||||
var view = uni.createSelectorQuery().in(this).select(".imgwindow-item");
|
||||
view.boundingClientRect(data => {
|
||||
this.height = 50;
|
||||
// 橱窗小图高度
|
||||
this.height1 = 50 / 2;
|
||||
}).exec();
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-ALIPAY
|
||||
var view = uni.createSelectorQuery().in(this).select(".content").boundingClientRect().exec(data => {
|
||||
this.height1 = data[0].width / 4;
|
||||
if (this.data.params.style == '3') {
|
||||
this.height = data[0].width / 3;
|
||||
} else if (this.data.params.style == '2') {
|
||||
this.height = data[0].width / 2;
|
||||
} else if (this.data.params.style == '4') {
|
||||
this.height = data[0].width / 4;
|
||||
} else if (this.data.params.style == '0') {
|
||||
this.height = data[0].width / 2;
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
|
||||
var view = uni.createSelectorQuery().select(".content");
|
||||
|
||||
view.boundingClientRect(jdata => {
|
||||
|
||||
this.height1 = jdata.width / 4;
|
||||
if (this.jdata.params.style == '3') {
|
||||
this.height = jdata.width / 3;
|
||||
} else if (this.jdata.params.style == '2') {
|
||||
this.height = jdata.width / 2;
|
||||
} else if (this.jdata.params.style == '4') {
|
||||
this.height = jdata.width / 4;
|
||||
} else if (this.jdata.params.style == '0') {
|
||||
this.height = jdata.width / 2;
|
||||
}
|
||||
}).exec();
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
showSliderInfo(type, val) {
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
if (type == 1) {
|
||||
if (val.indexOf('http') != -1) {
|
||||
// #ifdef H5
|
||||
window.location.href = val
|
||||
// #endif
|
||||
} else {
|
||||
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
|
||||
if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val ==
|
||||
'/pages/member/index/index') {
|
||||
uni.switchTab({
|
||||
url: val
|
||||
});
|
||||
return;
|
||||
} else if(val.indexOf('/pages/coupon/coupon')>-1){
|
||||
var id = val.replace('/pages/coupon/coupon?id=',"");
|
||||
this.receiveCoupon(id)
|
||||
} else {
|
||||
this.$common.navigateTo(val);
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
} else if (type == 2) {
|
||||
// 商品详情
|
||||
this.goodsDetail(val)
|
||||
} else if (type == 3) {
|
||||
// 文章详情
|
||||
this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
|
||||
} else if (type == 4) {
|
||||
// 文章列表
|
||||
this.$common.navigateTo('/pages/article/list?cid=' + val)
|
||||
} else if (type == 5) {
|
||||
//智能表单
|
||||
this.$common.navigateTo('/pages/form/detail/form?id=' + val)
|
||||
}
|
||||
},
|
||||
//跳转到商品详情页面
|
||||
goodsDetail: function(id) {
|
||||
let url = '/pages/goods/index/index?id=' + id;
|
||||
this.$common.navigateTo(url);
|
||||
},
|
||||
// 用户领取优惠券
|
||||
receiveCoupon(couponId) {
|
||||
let data = {
|
||||
promotion_id: couponId
|
||||
}
|
||||
this.$api.getCoupon(data, res => {
|
||||
if (res.status) {
|
||||
this.$common.successToShow(res.msg)
|
||||
} else {
|
||||
this.$common.errorToShow(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.imgwindow {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.imgwindow-list {
|
||||
/* overflow: hidden; */
|
||||
/* margin: -16upx; */
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* 堆积两列 */
|
||||
.imgwindow-list .imgwindow-item {
|
||||
height: auto;
|
||||
flex: 1;
|
||||
/* float: left; */
|
||||
/* padding: 8upx; */
|
||||
}
|
||||
|
||||
.imgwindow-list .imgwindow-item image {
|
||||
width: 100%;
|
||||
/* height: 100%; */
|
||||
}
|
||||
|
||||
.imgwindow-list.row0{
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
}
|
||||
.imgwindow-list.row0 .imgwindow-item {
|
||||
height: auto;
|
||||
flex: auto;
|
||||
float: left;
|
||||
/* padding: 8upx; */
|
||||
}
|
||||
.imgwindow-list.row0 .imgwindow-item image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.imgwindow-list.row0 .imgwindow-item:first-child {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.imgwindow-list.row0 .imgwindow-item:nth-child(2) {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.imgwindow-list.row0 .imgwindow-item:nth-child(3),
|
||||
.imgwindow-list.row0 .imgwindow-item:nth-child(4) {
|
||||
width: 25%;
|
||||
|
||||
}
|
||||
|
||||
/* .imgwindow-list.row2 .imgwindow-item {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.imgwindow-list.row3 .imgwindow-item {
|
||||
width: 33.3%;
|
||||
}
|
||||
|
||||
.imgwindow-list.row4 .imgwindow-item {
|
||||
width: 25%;
|
||||
} */
|
||||
</style>
|
||||
616
mallplusui-uniapp-app/components/jshop/jshop-navBar.vue
Normal file
616
mallplusui-uniapp-app/components/jshop/jshop-navBar.vue
Normal file
@@ -0,0 +1,616 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="cate-section">
|
||||
<view class="cate-item" v-for="(item, index) in jdata.options.colorGroup" @click="navToTabPage(item.tabContent[0].tabLink)">
|
||||
<image :src="item.tabContent[0].tabImg"></image>
|
||||
<text>{{item.tabs}}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshopnavbar",
|
||||
props: {
|
||||
jdata: {
|
||||
// type: Object,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
height: '',
|
||||
height1: ''
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
showSliderInfo(type, val) {
|
||||
console.log(val)
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
console.log("11")
|
||||
if (type == 1) {
|
||||
if (val.indexOf('http') != -1) {
|
||||
// #ifdef H5
|
||||
window.location.href = val
|
||||
// #endif
|
||||
} else {
|
||||
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
|
||||
if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
|
||||
uni.switchTab({
|
||||
url: val
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
this.$common.navigateTo(val);
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
} else if (type == 2) {
|
||||
// 商品详情
|
||||
this.goodsDetail(val)
|
||||
} else if (type == 3) {
|
||||
// 文章详情
|
||||
this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
|
||||
} else if (type == 4) {
|
||||
// console.log("11")
|
||||
// 文章列表
|
||||
this.$common.navigateTo('/pages/article/list?cid=' + val)
|
||||
} else if (type == 5) {
|
||||
//智能表单
|
||||
this.$common.navigateTo('/pages/form/detail/form?id=' + val)
|
||||
}
|
||||
},
|
||||
//跳转到商品详情页面
|
||||
goodsDetail: function(id) {
|
||||
let url = '/pages/goods/index/index?id=' + id;
|
||||
this.$common.navigateTo(url);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.MP-search{
|
||||
background: #FFFFFF;height: 80upx;display: flex;justify-content: center;align-items: center;position: fixed;width: 100%;z-index: 999;
|
||||
}
|
||||
.MP-search-input{
|
||||
font-size: 28upx;background: #F5F5F5;height: 60upx;width: 90%;border-radius: 50upx;text-align: center;
|
||||
}
|
||||
.mp-search-box {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 30upx;
|
||||
z-index: 9999;
|
||||
width: 100%;
|
||||
padding: 0 80upx;
|
||||
.ser-input {
|
||||
flex: 1;
|
||||
height: 60upx;
|
||||
line-height: 60upx;
|
||||
text-align: center;
|
||||
font-size: 28upx;
|
||||
color: $font-color-base;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
page {
|
||||
.cate-section {
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
border-radius: 16upx 16upx 0 0;
|
||||
margin-top: -20upx;
|
||||
}
|
||||
.carousel-section {
|
||||
padding: 0;
|
||||
.titleNview-placing {
|
||||
padding-top: 0;
|
||||
height: 0;
|
||||
}
|
||||
.carousel {
|
||||
.carousel-item {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.swiper-dots {
|
||||
left: 45upx;
|
||||
bottom: 40upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
page {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.m-t {
|
||||
margin-top: 20upx;
|
||||
}
|
||||
/* 头部 轮播图 */
|
||||
.carousel-section {
|
||||
position: relative;
|
||||
padding-top: 10px;
|
||||
|
||||
.titleNview-placing {
|
||||
height: var(--status-bar-height);
|
||||
padding-top: 44px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.titleNview-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 426upx;
|
||||
transition: 0.4s;
|
||||
}
|
||||
}
|
||||
.carousel {
|
||||
width: 100%;
|
||||
height: 350upx;
|
||||
|
||||
.carousel-item {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 28upx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 10upx;
|
||||
}
|
||||
}
|
||||
.swiper-dots {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
left: 60upx;
|
||||
bottom: 15upx;
|
||||
width: 72upx;
|
||||
height: 36upx;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTk4MzlBNjE0NjU1MTFFOUExNjRFQ0I3RTQ0NEExQjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTk4MzlBNjA0NjU1MTFFOUExNjRFQ0I3RTQ0NEExQjMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6Q0E3RUNERkE0NjExMTFFOTg5NzI4MTM2Rjg0OUQwOEUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6Q0E3RUNERkI0NjExMTFFOTg5NzI4MTM2Rjg0OUQwOEUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4Gh5BPAAACTUlEQVR42uzcQW7jQAwFUdN306l1uWwNww5kqdsmm6/2MwtVCp8CosQtP9vg/2+/gY+DRAMBgqnjIp2PaCxCLLldpPARRIiFj1yBbMV+cHZh9PURRLQNhY8kgWyL/WDtwujjI8hoE8rKLqb5CDJaRMJHokC6yKgSCR9JAukmokIknCQJpLOIrJFwMsBJELFcKHwM9BFkLBMKFxNcBCHlQ+FhoocgpVwwnv0Xn30QBJGMC0QcaBVJiAMiec/dcwKuL4j1QMsVCXFAJE4s4NQA3K/8Y6DzO4g40P7UcmIBJxbEesCKWBDg8wWxHrAiFgT4fEGsB/CwIhYE+AeBAAdPLOcV8HRmWRDAiQVcO7GcV8CLM8uCAE4sQCDAlHcQ7x+ABQEEAggEEAggEEAggEAAgQACASAQQCCAQACBAAIBBAIIBBAIIBBAIABe4e9iAe/xd7EAJxYgEGDeO4j3EODp/cOCAE4sYMyJ5cwCHs4rCwI4sYBxJ5YzC84rCwKcXxArAuthQYDzC2JF0H49LAhwYUGsCFqvx5EF2T07dMaJBetx4cRyaqFtHJ8EIhK0i8OJBQxcECuCVutxJhCRoE0cZwMRyRcFefa/ffZBVPogePihhyCnbBhcfMFFEFM+DD4m+ghSlgmDkwlOgpAl4+BkkJMgZdk4+EgaSCcpVX7bmY9kgXQQU+1TgE0c+QJZUUz1b2T4SBbIKmJW+3iMj2SBVBWz+leVfCQLpIqYbp8b85EskIxyfIOfK5Sf+wiCRJEsllQ+oqEkQfBxmD8BBgA5hVjXyrBNUQAAAABJRU5ErkJggg==);
|
||||
background-size: 100% 100%;
|
||||
|
||||
.num {
|
||||
width: 36upx;
|
||||
height: 36upx;
|
||||
border-radius: 50px;
|
||||
font-size: 24upx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 36upx;
|
||||
}
|
||||
|
||||
.sign {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
line-height: 36upx;
|
||||
font-size: 12upx;
|
||||
color: #fff;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
/* 分类 */
|
||||
.cate-section {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
padding: 30upx 22upx;
|
||||
background: #fff;
|
||||
.cate-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
}
|
||||
/* 原图标颜色太深,不想改图了,所以加了透明度 */
|
||||
image {
|
||||
width: 88upx;
|
||||
height: 88upx;
|
||||
margin-bottom: 14upx;
|
||||
border-radius: 50%;
|
||||
opacity: 0.7;
|
||||
box-shadow: 4upx 4upx 20upx rgba(250, 67, 106, 0.3);
|
||||
}
|
||||
}
|
||||
.ad-1 {
|
||||
width: 100%;
|
||||
height: 210upx;
|
||||
padding: 10upx 0;
|
||||
background: #fff;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
/* 秒杀专区 */
|
||||
.seckill-section {
|
||||
padding: 0upx 20upx 20upx;
|
||||
background: #fff;
|
||||
.s-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 90upx;
|
||||
line-height: 1;
|
||||
.s-img {
|
||||
width: 140upx;
|
||||
height: 30upx;
|
||||
}
|
||||
.tip {
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
// margin: 0 20upx 0 40upx;
|
||||
}
|
||||
.timer {
|
||||
display: inline-block;
|
||||
width: 40upx;
|
||||
height: 36upx;
|
||||
text-align: center;
|
||||
line-height: 36upx;
|
||||
margin-right: 14upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: #fff;
|
||||
border-radius: 2px;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
.icon-you {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-light;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
.floor-list {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.scoll-wrapper {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.floor-item {
|
||||
width: 150upx;
|
||||
margin-right: 20upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.8;
|
||||
image {
|
||||
width: 150upx;
|
||||
height: 150upx;
|
||||
border-radius: 6upx;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.f-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 140upx;
|
||||
padding: 0upx 20upx;
|
||||
background: #fff;
|
||||
image {
|
||||
flex-shrink: 0;
|
||||
width: 80upx;
|
||||
height: 80upx;
|
||||
margin-right: 20upx;
|
||||
}
|
||||
.tit-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.tit {
|
||||
font-size: $font-lg + 2upx;
|
||||
color: #font-color-dark;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.tit2 {
|
||||
font-size: $font-sm;
|
||||
color: $font-color-light;
|
||||
}
|
||||
.icon-you {
|
||||
font-size: $font-lg + 2upx;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
/* 团购楼层 */
|
||||
.group-section {
|
||||
background: #fff;
|
||||
.g-swiper {
|
||||
height: 650upx;
|
||||
padding-bottom: 20upx;
|
||||
}
|
||||
.g-swiper-item {
|
||||
width: 100%;
|
||||
padding: 0 20upx;
|
||||
display: flex;
|
||||
}
|
||||
image {
|
||||
width: 100%;
|
||||
height: 460upx;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.g-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.left {
|
||||
flex: 1.2;
|
||||
// margin-right: 24upx;
|
||||
.t-box {
|
||||
padding-top: 20upx;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
flex: 0.8;
|
||||
flex-direction: column-reverse;
|
||||
.t-box {
|
||||
padding-bottom: 20upx;
|
||||
}
|
||||
}
|
||||
.t-box {
|
||||
height: 160upx;
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
.m-price {
|
||||
font-size: $font-sm + 2upx;
|
||||
text-decoration: line-through;
|
||||
color: $font-color-light;
|
||||
margin-left: 8upx;
|
||||
}
|
||||
.pro-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10upx;
|
||||
font-size: $font-sm;
|
||||
color: $font-base;
|
||||
padding-right: 10upx;
|
||||
}
|
||||
.progress-box {
|
||||
flex: 1;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
margin-right: 8upx;
|
||||
}
|
||||
}
|
||||
/* 分类推荐楼层 */
|
||||
.hot-floor {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20upx;
|
||||
.floor-img-box {
|
||||
width: 100%;
|
||||
height: 320upx;
|
||||
position: relative;
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(rgba(255, 255, 255, 0.06) 30%, #f8f8f8);
|
||||
}
|
||||
}
|
||||
.floor-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.floor-list {
|
||||
white-space: nowrap;
|
||||
padding: 20upx;
|
||||
padding-right: 50upx;
|
||||
border-radius: 6upx;
|
||||
margin-top: -140upx;
|
||||
margin-left: 30upx;
|
||||
background: #fff;
|
||||
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.scoll-wrapper {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.floor-item {
|
||||
width: 180upx;
|
||||
margin-right: 20upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.8;
|
||||
image {
|
||||
width: 180upx;
|
||||
height: 180upx;
|
||||
border-radius: 6upx;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
}
|
||||
.more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
width: 180upx;
|
||||
height: 180upx;
|
||||
border-radius: 6upx;
|
||||
background: #f3f3f3;
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
text:first-child {
|
||||
margin-bottom: 4upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 单条商品 */
|
||||
.goods-box-single {
|
||||
display: flex;
|
||||
padding: 20upx 0;
|
||||
.goods-img {
|
||||
display: block;
|
||||
width: 120upx;
|
||||
height: 120upx;
|
||||
}
|
||||
.right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 30upx 0 24upx;
|
||||
overflow: hidden;
|
||||
.title {
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1;
|
||||
}
|
||||
.attr-box {
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-light;
|
||||
padding: 10upx 12upx;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
&:before {
|
||||
content: '¥';
|
||||
font-size: $font-sm;
|
||||
margin: 0 2upx 0 8upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.price-box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: baseline;
|
||||
padding: 20upx 30upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-light;
|
||||
.num {
|
||||
margin: 0 8upx;
|
||||
color: $font-color-dark;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
&:before {
|
||||
content: '¥';
|
||||
font-size: $font-sm;
|
||||
margin: 0 2upx 0 8upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.action-box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: 100upx;
|
||||
position: relative;
|
||||
padding-right: 30upx;
|
||||
}
|
||||
.action-btn {
|
||||
width: 160upx;
|
||||
height: 60upx;
|
||||
margin: 0;
|
||||
margin-left: 24upx;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
line-height: 60upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
background: #fff;
|
||||
border-radius: 100px;
|
||||
&:after {
|
||||
border-radius: 100px;
|
||||
}
|
||||
&.recom {
|
||||
background: #fff9f9;
|
||||
color: $base-color;
|
||||
&:after {
|
||||
border-color: #f7bcc8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 猜你喜欢 */
|
||||
.guess-section {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0 30upx;
|
||||
background: #fff;
|
||||
.guess-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 48%;
|
||||
padding-bottom: 40upx;
|
||||
&:nth-child(2n + 1) {
|
||||
margin-right: 4%;
|
||||
}
|
||||
}
|
||||
.image-wrapper {
|
||||
width: 100%;
|
||||
height: 330upx;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
line-height: 80upx;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-lg;
|
||||
color: $uni-color-primary;
|
||||
line-height: 1;
|
||||
}
|
||||
.coupon_box {
|
||||
width:100%; height:auto; display:table; padding:6upx 26upx 26upx 26upx;
|
||||
}
|
||||
|
||||
.other_type {
|
||||
width:100%; height:90upx; padding-top:50upx;
|
||||
|
||||
.text { width:100%; border-top:1px solid #eeeeee; display:block; text-align:center; position:relative; }
|
||||
.text span { width:180upx; height:40upx; line-height:40upx; color:#999999; display:block; background:#ffffff; position:absolute; left:50%; top:50%; margin-left:-90upx; margin-top:-20upx; font-size:$font-base; }
|
||||
}
|
||||
}
|
||||
.getPosition{
|
||||
height: 100upx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 32upx;
|
||||
background-color: #FFF;
|
||||
}
|
||||
</style>
|
||||
69
mallplusui-uniapp-app/components/jshop/jshop-notice.vue
Normal file
69
mallplusui-uniapp-app/components/jshop/jshop-notice.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<view class="notice bottom-cell-group" v-if="jdata.options.colorGroup && count">
|
||||
<view class="notice-icon">
|
||||
<image class="icon news-icon" src="/static/image/news.png" mode=""></image>
|
||||
</view>
|
||||
<swiper class="notice-c" :indicator-dots="false" :autoplay="true" :interval="3000" :duration="1000" :vertical="true" :circular="true">
|
||||
<swiper-item v-for="item in jdata.options.colorGroup" :key="item.id">
|
||||
<view class="swiper-item" @click="goNotice(item.id)">{{ item.title }}</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshopnotice",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Object,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 点击公告
|
||||
goNotice(id) {
|
||||
// 文章详情
|
||||
this.$common.navigateTo('/pages/article/index?id=' + id+'&id_type=2')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.notice {
|
||||
padding: 6upx 26upx 6upx 60upx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
}
|
||||
.notice-icon {
|
||||
display: inline-block;
|
||||
height: 40upx;
|
||||
position: absolute;
|
||||
top: 59%;
|
||||
left: 26upx;
|
||||
transform: translateY(-50%);
|
||||
overflow: hidden;
|
||||
}
|
||||
.news-icon {
|
||||
width: 30upx;
|
||||
height: 30upx;
|
||||
float: left;
|
||||
}
|
||||
.notice-c {
|
||||
margin-left: 10upx;
|
||||
height: 50upx;
|
||||
line-height: 50upx;
|
||||
width: 630upx;
|
||||
display: inline-block;
|
||||
font-size: 28upx;
|
||||
float: left;
|
||||
}
|
||||
</style>
|
||||
150
mallplusui-uniapp-app/components/jshop/jshop-onegoods.vue
Normal file
150
mallplusui-uniapp-app/components/jshop/jshop-onegoods.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<view class="index-goods">
|
||||
|
||||
|
||||
<!-- 列表平铺单列 -->
|
||||
<view class="img-list bottom-cell-group" >
|
||||
<view class='cell-item right-img' v-if="jdata.name != ''">
|
||||
<view class='cell-item-hd'>
|
||||
<view class='cell-hd-title'>{{jdata.name}}</view>
|
||||
</view>
|
||||
<view class='cell-item-bd'>
|
||||
</view>
|
||||
<view class='cell-item-ft' >
|
||||
<text class='cell-ft-text' @click="goodsList({cat_id: jdata.params.classifyId,brand_id:jdata.params.brandId})">查看更多</text>
|
||||
<image class='cell-ft-next icon' src='/static/image/right.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="count">
|
||||
<view class="img-list-item" v-for="(item, index) in jdata.options.colorGroup" :key="index" @click="goodsDetail(item.id)">
|
||||
<image class="img-list-item-l have-none" :src="item.pic" mode='aspectFill'></image>
|
||||
<view class="img-list-item-r">
|
||||
<view class="goods-name list-goods-name">
|
||||
{{item.title}}
|
||||
</view>
|
||||
<view class="goods-item-c">
|
||||
<view class="goods-price red-price">¥{{item.price}}</view>
|
||||
<view class="goods-buy">
|
||||
<view class="goods-salesvolume" v-if="item.comments_count > 0">{{item.comments_count}}条评论</view>
|
||||
<view class="goods-salesvolume" v-else-if="item.comments_count <= 0">暂无评论</view>
|
||||
<image class="goods-cart" src="/static/image/ic-car.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="order-none" v-else>
|
||||
<image class="order-none-img" src="/static/image/order.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {goods} from '@/config/mixins.js'
|
||||
export default {
|
||||
filters:{
|
||||
substr(val) {
|
||||
if (val.length == 0 || val == undefined) {
|
||||
return false;
|
||||
} else if (val.length > 13) {
|
||||
return val.substring(0, 13) + "...";
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
},
|
||||
mixins: [goods],
|
||||
name: "jshoponegoods",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//跳转到商品详情页面
|
||||
goodsDetail: function(id) {
|
||||
let url = '/pages/goods/index/index?id=' + id;
|
||||
this.$common.navigateTo(url);
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.cell-item {
|
||||
border: none;
|
||||
/* padding-bottom: 0; */
|
||||
}
|
||||
.cell-ft-text {
|
||||
font-size: 22upx;
|
||||
color: #999;
|
||||
}
|
||||
.img-grids,.img-list{
|
||||
/* margin-top: 20upx; */
|
||||
background-color: #fff;
|
||||
}
|
||||
.img-grids-item{
|
||||
display: inline-table;
|
||||
margin-top: 0;
|
||||
margin-bottom: 14upx;
|
||||
}
|
||||
.column3 .img-grids-item{
|
||||
width: 230upx;
|
||||
height: 364rpx !important;
|
||||
margin: 15upx;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 6upx;
|
||||
}
|
||||
.column3 .img-grids-item:nth-child(3n){
|
||||
margin-right: 15upx;
|
||||
}
|
||||
.column3 .img-grids-item-t{
|
||||
width: 230upx;
|
||||
height: 230upx;
|
||||
}
|
||||
.column3 .grids-goods-name{
|
||||
font-size: 24upx;
|
||||
/* height: 68upx; */
|
||||
/* min-height: 54rpx; */
|
||||
}
|
||||
.column3 .img-grids-item-b{
|
||||
padding: 0 8upx 8upx;
|
||||
}
|
||||
.column3 .goods-price{
|
||||
font-size: 26upx;
|
||||
}
|
||||
.slide3 .img-grids-item{
|
||||
width: 200upx;
|
||||
}
|
||||
.slide3 .img-grids-item-t{
|
||||
width: 200upx;
|
||||
height: 200upx;
|
||||
}
|
||||
.slide3 .grids-goods-name{
|
||||
font-size: 24rpx;
|
||||
height: 66rpx;
|
||||
}
|
||||
.index-goods .img-grids-item{
|
||||
display: inline-block;
|
||||
margin-top: 0;
|
||||
}
|
||||
.index-goods .img-list-item{
|
||||
padding: 0upx 26upx;
|
||||
margin-bottom: 14upx;
|
||||
}
|
||||
.index-goods .img-list{
|
||||
padding-bottom: 10upx;
|
||||
}
|
||||
</style>
|
||||
83
mallplusui-uniapp-app/components/jshop/jshop-pintuan.vue
Normal file
83
mallplusui-uniapp-app/components/jshop/jshop-pintuan.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<!-- 拼团 -->
|
||||
<view class="img-list bottom-cell-group group-buying" v-if="jdata.options.colorGroup && count">
|
||||
<view class='cell-item right-img'>
|
||||
<view class='cell-item-hd group-title'>
|
||||
{{jdata.params.title}}
|
||||
</view>
|
||||
</view>
|
||||
<view class='swiper-grids' >
|
||||
<scroll-view class='swiper-list' scroll-x="true">
|
||||
<view class="img-list-item" v-if="item.goods_id !== 'undefined' && item.goods_id" v-for="(item, key) in jdata.options.colorGroup" :key="key">
|
||||
<image class="img-list-item-l medium-img have-none" :src="item.goods_image" mode='aspectFill' @click="pintuanDetail(item.goods_id)"></image>
|
||||
<view class="img-list-item-r medium-right">
|
||||
<view class="goods-name list-goods-name" @click="pintuanDetail(item.goods_id)">{{item.goods_name}}</view>
|
||||
<view class="goods-item-c">
|
||||
<view class="goods-price red-price">¥{{item.pintuan_price}}</view>
|
||||
<view class="goods-buy">
|
||||
<view class="goods-salesvolume red-price" v-if="(item.pintuan_start_status == 1) && item.lasttime">剩余:<uni-countdown :day="item.lasttime.day" :hour="item.lasttime.hour" :minute="item.lasttime.minute" :second="item.lasttime.second"></uni-countdown></view>
|
||||
<view class="goods-salesvolume red-price" v-if="item.pintuan_start_status == 3">已结束</view>
|
||||
<view class="goods-salesvolume red-price" v-if="item.pintuan_start_status == 2">即将开团</view>
|
||||
|
||||
<image class="goods-cart" src="/static/image/ic-car.png" @click="pintuanDetail(item.goods_id)"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniCountdown from "@/components/uni-countdown/uni-countdown.vue"
|
||||
import {goods} from '@/config/mixins.js'
|
||||
export default {
|
||||
mixins: [goods],
|
||||
components:{uniCountdown},
|
||||
name: "jshoppintuan",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Array,
|
||||
required: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.img-list, .img-grids {
|
||||
background-color: #fff;
|
||||
}
|
||||
.cell-item{
|
||||
border: none;
|
||||
}
|
||||
.group-buying .img-list-item{
|
||||
min-height: 236upx;
|
||||
padding: 20upx;
|
||||
margin-left: 26upx;
|
||||
margin-bottom: 26upx;
|
||||
display: inline-table;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.swiper-grids .img-list-item:last-child{
|
||||
margin-right: 26upx;
|
||||
}
|
||||
|
||||
/* .group-buying .goods-name{
|
||||
min-height: 74upx;
|
||||
} */
|
||||
.group-buying .group-title{
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
187
mallplusui-uniapp-app/components/jshop/jshop-record.vue
Normal file
187
mallplusui-uniapp-app/components/jshop/jshop-record.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<view class="adbrathing"
|
||||
v-show="adbshow"
|
||||
v-bind:class="['adbrathing'+jdata.params.style.align,!hideanimation?'pc':hideanimation?'hc':'']"
|
||||
:style="{top:jdata.params.style.top+'%'}" >
|
||||
<view class="adbrathing-c">
|
||||
<view class="adbrathing-l">
|
||||
<image class="user-head-img" :src="log.avatar" mode="aspectFill"></image>
|
||||
<view class="user-name">
|
||||
{{log.nickname}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="adbrathing-r">
|
||||
{{log.ctime}}{{log.desc}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { apiBaseUrl } from '@/config/config.js';
|
||||
export default {
|
||||
name: "jshoprecord",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Object,
|
||||
required: true,
|
||||
},
|
||||
//记录显示的位置类型
|
||||
ltype:{
|
||||
type: String,
|
||||
required: false,
|
||||
default:'home',
|
||||
},
|
||||
//记录显示的位置的值
|
||||
lvalue:{
|
||||
type: String,
|
||||
required: false,
|
||||
default:'0',
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
adbshow:false,
|
||||
hideanimation: true,
|
||||
log:{
|
||||
avatar:'/static/demo-img/user-head.jpg',
|
||||
nickname:'',
|
||||
desc:'',
|
||||
ctime:'',
|
||||
},
|
||||
times:{},//定时器
|
||||
};
|
||||
},
|
||||
methods:{
|
||||
//隐藏
|
||||
hideLog(){
|
||||
var _this = this;
|
||||
_this.times = setInterval(function(){
|
||||
_this.adbshow = !_this.adbshow;
|
||||
_this.hideanimation = !_this.hideanimation;
|
||||
clearInterval(_this.times);
|
||||
_this.times = setInterval(function(){
|
||||
_this.getRecod();
|
||||
},5000);
|
||||
},3000)
|
||||
},
|
||||
//获取日志
|
||||
getRecod(){
|
||||
var _this = this;
|
||||
if(_this.times !={}){
|
||||
clearInterval(_this.times);
|
||||
}
|
||||
var data = {
|
||||
type:_this.ltype,
|
||||
value:_this.lvalue,
|
||||
method:'pages.getrecod',
|
||||
};
|
||||
uni.request({
|
||||
url: apiBaseUrl+'api.html',
|
||||
data: data,
|
||||
header: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
method: 'POST',
|
||||
success: (response) => {
|
||||
var res = response.data;
|
||||
if(res.status == true){
|
||||
if(res.data){
|
||||
_this.log = res.data;
|
||||
_this.adbshow = true;
|
||||
_this.hideanimation = false;
|
||||
_this.hideLog();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getRecod();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.adbrathing{
|
||||
position: fixed;
|
||||
// top: 100px;
|
||||
// right: 30upx;
|
||||
// max-width: 400upx;
|
||||
height: 70upx;
|
||||
background-color: rgba(0,0,0,.5);
|
||||
border-radius: 10upx;
|
||||
padding: 10upx;
|
||||
z-index: 666;
|
||||
.adbrathing-c{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
font-size: 24upx;
|
||||
|
||||
.adbrathing-l{
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
.user-head-img{
|
||||
width: 50upx;
|
||||
height: 50upx;
|
||||
border-radius: 50%;
|
||||
float: left;
|
||||
|
||||
}
|
||||
.user-name{
|
||||
float: left;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
line-height: 50upx;
|
||||
margin: 0 4upx 0 10upx;
|
||||
max-width: 120upx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.adbrathing-r{
|
||||
float: left;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
line-height: 50upx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.adbrathingleft{
|
||||
left: 30upx
|
||||
}
|
||||
.adbrathingright{
|
||||
right: 30upx
|
||||
}
|
||||
.pc{
|
||||
animation: showcenter .55s;
|
||||
}
|
||||
.hc{
|
||||
animation: hidecenter .55s;
|
||||
}
|
||||
@keyframes showcenter{
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes hidecenter{
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
118
mallplusui-uniapp-app/components/jshop/jshop-search.vue
Normal file
118
mallplusui-uniapp-app/components/jshop/jshop-search.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<view class="" >
|
||||
<!-- 搜索框 -->
|
||||
<view class="search" ref="searchBar" id="search">
|
||||
<view class='search-c round' @click='goSearch()'>
|
||||
<view class='search-input search-input-p'>
|
||||
<view class="search-input-p-c">
|
||||
{{jdata.options.search_tips}}
|
||||
</view>
|
||||
</view>
|
||||
<image class='icon search-icon' src='/static/image/zoom.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 搜索框 -->
|
||||
<view class="search search-fixed" v-show="searchFixed">
|
||||
<view class='search-c round' @click='goSearch()' >
|
||||
<view class='search-input search-input-p'>
|
||||
<view class="search-input-p-c">
|
||||
{{jdata.options.search_tips}}
|
||||
</view>
|
||||
</view>
|
||||
<image class='icon search-icon' src='/static/image/zoom.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "jshopsearch",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Object,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
keyword:'',
|
||||
searchTop: 0,
|
||||
scrollTop: 0,
|
||||
searchFixed: this.$store.state.searchFixed||false
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
//#ifdef H5
|
||||
this.$nextTick(() => {
|
||||
this.searchTop = this.$refs.searchBar.$el.offsetTop;
|
||||
})
|
||||
// #endif
|
||||
this.searchStyle()
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// #ifdef H5
|
||||
window.addEventListener('scroll', this.handleScroll)
|
||||
// #endif
|
||||
},
|
||||
|
||||
|
||||
methods: {
|
||||
searchStyle (){
|
||||
|
||||
},
|
||||
goSearch() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/index/search'
|
||||
});
|
||||
},
|
||||
handleScroll() {
|
||||
this.scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
|
||||
this.scrollTop >= this.searchTop? this.searchFixed = true : this.searchFixed = false;
|
||||
},
|
||||
},
|
||||
/*
|
||||
//失效
|
||||
onPageScroll(){
|
||||
var _this = this;
|
||||
// #ifdef MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query.select('.search').boundingClientRect(function(res){
|
||||
if(res.top<0){
|
||||
_this.searchFixed = true ;
|
||||
}else{
|
||||
_this.searchFixed = false;
|
||||
}
|
||||
}).exec()
|
||||
// #endif
|
||||
} */
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.search-input-p {
|
||||
color: #888;
|
||||
}
|
||||
.square{
|
||||
border-radius: 0;
|
||||
}
|
||||
.radius{
|
||||
border-radius: 12upx;
|
||||
}
|
||||
.search-fixed{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
/* background: linear-gradient(rgba(0, 0, 0, .5), rgba(0, 0, 0, 0)); */
|
||||
transition: all .5s;
|
||||
}
|
||||
/* .isOpacity {
|
||||
background: linear-gradient(rgba(0, 0, 0, .5), rgba(0, 0, 0, 0));
|
||||
transition: all .5s;
|
||||
}
|
||||
|
||||
.isOpacity .search-input {
|
||||
background-color: rgba(255, 255, 255, .5);
|
||||
transition: all .5s;
|
||||
} */
|
||||
</style>
|
||||
614
mallplusui-uniapp-app/components/jshop/jshop-slidegoods.vue
Normal file
614
mallplusui-uniapp-app/components/jshop/jshop-slidegoods.vue
Normal file
@@ -0,0 +1,614 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
|
||||
<!-- 团购楼层 -->
|
||||
<view class="f-header m-t" @click="navToTabPage('../../pagesA/product/groupList')" v-if="jdata.options.colorGroup.length > 0">
|
||||
<image src="/static/temp/h1.png"></image>
|
||||
<view class="tit-box">
|
||||
<text class="tit" >精品团购</text>
|
||||
<text class="tit2">Boutique Group Buying</text>
|
||||
</view>
|
||||
<text class="yticon icon-you"></text>
|
||||
</view>
|
||||
<view class="group-section">
|
||||
<swiper class="g-swiper" :duration="500">
|
||||
<swiper-item class="g-swiper-item" v-for="(item, index) in jdata.options.colorGroup" :key="index" @click="goodsDetail(item.id)">
|
||||
<view class="g-item left">
|
||||
<image :src="item.pic" mode="aspectFill"></image>
|
||||
<view class="t-box">
|
||||
<text class="title clamp">{{ item.title }}</text>
|
||||
<view class="price-box">
|
||||
<text class="price">{{ item.price }}</text>
|
||||
<text class="m-price">¥{{ item.price }}</text>
|
||||
</view>
|
||||
<view class="pro-box">
|
||||
<view class="progress-box"><progress percent="72" activeColor="#fa436a" active stroke-width="6" /></view>
|
||||
<text>{{ item.maxPeople }}人成团</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {goods} from '@/config/mixins.js'
|
||||
export default {
|
||||
filters:{
|
||||
substr(val) {
|
||||
if (val.length == 0 || val == undefined) {
|
||||
return false;
|
||||
} else if (val.length > 13) {
|
||||
return val.substring(0, 13) + "...";
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
},
|
||||
mixins: [goods],
|
||||
name: "jshopgoods",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
return (this.jdata.options.colorGroup.length > 0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
navToTabPage(url) {
|
||||
uni.navigateTo({
|
||||
url: url
|
||||
});
|
||||
},
|
||||
//跳转到商品详情页面
|
||||
goodsDetail: function(id) {
|
||||
let url = '../../pagesA/product/product?id=' + id;
|
||||
|
||||
this.$common.navigateTo(url);
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.MP-search{
|
||||
background: #FFFFFF;height: 80upx;display: flex;justify-content: center;align-items: center;position: fixed;width: 100%;z-index: 999;
|
||||
}
|
||||
.MP-search-input{
|
||||
font-size: 28upx;background: #F5F5F5;height: 60upx;width: 90%;border-radius: 50upx;text-align: center;
|
||||
}
|
||||
.mp-search-box {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 30upx;
|
||||
z-index: 9999;
|
||||
width: 100%;
|
||||
padding: 0 80upx;
|
||||
.ser-input {
|
||||
flex: 1;
|
||||
height: 60upx;
|
||||
line-height: 60upx;
|
||||
text-align: center;
|
||||
font-size: 28upx;
|
||||
color: $font-color-base;
|
||||
border-radius: 20px;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
page {
|
||||
.cate-section {
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
border-radius: 16upx 16upx 0 0;
|
||||
margin-top: -20upx;
|
||||
}
|
||||
.carousel-section {
|
||||
padding: 0;
|
||||
.titleNview-placing {
|
||||
padding-top: 0;
|
||||
height: 0;
|
||||
}
|
||||
.carousel {
|
||||
.carousel-item {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.swiper-dots {
|
||||
left: 45upx;
|
||||
bottom: 40upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
page {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.m-t {
|
||||
margin-top: 20upx;
|
||||
}
|
||||
/* 头部 轮播图 */
|
||||
.carousel-section {
|
||||
position: relative;
|
||||
padding-top: 10px;
|
||||
|
||||
.titleNview-placing {
|
||||
height: var(--status-bar-height);
|
||||
padding-top: 44px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.titleNview-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 426upx;
|
||||
transition: 0.4s;
|
||||
}
|
||||
}
|
||||
.carousel {
|
||||
width: 100%;
|
||||
height: 350upx;
|
||||
|
||||
.carousel-item {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 28upx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 10upx;
|
||||
}
|
||||
}
|
||||
.swiper-dots {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
left: 60upx;
|
||||
bottom: 15upx;
|
||||
width: 72upx;
|
||||
height: 36upx;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTk4MzlBNjE0NjU1MTFFOUExNjRFQ0I3RTQ0NEExQjMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTk4MzlBNjA0NjU1MTFFOUExNjRFQ0I3RTQ0NEExQjMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6Q0E3RUNERkE0NjExMTFFOTg5NzI4MTM2Rjg0OUQwOEUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6Q0E3RUNERkI0NjExMTFFOTg5NzI4MTM2Rjg0OUQwOEUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4Gh5BPAAACTUlEQVR42uzcQW7jQAwFUdN306l1uWwNww5kqdsmm6/2MwtVCp8CosQtP9vg/2+/gY+DRAMBgqnjIp2PaCxCLLldpPARRIiFj1yBbMV+cHZh9PURRLQNhY8kgWyL/WDtwujjI8hoE8rKLqb5CDJaRMJHokC6yKgSCR9JAukmokIknCQJpLOIrJFwMsBJELFcKHwM9BFkLBMKFxNcBCHlQ+FhoocgpVwwnv0Xn30QBJGMC0QcaBVJiAMiec/dcwKuL4j1QMsVCXFAJE4s4NQA3K/8Y6DzO4g40P7UcmIBJxbEesCKWBDg8wWxHrAiFgT4fEGsB/CwIhYE+AeBAAdPLOcV8HRmWRDAiQVcO7GcV8CLM8uCAE4sQCDAlHcQ7x+ABQEEAggEEAggEEAggEAAgQACASAQQCCAQACBAAIBBAIIBBAIIBBAIABe4e9iAe/xd7EAJxYgEGDeO4j3EODp/cOCAE4sYMyJ5cwCHs4rCwI4sYBxJ5YzC84rCwKcXxArAuthQYDzC2JF0H49LAhwYUGsCFqvx5EF2T07dMaJBetx4cRyaqFtHJ8EIhK0i8OJBQxcECuCVutxJhCRoE0cZwMRyRcFefa/ffZBVPogePihhyCnbBhcfMFFEFM+DD4m+ghSlgmDkwlOgpAl4+BkkJMgZdk4+EgaSCcpVX7bmY9kgXQQU+1TgE0c+QJZUUz1b2T4SBbIKmJW+3iMj2SBVBWz+leVfCQLpIqYbp8b85EskIxyfIOfK5Sf+wiCRJEsllQ+oqEkQfBxmD8BBgA5hVjXyrBNUQAAAABJRU5ErkJggg==);
|
||||
background-size: 100% 100%;
|
||||
|
||||
.num {
|
||||
width: 36upx;
|
||||
height: 36upx;
|
||||
border-radius: 50px;
|
||||
font-size: 24upx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 36upx;
|
||||
}
|
||||
|
||||
.sign {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
line-height: 36upx;
|
||||
font-size: 12upx;
|
||||
color: #fff;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
/* 分类 */
|
||||
.cate-section {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
padding: 30upx 22upx;
|
||||
background: #fff;
|
||||
.cate-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
}
|
||||
/* 原图标颜色太深,不想改图了,所以加了透明度 */
|
||||
image {
|
||||
width: 88upx;
|
||||
height: 88upx;
|
||||
margin-bottom: 14upx;
|
||||
border-radius: 50%;
|
||||
opacity: 0.7;
|
||||
box-shadow: 4upx 4upx 20upx rgba(250, 67, 106, 0.3);
|
||||
}
|
||||
}
|
||||
.ad-1 {
|
||||
width: 100%;
|
||||
height: 210upx;
|
||||
padding: 10upx 0;
|
||||
background: #fff;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
/* 秒杀专区 */
|
||||
.seckill-section {
|
||||
padding: 0upx 20upx 20upx;
|
||||
background: #fff;
|
||||
.s-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 90upx;
|
||||
line-height: 1;
|
||||
.s-img {
|
||||
width: 140upx;
|
||||
height: 30upx;
|
||||
}
|
||||
.tip {
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
// margin: 0 20upx 0 40upx;
|
||||
}
|
||||
.timer {
|
||||
display: inline-block;
|
||||
width: 40upx;
|
||||
height: 36upx;
|
||||
text-align: center;
|
||||
line-height: 36upx;
|
||||
margin-right: 14upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: #fff;
|
||||
border-radius: 2px;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
.icon-you {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-light;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
.floor-list {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.scoll-wrapper {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.floor-item {
|
||||
width: 150upx;
|
||||
margin-right: 20upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.8;
|
||||
image {
|
||||
width: 150upx;
|
||||
height: 150upx;
|
||||
border-radius: 6upx;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.f-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 140upx;
|
||||
padding: 0upx 20upx;
|
||||
background: #fff;
|
||||
image {
|
||||
flex-shrink: 0;
|
||||
width: 80upx;
|
||||
height: 80upx;
|
||||
margin-right: 20upx;
|
||||
}
|
||||
.tit-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.tit {
|
||||
font-size: $font-lg + 2upx;
|
||||
color: #font-color-dark;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.tit2 {
|
||||
font-size: $font-sm;
|
||||
color: $font-color-light;
|
||||
}
|
||||
.icon-you {
|
||||
font-size: $font-lg + 2upx;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
/* 团购楼层 */
|
||||
.group-section {
|
||||
background: #fff;
|
||||
.g-swiper {
|
||||
height: 650upx;
|
||||
padding-bottom: 20upx;
|
||||
}
|
||||
.g-swiper-item {
|
||||
width: 100%;
|
||||
padding: 0 20upx;
|
||||
display: flex;
|
||||
}
|
||||
image {
|
||||
width: 100%;
|
||||
height: 460upx;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.g-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.left {
|
||||
flex: 1.2;
|
||||
// margin-right: 24upx;
|
||||
.t-box {
|
||||
padding-top: 20upx;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
flex: 0.8;
|
||||
flex-direction: column-reverse;
|
||||
.t-box {
|
||||
padding-bottom: 20upx;
|
||||
}
|
||||
}
|
||||
.t-box {
|
||||
height: 160upx;
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
.m-price {
|
||||
font-size: $font-sm + 2upx;
|
||||
text-decoration: line-through;
|
||||
color: $font-color-light;
|
||||
margin-left: 8upx;
|
||||
}
|
||||
.pro-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10upx;
|
||||
font-size: $font-sm;
|
||||
color: $font-base;
|
||||
padding-right: 10upx;
|
||||
}
|
||||
.progress-box {
|
||||
flex: 1;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
margin-right: 8upx;
|
||||
}
|
||||
}
|
||||
/* 分类推荐楼层 */
|
||||
.hot-floor {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20upx;
|
||||
.floor-img-box {
|
||||
width: 100%;
|
||||
height: 320upx;
|
||||
position: relative;
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(rgba(255, 255, 255, 0.06) 30%, #f8f8f8);
|
||||
}
|
||||
}
|
||||
.floor-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.floor-list {
|
||||
white-space: nowrap;
|
||||
padding: 20upx;
|
||||
padding-right: 50upx;
|
||||
border-radius: 6upx;
|
||||
margin-top: -140upx;
|
||||
margin-left: 30upx;
|
||||
background: #fff;
|
||||
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.scoll-wrapper {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.floor-item {
|
||||
width: 180upx;
|
||||
margin-right: 20upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1.8;
|
||||
image {
|
||||
width: 180upx;
|
||||
height: 180upx;
|
||||
border-radius: 6upx;
|
||||
}
|
||||
.price {
|
||||
color: $uni-color-primary;
|
||||
}
|
||||
}
|
||||
.more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
width: 180upx;
|
||||
height: 180upx;
|
||||
border-radius: 6upx;
|
||||
background: #f3f3f3;
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
text:first-child {
|
||||
margin-bottom: 4upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 单条商品 */
|
||||
.goods-box-single {
|
||||
display: flex;
|
||||
padding: 20upx 0;
|
||||
.goods-img {
|
||||
display: block;
|
||||
width: 120upx;
|
||||
height: 120upx;
|
||||
}
|
||||
.right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 30upx 0 24upx;
|
||||
overflow: hidden;
|
||||
.title {
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
line-height: 1;
|
||||
}
|
||||
.attr-box {
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-light;
|
||||
padding: 10upx 12upx;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
&:before {
|
||||
content: '¥';
|
||||
font-size: $font-sm;
|
||||
margin: 0 2upx 0 8upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.price-box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: baseline;
|
||||
padding: 20upx 30upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-light;
|
||||
.num {
|
||||
margin: 0 8upx;
|
||||
color: $font-color-dark;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
&:before {
|
||||
content: '¥';
|
||||
font-size: $font-sm;
|
||||
margin: 0 2upx 0 8upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.action-box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: 100upx;
|
||||
position: relative;
|
||||
padding-right: 30upx;
|
||||
}
|
||||
.action-btn {
|
||||
width: 160upx;
|
||||
height: 60upx;
|
||||
margin: 0;
|
||||
margin-left: 24upx;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
line-height: 60upx;
|
||||
font-size: $font-sm + 2upx;
|
||||
color: $font-color-dark;
|
||||
background: #fff;
|
||||
border-radius: 100px;
|
||||
&:after {
|
||||
border-radius: 100px;
|
||||
}
|
||||
&.recom {
|
||||
background: #fff9f9;
|
||||
color: $base-color;
|
||||
&:after {
|
||||
border-color: #f7bcc8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 猜你喜欢 */
|
||||
.guess-section {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0 30upx;
|
||||
background: #fff;
|
||||
.guess-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 48%;
|
||||
padding-bottom: 40upx;
|
||||
&:nth-child(2n + 1) {
|
||||
margin-right: 4%;
|
||||
}
|
||||
}
|
||||
.image-wrapper {
|
||||
width: 100%;
|
||||
height: 330upx;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
line-height: 80upx;
|
||||
}
|
||||
.price {
|
||||
font-size: $font-lg;
|
||||
color: $uni-color-primary;
|
||||
line-height: 1;
|
||||
}
|
||||
.coupon_box {
|
||||
width:100%; height:auto; display:table; padding:6upx 26upx 26upx 26upx;
|
||||
}
|
||||
|
||||
.other_type {
|
||||
width:100%; height:90upx; padding-top:50upx;
|
||||
|
||||
.text { width:100%; border-top:1px solid #eeeeee; display:block; text-align:center; position:relative; }
|
||||
.text span { width:180upx; height:40upx; line-height:40upx; color:#999999; display:block; background:#ffffff; position:absolute; left:50%; top:50%; margin-left:-90upx; margin-top:-20upx; font-size:$font-base; }
|
||||
}
|
||||
}
|
||||
.getPosition{
|
||||
height: 100upx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 32upx;
|
||||
background-color: #FFF;
|
||||
}
|
||||
</style>
|
||||
163
mallplusui-uniapp-app/components/jshop/jshop-tabbar.vue
Normal file
163
mallplusui-uniapp-app/components/jshop/jshop-tabbar.vue
Normal file
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<view class="">
|
||||
<view class="jshop-tabbar bottom-cell-group" ref="tabBar">
|
||||
<scroll-view scroll-x='true' class="tabbar-list">
|
||||
<view class="tabbar-item" v-for="(item, index) in jdata.options.colorGroup" :key="index" @click="showSliderInfo(item.linkType, item.linkValue)">
|
||||
{{item.text}}
|
||||
<view class="active-tabbar"></view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<!-- <view class="jshop-tabbar bottom-cell-group tabbar-fixed" v-show="tabbarFixed">
|
||||
<scroll-view scroll-x='true' class="tabbar-list">
|
||||
<view class="tabbar-item" v-for="(item, index) in jdata.options.colorGroup" :key="index" @click="showSliderInfo(item.linkType, item.linkValue)">
|
||||
{{item.text}}
|
||||
<view class="active-tabbar"></view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshopTabbar",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Object,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchTop: 0,
|
||||
scrollTop: 0,
|
||||
tabbarFixed: false
|
||||
};
|
||||
},
|
||||
created() {
|
||||
//#ifdef H5
|
||||
this.$nextTick(() => {
|
||||
this.searchTop = this.$refs.tabBar.$el.offsetTop - 52;
|
||||
})
|
||||
// #endif
|
||||
this.searchStyle()
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// #ifdef H5
|
||||
window.addEventListener('scroll', this.handleScroll)
|
||||
// #endif
|
||||
|
||||
|
||||
},
|
||||
methods: {
|
||||
searchStyle (){
|
||||
this.$store.commit('searchStyle',this.jdata.params.style)
|
||||
// console.log(this.data.params.style)
|
||||
},
|
||||
handleScroll() {
|
||||
this.scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
|
||||
this.scrollTop >= this.searchTop? this.tabbarFixed = true : this.tabbarFixed = false;
|
||||
},
|
||||
goClassify(){
|
||||
uni.switchTab({
|
||||
url: '/pages/classify/classify'
|
||||
});
|
||||
// this.$common.navigateTo('/pages/classify/classify')
|
||||
},
|
||||
showSliderInfo(type, val) {
|
||||
console.log(val)
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
console.log("11")
|
||||
if (type == 1) {
|
||||
if (val.indexOf('http') != -1) {
|
||||
// #ifdef H5
|
||||
window.location.href = val
|
||||
// #endif
|
||||
} else {
|
||||
// #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
|
||||
if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
|
||||
uni.switchTab({
|
||||
url: val
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
this.$common.navigateTo(val);
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
} else if (type == 2) {
|
||||
// 商品详情
|
||||
this.goodsDetail(val)
|
||||
} else if (type == 3) {
|
||||
// 文章详情
|
||||
this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
|
||||
} else if (type == 4) {
|
||||
// console.log("11")
|
||||
// 文章列表
|
||||
this.$common.navigateTo('/pages/article/list?cid=' + val)
|
||||
} else if (type == 5) {
|
||||
//智能表单
|
||||
this.$common.navigateTo('/pages/form/detail/form?id=' + val)
|
||||
}
|
||||
},
|
||||
//跳转到商品详情页面
|
||||
goodsDetail: function(id) {
|
||||
let url = '/pages/goods/index/index?id=' + id;
|
||||
this.$common.navigateTo(url);
|
||||
},
|
||||
},
|
||||
onPageScroll(){
|
||||
var _this = this;
|
||||
// #ifdef MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query.select('.search').boundingClientRect(function(res){
|
||||
if(res.top<0){
|
||||
_this.tabbarFixed = true ;
|
||||
}else{
|
||||
_this.tabbarFixed = false;
|
||||
}
|
||||
}).exec()
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.tabbar-list{
|
||||
padding: 10rpx 0;
|
||||
background-color: #fff;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
.tabbar-item{
|
||||
display: inline-block;
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
.tabbar-item:first-of-type{
|
||||
color: #FF7159;
|
||||
}
|
||||
.active-tabbar{
|
||||
display: none;
|
||||
}
|
||||
.tabbar-item:first-of-type .active-tabbar{
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 4rpx;
|
||||
margin: 10rpx auto 0;
|
||||
background-color: #FF7159;
|
||||
}
|
||||
.tabbar-fixed{
|
||||
position: fixed;
|
||||
top: 104rpx;
|
||||
transition: all .5s;
|
||||
z-index: 999;
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
59
mallplusui-uniapp-app/components/jshop/jshop-textarea.vue
Normal file
59
mallplusui-uniapp-app/components/jshop/jshop-textarea.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<view class="clearfix">
|
||||
<view class="textarea bottom-cell-group" >
|
||||
<jshopContent :content="jdata.params" v-if="jdata.params"></jshopContent>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import htmlParser from '@/common/html-parser'
|
||||
import jshopContent from '@/components/jshop/jshop-content.vue'//视频和文本解析组件
|
||||
|
||||
export default {
|
||||
components: {
|
||||
jshopContent
|
||||
},
|
||||
name: "jshoptextarea",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Object,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
//this.jdata.params = htmlParser(this.jdata.params)
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.textarea{
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
padding: 10upx 26upx;
|
||||
/* height: 40upx; */
|
||||
}
|
||||
.textarea p img{
|
||||
width: 100% !important;
|
||||
}
|
||||
.textarea div{
|
||||
background-color: #000;
|
||||
}
|
||||
.textarea p {
|
||||
background-color: #000;
|
||||
}
|
||||
.clearfix:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
</style>
|
||||
30
mallplusui-uniapp-app/components/jshop/jshop-video.vue
Normal file
30
mallplusui-uniapp-app/components/jshop/jshop-video.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<view class="video bottom-cell-group" >
|
||||
<video :src="jdata.options.video_link" :poster="jdata.options.video_img" controls></video>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "jshopvideo",
|
||||
props: {
|
||||
jdata:{
|
||||
type: Object,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
onLoad(){
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.video video{
|
||||
width: 100%;
|
||||
min-height: 200upx;
|
||||
}
|
||||
</style>
|
||||
88
mallplusui-uniapp-app/components/jshop/jshop.vue
Normal file
88
mallplusui-uniapp-app/components/jshop/jshop.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<view>
|
||||
<block v-for="(item,index) in jdata" :key="index">
|
||||
<jshopsearch :jdata="item" v-if="item.components=='search' "></jshopsearch>
|
||||
<jshoptabbar :jdata="item" v-if="item.components=='tabBar' "></jshoptabbar>
|
||||
<jshopnotice :jdata="item" v-if="item.components=='notice' "></jshopnotice>
|
||||
<jshopimgSlide :jdata="item" v-if="item.components=='banner' "></jshopimgSlide>
|
||||
<jshopcoupon :jdata="item" v-if="item.components=='coupon' "></jshopcoupon>
|
||||
<jshopblank :jdata="item" v-if="item.components=='blank' "></jshopblank>
|
||||
<jshoptextarea :jdata="item" v-if="item.components=='textarea' "></jshoptextarea>
|
||||
<jshopvideo :jdata="item" v-if="item.components=='video' "></jshopvideo>
|
||||
<jshopimgWindow :jdata="item" v-if="item.components=='imgWin' "></jshopimgWindow>
|
||||
<jshopimgSingle :jdata="item" v-if="item.components=='imgImgSlide' "></jshopimgSingle>
|
||||
<jshopgoods :jdata="item" v-if="item.components=='shuanglieshangpin' "></jshopgoods>
|
||||
<jshopslidegoods :jdata="item" v-if="item.components=='danlieshangpin' "></jshopslidegoods>
|
||||
|
||||
<jshoparticle :jdata="item" v-if="item.components=='article' "></jshoparticle>
|
||||
<jshoparticleClassify :jdata="item" v-if="item.components=='articleClassify' "></jshoparticleClassify>
|
||||
<jshopnavBar :jdata="item" v-if="item.components=='xuanxiangqia' "></jshopnavBar>
|
||||
<jshopgroupPurchase :jdata="item" v-if="item.components=='groupPurchase' "></jshopgroupPurchase>
|
||||
<jshoprecord :jdata="item" v-if="item.components=='record' "></jshoprecord>
|
||||
<jshoppintuan :jdata="item" v-if="item.components=='pintuan' "></jshoppintuan>
|
||||
<jshopadpop :jdata="item" v-if="item.components=='imgGroup' "></jshopadpop>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 吉海科技jshop小程序插件集合。
|
||||
* author:novice
|
||||
* date:2019:05:20
|
||||
*/
|
||||
import uniCountdown from '@/components/uni-countdown/uni-countdown.vue'
|
||||
import jshopimgSlide from '@/components/jshop/jshop-imgSlide.vue'
|
||||
import jshopsearch from '@/components/jshop/jshop-search.vue'
|
||||
import jshopnotice from '@/components/jshop/jshop-notice.vue'
|
||||
import jshopcoupon from '@/components/jshop/jshop-coupon.vue'
|
||||
import jshopblank from '@/components/jshop/jshop-blank.vue'
|
||||
import jshoptextarea from '@/components/jshop/jshop-textarea.vue'
|
||||
import jshopvideo from '@/components/jshop/jshop-video.vue'
|
||||
import jshopimgWindow from '@/components/jshop/jshop-imgWindow.vue'
|
||||
import jshopimgSingle from '@/components/jshop/jshop-imgSingle.vue'
|
||||
import jshopgoods from '@/components/jshop/jshop-goods.vue'
|
||||
import jshoponegoods from '@/components/jshop/jshop-onegoods.vue'
|
||||
import jshopslidegoods from '@/components/jshop/jshop-slidegoods.vue'
|
||||
import jshoparticle from '@/components/jshop/jshop-article.vue'
|
||||
import jshoparticleClassify from '@/components/jshop/jshop-articleClassify.vue'
|
||||
import jshopnavBar from '@/components/jshop/jshop-navBar.vue'
|
||||
import jshopgroupPurchase from '@/components/jshop/jshop-groupPurchase.vue'
|
||||
import jshoprecord from '@/components/jshop/jshop-record.vue'
|
||||
import jshoppintuan from '@/components/jshop/jshop-pintuan.vue'
|
||||
import jshoptabbar from '@/components/jshop/jshop-tabbar.vue'
|
||||
import jshopadpop from '@/components/jshop/jshop-adpop.vue'
|
||||
|
||||
export default {
|
||||
name: 'jshop',
|
||||
components: {
|
||||
jshopimgSlide,
|
||||
jshopsearch,
|
||||
jshopnotice,
|
||||
jshoponegoods,
|
||||
jshopslidegoods,
|
||||
jshopcoupon,
|
||||
jshopblank,
|
||||
jshoptextarea,
|
||||
jshopvideo,
|
||||
jshopimgWindow,
|
||||
jshopimgSingle,
|
||||
jshopgoods,
|
||||
jshoparticle,
|
||||
jshoparticleClassify,
|
||||
jshopnavBar,
|
||||
jshopgroupPurchase,
|
||||
jshoprecord,
|
||||
jshoppintuan,
|
||||
jshoptabbar,
|
||||
jshopadpop
|
||||
},
|
||||
props: {
|
||||
jdata: {
|
||||
default: function() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
284
mallplusui-uniapp-app/components/jshop/test
Normal file
284
mallplusui-uniapp-app/components/jshop/test
Normal file
@@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<view class="index-goods">
|
||||
<!-- 列表平铺两列三列 -->
|
||||
<view class='img-grids bottom-cell-group'
|
||||
v-if="jdata.params.column == '2' && jdata.params.display == 'list' || jdata.params.column == '3' && jdata.params.display == 'list'"
|
||||
v-bind:class="'column'+jdata.params.column">
|
||||
<view class='cell-item right-img' v-if="jdata.params.title != ''">
|
||||
<view class='cell-item-hd'>
|
||||
<view class='cell-hd-title'>{{jdata.params.title}}</view>
|
||||
</view>
|
||||
<view class='cell-item-bd'>
|
||||
</view>
|
||||
<view class='cell-item-ft' v-if="jdata.params.lookMore == 'true'">
|
||||
|
||||
<text class='cell-ft-text' @click="goodsList({cat_id: jdata.params.classifyId,brand_id:jdata.params.brandId})">查看更多</text>
|
||||
<image class='cell-ft-next icon' src='/static/image/right.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class='img-grids'> -->
|
||||
<view class="" v-if="count">
|
||||
<view class="img-grids-item" v-for="item in jdata.params.list" :key="item.id" @click="goodsDetail(item.id)">
|
||||
<image
|
||||
class="img-grids-item-t have-none"
|
||||
:src="item.image_url"
|
||||
mode='aspectFill'
|
||||
></image>
|
||||
<view class="img-grids-item-b">
|
||||
<view class="goods-name grids-goods-name">
|
||||
{{item.name}}
|
||||
</view>
|
||||
<view class="goods-item-c">
|
||||
<view class="goods-price red-price">¥{{item.price}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else-if="!count && !jdata.params.listAjax">
|
||||
<view class='img-grids-item'>
|
||||
<image class='img-grids-item-t have-none' src='' mode=''></image>
|
||||
<view class='img-grids-item-b'>
|
||||
<view class='goods-name grids-goods-name have-none'></view>
|
||||
<view class='goods-item-c'>
|
||||
<view class='goods-price red-price have-none'></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='img-grids-item'>
|
||||
<image class='img-grids-item-t have-none' src='' mode=''></image>
|
||||
<view class='img-grids-item-b'>
|
||||
<view class='goods-name grids-goods-name have-none'></view>
|
||||
<view class='goods-item-c'>
|
||||
<view class='goods-price red-price have-none'></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='img-grids-item'>
|
||||
<image class='img-grids-item-t have-none' src='' mode=''></image>
|
||||
<view class='img-grids-item-b'>
|
||||
<view class='goods-name grids-goods-name have-none'></view>
|
||||
<view class='goods-item-c'>
|
||||
<view class='goods-price red-price have-none'></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view v-else="">
|
||||
<scroll-view class='swiper-list' scroll-x="true"></scroll-view>
|
||||
</view> -->
|
||||
<!-- </view> -->
|
||||
</view>
|
||||
|
||||
<!-- 列表平铺单列 -->
|
||||
<view class="img-list bottom-cell-group"
|
||||
v-if="jdata.params.column == '1' && jdata.params.display == 'list'" >
|
||||
<view class='cell-item right-img' v-if="jdata.params.title != ''">
|
||||
<view class='cell-item-hd'>
|
||||
<view class='cell-hd-title'>{{jdata.params.title}}</view>
|
||||
</view>
|
||||
<view class='cell-item-bd'>
|
||||
</view>
|
||||
<view class='cell-item-ft' v-if="jdata.params.lookMore == 'true'">
|
||||
|
||||
<text class='cell-ft-text' @click="goodsList({cat_id: jdata.params.classifyId,brand_id:jdata.params.brandId})">查看更多</text>
|
||||
<image class='cell-ft-next icon' src='/static/image/right.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="count">
|
||||
<view class="img-list-item" v-for="(item, index) in jdata.params.list" :key="index" @click="goodsDetail(item.id)">
|
||||
<image class="img-list-item-l have-none" :src="item.image_url" mode='aspectFill'></image>
|
||||
<view class="img-list-item-r">
|
||||
<view class="goods-name list-goods-name">
|
||||
{{item.name}}
|
||||
</view>
|
||||
<view class="goods-item-c">
|
||||
<view class="goods-price red-price">¥{{item.price}}</view>
|
||||
<view class="goods-buy">
|
||||
<view class="goods-salesvolume" v-if="item.comments_count > 0">{{item.comments_count}}条评论</view>
|
||||
<view class="goods-salesvolume" v-else-if="item.comments_count <= 0">暂无评论</view>
|
||||
<image class="goods-cart" src="/static/image/ic-car.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="order-none" v-else>
|
||||
<image class="order-none-img" src="/static/image/order.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 横向滚动 -->
|
||||
<view class='img-grids bottom-cell-group'
|
||||
v-if="jdata.params.column == '2' && jdata.params.display == 'slide' || jdata.params.column == '3' && jdata.params.display == 'slide'"
|
||||
v-bind:class="'slide'+jdata.params.column">
|
||||
<view class='cell-item right-img' v-if="jdata.params.title != ''">
|
||||
<view class='cell-item-hd'>
|
||||
<view class='cell-hd-title'>{{jdata.params.title}}</view>
|
||||
</view>
|
||||
<view class='cell-item-bd'>
|
||||
</view>
|
||||
<view class='cell-item-ft' v-if="jdata.params.lookMore == 'true'">
|
||||
|
||||
<text class='cell-ft-text' @click="goodsList({cat_id: jdata.params.classifyId,brand_id:jdata.params.brandId})">查看更多</text>
|
||||
<image class='cell-ft-next icon' src='/static/image/right.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class='swiper-grids'>
|
||||
<scroll-view class='swiper-list' scroll-x="true" v-if="count">
|
||||
<view class='img-grids-item' v-for="item in jdata.params.list" :key="item.id" @click="goodsDetail(item.id)">
|
||||
<image class='img-grids-item-t have-none' :src='item.image_url' mode='aspectFill'></image>
|
||||
<view class='img-grids-item-b'>
|
||||
<view class='goods-name grids-goods-name' >
|
||||
{{ item.name|substr }}
|
||||
</view>
|
||||
<view class='goods-item-c'>
|
||||
<view class='goods-price red-price'>¥{{ item.price }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view v-else-if="!goodsListOfHotAjax && !goodsListOfHot.length">
|
||||
<scroll-view class='swiper-list' scroll-x="true">
|
||||
<view class='img-grids-item'>
|
||||
<image class='img-grids-item-t have-none' src='' mode='aspectFill'></image>
|
||||
<view class='img-grids-item-b'>
|
||||
<view class='goods-name grids-goods-name have-none'></view>
|
||||
<view class='goods-item-c'>
|
||||
<view class='goods-price red-price have-none'></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='img-grids-item'>
|
||||
<image class='img-grids-item-t have-none' src='' mode='aspectFill'></image>
|
||||
<view class='img-grids-item-b'>
|
||||
<view class='goods-name grids-goods-name have-none'></view>
|
||||
<view class='goods-item-c'>
|
||||
<view class='goods-price red-price have-none'></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class='img-grids-item'>
|
||||
<image class='img-grids-item-t have-none' src='' mode=''></image>
|
||||
<view class='img-grids-item-b'>
|
||||
<view class='goods-name grids-goods-name have-none'></view>
|
||||
<view class='goods-item-c'>
|
||||
<view class='goods-price red-price have-none'></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view v-else="">
|
||||
<scroll-view class='swiper-list' scroll-x="true"></scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {goods} from '@/config/mixins.js'
|
||||
export default {
|
||||
filters:{
|
||||
substr(val) {
|
||||
if (val.length == 0 || val == undefined) {
|
||||
return false;
|
||||
} else if (val.length > 13) {
|
||||
return val.substring(0, 13) + "...";
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
},
|
||||
mixins: [goods],
|
||||
name: "jshopgoods",
|
||||
props: {
|
||||
jdata:{
|
||||
// type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
count() {
|
||||
return (this.jdata.params.list.length > 0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//跳转到商品详情页面
|
||||
goodsDetail: function(id) {
|
||||
let url = '/pages/goods/index/index?id=' + id;
|
||||
this.$common.navigateTo(url);
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.cell-item {
|
||||
border: none;
|
||||
/* padding-bottom: 0; */
|
||||
}
|
||||
.cell-ft-text {
|
||||
font-size: 22upx;
|
||||
color: #999;
|
||||
}
|
||||
.img-grids,.img-list{
|
||||
/* margin-top: 20upx; */
|
||||
background-color: #fff;
|
||||
}
|
||||
.img-grids-item{
|
||||
display: inline-table;
|
||||
margin-top: 0;
|
||||
margin-bottom: 14upx;
|
||||
}
|
||||
.column3 .img-grids-item{
|
||||
width: 230upx;
|
||||
height: 364rpx !important;
|
||||
margin: 15upx;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 6upx;
|
||||
}
|
||||
.column3 .img-grids-item:nth-child(3n){
|
||||
margin-right: 15upx;
|
||||
}
|
||||
.column3 .img-grids-item-t{
|
||||
width: 230upx;
|
||||
height: 230upx;
|
||||
}
|
||||
.column3 .grids-goods-name{
|
||||
font-size: 24upx;
|
||||
/* height: 68upx; */
|
||||
/* min-height: 54rpx; */
|
||||
}
|
||||
.column3 .img-grids-item-b{
|
||||
padding: 0 8upx 8upx;
|
||||
}
|
||||
.column3 .goods-price{
|
||||
font-size: 26upx;
|
||||
}
|
||||
.slide3 .img-grids-item{
|
||||
width: 200upx;
|
||||
}
|
||||
.slide3 .img-grids-item-t{
|
||||
width: 200upx;
|
||||
height: 200upx;
|
||||
}
|
||||
.slide3 .grids-goods-name{
|
||||
font-size: 24rpx;
|
||||
height: 66rpx;
|
||||
}
|
||||
.index-goods .img-grids-item{
|
||||
display: inline-block;
|
||||
margin-top: 0;
|
||||
}
|
||||
.index-goods .img-list-item{
|
||||
padding: 0upx 26upx;
|
||||
margin-bottom: 14upx;
|
||||
}
|
||||
.index-goods .img-list{
|
||||
padding-bottom: 10upx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<view class="cpr">
|
||||
<view class="color-9">
|
||||
{{sysInfo.company}} © {{sysInfo.subdomain}} 版权所有
|
||||
</view>
|
||||
<view class="color-9 beian">
|
||||
<view v-if="sysInfo.code"><a href="http://www.beian.miit.gov.cn/publish/query/indexFirst.action" target="_blank">冀ICP备10002647号-11</a></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
sysInfo : this.$db.get('sysInfo')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.cpr{
|
||||
text-align: center;
|
||||
font-size: 24upx;
|
||||
margin: 20upx 0;
|
||||
}
|
||||
.beian a{
|
||||
text-decoration: none;
|
||||
color: #999 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<view class="serach">
|
||||
<view class="content" :style="{'border-radius':radius+'px'}">
|
||||
<!-- HM修改 增加进入输入状态的点击范围 -->
|
||||
<view class="content-box" :class="{'center':mode === 2}" @click="getFocus">
|
||||
<text class="icon icon-serach"></text>
|
||||
<!-- HM修改 增加placeholder input confirm-type confirm-->
|
||||
<input :placeholder="placeholder" @input="inputChange" confirm-type="search" @confirm="triggerConfirm" class="input" :class="{'center':!active && mode === 2}" :focus="isFocus" v-model="inputVal" @focus="focus" @blur="blur"/>
|
||||
<!-- <view v-if="!active && mode === 2" class="input sub" @click="getFocus">请输入搜索内容</view> -->
|
||||
<!-- HM修改 @click换成@click.stop阻止冒泡 -->
|
||||
<text v-if="isDelShow" class="icon icon-del" @click.stop="clear"></text>
|
||||
</view>
|
||||
<view v-show="(active&&show&&button === 'inside')||(isDelShow && button === 'inside')" class="serachBtn" @click="search">
|
||||
搜索
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="button === 'outside'" class="button" :class="{'active':show||active}" @click="search">
|
||||
<view class="button-item">{{!show?searchName:'搜索'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
mode: {
|
||||
value: Number,
|
||||
default: 1
|
||||
},
|
||||
//HM修改 定义默认搜索关键词(水印文字)
|
||||
placeholder:{
|
||||
value: String,
|
||||
default: '请输入搜索内容'
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default:false
|
||||
},
|
||||
button: {
|
||||
value: String,
|
||||
default: 'outside'
|
||||
},
|
||||
show: {
|
||||
value: Boolean,
|
||||
default: true
|
||||
},
|
||||
radius: {
|
||||
value: String,
|
||||
default: 60
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: false,
|
||||
inputVal: '',
|
||||
searchName: '取消',
|
||||
isDelShow: false,
|
||||
isFocus: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
//HM修改 触发组件confirm事件
|
||||
triggerConfirm(){
|
||||
this.$emit('confirm', false);
|
||||
},
|
||||
//HM修改 触发组件input事件
|
||||
inputChange(event){
|
||||
var keyword = event.detail.value;
|
||||
this.$emit('input', keyword);
|
||||
if (this.inputVal) {
|
||||
this.isDelShow = true;
|
||||
}
|
||||
},
|
||||
focus() {
|
||||
this.active = true;
|
||||
//HM修改 增加获取焦点判断
|
||||
if (this.inputVal) {
|
||||
this.isDelShow = true;
|
||||
}
|
||||
},
|
||||
blur() {
|
||||
this.isFocus = false;
|
||||
if (!this.inputVal) {
|
||||
this.active = false;
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
//HM修改 收起键盘
|
||||
uni.hideKeyboard();
|
||||
this.isFocus = false;
|
||||
this.inputVal = '';
|
||||
this.active = false;
|
||||
//HM修改 清空内容时候触发组件input
|
||||
this.$emit('input', '');
|
||||
//this.$emit('search', '');//HM修改 清空内容时候不进行搜索
|
||||
|
||||
},
|
||||
getFocus() {
|
||||
this.isFocus = true;
|
||||
},
|
||||
search() {
|
||||
//HM修改 增加点击取消时候退出输入状态,内容为空时,输入默认关键字
|
||||
if (!this.inputVal) {
|
||||
if(!this.show&&this.searchName == '取消'){
|
||||
uni.hideKeyboard();
|
||||
this.isFocus = false;
|
||||
this.active = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log(this.inputVal);
|
||||
this.$emit('search', this.inputVal?this.inputVal:this.placeholder);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
inputVal(newVal) {
|
||||
if (newVal) {
|
||||
this.searchName = '搜索';
|
||||
//this.isDelShow = true; //HM修改 直接点击页面预设关键字样式异常,注销
|
||||
} else {
|
||||
this.searchName = '取消';
|
||||
this.isDelShow = false;
|
||||
}
|
||||
},
|
||||
//HM修改 双向绑定
|
||||
value(val) {
|
||||
this.inputVal = val;
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.serach {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
//border-bottom: 1px #f5f5f5 solid; //HM修改 去掉边框
|
||||
box-sizing: border-box;
|
||||
font-size: $uni-font-size-base;
|
||||
.content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 60upx;
|
||||
//border: 1px #ccc solid; //HM修改 去掉边框
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
transition: all 0.2s linear;
|
||||
border-radius: 30px;
|
||||
|
||||
.content-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&.center {
|
||||
justify-content: center;
|
||||
}
|
||||
.icon {
|
||||
padding: 0 15upx;
|
||||
&.icon-del {
|
||||
font-size: 38upx;
|
||||
&:before {content:"\e644";}
|
||||
}
|
||||
&.icon-serach:before {content:"\e61c";}
|
||||
}
|
||||
.input {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
line-height: 60upx;
|
||||
height: 60upx;
|
||||
transition: all 0.2s linear;
|
||||
&.center {
|
||||
width: 200upx;
|
||||
}
|
||||
&.sub {
|
||||
// position: absolute;
|
||||
width: auto;
|
||||
color: grey;
|
||||
}
|
||||
}
|
||||
}
|
||||
.serachBtn {
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
padding: 0 30upx;
|
||||
//HM修改 按钮背景色
|
||||
background:linear-gradient(to right,#ff9801,#ff570a);
|
||||
//background: $uni-color-success;
|
||||
line-height: 60upx;
|
||||
color: #fff;
|
||||
//border-left: 1px #ccc solid; //HM修改 去掉边框
|
||||
transition: all 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: 0;
|
||||
transition: all 0.2s linear;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
&.active {
|
||||
padding-left: 15upx;
|
||||
width: 100upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
//HM修改 把字体改成本地加载
|
||||
@font-face {font-family:"iconfont";src:url('data:application/x-font-woff;charset=utf-8;base64,AAEAAAALAIAAAwAwR1NVQrD+s+0AAAE4AAAAQk9TLzI8fEg3AAABfAAAAFZjbWFws6gbWQAAAeQAAAGcZ2x5ZqgAaogAAAOMAAABMGhlYWQTyEk0AAAA4AAAADZoaGVhB90DhQAAALwAAAAkaG10eBAA//8AAAHUAAAAEGxvY2EA0gBOAAADgAAAAAptYXhwARIANgAAARgAAAAgbmFtZT5U/n0AAAS8AAACbXBvc3SanfjSAAAHLAAAAEUAAQAAA4D/gABcBAD//wAABAAAAQAAAAAAAAAAAAAAAAAAAAQAAQAAAAEAAL8Cm/NfDzz1AAsEAAAAAADYVQKbAAAAANhVApv///+ABAADgQAAAAgAAgAAAAAAAAABAAAABAAqAAQAAAAAAAIAAAAKAAoAAAD/AAAAAAAAAAEAAAAKAB4ALAABREZMVAAIAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAAAAQQAAZAABQAIAokCzAAAAI8CiQLMAAAB6wAyAQgAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA5gbmRAOA/4AAXAOBAIAAAAABAAAAAAAABAAAAAQA//8EAAAABAAAAAAAAAUAAAADAAAALAAAAAQAAAFoAAEAAAAAAGIAAwABAAAALAADAAoAAAFoAAQANgAAAAgACAACAADmBuYc5kT//wAA5gbmHOZE//8AAAAAAAAAAQAIAAgACAAAAAIAAQADAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAA0AAAAAAAAAAMAAOYGAADmBgAAAAIAAOYcAADmHAAAAAEAAOZEAADmRAAAAAMAAAAAADoATgCYAAAAAv///4AEAAOAABMAHwAABQYiLwEGJCcmAjc2JBcWEgcXFhQBJiAHBhQXFiA3NjQD7RQyFMaG/sl9hw2BiQFqjXgTZccT/sBo/spoPz9oATZoPm0TE8dhDG6FAW2OhwaGfv6+h8YUMgLThoZV0FWGhlnMAAABAAD/gAMAA4EABQAACQE1CQE1AQACAP6IAXgBgP4AiAF4AXiIAAAABAAA//4DlAMnABAAIQAlACkAAAUuAzQ+AjIWFxYQBw4BAyIOAhQeAjI2NzYQJy4BFwEnAQU3AQcCAFKScz09c5Kkkjp2djqSUkiBZjU1ZoGQgTNoaDOBfP6YIAFo/qQgAVwgAgE9cpOjknM9PTl8/r18OT0C9zVmgZCBZTU1Mm4BHW0zNb/+mCABZysf/qQgAAAAAAAAEgDeAAEAAAAAAAAAFQAAAAEAAAAAAAEACAAVAAEAAAAAAAIABwAdAAEAAAAAAAMACAAkAAEAAAAAAAQACAAsAAEAAAAAAAUACwA0AAEAAAAAAAYACAA/AAEAAAAAAAoAKwBHAAEAAAAAAAsAEwByAAMAAQQJAAAAKgCFAAMAAQQJAAEAEACvAAMAAQQJAAIADgC/AAMAAQQJAAMAEADNAAMAAQQJAAQAEADdAAMAAQQJAAUAFgDtAAMAAQQJAAYAEAEDAAMAAQQJAAoAVgETAAMAAQQJAAsAJgFpCkNyZWF0ZWQgYnkgaWNvbmZvbnQKaWNvbmZvbnRSZWd1bGFyaWNvbmZvbnRpY29uZm9udFZlcnNpb24gMS4waWNvbmZvbnRHZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuaHR0cDovL2ZvbnRlbGxvLmNvbQAKAEMAcgBlAGEAdABlAGQAIABiAHkAIABpAGMAbwBuAGYAbwBuAHQACgBpAGMAbwBuAGYAbwBuAHQAUgBlAGcAdQBsAGEAcgBpAGMAbwBuAGYAbwBuAHQAaQBjAG8AbgBmAG8AbgB0AFYAZQByAHMAaQBvAG4AIAAxAC4AMABpAGMAbwBuAGYAbwBuAHQARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAAIAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAECAQMBBAEFAAZzb3VzdW8IamlhbnRvdTQHc2hhbmNodQAAAAAA');}
|
||||
|
||||
|
||||
.icon {
|
||||
font-family: iconfont;
|
||||
font-size: 32upx;
|
||||
font-style: normal;
|
||||
color: #999;
|
||||
|
||||
}
|
||||
</style>
|
||||
119
mallplusui-uniapp-app/components/mix-list-cell.vue
Normal file
119
mallplusui-uniapp-app/components/mix-list-cell.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
|
||||
<view class="mix-list-cell" :class="border" @click="eventClick" hover-class="cell-hover" :hover-stay-time="50">
|
||||
<text
|
||||
v-if="icon"
|
||||
class="cell-icon yticon"
|
||||
:style="[{
|
||||
color: iconColor,
|
||||
}]"
|
||||
:class="icon"
|
||||
></text>
|
||||
<text class="cell-tit clamp">{{title}}</text>
|
||||
<text v-if="tips" class="cell-tip">{{tips}}</text>
|
||||
<text class="cell-more yticon"
|
||||
:class="typeList[navigateType]"
|
||||
></text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 简单封装了下, 应用范围比较狭窄,可以在此基础上进行扩展使用
|
||||
* 比如加入image, iconSize可控等
|
||||
*/
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
typeList: {
|
||||
left: 'icon-zuo',
|
||||
right: 'icon-you',
|
||||
up: 'icon-shang',
|
||||
down: 'icon-xia'
|
||||
},
|
||||
}
|
||||
},
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '标题'
|
||||
},
|
||||
tips: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
navigateType: {
|
||||
type: String,
|
||||
default: 'right'
|
||||
},
|
||||
border: {
|
||||
type: String,
|
||||
default: 'b-b'
|
||||
},
|
||||
hoverClass: {
|
||||
type: String,
|
||||
default: 'cell-hover'
|
||||
},
|
||||
iconColor: {
|
||||
type: String,
|
||||
default: '#333'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
eventClick(){
|
||||
this.$emit('eventClick');
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
|
||||
.icon .mix-list-cell.b-b:after{
|
||||
left: 90upx;
|
||||
}
|
||||
.mix-list-cell{
|
||||
display:flex;
|
||||
align-items:baseline;
|
||||
padding: 20upx $page-row-spacing;
|
||||
line-height:60upx;
|
||||
position:relative;
|
||||
|
||||
&.cell-hover{
|
||||
background:#fafafa;
|
||||
}
|
||||
&.b-b:after{
|
||||
left: 30upx;
|
||||
}
|
||||
|
||||
.cell-icon{
|
||||
align-self:center;
|
||||
width:56upx;
|
||||
max-height:60upx;
|
||||
font-size:38upx;
|
||||
}
|
||||
.cell-more{
|
||||
align-self: center;
|
||||
font-size:30upx;
|
||||
color:$font-color-base;
|
||||
margin-left:$uni-spacing-row-sm;
|
||||
}
|
||||
.cell-tit{
|
||||
flex: 1;
|
||||
font-size: $font-base;
|
||||
color: $font-color-dark;
|
||||
margin-right:10upx;
|
||||
}
|
||||
.cell-tip{
|
||||
font-size: $font-sm+2upx;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
68
mallplusui-uniapp-app/components/mix-loading/mix-loading.vue
Normal file
68
mallplusui-uniapp-app/components/mix-loading/mix-loading.vue
Normal file
File diff suppressed because one or more lines are too long
12542
mallplusui-uniapp-app/components/mpvue-citypicker/city-data/area.js
Normal file
12542
mallplusui-uniapp-app/components/mpvue-citypicker/city-data/area.js
Normal file
File diff suppressed because it is too large
Load Diff
1503
mallplusui-uniapp-app/components/mpvue-citypicker/city-data/city.js
Normal file
1503
mallplusui-uniapp-app/components/mpvue-citypicker/city-data/city.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,139 @@
|
||||
/* eslint-disable */
|
||||
var provinceData = [{
|
||||
"label": "北京市",
|
||||
"value": "11"
|
||||
},
|
||||
{
|
||||
"label": "天津市",
|
||||
"value": "12"
|
||||
},
|
||||
{
|
||||
"label": "河北省",
|
||||
"value": "13"
|
||||
},
|
||||
{
|
||||
"label": "山西省",
|
||||
"value": "14"
|
||||
},
|
||||
{
|
||||
"label": "内蒙古自治区",
|
||||
"value": "15"
|
||||
},
|
||||
{
|
||||
"label": "辽宁省",
|
||||
"value": "21"
|
||||
},
|
||||
{
|
||||
"label": "吉林省",
|
||||
"value": "22"
|
||||
},
|
||||
{
|
||||
"label": "黑龙江省",
|
||||
"value": "23"
|
||||
},
|
||||
{
|
||||
"label": "上海市",
|
||||
"value": "31"
|
||||
},
|
||||
{
|
||||
"label": "江苏省",
|
||||
"value": "32"
|
||||
},
|
||||
{
|
||||
"label": "浙江省",
|
||||
"value": "33"
|
||||
},
|
||||
{
|
||||
"label": "安徽省",
|
||||
"value": "34"
|
||||
},
|
||||
{
|
||||
"label": "福建省",
|
||||
"value": "35"
|
||||
},
|
||||
{
|
||||
"label": "江西省",
|
||||
"value": "36"
|
||||
},
|
||||
{
|
||||
"label": "山东省",
|
||||
"value": "37"
|
||||
},
|
||||
{
|
||||
"label": "河南省",
|
||||
"value": "41"
|
||||
},
|
||||
{
|
||||
"label": "湖北省",
|
||||
"value": "42"
|
||||
},
|
||||
{
|
||||
"label": "湖南省",
|
||||
"value": "43"
|
||||
},
|
||||
{
|
||||
"label": "广东省",
|
||||
"value": "44"
|
||||
},
|
||||
{
|
||||
"label": "广西壮族自治区",
|
||||
"value": "45"
|
||||
},
|
||||
{
|
||||
"label": "海南省",
|
||||
"value": "46"
|
||||
},
|
||||
{
|
||||
"label": "重庆市",
|
||||
"value": "50"
|
||||
},
|
||||
{
|
||||
"label": "四川省",
|
||||
"value": "51"
|
||||
},
|
||||
{
|
||||
"label": "贵州省",
|
||||
"value": "52"
|
||||
},
|
||||
{
|
||||
"label": "云南省",
|
||||
"value": "53"
|
||||
},
|
||||
{
|
||||
"label": "西藏自治区",
|
||||
"value": "54"
|
||||
},
|
||||
{
|
||||
"label": "陕西省",
|
||||
"value": "61"
|
||||
},
|
||||
{
|
||||
"label": "甘肃省",
|
||||
"value": "62"
|
||||
},
|
||||
{
|
||||
"label": "青海省",
|
||||
"value": "63"
|
||||
},
|
||||
{
|
||||
"label": "宁夏回族自治区",
|
||||
"value": "64"
|
||||
},
|
||||
{
|
||||
"label": "新疆维吾尔自治区",
|
||||
"value": "65"
|
||||
},
|
||||
{
|
||||
"label": "台湾",
|
||||
"value": "66"
|
||||
},
|
||||
{
|
||||
"label": "香港",
|
||||
"value": "67"
|
||||
},
|
||||
{
|
||||
"label": "澳门",
|
||||
"value": "68"
|
||||
}
|
||||
]
|
||||
export default provinceData;
|
||||
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<div class="mpvue-picker">
|
||||
<div :class="{'pickerMask':showPicker}" @click="maskClick" catchtouchmove="true"></div>
|
||||
<div class="mpvue-picker-content " :class="{'mpvue-picker-view-show':showPicker}">
|
||||
<div class="mpvue-picker__hd" catchtouchmove="true">
|
||||
<div class="mpvue-picker__action" @click="pickerCancel">取消</div>
|
||||
<div class="mpvue-picker__action" :style="{color:themeColor}" @click="pickerConfirm">确定</div>
|
||||
</div>
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange">
|
||||
<block>
|
||||
<picker-view-column>
|
||||
<div class="picker-item" v-for="(item,index) in provinceDataList" :key="index">{{item.label}}</div>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<div class="picker-item" v-for="(item,index) in cityDataList" :key="index">{{item.label}}</div>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<div class="picker-item" v-for="(item,index) in areaDataList" :key="index">{{item.label}}</div>
|
||||
</picker-view-column>
|
||||
</block>
|
||||
</picker-view>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import provinceData from './city-data/province.js';
|
||||
import cityData from './city-data/city.js';
|
||||
import areaData from './city-data/area.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickerValue: [0, 0, 0],
|
||||
provinceDataList: [],
|
||||
cityDataList: [],
|
||||
areaDataList: [],
|
||||
/* 是否显示控件 */
|
||||
showPicker: false,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
props: {
|
||||
/* 默认值 */
|
||||
pickerValueDefault: {
|
||||
type: Array,
|
||||
default(){
|
||||
return [0, 0, 0]
|
||||
}
|
||||
},
|
||||
/* 主题色 */
|
||||
themeColor: String
|
||||
},
|
||||
watch:{
|
||||
pickerValueDefault(){
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.handPickValueDefault(); // 对 pickerValueDefault 做兼容处理
|
||||
this.provinceDataList = provinceData;
|
||||
this.cityDataList = cityData[this.pickerValueDefault[0]];
|
||||
this.areaDataList = areaData[this.pickerValueDefault[0]][this.pickerValueDefault[1]];
|
||||
this.pickerValue = this.pickerValueDefault;
|
||||
},
|
||||
show() {
|
||||
setTimeout(() => {
|
||||
this.showPicker = true;
|
||||
}, 0);
|
||||
},
|
||||
maskClick() {
|
||||
this.pickerCancel();
|
||||
},
|
||||
pickerCancel() {
|
||||
this.showPicker = false;
|
||||
this._$emit('onCancel');
|
||||
},
|
||||
pickerConfirm(e) {
|
||||
this.showPicker = false;
|
||||
this._$emit('onConfirm');
|
||||
},
|
||||
showPickerView() {
|
||||
this.showPicker = true;
|
||||
},
|
||||
handPickValueDefault() {
|
||||
if (this.pickerValueDefault !== [0, 0, 0]) {
|
||||
if (this.pickerValueDefault[0] > provinceData.length - 1) {
|
||||
this.pickerValueDefault[0] = provinceData.length - 1;
|
||||
}
|
||||
if (this.pickerValueDefault[1] > cityData[this.pickerValueDefault[0]].length - 1) {
|
||||
this.pickerValueDefault[1] = cityData[this.pickerValueDefault[0]].length - 1;
|
||||
}
|
||||
if (this.pickerValueDefault[2] > areaData[this.pickerValueDefault[0]][this.pickerValueDefault[1]].length - 1) {
|
||||
this.pickerValueDefault[2] = areaData[this.pickerValueDefault[0]][this.pickerValueDefault[1]].length - 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
pickerChange(e) {
|
||||
let changePickerValue = e.mp.detail.value;
|
||||
if (this.pickerValue[0] !== changePickerValue[0]) {
|
||||
// 第一级发生滚动
|
||||
this.cityDataList = cityData[changePickerValue[0]];
|
||||
this.areaDataList = areaData[changePickerValue[0]][0];
|
||||
changePickerValue[1] = 0;
|
||||
changePickerValue[2] = 0;
|
||||
} else if (this.pickerValue[1] !== changePickerValue[1]) {
|
||||
// 第二级滚动
|
||||
this.areaDataList =
|
||||
areaData[changePickerValue[0]][changePickerValue[1]];
|
||||
changePickerValue[2] = 0;
|
||||
}
|
||||
this.pickerValue = changePickerValue;
|
||||
this._$emit('onChange');
|
||||
},
|
||||
_$emit(emitName) {
|
||||
let pickObj = {
|
||||
label: this._getLabel(),
|
||||
value: this.pickerValue,
|
||||
cityCode: this._getCityCode()
|
||||
};
|
||||
this.$emit(emitName, pickObj);
|
||||
},
|
||||
_getLabel() {
|
||||
let pcikerLabel =
|
||||
this.provinceDataList[this.pickerValue[0]].label +
|
||||
'-' +
|
||||
this.cityDataList[this.pickerValue[1]].label +
|
||||
'-' +
|
||||
this.areaDataList[this.pickerValue[2]].label;
|
||||
return pcikerLabel;
|
||||
},
|
||||
_getCityCode() {
|
||||
return this.areaDataList[this.pickerValue[2]].value;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.pickerMask {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
.mpvue-picker-content {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
transition: all 0.3s ease;
|
||||
transform: translateY(100%);
|
||||
z-index: 3000;
|
||||
}
|
||||
.mpvue-picker-view-show {
|
||||
transform: translateY(0);
|
||||
}
|
||||
.mpvue-picker__hd {
|
||||
display: flex;
|
||||
padding: 9px 15px;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
font-size: 17px;
|
||||
}
|
||||
.mpvue-picker__hd:after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
color: #e5e5e5;
|
||||
transform-origin: 0 100%;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.mpvue-picker__action {
|
||||
display: block;
|
||||
flex: 1;
|
||||
color: #1aad19;
|
||||
}
|
||||
.mpvue-picker__action:first-child {
|
||||
text-align: left;
|
||||
color: #888;
|
||||
}
|
||||
.mpvue-picker__action:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
.picker-item {
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
}
|
||||
.mpvue-picker-view {
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 238px;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
</style>
|
||||
463
mallplusui-uniapp-app/components/mpvue-picker/mpvuePicker.vue
Normal file
463
mallplusui-uniapp-app/components/mpvue-picker/mpvuePicker.vue
Normal file
@@ -0,0 +1,463 @@
|
||||
<template>
|
||||
<view class="mpvue-picker">
|
||||
<view :class="{'pickerMask':showPicker}" @click="maskClick" catchtouchmove="true"></view>
|
||||
<view class="mpvue-picker-content " :class="{'mpvue-picker-view-show':showPicker}">
|
||||
<view class="mpvue-picker__hd" catchtouchmove="true">
|
||||
<view class="mpvue-picker__action" @click="pickerCancel">取消</view>
|
||||
<view class="mpvue-picker__action" :style="{color:themeColor}" @click="pickerConfirm">确定</view>
|
||||
</view>
|
||||
<!-- 单列 -->
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange" v-if="mode==='selector' && pickerValueSingleArray.length > 0">
|
||||
<block>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueSingleArray" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
</block>
|
||||
</picker-view>
|
||||
<!-- 时间选择器 -->
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange" v-if="mode==='timeSelector'">
|
||||
<block>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueHour" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMinute" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
</block>
|
||||
</picker-view>
|
||||
<!-- 多列选择 -->
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange" v-if="mode==='multiSelector'">
|
||||
<block v-for="(n,index) in pickerValueMulArray.length" :key="index">
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index1) in pickerValueMulArray[n]" :key="index1">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
</block>
|
||||
</picker-view>
|
||||
<!-- 二级联动 -->
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChangeMul" v-if="mode==='multiLinkageSelector' && deepLength===2">
|
||||
<block>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMulTwoOne" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMulTwoTwo" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
</block>
|
||||
</picker-view>
|
||||
<!-- 三级联动 -->
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChangeMul" v-if="mode==='multiLinkageSelector' && deepLength===3">
|
||||
<block>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMulThreeOne" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMulThreeTwo" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMulThreeThree" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
</block>
|
||||
</picker-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickerChangeValue: [],
|
||||
pickerValue: [],
|
||||
pickerValueArrayChange: true,
|
||||
modeChange: false,
|
||||
pickerValueSingleArray: [],
|
||||
pickerValueHour: [],
|
||||
pickerValueMinute: [],
|
||||
pickerValueMulArray: [],
|
||||
pickerValueMulTwoOne: [],
|
||||
pickerValueMulTwoTwo: [],
|
||||
pickerValueMulThreeOne: [],
|
||||
pickerValueMulThreeTwo: [],
|
||||
pickerValueMulThreeThree: [],
|
||||
/* 是否显示控件 */
|
||||
showPicker: false,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
/* mode */
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'selector'
|
||||
},
|
||||
/* picker 数值 */
|
||||
pickerValueArray: {
|
||||
type: Array,
|
||||
default(){
|
||||
return []
|
||||
}
|
||||
},
|
||||
/* 默认值 */
|
||||
pickerValueDefault: {
|
||||
type: Array,
|
||||
default(){
|
||||
return []
|
||||
}
|
||||
},
|
||||
/* 几级联动 */
|
||||
deepLength: {
|
||||
type: Number,
|
||||
default: 2
|
||||
},
|
||||
/* 主题色 */
|
||||
themeColor: String
|
||||
},
|
||||
watch: {
|
||||
pickerValueArray(oldVal, newVal) {
|
||||
this.pickerValueArrayChange = true;
|
||||
},
|
||||
mode(oldVal, newVal) {
|
||||
this.modeChange = true;
|
||||
},
|
||||
pickerValueArray(val){
|
||||
this.initPicker(val);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initPicker(valueArray) {
|
||||
let pickerValueArray = valueArray;
|
||||
this.pickerValue = this.pickerValueDefault;
|
||||
// 初始化多级联动
|
||||
if (this.mode === 'selector') {
|
||||
this.pickerValueSingleArray = valueArray;
|
||||
} else if (this.mode === 'timeSelector') {
|
||||
this.modeChange = false;
|
||||
let hourArray = [];
|
||||
let minuteArray = [];
|
||||
for (let i = 0; i < 24; i++) {
|
||||
hourArray.push({
|
||||
value: i,
|
||||
label: i > 9 ? `${i} 时` : `0${i} 时`
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < 60; i++) {
|
||||
minuteArray.push({
|
||||
value: i,
|
||||
label: i > 9 ? `${i} 分` : `0${i} 分`
|
||||
});
|
||||
}
|
||||
this.pickerValueHour = hourArray;
|
||||
this.pickerValueMinute = minuteArray;
|
||||
} else if (this.mode === 'multiSelector') {
|
||||
this.pickerValueMulArray = valueArray;
|
||||
} else if (this.mode === 'multiLinkageSelector' && this.deepLength === 2) {
|
||||
// 两级联动
|
||||
let pickerValueMulTwoOne = [];
|
||||
let pickerValueMulTwoTwo = [];
|
||||
// 第一列
|
||||
for (let i = 0, length = pickerValueArray.length; i < length; i++) {
|
||||
pickerValueMulTwoOne.push(pickerValueArray[i]);
|
||||
}
|
||||
// 渲染第二列
|
||||
// 如果有设定的默认值
|
||||
if (this.pickerValueDefault.length === 2) {
|
||||
let num = this.pickerValueDefault[0];
|
||||
for (
|
||||
let i = 0, length = pickerValueArray[num].children.length; i < length; i++
|
||||
) {
|
||||
pickerValueMulTwoTwo.push(pickerValueArray[num].children[i]);
|
||||
}
|
||||
} else {
|
||||
for (
|
||||
let i = 0, length = pickerValueArray[0].children.length; i < length; i++
|
||||
) {
|
||||
pickerValueMulTwoTwo.push(pickerValueArray[0].children[i]);
|
||||
}
|
||||
}
|
||||
this.pickerValueMulTwoOne = pickerValueMulTwoOne;
|
||||
this.pickerValueMulTwoTwo = pickerValueMulTwoTwo;
|
||||
} else if (
|
||||
this.mode === 'multiLinkageSelector' &&
|
||||
this.deepLength === 3
|
||||
) {
|
||||
let pickerValueMulThreeOne = [];
|
||||
let pickerValueMulThreeTwo = [];
|
||||
let pickerValueMulThreeThree = [];
|
||||
// 第一列
|
||||
for (let i = 0, length = pickerValueArray.length; i < length; i++) {
|
||||
pickerValueMulThreeOne.push(pickerValueArray[i]);
|
||||
}
|
||||
// 渲染第二列
|
||||
this.pickerValueDefault =
|
||||
this.pickerValueDefault.length === 3 ?
|
||||
this.pickerValueDefault :
|
||||
[0, 0, 0];
|
||||
if (this.pickerValueDefault.length === 3) {
|
||||
let num = this.pickerValueDefault[0];
|
||||
for (
|
||||
let i = 0, length = pickerValueArray[num].children.length; i < length; i++
|
||||
) {
|
||||
pickerValueMulThreeTwo.push(pickerValueArray[num].children[i]);
|
||||
}
|
||||
// 第三列
|
||||
let numSecond = this.pickerValueDefault[1];
|
||||
for (let i = 0, length = pickerValueArray[num].children[numSecond].children.length; i < length; i++) {
|
||||
pickerValueMulThreeThree.push(
|
||||
pickerValueArray[num].children[numSecond].children[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
this.pickerValueMulThreeOne = pickerValueMulThreeOne;
|
||||
this.pickerValueMulThreeTwo = pickerValueMulThreeTwo;
|
||||
this.pickerValueMulThreeThree = pickerValueMulThreeThree;
|
||||
}
|
||||
},
|
||||
show() {
|
||||
setTimeout(() => {
|
||||
if (this.pickerValueArrayChange || this.modeChange) {
|
||||
this.initPicker(this.pickerValueArray);
|
||||
this.showPicker = true;
|
||||
this.pickerValueArrayChange = false;
|
||||
this.modeChange = false;
|
||||
} else {
|
||||
this.showPicker = true;
|
||||
}
|
||||
}, 0);
|
||||
},
|
||||
maskClick() {
|
||||
this.pickerCancel();
|
||||
},
|
||||
pickerCancel() {
|
||||
this.showPicker = false;
|
||||
this._initPickerVale();
|
||||
let pickObj = {
|
||||
index: this.pickerValue,
|
||||
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
|
||||
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
|
||||
};
|
||||
this.$emit('onCancel', pickObj);
|
||||
},
|
||||
pickerConfirm(e) {
|
||||
this.showPicker = false;
|
||||
this._initPickerVale();
|
||||
let pickObj = {
|
||||
index: this.pickerValue,
|
||||
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
|
||||
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
|
||||
};
|
||||
this.$emit('onConfirm', pickObj);
|
||||
},
|
||||
showPickerView() {
|
||||
this.showPicker = true;
|
||||
},
|
||||
pickerChange(e) {
|
||||
this.pickerValue = e.mp.detail.value;
|
||||
let pickObj = {
|
||||
index: this.pickerValue,
|
||||
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
|
||||
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
|
||||
};
|
||||
this.$emit('onChange', pickObj);
|
||||
},
|
||||
pickerChangeMul(e) {
|
||||
if (this.deepLength === 2) {
|
||||
let pickerValueArray = this.pickerValueArray;
|
||||
let changeValue = e.mp.detail.value;
|
||||
// 处理第一列滚动
|
||||
if (changeValue[0] !== this.pickerValue[0]) {
|
||||
let pickerValueMulTwoTwo = [];
|
||||
// 第一列滚动第二列数据更新
|
||||
for (let i = 0, length = pickerValueArray[changeValue[0]].children.length; i < length; i++) {
|
||||
pickerValueMulTwoTwo.push(pickerValueArray[changeValue[0]].children[i]);
|
||||
}
|
||||
this.pickerValueMulTwoTwo = pickerValueMulTwoTwo;
|
||||
// 第二列初始化为 0
|
||||
changeValue[1] = 0;
|
||||
}
|
||||
this.pickerValue = changeValue;
|
||||
} else if (this.deepLength === 3) {
|
||||
let pickerValueArray = this.pickerValueArray;
|
||||
let changeValue = e.mp.detail.value;
|
||||
let pickerValueMulThreeTwo = [];
|
||||
let pickerValueMulThreeThree = [];
|
||||
// 重新渲染第二列
|
||||
// 如果是第一列滚动
|
||||
if (changeValue[0] !== this.pickerValue[0]) {
|
||||
this.pickerValueMulThreeTwo = [];
|
||||
for (let i = 0, length = pickerValueArray[changeValue[0]].children.length; i < length; i++) {
|
||||
pickerValueMulThreeTwo.push(pickerValueArray[changeValue[0]].children[i]);
|
||||
}
|
||||
// 重新渲染第三列
|
||||
for (let i = 0, length = pickerValueArray[changeValue[0]].children[0].children.length; i <
|
||||
length; i++) {
|
||||
pickerValueMulThreeThree.push(pickerValueArray[changeValue[0]].children[0].children[i]);
|
||||
}
|
||||
changeValue[1] = 0;
|
||||
changeValue[2] = 0;
|
||||
this.pickerValueMulThreeTwo = pickerValueMulThreeTwo;
|
||||
this.pickerValueMulThreeThree = pickerValueMulThreeThree;
|
||||
} else if (changeValue[1] !== this.pickerValue[1]) {
|
||||
// 第二列滚动
|
||||
// 重新渲染第三列
|
||||
this.pickerValueMulThreeThree = [];
|
||||
pickerValueMulThreeTwo = this.pickerValueMulThreeTwo;
|
||||
for (let i = 0, length = pickerValueArray[changeValue[0]].children[changeValue[1]].children.length; i <
|
||||
length; i++) {
|
||||
pickerValueMulThreeThree.push(pickerValueArray[changeValue[0]].children[changeValue[1]].children[
|
||||
i]);
|
||||
}
|
||||
changeValue[2] = 0;
|
||||
this.pickerValueMulThreeThree = pickerValueMulThreeThree;
|
||||
}
|
||||
this.pickerValue = changeValue;
|
||||
}
|
||||
let pickObj = {
|
||||
index: this.pickerValue,
|
||||
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
|
||||
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
|
||||
};
|
||||
this.$emit('onChange', pickObj);
|
||||
},
|
||||
// 获取 pxikerLabel
|
||||
_getPickerLabelAndValue(value, mode) {
|
||||
let pickerLable;
|
||||
let pickerGetValue = [];
|
||||
// selector
|
||||
if (mode === 'selector') {
|
||||
pickerLable = this.pickerValueSingleArray[value].label;
|
||||
pickerGetValue.push(this.pickerValueSingleArray[value].value);
|
||||
} else if (mode === 'timeSelector') {
|
||||
pickerLable = `${this.pickerValueHour[value[0]].label}-${this.pickerValueMinute[value[1]].label}`;
|
||||
pickerGetValue.push(this.pickerValueHour[value[0]].value);
|
||||
pickerGetValue.push(this.pickerValueHour[value[1]].value);
|
||||
} else if (mode === 'multiSelector') {
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (i > 0) {
|
||||
pickerLable += this.pickerValueMulArray[i][value[i]].label + (i === value.length - 1 ? '' :
|
||||
'-');
|
||||
} else {
|
||||
pickerLable = this.pickerValueMulArray[i][value[i]].label + '-';
|
||||
}
|
||||
pickerGetValue.push(this.pickerValueMulArray[i][value[i]].value);
|
||||
}
|
||||
} else if (mode === 'multiLinkageSelector') {
|
||||
/* eslint-disable indent */
|
||||
pickerLable =
|
||||
this.deepLength === 2 ?
|
||||
`${this.pickerValueMulTwoOne[value[0]].label}-${this.pickerValueMulTwoTwo[value[1]].label}` :
|
||||
`${this.pickerValueMulThreeOne[value[0]].label}-${this.pickerValueMulThreeTwo[value[1]].label}-${this.pickerValueMulThreeThree[value[2]].label}`;
|
||||
if (this.deepLength === 2) {
|
||||
pickerGetValue.push(this.pickerValueMulTwoOne[value[0]].value);
|
||||
pickerGetValue.push(this.pickerValueMulTwoTwo[value[1]].value);
|
||||
} else {
|
||||
pickerGetValue.push(this.pickerValueMulThreeOne[value[0]].value);
|
||||
pickerGetValue.push(this.pickerValueMulThreeTwo[value[1]].value);
|
||||
pickerGetValue.push(this.pickerValueMulThreeThree[value[2]].value);
|
||||
}
|
||||
/* eslint-enable indent */
|
||||
}
|
||||
return {
|
||||
label: pickerLable,
|
||||
value: pickerGetValue
|
||||
};
|
||||
},
|
||||
// 初始化 pickerValue 默认值
|
||||
_initPickerVale() {
|
||||
if (this.pickerValue.length === 0) {
|
||||
if (this.mode === 'selector') {
|
||||
this.pickerValue = [0];
|
||||
} else if (this.mode === 'multiSelector') {
|
||||
this.pickerValue = new Int8Array(this.pickerValueArray.length);
|
||||
} else if (
|
||||
this.mode === 'multiLinkageSelector' &&
|
||||
this.deepLength === 2
|
||||
) {
|
||||
this.pickerValue = [0, 0];
|
||||
} else if (
|
||||
this.mode === 'multiLinkageSelector' &&
|
||||
this.deepLength === 3
|
||||
) {
|
||||
this.pickerValue = [0, 0, 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.pickerMask {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.mpvue-picker-content {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
transition: all 0.3s ease;
|
||||
transform: translateY(100%);
|
||||
z-index: 3000;
|
||||
}
|
||||
|
||||
.mpvue-picker-view-show {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.mpvue-picker__hd {
|
||||
display: flex;
|
||||
padding: 9px 15px;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.mpvue-picker__hd:after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
color: #e5e5e5;
|
||||
transform-origin: 0 100%;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
.mpvue-picker__action {
|
||||
display: block;
|
||||
flex: 1;
|
||||
color: #1aad19;
|
||||
}
|
||||
|
||||
.mpvue-picker__action:first-child {
|
||||
text-align: left;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.mpvue-picker__action:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.picker-item {
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.mpvue-picker-view {
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 238px;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
</style>
|
||||
260
mallplusui-uniapp-app/components/neil-modal.vue
Normal file
260
mallplusui-uniapp-app/components/neil-modal.vue
Normal file
@@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<view class="neil-modal" @touchmove.stop.prevent="bindTouchmove" :class="{'neil-modal--show':isOpen}">
|
||||
<view class="neil-modal__mask" @click="clickMask"></view>
|
||||
<view class="neil-modal__container">
|
||||
<view class="neil-modal__header" v-if="title.length > 0">{{title}}</view>
|
||||
<view class="neil-modal__content" :class="content ? 'neil-modal--padding' : ''" :style="{textAlign:align}">
|
||||
<template v-if="content">
|
||||
<text class="modal-content">{{content}}</text>
|
||||
</template>
|
||||
<template v-else>
|
||||
<slot />
|
||||
</template>
|
||||
</view>
|
||||
<view class="neil-modal__footer">
|
||||
<view v-if="showCancel" class="neil-modal__footer-left" @click="clickLeft" :style="{color:cancelColor}"
|
||||
hover-class="neil-modal__footer-hover" :hover-start-time="20" :hover-stay-time="70">
|
||||
{{cancelText}}
|
||||
</view>
|
||||
<view class="neil-modal__footer-right" @click="clickRight" :style="{color:confirmColor}" hover-class="neil-modal__footer-hover"
|
||||
:hover-start-time="20" :hover-stay-time="70">
|
||||
{{confirmText}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'neil-modal',
|
||||
props: {
|
||||
title: { //标题
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
content: String, //提示的内容
|
||||
align: { //content 的对齐方式left/center/right
|
||||
type: String,
|
||||
default: 'left'
|
||||
},
|
||||
cancelText: { //取消按钮的文字,默认为"取消"
|
||||
type: String,
|
||||
default: '取消'
|
||||
},
|
||||
cancelColor: { //取消按钮颜色
|
||||
type: String,
|
||||
default: '#333333'
|
||||
},
|
||||
confirmText: { //确定按钮的文字,默认为"确定"
|
||||
type: String,
|
||||
default: '确定'
|
||||
},
|
||||
confirmColor: { //确认按钮颜色
|
||||
type: String,
|
||||
default: '#007aff'
|
||||
},
|
||||
showCancel: { //是否显示取消按钮,默认为 true
|
||||
type: [Boolean, String],
|
||||
default: true
|
||||
},
|
||||
show: { //是否显示模态框
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
autoClose: { //点击遮罩是否自动关闭弹窗
|
||||
type: [Boolean, String],
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isOpen: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show(val) {
|
||||
this.isOpen = val
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.isOpen = this.show
|
||||
},
|
||||
methods: {
|
||||
bindTouchmove() {},
|
||||
clickLeft() {
|
||||
setTimeout(() => {
|
||||
this.$emit('cancel')
|
||||
}, 200)
|
||||
this.closeModal()
|
||||
},
|
||||
clickRight() {
|
||||
setTimeout(() => {
|
||||
this.$emit('confirm')
|
||||
}, 200)
|
||||
this.closeModal()
|
||||
},
|
||||
clickMask(){
|
||||
if(this.autoClose){
|
||||
this.closeModal()
|
||||
}
|
||||
},
|
||||
closeModal() {
|
||||
this.showAnimation = false
|
||||
this.isOpen = false
|
||||
this.$emit('close')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
$bg-color-mask:rgba(0, 0, 0, 0.5); //遮罩颜色
|
||||
$bg-color-hover:#f1f1f1; //点击状态颜色
|
||||
|
||||
.neil-modal {
|
||||
position: fixed;
|
||||
visibility: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
transition:visibility 200ms ease-in;
|
||||
|
||||
&.neil-modal--show{
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
&__header {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
padding: 18upx 24upx;
|
||||
line-height: 1.5;
|
||||
color: #333;
|
||||
font-size: 32upx;
|
||||
text-align: center;
|
||||
|
||||
&::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
transform-origin: 0 0;
|
||||
transform: scaleY(.5);
|
||||
}
|
||||
}
|
||||
|
||||
&__container {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) ;
|
||||
transition: transform 0.3s;
|
||||
width: 540upx;
|
||||
border-radius: 20upx;
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease-in;
|
||||
}
|
||||
|
||||
&__content {
|
||||
position: relative;
|
||||
color: #333;
|
||||
font-size: 28upx;
|
||||
box-sizing: border-box;
|
||||
line-height: 1.5;
|
||||
|
||||
&::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -1px;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
transform-origin: 0 0;
|
||||
transform: scaleY(.5);
|
||||
}
|
||||
}
|
||||
|
||||
&__footer {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: #333;
|
||||
font-size: 32upx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
&-left,
|
||||
&-right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
height: 88upx;
|
||||
font-size: 28upx;
|
||||
line-height: 88upx;
|
||||
text-align: center;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
&-right {
|
||||
color: #007aff;
|
||||
}
|
||||
|
||||
&-left::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
right: -1px;
|
||||
top: 0;
|
||||
width: 1px;
|
||||
bottom: 0;
|
||||
border-right: 1px solid #e5e5e5;
|
||||
transform-origin: 0 0;
|
||||
transform: scaleX(.5);
|
||||
}
|
||||
|
||||
&-hover {
|
||||
background-color: $bg-color-hover;
|
||||
}
|
||||
}
|
||||
|
||||
&__mask {
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 998;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: $bg-color-mask;
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease-in;
|
||||
&.neil-modal--show{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&--padding {
|
||||
padding: 32upx 24upx;
|
||||
min-height: 90upx;
|
||||
}
|
||||
&--show {
|
||||
.neil-modal__container,.neil-modal__mask{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
246
mallplusui-uniapp-app/components/payments/paymentsByAli.vue
Normal file
246
mallplusui-uniapp-app/components/payments/paymentsByAli.vue
Normal file
@@ -0,0 +1,246 @@
|
||||
<template>
|
||||
<view class="pay-type-list">
|
||||
|
||||
<view class="type-item b-b" v-for="item in payments" :key="item.code" @click="toPayHandler(item.code)"
|
||||
v-if="!(type == 2 && item.code == 'balancepay')">
|
||||
<text v-if=" item.code == 'wechatpay'" class="icon yticon icon-weixinzhifu"></text>
|
||||
<text v-if=" item.code == 'alipay'" class="icon yticon icon-alipay"></text>
|
||||
<text v-if=" item.code == 'offline'" class="icon yticon icon-weixinzhifu"></text>
|
||||
<text v-if=" item.code == 'balancepay'" class="icon yticon icon-erjiye-yucunkuan"></text>
|
||||
|
||||
<view class="con">
|
||||
<text class="tit">{{ item.name }}</text>
|
||||
<text>{{ item.memo }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { apiBaseUrl } from '@/config/config.js';
|
||||
import mallplusCopyright from '@/components/mall-copyright/mallplusCopyright.vue';
|
||||
import Api from '@/common/api';
|
||||
export default {
|
||||
props: {
|
||||
// 如果是商品订单此参数必须
|
||||
orderId: {
|
||||
type: String,
|
||||
default () {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
// 如果是充值订单此参数必须
|
||||
recharge: {
|
||||
type: Number,
|
||||
default () {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
// 用户id
|
||||
uid: {
|
||||
type: Number,
|
||||
default () {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
// 订单类型
|
||||
type: {
|
||||
type: Number,
|
||||
default () {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
payments: []
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.getPayments();
|
||||
},
|
||||
methods: {
|
||||
// 获取可用支付方式列表
|
||||
async getPayments () {
|
||||
|
||||
let params = {};
|
||||
this.orderInfo = await Api.apiCall('get',Api.order.paymentlist,params);
|
||||
this.payments = this.formatPayments(this.orderInfo)
|
||||
|
||||
},
|
||||
// 支付方式处理
|
||||
formatPayments (payments) {
|
||||
payments = payments.filter(item => item.code !== 'wechatpay');
|
||||
|
||||
|
||||
// 如果是充值订单 过滤余额支付 过滤非线上支付方式
|
||||
if (this.type === 2) {
|
||||
payments = payments.filter(item => item.code !== 'balancepay' || item.is_online === 1)
|
||||
}
|
||||
|
||||
// 设置logo图片
|
||||
payments.forEach(item => {
|
||||
this.$set(item, 'icon', '/static/image/' + item.code + '.png');
|
||||
});
|
||||
|
||||
return payments;
|
||||
},
|
||||
// 用户点击支付方式处理
|
||||
async toPayHandler (code) {
|
||||
let params = {'orderId':this.orderId};
|
||||
let data = {
|
||||
payment_code: code,
|
||||
payment_type: this.type
|
||||
}
|
||||
data['ids'] = (this.type == 1 || this.type == 5 || this.type == 6) ? this.orderId : this.uid
|
||||
|
||||
// 判断订单支付类型
|
||||
if (this.type == 2 && this.recharge) {
|
||||
data['params'] = {
|
||||
money: this.recharge,
|
||||
trade_type: 'JSAPI'
|
||||
}
|
||||
} else if ((this.type == 5 || this.type == 6) && this.recharge) {
|
||||
data['params'] = {
|
||||
trade_type: 'JSAPI',
|
||||
formid: this.orderId
|
||||
}
|
||||
}else {
|
||||
data['params'] = {
|
||||
trade_type: 'JSAPI'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let _this = this;
|
||||
switch (code) {
|
||||
case 'alipay':
|
||||
let res = await Api.apiCall('get',Api.order.webPay,params);
|
||||
console.log(res);
|
||||
if (res) {
|
||||
|
||||
uni.requestPayment({
|
||||
provider: 'alipay',
|
||||
tradeNO:res.data.trade_no,
|
||||
success: function (e) {
|
||||
if (e.errMsg === 'requestPayment:ok') {
|
||||
_this.$common.successToShow(res.msg, () => {
|
||||
_this.$common.redirectTo('/pages/order/payment/result?id=' + res.data.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$common.errorToShow(res.msg);
|
||||
|
||||
}
|
||||
break
|
||||
case 'balancepay':
|
||||
//用户余额支付
|
||||
let params1 = {'orderId':this.orderId};
|
||||
let data1 = await Api.apiCall('post',Api.order.balancePay,params1);
|
||||
console.log(data1)
|
||||
if (data1) {
|
||||
uni.redirectTo({
|
||||
url: '/pages/order/payment/result?order=' + JSON.stringify(data1)
|
||||
})
|
||||
}else {
|
||||
this.$api.msg('余额支付失败');
|
||||
}
|
||||
break;
|
||||
case 'offline':
|
||||
//线下支付
|
||||
this.$common.modelShow('线下支付说明', '请联系客服进行线下支付',() => {}, false, '取消', '确定')
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
.app {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.price-box {
|
||||
background-color: #fff;
|
||||
height: 265upx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 28upx;
|
||||
color: #909399;
|
||||
|
||||
.price{
|
||||
font-size: 50upx;
|
||||
color: #303133;
|
||||
margin-top: 12upx;
|
||||
&:before{
|
||||
content: '¥';
|
||||
font-size: 40upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pay-type-list {
|
||||
margin-top: 20upx;
|
||||
background-color: #fff;
|
||||
padding-left: 60upx;
|
||||
|
||||
.type-item{
|
||||
height: 120upx;
|
||||
padding: 20upx 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-right: 60upx;
|
||||
font-size: 30upx;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.icon{
|
||||
width: 100upx;
|
||||
font-size: 52upx;
|
||||
}
|
||||
.icon-erjiye-yucunkuan {
|
||||
color: #fe8e2e;
|
||||
}
|
||||
.icon-weixinzhifu {
|
||||
color: #36cb59;
|
||||
}
|
||||
.icon-alipay {
|
||||
color: #01aaef;
|
||||
}
|
||||
.tit{
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
margin-bottom: 4upx;
|
||||
}
|
||||
.con{
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: $font-sm;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
.mix-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 630upx;
|
||||
height: 80upx;
|
||||
margin: 80upx auto 30upx;
|
||||
font-size: $font-lg;
|
||||
color: #fff;
|
||||
background-color: $base-color;
|
||||
border-radius: 10upx;
|
||||
box-shadow: 1px 2px 5px rgba(219, 63, 96, 0.4);
|
||||
}
|
||||
|
||||
</style>
|
||||
287
mallplusui-uniapp-app/components/payments/paymentsByApp.vue
Normal file
287
mallplusui-uniapp-app/components/payments/paymentsByApp.vue
Normal file
@@ -0,0 +1,287 @@
|
||||
<template>
|
||||
<view class="pay-type-list">
|
||||
<view class="type-item b-b" v-for="item in paymentss" :key="item.code" @click="toPayHandler(item.code)" v-if="!(type == 2 && item.code == 'balancepay')">
|
||||
<text v-if="item.code == 'wechatpay'" class="icon yticon icon-weixinzhifu"></text>
|
||||
<text v-if="item.code == 'alipay'" class="icon yticon icon-alipay"></text>
|
||||
<text v-if="item.code == 'offline'" class="icon yticon icon-weixinzhifu"></text>
|
||||
<text v-if="item.code == 'balancepay'" class="icon yticon icon-erjiye-yucunkuan"></text>
|
||||
|
||||
<view class="con">
|
||||
<text class="tit">{{ item.name }}</text>
|
||||
<text>{{ item.memo }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mallplusCopyright from '@/components/mall-copyright/mallplusCopyright.vue';
|
||||
import Api from '@/common/api';
|
||||
export default {
|
||||
props: {
|
||||
// 如果是商品订单此参数必须
|
||||
orderId: {
|
||||
type: String,
|
||||
default() {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
// 如果是充值订单此参数必须
|
||||
recharge: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
// 用户id
|
||||
uid: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
// 订单类型
|
||||
type: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
paymentss: []
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getPayment();
|
||||
},
|
||||
methods: {
|
||||
// 获取可用支付方式列表
|
||||
async getPayment() {
|
||||
console.log('getPayments');
|
||||
let params = {};
|
||||
this.orderInfo = await Api.apiCall('get', Api.order.paymentlist, params);
|
||||
this.paymentss = this.formatPayments(this.orderInfo);
|
||||
},
|
||||
// 支付方式处理
|
||||
formatPayments(payments) {
|
||||
// 如果是充值订单 过滤余额支付 过滤非线上支付方式
|
||||
if (this.type === 2) {
|
||||
payments = payments.filter(item => item.code !== 'balancepay' || item.is_online === 1);
|
||||
}
|
||||
|
||||
// 设置logo图片
|
||||
payments.forEach(item => {
|
||||
this.$set(item, 'icon', '/static/image/' + item.code + '.png');
|
||||
});
|
||||
return payments;
|
||||
},
|
||||
// 用户点击支付方式处理
|
||||
async toPayHandler(code) {
|
||||
let _this = this;
|
||||
let params = { orderId: this.orderId };
|
||||
let data = {
|
||||
payment_code: code,
|
||||
payment_type: _this.type
|
||||
};
|
||||
|
||||
data['ids'] = this.type == 1 || this.type == 5 || this.type == 6 ? this.orderId : this.uid;
|
||||
if ((this.type == 5 || this.type == 6) && this.recharge) {
|
||||
data['params'] = {
|
||||
trade_type: 'APP',
|
||||
formid: this.orderId
|
||||
};
|
||||
}
|
||||
switch (code) {
|
||||
case 'alipay':
|
||||
/**
|
||||
* 支付宝支付需要模拟GET提交数据
|
||||
*/
|
||||
if (_this.type == 1 && _this.orderId) {
|
||||
data['params'] = {
|
||||
trade_type: 'APP'
|
||||
};
|
||||
} else if (_this.type == 2 && _this.recharge) {
|
||||
data['params'] = {
|
||||
trade_type: 'APP',
|
||||
money: _this.recharge
|
||||
};
|
||||
}
|
||||
|
||||
let res = await Api.apiCall('get', Api.order.aliAppPay, params);
|
||||
if (res) {
|
||||
console.log(res);
|
||||
uni.requestPayment({
|
||||
provider: 'alipay',
|
||||
orderInfo: res,
|
||||
success: function(data) {
|
||||
let rawdataResult = JSON.parse(data.rawdata).result;
|
||||
let r = rawdataResult.split(';')[0];
|
||||
let r1 = rawdataResult.split(';')[0].length - 1;
|
||||
let r2 = rawdataResult.split(';')[0].length - 2;
|
||||
let alipayTradeAppPayResponse = JSON.parse(r.substr(0, r1)).alipay_trade_app_pay_response;
|
||||
let out_trade_no = alipayTradeAppPayResponse.out_trade_no;
|
||||
_this.$common.successToShow('支付成功', () => {
|
||||
//_this.redirectHandler(res.data.payment_id)
|
||||
_this.redirectHandler(out_trade_no);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_this.$comon.errorToShow(res.msg);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'wechatpay':
|
||||
// 微信 H5支付
|
||||
if (_this.type == 1 && _this.orderId) {
|
||||
data['params'] = {
|
||||
trade_type: 'APP'
|
||||
};
|
||||
} else if (_this.type == 2 && _this.recharge) {
|
||||
data['params'] = {
|
||||
trade_type: 'APP',
|
||||
money: _this.recharge
|
||||
};
|
||||
}
|
||||
|
||||
// 微信app支付
|
||||
let res1 = await Api.apiCall('get', Api.order.appPay, params);
|
||||
debugger
|
||||
console.log(res1)
|
||||
console.log(data)
|
||||
if (res1) {
|
||||
// 调用微信支付
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
orderInfo: res1,
|
||||
success: function(data) {
|
||||
console.log(res1)
|
||||
console.log(data)
|
||||
_this.$common.successToShow('支付成功', () => {
|
||||
_this.redirectHandler(data);
|
||||
});
|
||||
},
|
||||
fail: function(res) {
|
||||
console.log(JSON.stringify(res));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_this.$common.errorToShow(res.msg);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'balancepay':
|
||||
/**
|
||||
* 用户余额支付
|
||||
*
|
||||
*/
|
||||
let params1 = { orderId: this.orderId };
|
||||
let data1 = await Api.apiCall('post', Api.order.balancePay, params1);
|
||||
console.log(data1);
|
||||
if (data1) {
|
||||
uni.redirectTo({
|
||||
url: '/pages/order/payment/result?order=' + JSON.stringify(data1)
|
||||
});
|
||||
} else {
|
||||
this.$api.msg(data1.data);
|
||||
}
|
||||
break;
|
||||
case 'offline':
|
||||
/**
|
||||
* 线下支付
|
||||
*/
|
||||
_this.$common.modelShow('线下支付说明', '请联系客服进行线下支付', () => {}, false, '取消', '确定');
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 支付成功后跳转操作
|
||||
redirectHandler(paymentId) {
|
||||
this.$common.redirectTo('/pages/order/payment/result?id=' + paymentId);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.app {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.price-box {
|
||||
background-color: #fff;
|
||||
height: 265upx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 28upx;
|
||||
color: #909399;
|
||||
|
||||
.price {
|
||||
font-size: 50upx;
|
||||
color: #303133;
|
||||
margin-top: 12upx;
|
||||
&:before {
|
||||
content: '¥';
|
||||
font-size: 40upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pay-type-list {
|
||||
margin-top: 20upx;
|
||||
background-color: #fff;
|
||||
padding-left: 60upx;
|
||||
|
||||
.type-item {
|
||||
height: 120upx;
|
||||
padding: 20upx 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-right: 60upx;
|
||||
font-size: 30upx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 100upx;
|
||||
font-size: 52upx;
|
||||
}
|
||||
.icon-erjiye-yucunkuan {
|
||||
color: #fe8e2e;
|
||||
}
|
||||
.icon-weixinzhifu {
|
||||
color: #36cb59;
|
||||
}
|
||||
.icon-alipay {
|
||||
color: #01aaef;
|
||||
}
|
||||
.tit {
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
margin-bottom: 4upx;
|
||||
}
|
||||
.con {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: $font-sm;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
.mix-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 630upx;
|
||||
height: 80upx;
|
||||
margin: 80upx auto 30upx;
|
||||
font-size: $font-lg;
|
||||
color: #fff;
|
||||
background-color: $base-color;
|
||||
border-radius: 10upx;
|
||||
box-shadow: 1px 2px 5px rgba(219, 63, 96, 0.4);
|
||||
}
|
||||
</style>
|
||||
412
mallplusui-uniapp-app/components/payments/paymentsByH5.vue
Normal file
412
mallplusui-uniapp-app/components/payments/paymentsByH5.vue
Normal file
@@ -0,0 +1,412 @@
|
||||
<template>
|
||||
<view class="pay-type-list">
|
||||
|
||||
<view class="type-item b-b" v-for="item in payments" :key="item.code" @click="toPayHandler(item.code)"
|
||||
v-if="!(type == 2 && item.code == 'balancepay')">
|
||||
<text v-if=" item.code == 'wechatpay'" class="icon yticon icon-weixinzhifu"></text>
|
||||
<text v-if=" item.code == 'alipay'" class="icon yticon icon-alipay"></text>
|
||||
<text v-if=" item.code == 'offline'" class="icon yticon icon-weixinzhifu"></text>
|
||||
<text v-if=" item.code == 'balancepay'" class="icon yticon icon-erjiye-yucunkuan"></text>
|
||||
<view class="con">
|
||||
<text class="tit">{{ item.name }}</text>
|
||||
<text>{{ item.memo }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!--<view class='cell-group payment-method'>
|
||||
<view class='cell-item add-title-item' v-for="item in payments" :key="item.code" @click="toPayHandler(item.code)"
|
||||
v-if="!(type == 2 && item.code == 'balancepay')">
|
||||
<view class='cell-item-hd'>
|
||||
<image class='cell-hd-icon' :src='item.icon'></image>
|
||||
</view>
|
||||
<view class='cell-item-bd'>
|
||||
<view class="cell-bd-view">
|
||||
<text class="cell-bd-text">{{ item.name }}</text>
|
||||
</view>
|
||||
<view class="cell-bd-view">
|
||||
<text class="cell-bd-text address">{{ item.memo }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class='cell-item-ft'>
|
||||
<image class='cell-ft-next icon' src='../../../static/image/right.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>-->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
baseUrl
|
||||
} from '@/config/config.js'
|
||||
import mallplusCopyright from '@/components/mall-copyright/mallplusCopyright.vue';
|
||||
import Api from '@/common/api';
|
||||
export default {
|
||||
props: {
|
||||
// 如果是商品订单此参数必须
|
||||
orderId: {
|
||||
type: String,
|
||||
default () {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
// 如果是充值订单此参数必须
|
||||
recharge: {
|
||||
type: Number,
|
||||
default () {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
// 用户id
|
||||
uid: {
|
||||
type: Number,
|
||||
default () {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
// 订单类型
|
||||
type: {
|
||||
type: Number,
|
||||
default () {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
payments: [],
|
||||
openid: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getPayments()
|
||||
},
|
||||
methods: {
|
||||
// 获取可用支付方式列表
|
||||
async getPayments() {
|
||||
let params = {};
|
||||
this.orderInfo = await Api.apiCall('get',Api.order.paymentlist,params);
|
||||
this.payments = this.formatPayments(this.orderInfo)
|
||||
},
|
||||
// 支付方式处理
|
||||
formatPayments(payments) {
|
||||
// h5支付并且是在微信浏览器内 过滤支付宝支付
|
||||
if (this.$common.isWeiXinBrowser()) {
|
||||
payments = payments.filter(item => item.code !== 'alipay')
|
||||
}
|
||||
|
||||
// 如果是充值订单 过滤余额支付 过滤非线上支付方式
|
||||
if (this.type === 2) {
|
||||
payments = payments.filter(
|
||||
item => item.code !== 'balancepay' || item.is_online === 1
|
||||
)
|
||||
}
|
||||
|
||||
// 设置logo图片
|
||||
payments.forEach(item => {
|
||||
this.$set(item, 'icon', '/static/image/' + item.code + '.png')
|
||||
})
|
||||
console.log(payments)
|
||||
return payments
|
||||
},
|
||||
checkWXJSBridge(data) {
|
||||
let that = this
|
||||
let interval = setInterval(() => {
|
||||
if (typeof window.WeixinJSBridge != 'undefined') {
|
||||
clearTimeout(interval)
|
||||
that.onBridgeReady(data)
|
||||
}
|
||||
}, 200)
|
||||
},
|
||||
onBridgeReady(data) {
|
||||
var _this = this
|
||||
window.WeixinJSBridge.invoke(
|
||||
'getBrandWCPayRequest', {
|
||||
appId: data.appId, // 公众号名称,由商户传入
|
||||
timeStamp: data.timeStamp, // 时间戳,自1970年以来的秒数
|
||||
nonceStr: data.nonceStr, // 随机串
|
||||
package: data.package,
|
||||
signType: data.signType, // 微信签名方式:
|
||||
paySign: data.paySign // 微信签名
|
||||
},
|
||||
function(res) {
|
||||
if (res.err_msg === 'get_brand_wcpay_request:ok') {
|
||||
_this.$common.successToShow('支付成功')
|
||||
} else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
|
||||
_this.$common.errorToShow('取消支付')
|
||||
} else {
|
||||
_this.$common.errorToShow('支付失败')
|
||||
}
|
||||
setTimeout(() => {
|
||||
_this.$common.redirectTo(
|
||||
'/pages/order/payment/result?id=' + data.payment_id
|
||||
)
|
||||
}, 1000)
|
||||
}
|
||||
)
|
||||
},
|
||||
// 用户点击支付方式处理
|
||||
async toPayHandler(code) {
|
||||
let params = {'orderId':this.orderId};
|
||||
let data = {
|
||||
payment_code: code,
|
||||
payment_type: this.type
|
||||
}
|
||||
data['orderId'] = (this.type == 1 || this.type == 5 || this.type == 6) ? this.orderId : this.uid
|
||||
switch (code) {
|
||||
case 'alipay':
|
||||
|
||||
let res = await Api.apiCall('get',Api.order.aliWapPay,params);
|
||||
console.log('============================')
|
||||
console.log(res);
|
||||
console.log('success:' + JSON.stringify(res));
|
||||
if (res) {
|
||||
|
||||
document.body.appendChild(JSON.stringify(res))
|
||||
let testForm = document.getElementsByName('punchout_form')
|
||||
// 模拟GET提交
|
||||
/*
|
||||
const url = res.data.url
|
||||
const data = res.data.data
|
||||
let tempForm = document.createElement('form')
|
||||
tempForm.id = 'aliPay'
|
||||
tempForm.methods = 'post'
|
||||
tempForm.action = url
|
||||
tempForm.target = '_self'
|
||||
let input = []
|
||||
for (let k in data) {
|
||||
input[k] = document.createElement('input')
|
||||
input[k].type = 'hidden'
|
||||
input[k].name = k
|
||||
input[k].value = data[k]
|
||||
tempForm.appendChild(input[k])
|
||||
}
|
||||
tempForm.addEventListener('submit', function() {}, false)
|
||||
document.body.appendChild(tempForm)*/
|
||||
testForm.dispatchEvent(new Event('submit'))
|
||||
console.log(tempForm);
|
||||
testForm.submit()
|
||||
document.body.removeChild(testForm)
|
||||
|
||||
}
|
||||
break
|
||||
case 'wechatpay':
|
||||
|
||||
/**
|
||||
* 微信支付有两种
|
||||
* 判断是否在微信浏览器
|
||||
* 微信jsapi支付
|
||||
*/
|
||||
let isWeiXin = this.$common.isWeiXinBrowser()
|
||||
|
||||
if (isWeiXin) {
|
||||
var transitUrl =
|
||||
baseUrl +
|
||||
'wap/#/pages/order/payment/auth?order_id=' +
|
||||
this.orderId +
|
||||
'&type=' +
|
||||
this.type;
|
||||
|
||||
if (this.type == 1 && this.orderId) {
|
||||
// 微信jsapi支付
|
||||
// if (this.openid) {
|
||||
// data['params'] = {
|
||||
// trade_type: 'JSAPI_OFFICIAL',
|
||||
// openid: this.openid
|
||||
// }
|
||||
// } else {
|
||||
// data['params'] = {
|
||||
// trade_type: 'JSAPI_OFFICIAL',
|
||||
// url: window.location.href
|
||||
// }
|
||||
// }
|
||||
data['params'] = {
|
||||
trade_type: 'JSAPI_OFFICIAL',
|
||||
url: transitUrl
|
||||
}
|
||||
} else if (this.type == 2 && this.recharge) {
|
||||
data['params'] = {
|
||||
trade_type: 'JSAPI_OFFICIAL',
|
||||
money: this.recharge,
|
||||
url: transitUrl + '&uid=' + this.uid + '&money=' + this.recharge
|
||||
}
|
||||
// if (this.openid) {
|
||||
// data['params'] = {
|
||||
// money: this.recharge,
|
||||
// openid: this.openid
|
||||
// }
|
||||
// } else {
|
||||
// data['params'] = {
|
||||
// money: this.recharge,
|
||||
// url: window.location.href
|
||||
// }
|
||||
// }
|
||||
} else if ((this.type == 5 || this.type == 6) && this.recharge) {
|
||||
data['params'] = {
|
||||
orderId: this.orderId
|
||||
}
|
||||
}
|
||||
let res = await Api.apiCall('get',Api.order.webPay,params);
|
||||
console.log(res);
|
||||
if (res) {
|
||||
this.checkWXJSBridge(res)
|
||||
}else{
|
||||
window.location.href = res.msg
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// 微信 H5支付
|
||||
if (this.type == 1 && this.orderId) {
|
||||
data['params'] = {
|
||||
trade_type: 'MWEB',
|
||||
return_url: baseUrl +
|
||||
'wap/#/pages/order/payment/result'
|
||||
}
|
||||
} else if (this.type == 2 && this.recharge) {
|
||||
data['params'] = {
|
||||
trade_type: 'MWEB',
|
||||
money: this.recharge,
|
||||
return_url: baseUrl + 'wap/#/pages/order/payment/result'
|
||||
}
|
||||
} else if ((this.type == 5 || this.type == 6) && this.recharge) {
|
||||
data['params'] = {
|
||||
orderId: this.orderId
|
||||
}
|
||||
}
|
||||
console.log(data);
|
||||
// 微信h5支付
|
||||
let res = await Api.apiCall('get',Api.order.wapPay,params);
|
||||
console.log(res);
|
||||
if (res) {
|
||||
|
||||
if (res) {
|
||||
location.href = res
|
||||
} else {
|
||||
this.$common.errorToShow(res)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'balancepay':
|
||||
/**
|
||||
* 用户余额支付
|
||||
*
|
||||
*/
|
||||
if ((this.type == 5 || this.type == 6) && this.recharge) {
|
||||
data['params'] = {
|
||||
orderId: this.orderId
|
||||
}
|
||||
}
|
||||
let params1 = {'orderId':this.orderId};
|
||||
let data1 = await Api.apiCall('post',Api.order.balancePay,params1);
|
||||
console.log(data1)
|
||||
if (data1) {
|
||||
uni.redirectTo({
|
||||
url: '/pages/order/payment/result?order=' + JSON.stringify(data1)
|
||||
})
|
||||
}else {
|
||||
this.$api.msg(data1.data);
|
||||
}
|
||||
|
||||
break
|
||||
case 'offline':
|
||||
/**
|
||||
* 线下支付
|
||||
*/
|
||||
this.$common.modelShow(
|
||||
'线下支付说明',
|
||||
'请联系客服进行线下支付qq:951449465',
|
||||
() => {},
|
||||
false,
|
||||
'取消',
|
||||
'确定'
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
.app {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.price-box {
|
||||
background-color: #fff;
|
||||
height: 265upx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 28upx;
|
||||
color: #909399;
|
||||
|
||||
.price{
|
||||
font-size: 50upx;
|
||||
color: #303133;
|
||||
margin-top: 12upx;
|
||||
&:before{
|
||||
content: '¥';
|
||||
font-size: 40upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pay-type-list {
|
||||
margin-top: 20upx;
|
||||
background-color: #fff;
|
||||
padding-left: 60upx;
|
||||
|
||||
.type-item{
|
||||
height: 120upx;
|
||||
padding: 20upx 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-right: 60upx;
|
||||
font-size: 30upx;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.icon{
|
||||
width: 100upx;
|
||||
font-size: 52upx;
|
||||
}
|
||||
.icon-erjiye-yucunkuan {
|
||||
color: #fe8e2e;
|
||||
}
|
||||
.icon-weixinzhifu {
|
||||
color: #36cb59;
|
||||
}
|
||||
.icon-alipay {
|
||||
color: #01aaef;
|
||||
}
|
||||
.tit{
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
margin-bottom: 4upx;
|
||||
}
|
||||
.con{
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: $font-sm;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
.mix-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 630upx;
|
||||
height: 80upx;
|
||||
margin: 80upx auto 30upx;
|
||||
font-size: $font-lg;
|
||||
color: #fff;
|
||||
background-color: $base-color;
|
||||
border-radius: 10upx;
|
||||
box-shadow: 1px 2px 5px rgba(219, 63, 96, 0.4);
|
||||
}
|
||||
|
||||
</style>
|
||||
249
mallplusui-uniapp-app/components/payments/paymentsByWx.vue
Normal file
249
mallplusui-uniapp-app/components/payments/paymentsByWx.vue
Normal file
@@ -0,0 +1,249 @@
|
||||
<template>
|
||||
<view class="pay-type-list">
|
||||
|
||||
<view class="type-item b-b" v-for="item in payments" :key="item.code"
|
||||
report-submit="true" @click="toPayHandler(item.code)"
|
||||
v-if="!(type == 2 && item.code == 'balancepay')">
|
||||
<!-- <text class="icon yticon icon-weixinzhifu"></text> -->
|
||||
<image :src="item.img" style="width: 80upx;height: 80upx;margin-right: 20upx;"></image>
|
||||
<view class="con">
|
||||
<text class="tit">{{ item.name }}</text>
|
||||
<text>{{ item.memo }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { apiBaseUrl } from '@/config/config.js'
|
||||
import mallplusCopyright from '@/components/mall-copyright/mallplusCopyright.vue';
|
||||
import Api from '@/common/api';
|
||||
export default {
|
||||
props: {
|
||||
// 如果是商品订单此参数必须
|
||||
orderId: {
|
||||
type: String,
|
||||
default () {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
// 如果是充值订单此参数必须
|
||||
recharge: {
|
||||
type: Number,
|
||||
default () {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
// 用户id
|
||||
uid: {
|
||||
type: Number,
|
||||
default () {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
// 订单类型
|
||||
type: {
|
||||
type: Number,
|
||||
default () {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
payments: [],
|
||||
imgList: [
|
||||
'/static/image/wechatpay.png','/static/image/balancepay.png','/static/image/payment_balance.png',
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.getPayments()
|
||||
},
|
||||
methods: {
|
||||
// 获取可用支付方式列表
|
||||
async getPayments () {
|
||||
|
||||
let params = {};
|
||||
this.orderInfo = await Api.apiCall('get',Api.order.paymentlist,params);
|
||||
this.payments = this.formatPayments(this.orderInfo)
|
||||
for(var i = 0;i < this.payments.length;i++){
|
||||
this.payments[i].img = this.imgList[i]
|
||||
}
|
||||
console.log('------',this.payments)
|
||||
},
|
||||
|
||||
// 支付方式处理
|
||||
formatPayments (payments) {
|
||||
// 过滤支付宝支付
|
||||
payments = payments.filter(item => item.code !== 'alipay')
|
||||
|
||||
// 如果是充值订单 过滤余额支付 过滤非线上支付方式
|
||||
if (this.type === 2) {
|
||||
payments = payments.filter(item => item.code !== 'balancepay' || item.is_online === 1)
|
||||
}
|
||||
|
||||
// 设置logo图片
|
||||
payments.forEach(item => {
|
||||
this.$set(item, 'icon', '/static/image/' + item.code + '.png')
|
||||
})
|
||||
|
||||
return payments
|
||||
},
|
||||
// 用户点击支付方式处理
|
||||
async toPayHandler (code) {
|
||||
|
||||
let params = {'orderId':this.orderId,
|
||||
payment_type: this.type};
|
||||
|
||||
|
||||
// 判断订单支付类型
|
||||
if (this.type == 2 && this.recharge) {
|
||||
|
||||
}else if ((this.type == 5 || this.type == 6) && this.recharge) {
|
||||
|
||||
}
|
||||
let _this = this
|
||||
switch (code) {
|
||||
case 'wechatpay':
|
||||
|
||||
let res = await Api.apiCall('post',Api.order.weixinAppletPay,params);
|
||||
console.log(res);
|
||||
if (res) {
|
||||
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
timeStamp: res.timeStamp,
|
||||
nonceStr: res.nonceStr,
|
||||
package: res.package,
|
||||
signType: res.signType,
|
||||
paySign: res.paySign,
|
||||
success: function (e) {
|
||||
if (e.errMsg === 'requestPayment:ok') {
|
||||
_this.$common.successToShow(res.msg, () => {
|
||||
_this.$common.redirectTo('/pages/order/payment/result?id=' + res.id)
|
||||
})
|
||||
}else{
|
||||
this.$common.errorToShow(res.msg)
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$common.errorToShow(res.msg)
|
||||
}
|
||||
|
||||
break
|
||||
case 'balancepay':
|
||||
/**
|
||||
* 用户余额支付
|
||||
*
|
||||
*/
|
||||
let params1 = {'orderId':this.orderId};
|
||||
let data1 = await Api.apiCall('post',Api.order.balancePay,params1);
|
||||
console.log(data1)
|
||||
if (data1) {
|
||||
uni.redirectTo({
|
||||
url: '/pages/order/payment/result?order=' + JSON.stringify(data1)
|
||||
})
|
||||
}else {
|
||||
this.$api.msg(data1.data);
|
||||
}
|
||||
break
|
||||
case 'offline':
|
||||
/**
|
||||
* 线下支付
|
||||
*/
|
||||
this.$common.modelShow('线下支付说明', '请联系客服进行线下支付', () => {},false, '取消', '确定')
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
.app {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.price-box {
|
||||
background-color: #fff;
|
||||
height: 265upx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 28upx;
|
||||
color: #909399;
|
||||
|
||||
.price{
|
||||
font-size: 50upx;
|
||||
color: #303133;
|
||||
margin-top: 12upx;
|
||||
&:before{
|
||||
content: '¥';
|
||||
font-size: 40upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pay-type-list {
|
||||
margin-top: 20upx;
|
||||
background-color: #fff;
|
||||
padding-left: 60upx;
|
||||
|
||||
.type-item{
|
||||
height: 120upx;
|
||||
padding: 20upx 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-right: 60upx;
|
||||
font-size: 30upx;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.icon{
|
||||
width: 100upx;
|
||||
font-size: 52upx;
|
||||
}
|
||||
.icon-erjiye-yucunkuan {
|
||||
color: #fe8e2e;
|
||||
}
|
||||
.icon-weixinzhifu {
|
||||
color: #36cb59;
|
||||
}
|
||||
.icon-alipay {
|
||||
color: #01aaef;
|
||||
}
|
||||
.tit{
|
||||
font-size: $font-lg;
|
||||
color: $font-color-dark;
|
||||
margin-bottom: 4upx;
|
||||
}
|
||||
.con{
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: $font-sm;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
.mix-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 630upx;
|
||||
height: 80upx;
|
||||
margin: 80upx auto 30upx;
|
||||
font-size: $font-lg;
|
||||
color: #fff;
|
||||
background-color: $base-color;
|
||||
border-radius: 10upx;
|
||||
box-shadow: 1px 2px 5px rgba(219, 63, 96, 0.4);
|
||||
}
|
||||
|
||||
</style>
|
||||
79
mallplusui-uniapp-app/components/red-bag/index.vue
Normal file
79
mallplusui-uniapp-app/components/red-bag/index.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<view class="wrapper" v-show="redBagShow">
|
||||
<view class="modal-bg" >
|
||||
</view>
|
||||
<view class="rb-wrapper">
|
||||
<view class="rb-content" @click="handleBtn">
|
||||
|
||||
</view>
|
||||
<view class="close" @click="handleClose">
|
||||
<image src='/static/image/close.png' class="img"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'redBag',
|
||||
components: {},
|
||||
props: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
redBagShow: true
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
computed: {},
|
||||
methods: {
|
||||
handleClose() {
|
||||
this.redBagShow=false
|
||||
},
|
||||
handleBtn() {
|
||||
this.$emit('click')
|
||||
this.redBagShow=false
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.modal-bg {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.rb-wrapper {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 60%;
|
||||
height: 600upx;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
background: red;
|
||||
padding: 40upx;
|
||||
.rb-content{
|
||||
height: 100%;
|
||||
}
|
||||
.close {
|
||||
position: absolute;
|
||||
bottom: -120upx;
|
||||
left: 50%;
|
||||
margin-left: -30upx;
|
||||
width: 60upx;
|
||||
height: 60upx;
|
||||
border-radius: 50%;
|
||||
background: #ddd;
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
496
mallplusui-uniapp-app/components/reserve-date/reserve-date.vue
Normal file
496
mallplusui-uniapp-app/components/reserve-date/reserve-date.vue
Normal file
@@ -0,0 +1,496 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="body">
|
||||
<view class="head-body">
|
||||
<text class="date-head">{{swiperData.year}}年{{swiperData.month}}月</text>
|
||||
<view>
|
||||
<view class='pr40' style="display: inline-block;"><uni-icon type="arrowup" size='26' color='#fff' @click='prevDeta'/></view>
|
||||
<view style="display: inline-block;"><uni-icon type="arrowdown" size='26' color='#fff' @click='nextDate' /></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mian-body">
|
||||
<!-- 星期 -->
|
||||
<view class="mian-bolck"> <text>日</text> </view>
|
||||
<view class="mian-bolck"> <text>一</text> </view>
|
||||
<view class="mian-bolck"> <text>二</text> </view>
|
||||
<view class="mian-bolck"> <text>三</text> </view>
|
||||
<view class="mian-bolck"> <text>四</text> </view>
|
||||
<view class="mian-bolck"> <text>五</text> </view>
|
||||
<view class="mian-bolck"> <text>六</text> </view>
|
||||
<!-- 日 -->
|
||||
<view v-for="(val, index) in swiperData.dateDay" class="mian-bolck" :class="val.disable == true ? 'disable' : val.Choice == true ? 'Choice' : ''"
|
||||
@click="ChoiceDate(index, val.disable)" :key='index'>
|
||||
<view class="border">
|
||||
<text class="day">{{val.day}}</text>
|
||||
<text class="price" v-show="val.priceType">{{val.price == undefined ? '' : val.price}}¥</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniIcon from './uni-icon.vue';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
swiperData: {},
|
||||
year: '',
|
||||
month: '',
|
||||
day: '',
|
||||
storageDate: []
|
||||
}
|
||||
},
|
||||
props: {
|
||||
// 当前日期
|
||||
date: {
|
||||
type: String,
|
||||
default: () => {
|
||||
let _dateData = new Date(),
|
||||
_date = `${_dateData.getFullYear()}-${_dateData.getMonth() + 1}-${_dateData.getDate()}`
|
||||
return _date
|
||||
}
|
||||
},
|
||||
// 禁用开始之前日期
|
||||
startDate: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 禁用开始之后日期
|
||||
endDate: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 是否禁用今天之前的日期
|
||||
disableBefore: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 价格
|
||||
price: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {type: false, data: []}
|
||||
}
|
||||
},
|
||||
// 是否选择默认日期
|
||||
isNowDate: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 单选或多选
|
||||
singleElection: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
PriceData: {
|
||||
get() {
|
||||
return this.price.data
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
let dateArr = this.date.split('-')
|
||||
if (this.date != '' && dateArr.length == 3) {
|
||||
// 初始化年月日
|
||||
this.year = Number(dateArr[0])
|
||||
this.month = Number(dateArr[1])
|
||||
this.day = Number(dateArr[2])
|
||||
this.InitializationHomeDate(true).then((val) => {
|
||||
this.Preprocessing(dateArr)
|
||||
})
|
||||
} else {
|
||||
console.error('error 请检查传入日期是否正确,如: 2019-5-12')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 是否添加初始化日期
|
||||
InitializationHomeDate(type) {
|
||||
// 指定日期
|
||||
let ThisDate = this.compareDate(this.date)
|
||||
// 禁用开始时间
|
||||
let startDate = this.compareDate(this.startDate)
|
||||
// 禁用结束时间
|
||||
let endDate = this.compareDate(this.endDate)
|
||||
// 当前日期
|
||||
let _date = new Date()
|
||||
let currDate = this.compareDate(`${_date.getFullYear()}-${_date.getMonth() + 1}-${_date.getDate()}`)
|
||||
return new Promise((resolve, reject) => {
|
||||
let judge = (this.disableBefore == false && this.startDate == '' && this.endDate == '') || // 没有任何禁止
|
||||
(this.disableBefore == true && ThisDate >= currDate) || // 是否禁用今天之前的日期
|
||||
(ThisDate >= startDate && this.disableBefore == false && this.startDate != '') || // 禁用只有开始时间,没有结束时间
|
||||
(ThisDate <= endDate && this.disableBefore == false && this.endDate != '') || // 禁用只有结束时间,没有开始时间
|
||||
(ThisDate <= endDate && this.disableBefore == false && ThisDate >= startDate && this.startDate != '' &&this.endDate != '') // 禁用结束时间,开始时间
|
||||
if (this.isNowDate == false) {
|
||||
resolve(true)
|
||||
return false
|
||||
} else if (judge && type) {
|
||||
this.storageDate.push({date: this.date})
|
||||
}
|
||||
resolve(true)
|
||||
})
|
||||
},
|
||||
// 时间转换为时间戳
|
||||
compareDate(s1) {
|
||||
let curTime = new Date();
|
||||
//把字符串格式转化为日期类
|
||||
return s1 ? new Date(s1).valueOf() : false
|
||||
},
|
||||
// 上一个月
|
||||
prevDeta() {
|
||||
let dateLen = new Date(this.year, this.month - 1, 0).getDate()
|
||||
this.month = Number(this.month) - 1
|
||||
if (this.month == 0) {
|
||||
this.month = 12
|
||||
this.year = Number(this.year) - 1
|
||||
}
|
||||
if (this.month<10){
|
||||
this.month='0'+this.month;
|
||||
}
|
||||
this.Preprocessing([this.year, this.month, this.day])
|
||||
if (this.price.type) {
|
||||
this.$emit('changeMonth', [this.year, this.month, dateLen])
|
||||
}
|
||||
},
|
||||
// 下一个月
|
||||
nextDate() {
|
||||
let dateLen = new Date(this.year, this.month - 1, 0).getDate()
|
||||
this.month = 1 + Number(this.month)
|
||||
if (this.month == 13) {
|
||||
this.month = 1
|
||||
this.year = 1 + Number(this.year)
|
||||
}
|
||||
if (this.month<10){
|
||||
this.month='0'+this.month;
|
||||
}
|
||||
this.Preprocessing([this.year, this.month, this.day])
|
||||
if (this.price.type) {
|
||||
this.$emit('changeMonth', [this.year, this.month, dateLen])
|
||||
}
|
||||
},
|
||||
// 数据发布
|
||||
ChoiceDate(index, disable) {
|
||||
let day = this.swiperData.dateDay[index].day
|
||||
let _Choice = this.swiperData.dateDay[index].Choice
|
||||
let _date = {}
|
||||
if (this.price.type == true) {
|
||||
_date = {date: `${this.swiperData.year}-${this.swiperData.month}-${day}`, price: this.swiperData.dateDay[index].price}
|
||||
} else {
|
||||
_date = {date: `${this.swiperData.year}-${this.swiperData.month}-${day}`}
|
||||
}
|
||||
if (disable != true) {
|
||||
// 添加数据
|
||||
if (JSON.stringify(this.storageDate).indexOf(_date.date) == -1) {
|
||||
// 单选还是多选
|
||||
if (this.singleElection == true) {
|
||||
this.storageDate = []
|
||||
this.swiperData.dateDay.forEach((val, inde) => {
|
||||
val.Choice = false
|
||||
})
|
||||
// 多选
|
||||
}
|
||||
this.storageDate.push(_date)
|
||||
// 删除数据
|
||||
} else {
|
||||
this.storageDate = this.storageDate.filter((val, index) => {
|
||||
if (val.date != _date.date) {
|
||||
return val
|
||||
}
|
||||
})
|
||||
}
|
||||
this.swiperData.dateDay[index].Choice = !_Choice
|
||||
this.$emit('changeDay', this.storageDate)
|
||||
}
|
||||
},
|
||||
// 日期初始化
|
||||
Preprocessing(arr) {
|
||||
let swiperData = {}
|
||||
this.getDay(`${arr[0]}-${arr[1]}-${arr[2]}`).then((val) => {
|
||||
swiperData = val
|
||||
this.$emit('changeDay', this.storageDate)
|
||||
this.$set(this, 'swiperData', swiperData)
|
||||
})
|
||||
},
|
||||
// 判断当前是 安卓还是ios ,传入不容的日期格式
|
||||
judgeDate(dateData) {
|
||||
if (typeof dateData !== 'object') {
|
||||
dateData = dateData.replace(/-/g, '/')
|
||||
}
|
||||
return dateData
|
||||
},
|
||||
// 循环上个月末尾几天添加到数组
|
||||
getDay(dateData) {
|
||||
dateData = this.judgeDate(dateData)
|
||||
// 获取年,月,日,星期
|
||||
let _date = new Date(dateData),
|
||||
year = _date.getFullYear(),
|
||||
month = _date.getMonth() + 1,
|
||||
date = _date.getDate(),
|
||||
day = _date.getDay()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
//获取上个月末尾几天
|
||||
let prevDayArr = [],
|
||||
prevDayLength = new Date(year, month - 1, 1).getDay()
|
||||
for (let i = prevDayLength; i > 0; i--) {
|
||||
let prevDay = new Date(year, month - 1, -i + 1).getDate()
|
||||
prevDayArr.push({
|
||||
day: prevDay,
|
||||
disable: true,
|
||||
Choice: false
|
||||
})
|
||||
}
|
||||
|
||||
// 获取本月
|
||||
let thisDayArr = [],
|
||||
thisDaylength = new Date(year, month - 1, 0).getDate()
|
||||
for (let i = 1; i <= new Date(year, month, 0).getDate(); i++) {
|
||||
thisDayArr.push({
|
||||
day: i,
|
||||
disable: false,
|
||||
Choice: false,
|
||||
price: this.price.data[i-1],
|
||||
priceType: this.price.type
|
||||
})
|
||||
// 重绘已选择日期
|
||||
this.storageDate.forEach((val, index) => {
|
||||
let valArr = val.date.split('-');
|
||||
if (year == valArr[0] && month == valArr[1] && i == valArr[2]) {
|
||||
thisDayArr[i - 1].Choice = true
|
||||
val.price = this.price.data[i-1]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 获取下个月开始几天
|
||||
let nextDayArr = [],
|
||||
nextDaylength = 42 - (prevDayArr.length + thisDayArr.length)
|
||||
for (let i = 1; i < nextDaylength + 1; i++) {
|
||||
nextDayArr.push({
|
||||
day: i,
|
||||
disable: true,
|
||||
Choice: false
|
||||
})
|
||||
}
|
||||
|
||||
// 数据合并
|
||||
let dateShow = []
|
||||
dateShow = dateShow.concat(prevDayArr, thisDayArr, nextDayArr)
|
||||
|
||||
// 禁用今天之前的日期
|
||||
if (this.disableBefore) {
|
||||
let __beForeDeta = new Date(),
|
||||
dDate = `${__beForeDeta.getFullYear()}-${__beForeDeta.getMonth() + 1}-${__beForeDeta.getDate()}`
|
||||
this.disableDatePrevFn(dateShow, dDate.split('-'), year, month).then((val) => {
|
||||
resolve({
|
||||
dateDay: val,
|
||||
year: year,
|
||||
month: month
|
||||
})
|
||||
})
|
||||
// 禁用双向指定范围可用
|
||||
} else if (this.startDate != '' && this.endDate != '') {
|
||||
let startDateArr = this.startDate.split('-')
|
||||
let endDateArr = this.endDate.split('-')
|
||||
if (startDateArr.length == 3 && endDateArr.length == 3) {
|
||||
this.disableDatePrevFn(dateShow, startDateArr, year, month).then((val) => {
|
||||
return this.disableDateNextFn(val, endDateArr, year, month)
|
||||
}).then((val) => {
|
||||
resolve({
|
||||
dateDay: val,
|
||||
year: year,
|
||||
month: month
|
||||
})
|
||||
})
|
||||
} else if (endDateArr.length != 3) {
|
||||
console.error('error 日期选择范围-结束日期错误,如: 2019-5-12')
|
||||
if (startDateArr.length != 3) {
|
||||
console.error('error 日期选择范围-开始日期错误,如: 2019-5-12')
|
||||
}
|
||||
}
|
||||
// 禁用开始日期之前
|
||||
} else if (this.startDate != '') {
|
||||
let startDateArr = this.startDate.split('-')
|
||||
if (startDateArr.length == 3) {
|
||||
this.disableDatePrevFn(dateShow, startDateArr, year, month).then((val) => {
|
||||
resolve({
|
||||
dateDay: val,
|
||||
year: year,
|
||||
month: month
|
||||
})
|
||||
})
|
||||
} else {
|
||||
console.error('error 日期选择范围-开始日期错误,如: 2019-5-12')
|
||||
}
|
||||
// 禁用结束日期之前
|
||||
} else if (this.endDate != '') {
|
||||
let endDateArr = this.endDate.split('-')
|
||||
if (endDateArr.length == 3) {
|
||||
this.disableDateNextFn(dateShow, endDateArr, year, month).then((val) => {
|
||||
resolve({
|
||||
dateDay: val,
|
||||
year: year,
|
||||
month: month
|
||||
})
|
||||
})
|
||||
} else {
|
||||
console.error('error 日期选择范围-结束日期错误,如: 2019-5-12')
|
||||
}
|
||||
// 不禁用
|
||||
} else {
|
||||
this.disableDatePrevFn(dateShow, new Array(3), year, month).then((val) => {
|
||||
resolve({
|
||||
dateDay: val,
|
||||
year: year,
|
||||
month: month
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 禁用指定日期之前的日期
|
||||
disableDatePrevFn() {
|
||||
let DateObj = arguments,
|
||||
dateShow = DateObj[0],
|
||||
dDate = DateObj[1],
|
||||
year = DateObj[2],
|
||||
month = DateObj[3]
|
||||
return new Promise((resolve, reject) => {
|
||||
dateShow = dateShow.map((val, index) => {
|
||||
if (dDate[0] > year) {
|
||||
val.disable = true
|
||||
} else if (dDate[1] > month && dDate[0] >= year) {
|
||||
val.disable = true
|
||||
} else if (dDate[0] >= year && dDate[2] > val.day && dDate[1] >= month) {
|
||||
val.disable = true
|
||||
}
|
||||
return val
|
||||
})
|
||||
resolve(dateShow)
|
||||
})
|
||||
},
|
||||
// 禁用指定日期之后的日期
|
||||
disableDateNextFn() {
|
||||
let DateObj = arguments,
|
||||
dateShow = DateObj[0],
|
||||
dDate = DateObj[1],
|
||||
year = DateObj[2],
|
||||
month = DateObj[3]
|
||||
return new Promise((resolve, reject) => {
|
||||
dateShow = dateShow.map((val, index) => {
|
||||
if (dDate[0] < year) {
|
||||
val.disable = true
|
||||
} else if (dDate[0] <= year && dDate[1] < month) {
|
||||
val.disable = true
|
||||
} else if (dDate[0] <= year && dDate[1] <= month && dDate[2] < val.day) {
|
||||
val.disable = true
|
||||
}
|
||||
return val
|
||||
})
|
||||
resolve(dateShow)
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
components: {
|
||||
uniIcon
|
||||
},
|
||||
watch: {
|
||||
'PriceData': {
|
||||
handler(newData, oldData) {
|
||||
this.InitializationHomeDate(false).then((val) => {
|
||||
this.Preprocessing([this.year, this.month, this.day])
|
||||
})
|
||||
},
|
||||
immediate: false,
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
.body {
|
||||
width: 100%;
|
||||
background: #000;
|
||||
.head-body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 41px;
|
||||
box-sizing: border-box;
|
||||
padding: 5px 30upx 10px 30upx;
|
||||
justify-content: space-between;
|
||||
|
||||
.date-head {
|
||||
font-size: 36upx;
|
||||
color: #fff;
|
||||
line-height: 26px;
|
||||
letter-spacing: 1px;
|
||||
text{
|
||||
font-size: 36upx;
|
||||
}
|
||||
}
|
||||
.pr40 {
|
||||
padding-right: 40upx;
|
||||
}
|
||||
}
|
||||
|
||||
.mian-body {
|
||||
width: 100%;
|
||||
height: calc(100% - 46px);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.mian-bolck {
|
||||
width: calc(100% / 7 - 10upx);
|
||||
padding: 8upx 0;
|
||||
min-height: calc(750upx / 7 - 26upx);
|
||||
box-sizing: border-box;
|
||||
font-size: 34upx;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 5upx;
|
||||
cursor: pointer;
|
||||
.border {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
.price{
|
||||
font-size: 24upx;
|
||||
}
|
||||
.day{
|
||||
width: 100%;
|
||||
}
|
||||
text{
|
||||
font-size: 36upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.disable {
|
||||
color: #939393;
|
||||
}
|
||||
.Choice {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
background: #0078d7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
419
mallplusui-uniapp-app/components/reserve-date/uni-icon.vue
Normal file
419
mallplusui-uniapp-app/components/reserve-date/uni-icon.vue
Normal file
File diff suppressed because one or more lines are too long
238
mallplusui-uniapp-app/components/share.vue
Normal file
238
mallplusui-uniapp-app/components/share.vue
Normal file
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<view v-if="show" class="mask" @click="toggleMask" @touchmove.stop.prevent="stopPrevent" :style="{ backgroundColor: backgroundColor }">
|
||||
<view
|
||||
class="mask-content"
|
||||
@click.stop.prevent="stopPrevent"
|
||||
:style="[
|
||||
{
|
||||
height: config.height,
|
||||
transform: transform
|
||||
}
|
||||
]"
|
||||
>
|
||||
<scroll-view class="view-content" show-scrollbar="false" scroll-y>
|
||||
<view class="share-header">分享到</view>
|
||||
<view class="share-list">
|
||||
<view v-for="(item, index) in shareList" :key="index" class="share-item" @click="shareToFriend(item.typeIcon, item.scene, item.provider)">
|
||||
<image :src="item.icon" mode=""></image>
|
||||
<text>{{ item.text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="bottom b-t" @click="toggleMask">取消</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
var href = null;
|
||||
var title = null;
|
||||
var imgUrl = null;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
transform: 'translateY(50vh)',
|
||||
timer: 0,
|
||||
backgroundColor: 'rgba(0,0,0,0)',
|
||||
show: false,
|
||||
config: {}
|
||||
};
|
||||
},
|
||||
props: {
|
||||
contentHeight: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
//是否是tabbar页面
|
||||
hasTabbar: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
shareList: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const height = uni.upx2px(this.contentHeight) + 'px';
|
||||
this.config = {
|
||||
height: height,
|
||||
transform: `translateY(${height})`,
|
||||
backgroundColor: 'rgba(0,0,0,.4)'
|
||||
};
|
||||
this.transform = this.config.transform;
|
||||
},
|
||||
methods: {
|
||||
toggleMask(title, imgUrl, href) {
|
||||
this.title = title;
|
||||
this.imgUrl = imgUrl;
|
||||
this.href = href;
|
||||
//防止高频点击
|
||||
if (this.timer == 1) {
|
||||
return;
|
||||
}
|
||||
this.timer = 1;
|
||||
setTimeout(() => {
|
||||
this.timer = 0;
|
||||
}, 500);
|
||||
|
||||
if (this.show) {
|
||||
this.transform = this.config.transform;
|
||||
this.backgroundColor = 'rgba(0,0,0,0)';
|
||||
setTimeout(() => {
|
||||
this.show = false;
|
||||
this.hasTabbar && uni.showTabBar();
|
||||
}, 200);
|
||||
return;
|
||||
}
|
||||
|
||||
this.show = true;
|
||||
//等待mask重绘完成执行
|
||||
if (this.hasTabbar) {
|
||||
uni.hideTabBar({
|
||||
success: () => {
|
||||
setTimeout(() => {
|
||||
this.backgroundColor = this.config.backgroundColor;
|
||||
this.transform = 'translateY(0px)';
|
||||
}, 10);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.backgroundColor = this.config.backgroundColor;
|
||||
this.transform = 'translateY(0px)';
|
||||
}, 10);
|
||||
}
|
||||
},
|
||||
//防止冒泡和滚动穿透
|
||||
stopPrevent() {},
|
||||
//分享操作
|
||||
shareToFriend(type, scene, provider) {
|
||||
// this.$api.msg(`分享给${type}`);
|
||||
// this.toggleMask();
|
||||
var url = this.href;
|
||||
var title = this.title;
|
||||
var imgUrl = this.imgUrl;
|
||||
uni.share({
|
||||
provider: provider,
|
||||
scene: scene,
|
||||
type: type,
|
||||
href: url,
|
||||
title: title,
|
||||
imageUrl: imgUrl,
|
||||
success: function(res) {
|
||||
console.log(JSON.stringify(res));
|
||||
uni.showToast({
|
||||
title: '已分享',
|
||||
duration: 2000
|
||||
});
|
||||
},
|
||||
|
||||
fail: function(err) {
|
||||
var errrr = JSON.stringify(err);
|
||||
if (errrr) {
|
||||
uni.showModal({
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
console.log('用户点击确定');
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
this.toggleMask();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.mask {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-end;
|
||||
z-index: 998;
|
||||
transition: 0.3s;
|
||||
.bottom {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 90upx;
|
||||
background: #fff;
|
||||
z-index: 9;
|
||||
font-size: $font-base + 2upx;
|
||||
color: $font-color-dark;
|
||||
}
|
||||
}
|
||||
|
||||
.mask-content {
|
||||
width: 100%;
|
||||
height: 580upx;
|
||||
transition: 0.3s;
|
||||
background: #fff;
|
||||
&.has-bottom {
|
||||
padding-bottom: 90upx;
|
||||
}
|
||||
.view-content {
|
||||
height: 100%;
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
.share-header {
|
||||
height: 110upx;
|
||||
font-size: $font-base + 2upx;
|
||||
color: font-color-dark;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: 10upx;
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
width: 240upx;
|
||||
heighg: 0;
|
||||
border-top: 1px solid $border-color-base;
|
||||
transform: scaleY(0.5);
|
||||
margin-right: 30upx;
|
||||
}
|
||||
&:after {
|
||||
margin-left: 30upx;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
.share-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.share-item {
|
||||
min-width: 33.33%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 180upx;
|
||||
image {
|
||||
width: 80upx;
|
||||
height: 80upx;
|
||||
margin-bottom: 16upx;
|
||||
}
|
||||
text {
|
||||
font-size: $font-base;
|
||||
color: $font-color-base;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
205
mallplusui-uniapp-app/components/time-filter/time-filter.vue
Normal file
205
mallplusui-uniapp-app/components/time-filter/time-filter.vue
Normal file
@@ -0,0 +1,205 @@
|
||||
<template>
|
||||
<view class="dateContent">
|
||||
<view class="line"></view>
|
||||
<view v-for="(item,key) in dateList" :class="{'item':true, 'item-checked': key==nowIndex, 'item-close': !item.isActive}" :key="key" @click="choseTime(item,key)">
|
||||
<!--<view class="value">{{item.value}}</view>-->
|
||||
<view class="circle"></view>
|
||||
<view class="week">{{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'month'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dateList() {
|
||||
var arr = this.getArr(this.type)
|
||||
return arr
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nowIndex: 6
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getArr(type) {
|
||||
var timeArr = []
|
||||
if(type == 'month'){
|
||||
timeArr = [
|
||||
{
|
||||
name: '6月前',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -6
|
||||
},
|
||||
{
|
||||
name: '5月前',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -5
|
||||
},
|
||||
{
|
||||
name: '4月前',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -4
|
||||
},
|
||||
{
|
||||
name: '3月前',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -3
|
||||
},
|
||||
{
|
||||
name: '2月前',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -2
|
||||
},
|
||||
{
|
||||
name: '上月',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -1
|
||||
},
|
||||
{
|
||||
name: '本月',
|
||||
isActive: true,
|
||||
checked: true,
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
if(type == 'day'){
|
||||
timeArr = [
|
||||
{
|
||||
name: '6天前',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -6
|
||||
},
|
||||
{
|
||||
name: '5天前',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -5
|
||||
},
|
||||
{
|
||||
name: '4天前',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -4
|
||||
},
|
||||
{
|
||||
name: '3天前',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -3
|
||||
},
|
||||
{
|
||||
name: '2天前',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -2
|
||||
},
|
||||
{
|
||||
name: '昨天',
|
||||
isActive: true,
|
||||
checked: false,
|
||||
value: -1
|
||||
},
|
||||
{
|
||||
name: '今天',
|
||||
isActive: true,
|
||||
checked: true,
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
return timeArr;
|
||||
},
|
||||
getMonth(month) {
|
||||
var time = new Date();
|
||||
time.setMonth(time.getMonth() + month);//设置month月后的时间
|
||||
var y = time.getFullYear();
|
||||
var m = time.getMonth() + 1;//获取当前月份
|
||||
var d = time.getDate();
|
||||
if(m<10){
|
||||
m = "0"+m
|
||||
}
|
||||
return y + "-" + m ;
|
||||
},
|
||||
addDate(days) {
|
||||
var d = new Date();
|
||||
d.setDate(d.getDate() + days);
|
||||
var m = d.getMonth() + 1;
|
||||
if(m < 10){
|
||||
m='0'+m
|
||||
}
|
||||
var day = d.getDate()
|
||||
if(day < 10){
|
||||
day='0'+day
|
||||
}
|
||||
return d.getFullYear() + '-' + m + '-' + day;
|
||||
},
|
||||
choseTime(item, index) {
|
||||
this.$emit('chooseTime', item)
|
||||
this.nowIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.dateContent{
|
||||
background: $uni-bg-color;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 18upx 6upx 4upx 6upx;
|
||||
.item{
|
||||
z-index: 9;
|
||||
color: $uni-text-color-grey;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding-bottom: 12upx;
|
||||
&-checked{
|
||||
color: #3FC0A2;
|
||||
font-weight: bolder;
|
||||
.circle{
|
||||
background-color: #3FC0A2!important;
|
||||
}
|
||||
}
|
||||
&-close{
|
||||
color: $uni-text-color-grey;
|
||||
}
|
||||
.week{
|
||||
margin-top: 4upx;
|
||||
font-size: $uni-font-size-base;
|
||||
}
|
||||
.circle{
|
||||
width: 18upx;
|
||||
height: 18upx;
|
||||
border-radius: 50%;
|
||||
border:1px solid #ebedf0;
|
||||
margin: 20upx auto ;
|
||||
background-color: $uni-bg-color;
|
||||
}
|
||||
}
|
||||
.line{
|
||||
position: absolute;
|
||||
top: 47upx;
|
||||
width: 94%;
|
||||
left: 3%;
|
||||
height: 4upx;
|
||||
background-color: #ebedf0;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
165
mallplusui-uniapp-app/components/u-charts/component.vue
Normal file
165
mallplusui-uniapp-app/components/u-charts/component.vue
Normal file
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<canvas v-if="canvasId" :id="canvasId" :canvasId="canvasId" :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"
|
||||
@touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error">
|
||||
</canvas>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uCharts from './u-charts.js';
|
||||
var canvases = {};
|
||||
|
||||
export default {
|
||||
props: {
|
||||
chartType: {
|
||||
required: true,
|
||||
type: String,
|
||||
default: 'column'
|
||||
},
|
||||
opts: {
|
||||
required: true,
|
||||
type: Object,
|
||||
default () {
|
||||
return null;
|
||||
},
|
||||
},
|
||||
canvasId: {
|
||||
type: String,
|
||||
default: 'u-canvas',
|
||||
},
|
||||
cWidth: {
|
||||
default: 375,
|
||||
},
|
||||
cHeight: {
|
||||
default: 250,
|
||||
},
|
||||
pixelRatio: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
switch (this.chartType) {
|
||||
case 'column':
|
||||
this.initColumnChart();
|
||||
break;
|
||||
case 'line':
|
||||
this.initLineChart();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
initColumnChart() {
|
||||
canvases[this.canvasId] = new uCharts({
|
||||
$this: this,
|
||||
canvasId: this.canvasId,
|
||||
type: 'column',
|
||||
legend: true,
|
||||
fontSize: 11,
|
||||
background: '#FFFFFF',
|
||||
pixelRatio: this.pixelRatio,
|
||||
animation: true,
|
||||
categories: this.opts.categories,
|
||||
series: this.opts.series,
|
||||
enableScroll: true,
|
||||
xAxis: {
|
||||
disableGrid: true,
|
||||
itemCount: 4,
|
||||
scrollShow: true
|
||||
},
|
||||
yAxis: {
|
||||
//disabled:true
|
||||
},
|
||||
dataLabel: true,
|
||||
width: this.cWidth * this.pixelRatio,
|
||||
height: this.cHeight * this.pixelRatio,
|
||||
extra: {
|
||||
column: {
|
||||
type: 'group',
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
initLineChart() {
|
||||
canvases[this.canvasId] = new uCharts({
|
||||
$this: this,
|
||||
canvasId: this.canvasId,
|
||||
type: 'line',
|
||||
fontSize: 11,
|
||||
legend: true,
|
||||
dataLabel: false,
|
||||
dataPointShape: true,
|
||||
background: '#FFFFFF',
|
||||
pixelRatio: this.pixelRatio,
|
||||
categories: this.opts.categories,
|
||||
series: this.opts.series,
|
||||
animation: true,
|
||||
enableScroll: true,
|
||||
xAxis: {
|
||||
type: 'grid',
|
||||
gridColor: '#CCCCCC',
|
||||
gridType: 'dash',
|
||||
dashLength: 8,
|
||||
itemCount: 4,
|
||||
scrollShow: true
|
||||
},
|
||||
yAxis: {
|
||||
gridType: 'dash',
|
||||
gridColor: '#CCCCCC',
|
||||
dashLength: 8,
|
||||
splitNumber: 5,
|
||||
min: 10,
|
||||
max: 180,
|
||||
format: (val) => {
|
||||
return val.toFixed(0) + '元'
|
||||
}
|
||||
},
|
||||
width: this.cWidth * this.pixelRatio,
|
||||
height: this.cHeight * this.pixelRatio,
|
||||
extra: {
|
||||
line: {
|
||||
type: 'straight'
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// 这里仅作为示例传入两个参数,cid为canvas-id,newdata为更新的数据,需要更多参数请自行修改
|
||||
changeData(cid,newdata) {
|
||||
canvases[cid].updateData({
|
||||
series: newdata.series,
|
||||
categories: newdata.categories
|
||||
});
|
||||
},
|
||||
touchStart(e) {
|
||||
canvases[this.canvasId].showToolTip(e, {
|
||||
format: function(item, category) {
|
||||
return category + ' ' + item.name + ':' + item.data
|
||||
}
|
||||
});
|
||||
canvases[this.canvasId].scrollStart(e);
|
||||
},
|
||||
touchMove(e) {
|
||||
canvases[this.canvasId].scroll(e);
|
||||
},
|
||||
touchEnd(e) {
|
||||
canvases[this.canvasId].scrollEnd(e);
|
||||
},
|
||||
error(e) {
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.charts {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
5633
mallplusui-uniapp-app/components/u-charts/u-charts.js
Normal file
5633
mallplusui-uniapp-app/components/u-charts/u-charts.js
Normal file
File diff suppressed because it is too large
Load Diff
1
mallplusui-uniapp-app/components/u-charts/u-charts.min.js
vendored
Normal file
1
mallplusui-uniapp-app/components/u-charts/u-charts.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
101
mallplusui-uniapp-app/components/uni-badge/uni-badge.vue
Normal file
101
mallplusui-uniapp-app/components/uni-badge/uni-badge.vue
Normal file
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<text v-if="text" :class="inverted ? 'uni-badge-' + type + ' uni-badge--' + size + ' uni-badge-inverted' : 'uni-badge-' + type + ' uni-badge--' + size"
|
||||
class="uni-badge" @click="onClick()">{{ text }}</text>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UniBadge',
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'default'
|
||||
},
|
||||
inverted: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
size: { // small.normal
|
||||
type: String,
|
||||
default: 'normal'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('click')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
$bage-size:12px;
|
||||
$bage-small:scale(0.8);
|
||||
|
||||
.uni-badge {
|
||||
font-family: 'Helvetica Neue', Helvetica, sans-serif;
|
||||
box-sizing: border-box;
|
||||
font-size: $bage-size;
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
padding: 3px 6px;
|
||||
color: $uni-text-color;
|
||||
border-radius: 100px;
|
||||
background-color: $uni-bg-color-hover;
|
||||
|
||||
&.uni-badge-inverted {
|
||||
padding: 0 5px 0 0;
|
||||
color: $uni-text-color-grey;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&-primary {
|
||||
color: $uni-text-color-inverse;
|
||||
background-color: $uni-color-primary;
|
||||
|
||||
&.uni-badge-inverted {
|
||||
color: $uni-color-primary;
|
||||
background-color: transparent
|
||||
}
|
||||
}
|
||||
|
||||
&-success {
|
||||
color: $uni-text-color-inverse;
|
||||
background-color: $uni-color-success;
|
||||
|
||||
&.uni-badge-inverted {
|
||||
color: $uni-color-success;
|
||||
background-color: transparent
|
||||
}
|
||||
}
|
||||
|
||||
&-warning {
|
||||
color: $uni-text-color-inverse;
|
||||
background-color: $uni-color-warning;
|
||||
|
||||
&.uni-badge-inverted {
|
||||
color: $uni-color-warning;
|
||||
background-color: transparent
|
||||
}
|
||||
}
|
||||
|
||||
&-error {
|
||||
color: $uni-text-color-inverse;
|
||||
background-color: $uni-color-error;
|
||||
|
||||
&.uni-badge-inverted {
|
||||
color: $uni-color-error;
|
||||
background-color: transparent
|
||||
}
|
||||
}
|
||||
|
||||
&--small {
|
||||
transform: $bage-small;
|
||||
transform-origin: center center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
73
mallplusui-uniapp-app/components/uni-countdown/readme.md
Normal file
73
mallplusui-uniapp-app/components/uni-countdown/readme.md
Normal file
@@ -0,0 +1,73 @@
|
||||
### CountDown 倒计时
|
||||
|
||||
倒计时组件,组件名:``uni-countdown``,代码块: uCountDown。
|
||||
|
||||
**使用方式:**
|
||||
|
||||
在 ``script`` 中引用组件
|
||||
|
||||
```javascript
|
||||
import uniCountdown from "@/components/uni-countdown/uni-countdown.vue"
|
||||
export default {
|
||||
components: {uniCountdown}
|
||||
}
|
||||
```
|
||||
|
||||
一般用法
|
||||
|
||||
```html
|
||||
<uni-countdown
|
||||
:day="1"
|
||||
:hour="1"
|
||||
:minute="12"
|
||||
:second="40">
|
||||
</uni-countdown>
|
||||
```
|
||||
|
||||
不显示天数
|
||||
|
||||
```html
|
||||
<uni-countdown
|
||||
:show-day="false"
|
||||
:hour="12"
|
||||
:minute="12"
|
||||
:second="12">
|
||||
</uni-countdown>
|
||||
```
|
||||
|
||||
修改颜色
|
||||
|
||||
```html
|
||||
<uni-countdown
|
||||
color="#FFFFFF"
|
||||
background-color="#00B26A"
|
||||
border-color="#00B26A"
|
||||
:day="1"
|
||||
:hour="2"
|
||||
:minute="30"
|
||||
:second="0">
|
||||
</uni-countdown>
|
||||
```
|
||||
|
||||
实际效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)
|
||||
|
||||
**uniCountDown 属性说明:**
|
||||
|
||||
|属性名|类型|默认值 |说明|
|
||||
|---|----|---|---|
|
||||
|background-color|String|#FFFFFF|背景色|
|
||||
|border-color|String|#000000|边框颜色|
|
||||
|color |String |#000000|文字颜色|
|
||||
|splitor-color|String|#000000|割符号颜色|
|
||||
|day|Number|0|天数|
|
||||
|hour|Number|0|小时|
|
||||
|minute|Number|0|分钟|
|
||||
|second|Number|0|秒|
|
||||
|show-day|Boolean|true|是否显示天数|
|
||||
|show-colon|Boolean|true|是否以冒号为分隔符|
|
||||
|
||||
**uniCountDown 事件说明:**
|
||||
|
||||
|事件称名|说明|返回参数|
|
||||
|---|----|---|
|
||||
|timeup|倒计时时间到触发事件|-|
|
||||
156
mallplusui-uniapp-app/components/uni-countdown/uni-countdown.vue
Normal file
156
mallplusui-uniapp-app/components/uni-countdown/uni-countdown.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<view class="uni-countdown">
|
||||
<view v-if="showDay && d!=0" class="uni-countdown__number" :style="{borderColor:borderColor, color:color, background:backgroundColor}">{{d}}</view>
|
||||
<view v-if="showDay && d!=0" class="uni-countdown__splitor" :style="{color:textColor}">天</view>
|
||||
<view class="uni-countdown__number" :style="{borderColor:borderColor, color:color, background:backgroundColor}">{{h}}</view>
|
||||
<view class="uni-countdown__splitor" :style="{color:textColor}">{{showColon ? ':' : '时'}}</view>
|
||||
<view class="uni-countdown__number" :style="{borderColor:borderColor, color:color, background:backgroundColor}">{{i}}</view>
|
||||
<view class="uni-countdown__splitor" :style="{color:textColor}">{{showColon ? ':' : '分'}}</view>
|
||||
<view class="uni-countdown__number" :style="{borderColor:borderColor, color:color, background:backgroundColor}">{{s}}</view>
|
||||
<view v-if="!showColon" class="uni-countdown__splitor" :style="{color:textColor}">秒</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "uni-countdown",
|
||||
props: {
|
||||
showDay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showColon: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
backgroundColor: {
|
||||
type: String,
|
||||
default: "#FFFFFF"
|
||||
},
|
||||
borderColor: {
|
||||
type: String,
|
||||
default: "#000000"
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
// value: "#000000"
|
||||
},
|
||||
textColor: {
|
||||
type: String,
|
||||
default: "#000000"
|
||||
},
|
||||
splitorColor: {
|
||||
type: String,
|
||||
default: "#000"
|
||||
},
|
||||
day: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
hour: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
minute: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
second: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
timer: null,
|
||||
d: '00',
|
||||
h: '00',
|
||||
i: '00',
|
||||
s: '00',
|
||||
leftTime: 0,
|
||||
seconds: 0
|
||||
}
|
||||
},
|
||||
created: function(e) {
|
||||
this.seconds = this.toSeconds(this.day, this.hour, this.minute, this.second)
|
||||
this.countDown()
|
||||
this.timer = setInterval(() => {
|
||||
this.seconds--
|
||||
if (this.seconds < 0) {
|
||||
this.timeUp()
|
||||
return
|
||||
}
|
||||
this.countDown()
|
||||
}, 1000)
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
toSeconds(day, hours, minutes, seconds) {
|
||||
return (day * 60 * 60 * 24) + (hours * 60 * 60) + (minutes * 60) + seconds
|
||||
},
|
||||
timeUp() {
|
||||
clearInterval(this.timer)
|
||||
this.$emit('timeup')
|
||||
},
|
||||
countDown() {
|
||||
let seconds = this.seconds
|
||||
let [day, hour, minute, second] = [0, 0, 0, 0]
|
||||
if (seconds > 0) {
|
||||
day = Math.floor(seconds / (60 * 60 * 24))
|
||||
hour = Math.floor(seconds / (60 * 60)) - (day * 24)
|
||||
minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
|
||||
second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
|
||||
} else {
|
||||
this.timeUp()
|
||||
}
|
||||
if (day < 10) {
|
||||
day = '0' + day
|
||||
}
|
||||
if (hour < 10) {
|
||||
hour = '0' + hour
|
||||
}
|
||||
if (minute < 10) {
|
||||
minute = '0' + minute
|
||||
}
|
||||
if (second < 10) {
|
||||
second = '0' + second
|
||||
}
|
||||
this.d = day
|
||||
this.h = hour
|
||||
this.i = minute
|
||||
this.s = second
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
$countdown-height:44upx;
|
||||
|
||||
.uni-countdown {
|
||||
padding: 2upx 0;
|
||||
display: inline-flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: center;
|
||||
|
||||
&__splitor {
|
||||
justify-content: center;
|
||||
line-height: $countdown-height;
|
||||
padding: 0 5upx;
|
||||
font-size: 24upx;
|
||||
// color: #d0d0d0;
|
||||
}
|
||||
|
||||
&__number {
|
||||
line-height: $countdown-height;
|
||||
justify-content: center;
|
||||
height: $countdown-height;
|
||||
border-radius: $uni-border-radius-base;
|
||||
// margin: 0 5upx;
|
||||
font-size: 24upx;
|
||||
// border: 1px solid #000000;
|
||||
font-size: $uni-font-size-sm;
|
||||
// padding: 0 10upx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
239
mallplusui-uniapp-app/components/uni-grid-item/uni-grid-item.vue
Normal file
239
mallplusui-uniapp-app/components/uni-grid-item/uni-grid-item.vue
Normal file
@@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<view
|
||||
v-if="width"
|
||||
:style="{ width: width }"
|
||||
class="uni-grid-item">
|
||||
<view
|
||||
:class="{ border: showBorder, 'uni-grid-item__box-square': square, 'border-top': showBorder && index < column, 'uni-highlight': highlight }"
|
||||
:style="{ 'border-color': borderColor }"
|
||||
class="uni-grid-item__box"
|
||||
@click="_onClick"
|
||||
>
|
||||
<view
|
||||
v-if="marker === 'dot'"
|
||||
:style="{ left: top + 'px', top: left + 'px' }"
|
||||
class="uni-grid-item__box-dot" />
|
||||
<view
|
||||
v-if="marker === 'badge'"
|
||||
:style="{ left: top + 'px', top: left + 'px' }"
|
||||
class="uni-grid-item__box-badge">
|
||||
<uni-badge
|
||||
:text="text"
|
||||
:type="type"
|
||||
:size="size"
|
||||
:inverted="inverted" />
|
||||
</view>
|
||||
<view
|
||||
v-if="marker === 'image'"
|
||||
:style="{ left: top + 'px', top: left + 'px' }"
|
||||
class="uni-grid-item__box-image">
|
||||
<image
|
||||
:style="{ width: imgWidth + 'px' }"
|
||||
:src="src"
|
||||
class="box-image"
|
||||
mode="widthFix" />
|
||||
</view>
|
||||
<view class="uni-grid-item__box-item"><slot /></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniBadge from '@/components/uni-badge/uni-badge.vue'
|
||||
|
||||
export default {
|
||||
name: 'UniGridItem',
|
||||
components: { uniBadge },
|
||||
props: {
|
||||
// 类型:可选值,dot:圆点;badge:角标;image:图片
|
||||
marker: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 水平方向
|
||||
hor: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 垂直方向
|
||||
ver: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// badge 下颜色类型,可选值:default(灰色)、primary(蓝色)、success(绿色)、warning(黄色)、error(红色)
|
||||
type: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// badge 下显示内容,汉字最多为1个
|
||||
text: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// badge 下 Badge 大小
|
||||
size: {
|
||||
type: String,
|
||||
default: 'normal'
|
||||
},
|
||||
// badge 下 是否无需背景颜色
|
||||
inverted: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// image 下图片路径
|
||||
src: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// image 下图片宽度 ,最大 为 100 。 默认为 30
|
||||
imgWidth: {
|
||||
type: Number,
|
||||
default: 30
|
||||
}
|
||||
},
|
||||
inject: ['grid'],
|
||||
data () {
|
||||
return {
|
||||
column: 0,
|
||||
showBorder: true,
|
||||
square: true,
|
||||
highlight: true,
|
||||
left: 0,
|
||||
top: 0,
|
||||
index: 0,
|
||||
openNum: 2,
|
||||
width: 0,
|
||||
borderColor: '#d0dee5'
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.column = this.grid.column
|
||||
this.showBorder = this.grid.showBorder
|
||||
this.square = this.grid.square
|
||||
this.highlight = this.grid.highlight
|
||||
this.top = this.hor === 0 ? this.grid.hor : this.hor
|
||||
this.left = this.ver === 0 ? this.grid.ver : this.ver
|
||||
this.borderColor = this.grid.borderColor
|
||||
this.index = this.grid.index++
|
||||
},
|
||||
// #ifdef H5
|
||||
mounted () {
|
||||
this.grid._getSize(width => {
|
||||
this.width = width
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
onReady () {
|
||||
this.grid._getSize(width => {
|
||||
this.width = width
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
methods: {
|
||||
_onClick () {
|
||||
// console.log('点击', this.index);
|
||||
this.grid.change({ detail: { index: this.index } })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.uni-grid-item {
|
||||
box-sizing: border-box;
|
||||
&__box {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
// overflow: hidden;
|
||||
&-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 32upx;
|
||||
color: #666;
|
||||
padding: 20upx 0;
|
||||
box-sizing: border-box;
|
||||
.image {
|
||||
width: 50upx;
|
||||
height: 50upx;
|
||||
}
|
||||
.text {
|
||||
font-size: 26upx;
|
||||
margin-top: 10upx;
|
||||
}
|
||||
}
|
||||
&.uni-grid-item__box-square {
|
||||
height: 0;
|
||||
padding-top: 100%;
|
||||
& .uni-grid-item__box-item {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
&.border {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
// box-shadow: 0 0 0 1px #d0dee5;
|
||||
// border-left: 1px #d0dee5 solid;
|
||||
border-bottom: 1px #d0dee5 solid;
|
||||
border-right: 1px #d0dee5 solid;
|
||||
// &::after {
|
||||
// content: '';
|
||||
// position: absolute;
|
||||
// top: 0%;
|
||||
// bottom: 0%;
|
||||
// left: 0%;
|
||||
// right: 0%;
|
||||
// border-right: 1px #d0dee5 solid;
|
||||
// border-bottom: 1px #d0dee5 solid;
|
||||
// }
|
||||
}
|
||||
&.border-top {
|
||||
border-top: 1px #d0dee5 solid;
|
||||
}
|
||||
&.uni-highlight:active {
|
||||
background-color: #eee;
|
||||
}
|
||||
&-dot,
|
||||
&-badge,
|
||||
&-image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
z-index: 10;
|
||||
}
|
||||
&-dot {
|
||||
width: 20upx;
|
||||
height: 20upx;
|
||||
background: #ff5a5f;
|
||||
border-radius: 50%;
|
||||
}
|
||||
&-badge {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
&-image {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100upx;
|
||||
height: 100upx;
|
||||
overflow: hidden;
|
||||
.box-image {
|
||||
width: 90upx;
|
||||
// height: 100upx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
96
mallplusui-uniapp-app/components/uni-grid/uni-grid.vue
Normal file
96
mallplusui-uniapp-app/components/uni-grid/uni-grid.vue
Normal file
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<view>
|
||||
<view
|
||||
:id="elId"
|
||||
:class="{ border: showBorder }"
|
||||
:style="{ 'border-left': showBorder ? '1px ' + borderColor + ' solid' : 'none' }"
|
||||
class="uni-grid"><slot /></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UniGrid',
|
||||
props: {
|
||||
// 每列显示个数
|
||||
column: {
|
||||
type: Number,
|
||||
default: 3
|
||||
},
|
||||
// 是否显示边框
|
||||
showBorder: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否显示边框
|
||||
borderColor: {
|
||||
type: String,
|
||||
default: '#d0dee5'
|
||||
},
|
||||
// 全局标记水平方向移动距离 ,起点为中心,负数为左移动,正数为右移动
|
||||
hor: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 全局标记垂直方向移动距离 ,起点为中心,负数为上移动,正数为下移动
|
||||
ver: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 是否正方形显示,默认为 true
|
||||
square: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
highlight: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
provide () {
|
||||
return {
|
||||
grid: this
|
||||
}
|
||||
},
|
||||
data () {
|
||||
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
|
||||
return {
|
||||
index: 0,
|
||||
elId
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.index = 0
|
||||
this.childrens = []
|
||||
this.pIndex = this.pIndex ? this.pIndex++ : 0
|
||||
},
|
||||
methods: {
|
||||
change (e) {
|
||||
this.$emit('change', e)
|
||||
},
|
||||
_getSize (fn) {
|
||||
uni.createSelectorQuery()
|
||||
.in(this)
|
||||
.select(`#${this.elId}`)
|
||||
.boundingClientRect()
|
||||
.exec(ret => {
|
||||
if (!ret[0]) {
|
||||
setTimeout(this._getSize(fn))
|
||||
return
|
||||
}
|
||||
let width = parseInt(ret[0].width / this.column) - 1 + 'px'
|
||||
typeof fn === 'function' && fn(width)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.uni-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
box-sizing: border-box;
|
||||
border-left: 1px #d0dee5 solid;
|
||||
}
|
||||
</style>
|
||||
127
mallplusui-uniapp-app/components/uni-icon/readme.md
Normal file
127
mallplusui-uniapp-app/components/uni-icon/readme.md
Normal file
@@ -0,0 +1,127 @@
|
||||
### Icon 图标
|
||||
|
||||
用于展示 icon,组件名:``uni-icon``,代码块: uIcon。
|
||||
|
||||
**使用方式:**
|
||||
|
||||
在 ``script`` 中引用组件
|
||||
|
||||
```javascript
|
||||
import uniIcon from "@/components/uni-icon/uni-icon.vue"
|
||||
export default {
|
||||
components: {uniIcon}
|
||||
}
|
||||
```
|
||||
|
||||
在 ``template`` 中使用组件
|
||||
|
||||
```html
|
||||
<uni-icon type="contact" size="30"></uni-icon>
|
||||
```
|
||||
|
||||
实际效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)
|
||||
|
||||
**Icon 属性说明:**
|
||||
|
||||
|属性名 |类型|默认值 |说明|
|
||||
|---|----|---|---|
|
||||
|type |String |-|图标图案,参考下表|
|
||||
|color |String |-|图标颜色 |
|
||||
|size |Number |24|图标大小|
|
||||
|@click |EventHandle|-|点击 Icon 触发事件|
|
||||
|
||||
**type 类型:**
|
||||
|
||||
<div>
|
||||
<link rel="stylesheet" type="text/css" href="https://img-cdn-qiniu.dcloud.net.cn/uniapp/doc/icon1.1.css"/>
|
||||
<ul class="icon-group">
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-contact"></span><span>contact</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-person"></span><span>person</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-personadd"></span><span>personadd</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-contact-filled"></span><span>contact-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-person-filled"></span><span>person-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-personadd-filled"></span><span>personadd-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-phone"></span><span>phone</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-email"></span><span>email</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-chatbubble"></span><span>chatbubble</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-chatboxes"></span><span>chatboxes</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-phone-filled"></span><span>phone-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-email-filled"></span><span>email-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-chatbubble-filled"></span><span>chatbubble-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-chatboxes-filled"></span><span>chatboxes-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-weibo"></span><span>weibo</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-weixin"></span><span>weixin</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-pengyouquan"></span><span>pengyouquan</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-chat"></span><span>chat</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-qq"></span><span>qq</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-videocam"></span><span>videocam</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-camera"></span><span>camera</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-mic"></span><span>mic</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-location"></span><span>location</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-mic-filled"></span><span>mic-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-location-filled"></span><span>location-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-micoff"></span><span>micoff</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-image"></span><span>image</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-map"></span><span>map</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-compose"></span><span>compose</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-trash"></span><span>trash</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-upload"></span><span>upload</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-download"></span><span>download</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-close"></span><span>close</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-redo"></span><span>redo</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-undo"></span><span>undo</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-refresh"></span><span>refresh</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-star"></span><span>star</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-plus"></span><span>plus</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-minus"></span><span>minus</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-circle"></span><span>circle</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-clear"></span><span>clear</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-refresh-filled"></span><span>refresh-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-star-filled"></span><span>star-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-plus-filled"></span><span>plus-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-minus-filled"></span><span>minus-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-circle-filled"></span><span>circle-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-checkbox-filled"></span><span>checkbox-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-closeempty"></span><span>closeempty</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-refreshempty"></span><span>refreshempty</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-reload"></span><span>reload</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-starhalf"></span><span>starhalf</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-spinner"></span><span>spinner</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-spinner-cycle"></span><span>spinner-cycle</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-search"></span><span>search</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-plusempty"></span><span>plusempty</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-forward"></span><span>forward</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-back"></span><span>back</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-checkmarkempty"></span><span>checkmarkempty</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-home"></span><span>home</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-navigate"></span><span>navigate</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-gear"></span><span>gear</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-paperplane"></span><span>paperplane</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-info"></span><span>info</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-help"></span><span>help</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-locked"></span><span>locked</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-more"></span><span>more</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-flag"></span><span>flag</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-home-filled"></span><span>home-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-gear-filled"></span><span>gear-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-info-filled"></span><span>info-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-help-filled"></span><span>help-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-more-filled"></span><span>more-filled</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-settings"></span><span>settings</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-list"></span><span>list</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-bars"></span><span>bars</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-loop"></span><span>loop</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-paperclip"></span><span>paperclip</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-eye"></span><span>eye</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-arrowup"></span><span>arrowup</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-arrowdown"></span><span>arrowdown</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-arrowleft"></span><span>arrowleft</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-arrowright"></span><span>arrowright</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-arrowthinup"></span><span>arrowthinup</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-arrowthindown"></span><span>arrowthindown</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-arrowthinleft"></span><span>arrowthinleft</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-arrowthinright"></span><span>arrowthinright</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-pulldown"></span><span>pulldown</span></li>
|
||||
<li class="icon-item"><span class="uni-icon uni-icon-scan"></span><span>scan</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
421
mallplusui-uniapp-app/components/uni-icon/uni-icon.vue
Normal file
421
mallplusui-uniapp-app/components/uni-icon/uni-icon.vue
Normal file
File diff suppressed because one or more lines are too long
194
mallplusui-uniapp-app/components/uni-load-more/uni-load-more.vue
Normal file
194
mallplusui-uniapp-app/components/uni-load-more/uni-load-more.vue
Normal file
@@ -0,0 +1,194 @@
|
||||
<template>
|
||||
<view class="uni-load-more">
|
||||
<view class="uni-load-more__img" v-show="status === 'loading' && showIcon">
|
||||
<view class="load1">
|
||||
<view :style="{background:color}"></view>
|
||||
<view :style="{background:color}"></view>
|
||||
<view :style="{background:color}"></view>
|
||||
<view :style="{background:color}"></view>
|
||||
</view>
|
||||
<view class="load2">
|
||||
<view :style="{background:color}"></view>
|
||||
<view :style="{background:color}"></view>
|
||||
<view :style="{background:color}"></view>
|
||||
<view :style="{background:color}"></view>
|
||||
</view>
|
||||
<view class="load3">
|
||||
<view :style="{background:color}"></view>
|
||||
<view :style="{background:color}"></view>
|
||||
<view :style="{background:color}"></view>
|
||||
<view :style="{background:color}"></view>
|
||||
</view>
|
||||
</view>
|
||||
<text class="uni-load-more__text" :style="{color:color}">{{status === 'more' ? contentText.contentdown : (status === 'loading' ? contentText.contentrefresh : contentText.contentnomore)}}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "uni-load-more",
|
||||
props: {
|
||||
status: {
|
||||
//上拉的状态:more-loading前;loading-loading中;noMore-没有更多了
|
||||
type: String,
|
||||
default: 'more'
|
||||
},
|
||||
showIcon: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: "#777777"
|
||||
},
|
||||
contentText: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {
|
||||
contentdown: "上拉显示更多",
|
||||
contentrefresh: "正在加载...",
|
||||
contentnomore: "没有更多数据了"
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@charset "UTF-8";
|
||||
|
||||
.uni-load-more {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 80upx;
|
||||
align-items: center;
|
||||
justify-content: center
|
||||
}
|
||||
|
||||
.uni-load-more__text {
|
||||
font-size: 28upx;
|
||||
color: #999
|
||||
}
|
||||
|
||||
.uni-load-more__img {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-right: 10px
|
||||
}
|
||||
|
||||
.uni-load-more__img>view {
|
||||
position: absolute
|
||||
}
|
||||
|
||||
.uni-load-more__img>view view {
|
||||
width: 6px;
|
||||
height: 2px;
|
||||
border-top-left-radius: 1px;
|
||||
border-bottom-left-radius: 1px;
|
||||
background: #999;
|
||||
position: absolute;
|
||||
opacity: .2;
|
||||
transform-origin: 50%;
|
||||
animation: load 1.56s ease infinite
|
||||
}
|
||||
|
||||
.uni-load-more__img>view view:nth-child(1) {
|
||||
transform: rotate(90deg);
|
||||
top: 2px;
|
||||
left: 9px
|
||||
}
|
||||
|
||||
.uni-load-more__img>view view:nth-child(2) {
|
||||
transform: rotate(180deg);
|
||||
top: 11px;
|
||||
right: 0
|
||||
}
|
||||
|
||||
.uni-load-more__img>view view:nth-child(3) {
|
||||
transform: rotate(270deg);
|
||||
bottom: 2px;
|
||||
left: 9px
|
||||
}
|
||||
|
||||
.uni-load-more__img>view view:nth-child(4) {
|
||||
top: 11px;
|
||||
left: 0
|
||||
}
|
||||
|
||||
.load1,
|
||||
.load2,
|
||||
.load3 {
|
||||
height: 24px;
|
||||
width: 24px
|
||||
}
|
||||
|
||||
.load2 {
|
||||
transform: rotate(30deg)
|
||||
}
|
||||
|
||||
.load3 {
|
||||
transform: rotate(60deg)
|
||||
}
|
||||
|
||||
.load1 view:nth-child(1) {
|
||||
animation-delay: 0s
|
||||
}
|
||||
|
||||
.load2 view:nth-child(1) {
|
||||
animation-delay: .13s
|
||||
}
|
||||
|
||||
.load3 view:nth-child(1) {
|
||||
animation-delay: .26s
|
||||
}
|
||||
|
||||
.load1 view:nth-child(2) {
|
||||
animation-delay: .39s
|
||||
}
|
||||
|
||||
.load2 view:nth-child(2) {
|
||||
animation-delay: .52s
|
||||
}
|
||||
|
||||
.load3 view:nth-child(2) {
|
||||
animation-delay: .65s
|
||||
}
|
||||
|
||||
.load1 view:nth-child(3) {
|
||||
animation-delay: .78s
|
||||
}
|
||||
|
||||
.load2 view:nth-child(3) {
|
||||
animation-delay: .91s
|
||||
}
|
||||
|
||||
.load3 view:nth-child(3) {
|
||||
animation-delay: 1.04s
|
||||
}
|
||||
|
||||
.load1 view:nth-child(4) {
|
||||
animation-delay: 1.17s
|
||||
}
|
||||
|
||||
.load2 view:nth-child(4) {
|
||||
animation-delay: 1.3s
|
||||
}
|
||||
|
||||
.load3 view:nth-child(4) {
|
||||
animation-delay: 1.43s
|
||||
}
|
||||
|
||||
@-webkit-keyframes load {
|
||||
0% {
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: .2
|
||||
}
|
||||
}
|
||||
</style>
|
||||
199
mallplusui-uniapp-app/components/uni-number-box.vue
Normal file
199
mallplusui-uniapp-app/components/uni-number-box.vue
Normal file
@@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<view class="uni-numbox">
|
||||
<view class="uni-numbox-minus"
|
||||
@click="_calcValue('subtract')"
|
||||
>
|
||||
<text class="yticon icon--jianhao" :class="minDisabled?'uni-numbox-disabled': ''" ></text>
|
||||
</view>
|
||||
<input
|
||||
class="uni-numbox-value"
|
||||
type="number"
|
||||
:disabled="disabled"
|
||||
:value="inputValue"
|
||||
|
||||
@blur="_onBlur"
|
||||
>
|
||||
<view
|
||||
class="uni-numbox-plus"
|
||||
@click="_calcValue('add')"
|
||||
>
|
||||
<text class="yticon icon-jia2" :class="maxDisabled?'uni-numbox-disabled': ''" ></text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'uni-number-box',
|
||||
props: {
|
||||
isMax: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isMin: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
default: -Infinity
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: Infinity
|
||||
},
|
||||
step: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inputValue: this.value,
|
||||
minDisabled: false,
|
||||
maxDisabled: false
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.maxDisabled = this.isMax;
|
||||
this.minDisabled = this.isMin;
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
inputValue(number) {
|
||||
const data = {
|
||||
number: number,
|
||||
index: this.index
|
||||
}
|
||||
this.$emit('eventChange', data);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
_calcValue(type) {
|
||||
const scale = this._getDecimalScale();
|
||||
let value = this.inputValue * scale;
|
||||
let newValue = 0;
|
||||
let step = this.step * scale;
|
||||
|
||||
if(type === 'subtract'){
|
||||
newValue = value - step;
|
||||
if (newValue <= this.min){
|
||||
this.minDisabled = true;
|
||||
}
|
||||
if(newValue < this.min){
|
||||
newValue = this.min
|
||||
}
|
||||
if(newValue < this.max && this.maxDisabled === true){
|
||||
this.maxDisabled = false;
|
||||
}
|
||||
}else if(type === 'add'){
|
||||
newValue = value + step;
|
||||
if (newValue >= this.max){
|
||||
this.maxDisabled = true;
|
||||
}
|
||||
if(newValue > this.max){
|
||||
newValue = this.max
|
||||
}
|
||||
if(newValue > this.min && this.minDisabled === true){
|
||||
this.minDisabled = false;
|
||||
}
|
||||
}
|
||||
if(newValue === value){
|
||||
return;
|
||||
}
|
||||
this.inputValue = newValue / scale;
|
||||
},
|
||||
_getDecimalScale() {
|
||||
let scale = 1;
|
||||
// 浮点型
|
||||
if (~~this.step !== this.step) {
|
||||
scale = Math.pow(10, (this.step + '').split('.')[1].length);
|
||||
}
|
||||
return scale;
|
||||
},
|
||||
_onBlur(event) {
|
||||
let value = event.detail.value;
|
||||
if (!value) {
|
||||
this.inputValue = 0;
|
||||
return
|
||||
}
|
||||
value = +value;
|
||||
if (value > this.max) {
|
||||
value = this.max;
|
||||
} else if (value < this.min) {
|
||||
value = this.min
|
||||
}
|
||||
|
||||
this.inputValue = value
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.uni-numbox {
|
||||
position:absolute;
|
||||
left: 30upx;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
width:230upx;
|
||||
height: 70upx;
|
||||
background:#f5f5f5;
|
||||
}
|
||||
|
||||
.uni-numbox-minus,
|
||||
.uni-numbox-plus {
|
||||
margin: 0;
|
||||
background-color: #f5f5f5;
|
||||
width: 70upx;
|
||||
height: 100%;
|
||||
line-height: 70upx;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
.uni-numbox-minus .yticon,
|
||||
.uni-numbox-plus .yticon{
|
||||
font-size: 36upx;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.uni-numbox-minus {
|
||||
border-right: none;
|
||||
border-top-left-radius: 6upx;
|
||||
border-bottom-left-radius: 6upx;
|
||||
}
|
||||
|
||||
.uni-numbox-plus {
|
||||
border-left: none;
|
||||
border-top-right-radius: 6upx;
|
||||
border-bottom-right-radius: 6upx;
|
||||
}
|
||||
|
||||
.uni-numbox-value {
|
||||
position: relative;
|
||||
background-color: #f5f5f5;
|
||||
width: 90upx;
|
||||
height: 50upx;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
font-size: 30upx;
|
||||
}
|
||||
|
||||
.uni-numbox-disabled.yticon {
|
||||
color: #d6d6d6;
|
||||
}
|
||||
</style>
|
||||
59
mallplusui-uniapp-app/components/uni-rate/readme.md
Normal file
59
mallplusui-uniapp-app/components/uni-rate/readme.md
Normal file
@@ -0,0 +1,59 @@
|
||||
### Rate 评分
|
||||
|
||||
评分组件,组件名:``uni-rate``,代码块: uRate。
|
||||
|
||||
**使用方式:**
|
||||
|
||||
在 ``script`` 中引用组件
|
||||
|
||||
```javascript
|
||||
import uniRate from "@/components/uni-rate/uni-rate.vue"
|
||||
export default {
|
||||
components: {uniRate}
|
||||
}
|
||||
```
|
||||
|
||||
基本用法
|
||||
|
||||
```html
|
||||
<uni-rate value="2"></uni-rate>
|
||||
```
|
||||
|
||||
自定义星星大小
|
||||
|
||||
```html
|
||||
<uni-rate size="18" value="5"></uni-rate>
|
||||
```
|
||||
|
||||
设置评分数
|
||||
|
||||
```html
|
||||
<uni-rate max="10" value="5"></uni-rate>
|
||||
```
|
||||
|
||||
不可点击状态
|
||||
|
||||
```html
|
||||
<uni-rate disabled="true" value="3.5"></uni-rate>
|
||||
```
|
||||
|
||||
实际效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)
|
||||
|
||||
**属性说明:**
|
||||
|
||||
|属性名|类型|默认值 |说明|
|
||||
|---|----|---|---|
|
||||
|value|Number|0|当前评分|
|
||||
|max|Number|5|最大的评分|
|
||||
|size|Number|24|星星的大小|
|
||||
|margin|Number|0|星星的间距|
|
||||
|color|String|#ececec|星星的颜色|
|
||||
|active-color|String|#ffca3e|选中状态的星星的颜色|
|
||||
|is-fill|Boolean|true|星星的类型,是否为实心类型|
|
||||
|disabled|Boolean|false|是否为不可点击状态|
|
||||
|
||||
**事件说明:**
|
||||
|
||||
|事件称名|说明|返回参数|
|
||||
|---|----|---|
|
||||
|change|Rate 的 value 改变时触发事件,返回参数为Rate的value|{value:Number}|
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user