331 changed files with 95753 additions and 0 deletions
@ -0,0 +1,15 @@ |
|||
# Maven # |
|||
target/ |
|||
|
|||
# IDEA # |
|||
.idea/ |
|||
*.iml |
|||
*.zip |
|||
# Eclipse # |
|||
.settings/ |
|||
.classpath |
|||
.project |
|||
|
|||
/vue |
|||
/unpackage |
|||
*/vue |
|||
@ -0,0 +1,16 @@ |
|||
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ |
|||
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 |
|||
"version": "0.0", |
|||
"configurations": [{ |
|||
"app-plus" : |
|||
{ |
|||
"launchtype" : "local" |
|||
}, |
|||
"default" : |
|||
{ |
|||
"launchtype" : "local" |
|||
}, |
|||
"type" : "uniCloud" |
|||
} |
|||
] |
|||
} |
|||
@ -0,0 +1,505 @@ |
|||
<script> |
|||
import Api from '@/common/api'; |
|||
// #ifdef APP-PLUS |
|||
import APPUpdate from "plugins/APPUpdate/index.js"; |
|||
// #endif |
|||
/** |
|||
* vuex管理登陆状态,具体可以参考官方登陆模板示例 |
|||
*/ |
|||
import { |
|||
mapMutations |
|||
} from 'vuex'; |
|||
export default { |
|||
methods: { |
|||
...mapMutations(['login']) , |
|||
// util.js |
|||
// 微信公众号授权 |
|||
wxAuthorize() { |
|||
let link = window.location.href; |
|||
let params = this._getUrlParams(link); // 地址解析 |
|||
|
|||
// 已经授权登录过的就不用再授权了 |
|||
if (store.state.token) return; |
|||
|
|||
// 如果拿到code,调用授权接口,没有拿到就跳转微信授权链接获取 |
|||
if (params.code) { |
|||
api.wxAuth(params.code); // 调用后台接口,授权 |
|||
} else { |
|||
let appid = 'wx8321531c6046c924'; |
|||
let uri = encodeURIComponent(link); |
|||
let authURL = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${uri}&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect`; |
|||
window.location.href = authURL; |
|||
} |
|||
}, |
|||
async typeGoodsList() { |
|||
let params = {}; |
|||
let list = await Api.apiCall('get', Api.goods.typeGoodsList, params); |
|||
this.$db.set('categoryList', list) |
|||
}, |
|||
async areaGoodsList() { |
|||
let params = {}; |
|||
let list = await Api.apiCall('get', Api.goods.areaGoodsList, params); |
|||
this.$db.set('areaGoodsList', list) |
|||
}, |
|||
async sysInfoMethod() { |
|||
let params = {}; |
|||
let list = await Api.apiCall('get', Api.index.sysInfo, params); |
|||
this.$db.set('sysInfo', list) |
|||
}, |
|||
|
|||
}, |
|||
onLaunch: function() { |
|||
let userInfo = uni.getStorageSync('userInfo') || ''; |
|||
let token = uni.getStorageSync('token') || ''; |
|||
if(token){ |
|||
//更新登陆状态 |
|||
uni.getStorage({ |
|||
key: 'userInfo', |
|||
success: (res) => { |
|||
this.login(res.data); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
let isWeiXin = this.$common.isWeiXinBrowser() |
|||
if (isWeiXin) { |
|||
this.wxAuthorize() |
|||
} |
|||
this.typeGoodsList(); |
|||
this.areaGoodsList(); |
|||
this.sysInfoMethod(); |
|||
// #ifdef APP-PLUS |
|||
APPUpdate(); |
|||
// uni.showToast({ |
|||
// title: "正式版本新版本哦2", |
|||
// icon: "none" |
|||
// }); |
|||
// #endif |
|||
}, |
|||
onShow: function() { |
|||
console.log('App Show') |
|||
}, |
|||
onHide: function() { |
|||
console.log('App Hide') |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang='scss'> |
|||
/* |
|||
全局公共样式和字体图标 |
|||
*/ |
|||
@font-face { |
|||
font-family: yticon; |
|||
font-weight: normal; |
|||
font-style: normal; |
|||
src: url('https://at.alicdn.com/t/font_1078604_w4kpxh0rafi.ttf') format('truetype'); |
|||
} |
|||
|
|||
.yticon { |
|||
font-family: "yticon" !important; |
|||
font-size: 16px; |
|||
font-style: normal; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} |
|||
|
|||
.icon-yiguoqi1:before { |
|||
content: "\e700"; |
|||
} |
|||
|
|||
.icon-iconfontshanchu1:before { |
|||
content: "\e619"; |
|||
} |
|||
|
|||
.icon-iconfontweixin:before { |
|||
content: "\e611"; |
|||
} |
|||
|
|||
.icon-alipay:before { |
|||
content: "\e636"; |
|||
} |
|||
|
|||
.icon-shang:before { |
|||
content: "\e624"; |
|||
} |
|||
|
|||
.icon-shouye:before { |
|||
content: "\e626"; |
|||
} |
|||
|
|||
.icon-shanchu4:before { |
|||
content: "\e622"; |
|||
} |
|||
|
|||
.icon-xiaoxi:before { |
|||
content: "\e618"; |
|||
} |
|||
|
|||
.icon-jiantour-copy:before { |
|||
content: "\e600"; |
|||
} |
|||
|
|||
.icon-fenxiang2:before { |
|||
content: "\e61e"; |
|||
} |
|||
|
|||
.icon-pingjia:before { |
|||
content: "\e67b"; |
|||
} |
|||
|
|||
.icon-daifukuan:before { |
|||
content: "\e68f"; |
|||
} |
|||
|
|||
.icon-pinglun-copy:before { |
|||
content: "\e612"; |
|||
} |
|||
|
|||
.icon-dianhua-copy:before { |
|||
content: "\e621"; |
|||
} |
|||
|
|||
.icon-shoucang:before { |
|||
content: "\e645"; |
|||
} |
|||
|
|||
.icon-xuanzhong2:before { |
|||
content: "\e62f"; |
|||
} |
|||
|
|||
.icon-gouwuche_:before { |
|||
content: "\e630"; |
|||
} |
|||
|
|||
.icon-icon-test:before { |
|||
content: "\e60c"; |
|||
} |
|||
|
|||
.icon-icon-test1:before { |
|||
content: "\e632"; |
|||
} |
|||
|
|||
.icon-bianji:before { |
|||
content: "\e646"; |
|||
} |
|||
|
|||
.icon-jiazailoading-A:before { |
|||
content: "\e8fc"; |
|||
} |
|||
|
|||
.icon-zuoshang:before { |
|||
content: "\e613"; |
|||
} |
|||
|
|||
.icon-jia2:before { |
|||
content: "\e60a"; |
|||
} |
|||
|
|||
.icon-huifu:before { |
|||
content: "\e68b"; |
|||
} |
|||
|
|||
.icon-sousuo:before { |
|||
content: "\e7ce"; |
|||
} |
|||
|
|||
.icon-arrow-fine-up:before { |
|||
content: "\e601"; |
|||
} |
|||
|
|||
.icon-hot:before { |
|||
content: "\e60e"; |
|||
} |
|||
|
|||
.icon-lishijilu:before { |
|||
content: "\e6b9"; |
|||
} |
|||
|
|||
.icon-zhengxinchaxun-zhifubaoceping-:before { |
|||
content: "\e616"; |
|||
} |
|||
|
|||
.icon-naozhong:before { |
|||
content: "\e64a"; |
|||
} |
|||
|
|||
.icon-xiatubiao--copy:before { |
|||
content: "\e608"; |
|||
} |
|||
|
|||
.icon-shoucang_xuanzhongzhuangtai:before { |
|||
content: "\e6a9"; |
|||
} |
|||
|
|||
.icon-jia1:before { |
|||
content: "\e61c"; |
|||
} |
|||
|
|||
.icon-bangzhu1:before { |
|||
content: "\e63d"; |
|||
} |
|||
|
|||
.icon-arrow-left-bottom:before { |
|||
content: "\e602"; |
|||
} |
|||
|
|||
.icon-arrow-right-bottom:before { |
|||
content: "\e603"; |
|||
} |
|||
|
|||
.icon-arrow-left-top:before { |
|||
content: "\e604"; |
|||
} |
|||
|
|||
.icon-icon--:before { |
|||
content: "\e744"; |
|||
} |
|||
|
|||
.icon-zuojiantou-up:before { |
|||
content: "\e605"; |
|||
} |
|||
|
|||
.icon-xia:before { |
|||
content: "\e62d"; |
|||
} |
|||
|
|||
.icon--jianhao:before { |
|||
content: "\e60b"; |
|||
} |
|||
|
|||
.icon-weixinzhifu:before { |
|||
content: "\e61a"; |
|||
} |
|||
|
|||
.icon-comment:before { |
|||
content: "\e64f"; |
|||
} |
|||
|
|||
.icon-weixin:before { |
|||
content: "\e61f"; |
|||
} |
|||
|
|||
.icon-fenlei1:before { |
|||
content: "\e620"; |
|||
} |
|||
|
|||
.icon-erjiye-yucunkuan:before { |
|||
content: "\e623"; |
|||
} |
|||
|
|||
.icon-Group-:before { |
|||
content: "\e688"; |
|||
} |
|||
|
|||
.icon-you:before { |
|||
content: "\e606"; |
|||
} |
|||
|
|||
.icon-forward:before { |
|||
content: "\e607"; |
|||
} |
|||
|
|||
.icon-tuijian:before { |
|||
content: "\e610"; |
|||
} |
|||
|
|||
.icon-bangzhu:before { |
|||
content: "\e679"; |
|||
} |
|||
|
|||
.icon-share:before { |
|||
content: "\e656"; |
|||
} |
|||
|
|||
.icon-yiguoqi:before { |
|||
content: "\e997"; |
|||
} |
|||
|
|||
.icon-shezhi1:before { |
|||
content: "\e61d"; |
|||
} |
|||
|
|||
.icon-fork:before { |
|||
content: "\e61b"; |
|||
} |
|||
|
|||
.icon-kafei:before { |
|||
content: "\e66a"; |
|||
} |
|||
|
|||
.icon-iLinkapp-:before { |
|||
content: "\e654"; |
|||
} |
|||
|
|||
.icon-saomiao:before { |
|||
content: "\e60d"; |
|||
} |
|||
|
|||
.icon-shezhi:before { |
|||
content: "\e60f"; |
|||
} |
|||
|
|||
.icon-shouhoutuikuan:before { |
|||
content: "\e631"; |
|||
} |
|||
|
|||
.icon-gouwuche:before { |
|||
content: "\e609"; |
|||
} |
|||
|
|||
.icon-dizhi:before { |
|||
content: "\e614"; |
|||
} |
|||
|
|||
.icon-fenlei:before { |
|||
content: "\e706"; |
|||
} |
|||
|
|||
.icon-xingxing:before { |
|||
content: "\e70b"; |
|||
} |
|||
|
|||
.icon-tuandui:before { |
|||
content: "\e633"; |
|||
} |
|||
|
|||
.icon-zuanshi:before { |
|||
content: "\e615"; |
|||
} |
|||
|
|||
.icon-zuo:before { |
|||
content: "\e63c"; |
|||
} |
|||
|
|||
.icon-shoucang2:before { |
|||
content: "\e62e"; |
|||
} |
|||
|
|||
.icon-shouhuodizhi:before { |
|||
content: "\e712"; |
|||
} |
|||
|
|||
.icon-yishouhuo:before { |
|||
content: "\e71a"; |
|||
} |
|||
|
|||
.icon-dianzan-ash:before { |
|||
content: "\e617"; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
view, |
|||
scroll-view, |
|||
swiper, |
|||
swiper-item, |
|||
cover-view, |
|||
cover-image, |
|||
icon, |
|||
text, |
|||
rich-text, |
|||
progress, |
|||
button, |
|||
checkbox, |
|||
form, |
|||
input, |
|||
label, |
|||
radio, |
|||
slider, |
|||
switch, |
|||
textarea, |
|||
navigator, |
|||
audio, |
|||
camera, |
|||
image, |
|||
video { |
|||
box-sizing: border-box; |
|||
} |
|||
/* 骨架屏替代方案 */ |
|||
.Skeleton { |
|||
background: #f3f3f3; |
|||
padding: 20upx 0; |
|||
border-radius: 8upx; |
|||
} |
|||
|
|||
/* 图片载入替代方案 */ |
|||
.image-wrapper { |
|||
font-size: 0; |
|||
background: #f3f3f3; |
|||
border-radius: 4px; |
|||
|
|||
image { |
|||
width: 100%; |
|||
height: 100%; |
|||
transition: .6s; |
|||
opacity: 0; |
|||
|
|||
&.loaded { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.clamp { |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
display: block; |
|||
} |
|||
|
|||
.common-hover { |
|||
background: #f5f5f5; |
|||
} |
|||
|
|||
/*边框*/ |
|||
.b-b:after, |
|||
.b-t:after { |
|||
position: absolute; |
|||
z-index: 3; |
|||
left: 0; |
|||
right: 0; |
|||
height: 0; |
|||
content: ''; |
|||
transform: scaleY(.5); |
|||
border-bottom: 1px solid $border-color-base; |
|||
} |
|||
|
|||
.b-b:after { |
|||
bottom: 0; |
|||
} |
|||
|
|||
.b-t:after { |
|||
top: 0; |
|||
} |
|||
|
|||
/* button样式改写 */ |
|||
uni-button, |
|||
button { |
|||
height: 80upx; |
|||
line-height: 80upx; |
|||
font-size: $font-lg + 2upx; |
|||
font-weight: normal; |
|||
|
|||
&.no-border:before, |
|||
&.no-border:after { |
|||
border: 0; |
|||
} |
|||
} |
|||
|
|||
uni-button[type=default], |
|||
button[type=default] { |
|||
color: $font-color-dark; |
|||
} |
|||
|
|||
/* input 样式 */ |
|||
.input-placeholder { |
|||
color: #999999; |
|||
} |
|||
|
|||
.placeholder { |
|||
color: #999999; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,672 @@ |
|||
/* 用户 */ |
|||
const userInfo = { |
|||
status: 1, |
|||
data: { |
|||
id: 1, |
|||
mobile: 18888888888, |
|||
nickname: 'Leo yo', |
|||
portrait: 'http://img.61ef.cn/news/201409/28/2014092805595807.jpg' |
|||
}, |
|||
msg: '提示' |
|||
} |
|||
/* 首页轮播图 */ |
|||
const carouselList = [{ |
|||
src: "/static/temp/banner3.jpg", |
|||
background: "rgb(203, 87, 60)", |
|||
}, |
|||
{ |
|||
src: "/static/temp/banner2.jpg", |
|||
background: "rgb(205, 215, 218)", |
|||
}, |
|||
{ |
|||
src: "/static/temp/banner4.jpg", |
|||
background: "rgb(183, 73, 69)", |
|||
} |
|||
] |
|||
/* 商品列表 */ |
|||
const goodsList = [{ |
|||
image: "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1553187020783&di=bac9dd78b36fd984502d404d231011c0&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201609%2F26%2F20160926173213_s5adi.jpeg", |
|||
image2: "http://pic.rmb.bdstatic.com/819a044daa66718c2c40a48c1ba971e6.jpeg", |
|||
image3: "http://img001.hc360.cn/y5/M00/1B/45/wKhQUVYFE0uEZ7zVAAAAAMj3H1w418.jpg", |
|||
title: "古黛妃 短袖t恤女夏装2019新款韩版宽松", |
|||
price: 179, |
|||
sales: 61, |
|||
}, |
|||
{ |
|||
image: "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4031878334,2682695508&fm=11&gp=0.jpg", |
|||
image2: "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1554013048&di=a3dc9fd1406dd7bad7fbb97b5489ec04&imgtype=jpg&er=1&src=http%3A%2F%2Fimg009.hc360.cn%2Fhb%2FnKo44ac2656F831c684507E3Da0E3a26841.jpg", |
|||
image3: "http://img.zcool.cn/community/017a4e58b4eab6a801219c77084373.jpg", |
|||
title: "潘歌针织连衣裙", |
|||
price: 78, |
|||
sales: 16, |
|||
}, |
|||
{ |
|||
image: "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1620020012,789258862&fm=26&gp=0.jpg", |
|||
image2: "http://m.360buyimg.com/n12/jfs/t247/42/1078640382/162559/3628a0b/53f5ad09N0dd79894.jpg%21q70.jpg", |
|||
image3: "http://ikids.61kids.com.cn/upload/2018-12-29/1546070626796114.jpg", |
|||
title: "巧谷2019春夏季新品新款女装", |
|||
price: 108.8, |
|||
sales: 5, |
|||
}, { |
|||
image: "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=756705744,3505936868&fm=11&gp=0.jpg", |
|||
image2: "http://images.jaadee.com/images/201702/goods_img/30150_d85aed83521.jpg", |
|||
image3: "http://img13.360buyimg.com/popWaterMark/jfs/t865/120/206320620/138889/dcc94caa/550acedcN613e2a9d.jpg", |
|||
title: "私萱连衣裙", |
|||
price: 265, |
|||
sales: 88, |
|||
}, { |
|||
image: "https://img13.360buyimg.com/n8/jfs/t1/30343/20/1029/481370/5c449438Ecb46a15b/2b2adccb6dc742fd.jpg", |
|||
image2: "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1553418265666&di=d4a7f7eb0ae3c859edeb921641ee1c3a&imgtype=0&src=http%3A%2F%2Fimg003.hc360.cn%2Fy3%2FM02%2FF8%2F9F%2FwKhQh1TuSkGELIlQAAAAAPuLl4M987.jpg", |
|||
image3: "http://img.ef43.com.cn/product/2016/8/05100204b0c.jpg", |
|||
title: "娇诗茹 ulzzang原宿风学生潮韩版春夏短", |
|||
price: 422, |
|||
sales: 137, |
|||
}, { |
|||
image: "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1553187020783&di=bac9dd78b36fd984502d404d231011c0&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201609%2F26%2F20160926173213_s5adi.jpeg", |
|||
image2: "http://image5.suning.cn/uimg/b2c/newcatentries/0070158827-000000000622091973_2_800x800.jpg", |
|||
image3: "http://img.61ef.cn/news/201903/20/2019032009251784.jpg", |
|||
title: "古黛妃 短袖t恤女夏装2019新款韩版宽松", |
|||
price: 179, |
|||
sales: 95, |
|||
}, |
|||
] |
|||
|
|||
/* 购物车 */ |
|||
const cartList = [{ |
|||
id: 1, |
|||
image: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1553005139&di=3368549edf9eee769a9bcb3fbbed2504&imgtype=jpg&er=1&src=http%3A%2F%2Fimg002.hc360.cn%2Fy3%2FM01%2F5F%2FDB%2FwKhQh1T7iceEGRdWAAAAADQvqk8733.jpg', |
|||
attr_val: '春装款 L', |
|||
stock: 15, |
|||
title: 'OVBE 长袖风衣', |
|||
price: 278.00, |
|||
number: 1 |
|||
}, |
|||
{ |
|||
id: 3, |
|||
image: 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2319343996,1107396922&fm=26&gp=0.jpg', |
|||
attr_val: '激光导航 扫拖一体', |
|||
stock: 3, |
|||
title: '科沃斯 Ecovacs 扫地机器人', |
|||
price: 1348.00, |
|||
number: 5 |
|||
}, |
|||
{ |
|||
id: 4, |
|||
image: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2668268226,1765897385&fm=26&gp=0.jpg', |
|||
attr_val: 'XL', |
|||
stock: 55, |
|||
title: '朵绒菲小西装', |
|||
price: 175.88, |
|||
number: 1 |
|||
}, |
|||
{ |
|||
id: 5, |
|||
image: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1552410549432&di=06dd3758053fb6d6362516f30a42d055&imgtype=0&src=http%3A%2F%2Fimgcache.mysodao.com%2Fimg3%2FM0A%2F67%2F42%2FCgAPD1vNSsHNm-TnAAEy61txQb4543_400x400x2.JPG', |
|||
attr_val: '520 #粉红色', |
|||
stock: 15, |
|||
title: '迪奥(Dior)烈艳唇膏', |
|||
price: 1089.00, |
|||
number: 1 |
|||
}, |
|||
{ |
|||
id: 6, |
|||
image: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1031875829,2994442603&fm=26&gp=0.jpg', |
|||
attr_val: '樱花味润手霜 30ml', |
|||
stock: 15, |
|||
title: "欧舒丹(L'OCCITANE)乳木果", |
|||
price: 128, |
|||
number: 1 |
|||
}, |
|||
{ |
|||
id: 7, |
|||
image: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1553007107&di=390915aa8a022cf0b03c03340881b0e7&imgtype=jpg&er=1&src=http%3A%2F%2Fimg13.360buyimg.com%2Fn0%2Fjfs%2Ft646%2F285%2F736444951%2F480473%2Faa701c97%2F548176feN10c9ed7b.jpg', |
|||
attr_val: '特级 12个', |
|||
stock: 7, |
|||
title: '新疆阿克苏苹果 特级', |
|||
price: 58.8, |
|||
number: 10 |
|||
}, |
|||
{ |
|||
id: 8, |
|||
image: 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2319343996,1107396922&fm=26&gp=0.jpg', |
|||
attr_val: '激光导航 扫拖一体', |
|||
stock: 15, |
|||
title: '科沃斯 Ecovacs 扫地机器人', |
|||
price: 1348.00, |
|||
number: 1 |
|||
}, |
|||
{ |
|||
id: 9, |
|||
image: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2668268226,1765897385&fm=26&gp=0.jpg', |
|||
attr_val: 'XL', |
|||
stock: 55, |
|||
title: '朵绒菲小西装', |
|||
price: 175.88, |
|||
number: 1 |
|||
}, |
|||
{ |
|||
id: 10, |
|||
image: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1552410549432&di=06dd3758053fb6d6362516f30a42d055&imgtype=0&src=http%3A%2F%2Fimgcache.mysodao.com%2Fimg3%2FM0A%2F67%2F42%2FCgAPD1vNSsHNm-TnAAEy61txQb4543_400x400x2.JPG', |
|||
attr_val: '520 #粉红色', |
|||
stock: 15, |
|||
title: '迪奥(Dior)烈艳唇膏', |
|||
price: 1089.00, |
|||
number: 1 |
|||
}, |
|||
{ |
|||
id: 11, |
|||
image: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1031875829,2994442603&fm=26&gp=0.jpg', |
|||
attr_val: '樱花味润手霜 30ml', |
|||
stock: 15, |
|||
title: "欧舒丹(L'OCCITANE)乳木果", |
|||
price: 128, |
|||
number: 1 |
|||
}, |
|||
{ |
|||
id: 12, |
|||
image: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1553007107&di=390915aa8a022cf0b03c03340881b0e7&imgtype=jpg&er=1&src=http%3A%2F%2Fimg13.360buyimg.com%2Fn0%2Fjfs%2Ft646%2F285%2F736444951%2F480473%2Faa701c97%2F548176feN10c9ed7b.jpg', |
|||
attr_val: '特级 12个', |
|||
stock: 7, |
|||
title: '新疆阿克苏苹果 特级', |
|||
price: 58.8, |
|||
number: 10 |
|||
}, |
|||
{ |
|||
id: 13, |
|||
image: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1552405266625&di=a703f2b2cdb0fe7f3f05f62dd91307ab&imgtype=0&src=http%3A%2F%2Fwww.78.cn%2Fzixun%2Fnews%2Fupload%2F20190214%2F1550114706486250.jpg', |
|||
attr_val: '春装款/m', |
|||
stock: 15, |
|||
title: '女装2019春秋新款', |
|||
price: 420.00, |
|||
number: 1 |
|||
} |
|||
]; |
|||
//详情展示页面
|
|||
const detailData = { |
|||
title: '纯种金毛幼犬活体有血统证书', |
|||
title2: '拆家小能手 你值得拥有', |
|||
favorite: true, |
|||
imgList: [{ |
|||
src: 'http://img0.imgtn.bdimg.com/it/u=2396068252,4277062836&fm=26&gp=0.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://img.pconline.com.cn/images/upload/upc/tx/itbbs/1309/06/c4/25310541_1378426131583.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1610/26/c4/28926240_1477451226577_mthumb.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://picture.ik123.com/uploads/allimg/190219/12-1Z219105139.jpg' |
|||
}, |
|||
], |
|||
episodeList: [ |
|||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 |
|||
], |
|||
guessList: [{ |
|||
src: 'http://img.52z.com/upload/news/image/20180530/20180530081619_31029.jpg', |
|||
title: '猫眼指甲油', |
|||
title2: '独树一帜的免照灯猫眼指甲' |
|||
}, |
|||
{ |
|||
src: 'http://m.china-7.net/uploads/14778449362891.jpg', |
|||
title: '创意屋', |
|||
title2: '创意屋形上下双层高低床' |
|||
}, |
|||
{ |
|||
src: 'http://www.k73.com/up/allimg/130415/22-130415093527.jpg', |
|||
title: 'MissCandy 指甲油', |
|||
title2: '十分适合喜欢素净的妹纸,尽显淡雅的气质' |
|||
}, |
|||
{ |
|||
src: 'http://img0.imgtn.bdimg.com/it/u=2108933440,2194129200&fm=214&gp=0.jpg ', |
|||
title: 'RMK 2017星空海蓝唇釉', |
|||
title2: '唇釉质地,上唇后很滋润。少女也会心动的蓝色,透明液体形状。' |
|||
} |
|||
], |
|||
evaList: [{ |
|||
src: 'http://gss0.baidu.com/-fo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/77c6a7efce1b9d1663174705fbdeb48f8d546486.jpg', |
|||
nickname: 'Ranth Allngal', |
|||
time: '09-20 12:54', |
|||
zan: '54', |
|||
content: '评论不要太苛刻,不管什么产品都会有瑕疵,客服也说了可以退货并且商家承担运费,我觉得至少态度就可以给五星。' |
|||
}, |
|||
{ |
|||
src: 'http://img0.imgtn.bdimg.com/it/u=2396068252,4277062836&fm=26&gp=0.jpg', |
|||
nickname: 'Ranth Allngal', |
|||
time: '09-20 12:54', |
|||
zan: '54', |
|||
content: '楼上说的好有道理。' |
|||
} |
|||
] |
|||
} |
|||
const shareList = [{ |
|||
type: 1, |
|||
icon: '/static/temp/share_wechat.png', |
|||
text: '微信好友', |
|||
provider: 'weixin', |
|||
scene: 'WXSceneSession', |
|||
typeIcon: 0 |
|||
}, |
|||
{ |
|||
type: 2, |
|||
icon: '/static/temp/share_moment.png', |
|||
text: '朋友圈', |
|||
provider: 'weixin', |
|||
scene: 'WXSenceTimeline', |
|||
typeIcon: 0 |
|||
}, |
|||
{ |
|||
type: 3, |
|||
icon: '/static/temp/share_qq.png', |
|||
text: 'QQ好友', |
|||
provider: 'qq', |
|||
scene: 'WXSceneSession', |
|||
typeIcon: 1 |
|||
}, |
|||
{ |
|||
type: 4, |
|||
icon: '/static/temp/share_qqzone.png', |
|||
text: 'QQ空间', |
|||
provider: 'qq', |
|||
scene: 'WXSenceTimeline', |
|||
typeIcon: 1 |
|||
} |
|||
] |
|||
const lazyLoadList = [{ |
|||
src: 'http://img0.imgtn.bdimg.com/it/u=2396068252,4277062836&fm=26&gp=0.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://img.pconline.com.cn/images/upload/upc/tx/itbbs/1309/06/c4/25310541_1378426131583.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1610/26/c4/28926240_1477451226577_mthumb.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://picture.ik123.com/uploads/allimg/190219/12-1Z219105139.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://img5.imgtn.bdimg.com/it/u=2904900134,438461613&fm=26&gp=0.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://img1.imgtn.bdimg.com/it/u=1690475408,2565370337&fm=26&gp=0.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://img.99114.com/group1/M00/7F/99/wKgGS1kVrPGAe5LmAAU2KrJmb3Q923_600_600.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://img4.imgtn.bdimg.com/it/u=261047209,372231813&fm=26&gp=0.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://i2.17173cdn.com/i7mz64/YWxqaGBf/tu17173com/20150107/eMyVMObjlbcvDEv.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://img008.hc360.cn/m4/M02/E7/87/wKhQ6FSrfU6EfUoyAAAAAITAfyc280.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://pic1.win4000.com/wallpaper/d/5991569950166.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://gss0.baidu.com/9fo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/6f061d950a7b0208f9fe945e60d9f2d3572cc85e.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://pic41.nipic.com/20140429/18169759_125841756000_2.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://www.k73.com/up/allimg/130415/22-130415093527.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://img.52z.com/upload/news/image/20180530/20180530081619_31029.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://b-ssl.duitang.com/uploads/item/201410/02/20141002111638_tXAzU.jpeg' |
|||
}, |
|||
{ |
|||
src: 'http://img2.ph.126.net/C4JW6f57QWSB21-8jh2UGQ==/1762596304262286698.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://att.bbs.duowan.com/forum/201405/17/190257nzcvkkdg6w2e8226.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://attach.bbs.miui.com/forum/201504/10/223644v3intigyvva0vgym.jpg' |
|||
}, |
|||
{ |
|||
src: 'http://pic1.win4000.com/mobile/3/57888a298d61d.jpg' |
|||
}, |
|||
] |
|||
|
|||
const orderList = [{ |
|||
time: '2019-04-06 11:37', |
|||
state: 1, |
|||
goodsList: [{ |
|||
image: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1553187020783&di=bac9dd78b36fd984502d404d231011c0&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201609%2F26%2F20160926173213_s5adi.jpeg', |
|||
}, |
|||
{ |
|||
image: 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4031878334,2682695508&fm=11&gp=0.jpg', |
|||
}, |
|||
{ |
|||
image: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1620020012,789258862&fm=26&gp=0.jpg', |
|||
}, |
|||
{ |
|||
image: 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4031878334,2682695508&fm=11&gp=0.jpg', |
|||
}, |
|||
{ |
|||
image: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1620020012,789258862&fm=26&gp=0.jpg', |
|||
}, |
|||
{ |
|||
image: 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4031878334,2682695508&fm=11&gp=0.jpg', |
|||
}, |
|||
{ |
|||
image: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1620020012,789258862&fm=26&gp=0.jpg', |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
time: '2019-04-06 11:37', |
|||
state: 9, |
|||
goodsList: [{ |
|||
title: '古黛妃 短袖t恤女 春夏装2019新款韩版宽松', |
|||
price: 179.5, |
|||
image: 'https://img13.360buyimg.com/n8/jfs/t1/30343/20/1029/481370/5c449438Ecb46a15b/2b2adccb6dc742fd.jpg', |
|||
number: 1, |
|||
attr: '珊瑚粉 M' |
|||
}] |
|||
}, |
|||
{ |
|||
time: '2019-04-06 11:37', |
|||
state: 1, |
|||
goodsList: [{ |
|||
image: 'https://img.alicdn.com/imgextra/https://img.alicdn.com/imgextra/i2/2120460599/O1CN01LBPS4C1GINkwsOTXS_!!2120460599.jpg_430x430q90.jpg', |
|||
}, |
|||
{ |
|||
image: 'https://img.alicdn.com/imgextra/i2/1069876356/TB2ocTQG4WYBuNjy1zkXXXGGpXa_!!1069876356.jpg_430x430q90.jpg', |
|||
}, |
|||
{ |
|||
image: 'https://img.alicdn.com/imgextra/https://img.alicdn.com/imgextra/i4/2120460599/O1CN01YsmgwZ1GINkv38rkn_!!2120460599.jpg_430x430q90.jpg', |
|||
}, |
|||
] |
|||
}, |
|||
{ |
|||
time: '2019-04-06 11:37', |
|||
state: 1, |
|||
goodsList: [{ |
|||
title: '回力女鞋高帮帆布鞋女学生韩版鞋子女2019潮鞋女鞋新款春季板鞋女', |
|||
price: 69, |
|||
image: 'https://img.alicdn.com/imgextra/i3/2128794607/TB2gzzoc41YBuNjy1zcXXbNcXXa_!!2128794607.jpg_430x430q90.jpg', |
|||
number: 1, |
|||
attr: '白色-高帮 39' |
|||
}] |
|||
}, |
|||
{ |
|||
time: '2019-04-06 11:37', |
|||
state: 1, |
|||
goodsList: [{ |
|||
image: 'https://img.alicdn.com/imgextra/https://img.alicdn.com/imgextra/i4/3358098495/O1CN01dhYyid2Ccl5MWLDok_!!3358098495.jpg_430x430q90.jpg', |
|||
}, |
|||
{ |
|||
image: 'https://img.alicdn.com/imgextra/https://img.alicdn.com/imgextra/i3/3358098495/O1CN01AWsnFA2Ccl5OzvqsL_!!3358098495.jpg_430x430q90.jpg', |
|||
}, |
|||
] |
|||
}, |
|||
{ |
|||
time: '2019-04-06 11:37', |
|||
state: 1, |
|||
goodsList: [{ |
|||
image: 'https://img.alicdn.com/imgextra/i4/3470687433/O1CN0124mMQOSERr18L1h_!!3470687433.jpg_430x430q90.jpg', |
|||
}, |
|||
{ |
|||
image: 'https://img.alicdn.com/imgextra/i3/2888462616/O1CN01ERra5J1VCAbZaKI5n_!!0-item_pic.jpg_430x430q90.jpg', |
|||
}, |
|||
{ |
|||
image: 'https://gd3.alicdn.com/imgextra/i3/819381730/O1CN01YV4mXj1OeNhQIhQlh_!!819381730.jpg_400x400.jpg', |
|||
}, |
|||
] |
|||
} |
|||
|
|||
] |
|||
const cateList = [{ |
|||
id: 1, |
|||
name: '手机数码' |
|||
}, |
|||
{ |
|||
id: 2, |
|||
name: '礼品鲜花' |
|||
}, |
|||
{ |
|||
id: 3, |
|||
name: '男装女装' |
|||
}, |
|||
{ |
|||
id: 4, |
|||
name: '母婴用品' |
|||
}, |
|||
{ |
|||
id: 5, |
|||
pid: 1, |
|||
name: '手机通讯' |
|||
}, |
|||
{ |
|||
id: 6, |
|||
pid: 1, |
|||
name: '运营商' |
|||
}, |
|||
{ |
|||
id: 8, |
|||
pid: 5, |
|||
name: '全面屏手机', |
|||
picture: '/static/temp/cate2.jpg' |
|||
}, |
|||
{ |
|||
id: 9, |
|||
pid: 5, |
|||
name: '游戏手机', |
|||
picture: '/static/temp/cate3.jpg' |
|||
}, |
|||
{ |
|||
id: 10, |
|||
pid: 5, |
|||
name: '老人机', |
|||
picture: '/static/temp/cate1.jpg' |
|||
}, |
|||
{ |
|||
id: 11, |
|||
pid: 5, |
|||
name: '拍照手机', |
|||
picture: '/static/temp/cate4.jpg' |
|||
}, |
|||
{ |
|||
id: 12, |
|||
pid: 5, |
|||
name: '女性手机', |
|||
picture: '/static/temp/cate5.jpg' |
|||
}, |
|||
{ |
|||
id: 14, |
|||
pid: 6, |
|||
name: '合约机', |
|||
picture: '/static/temp/cate1.jpg' |
|||
}, |
|||
{ |
|||
id: 15, |
|||
pid: 6, |
|||
name: '选好卡', |
|||
picture: '/static/temp/cate4.jpg' |
|||
}, |
|||
{ |
|||
id: 16, |
|||
pid: 6, |
|||
name: '办套餐', |
|||
picture: '/static/temp/cate5.jpg' |
|||
}, |
|||
{ |
|||
id: 17, |
|||
pid: 2, |
|||
name: '礼品', |
|||
}, |
|||
{ |
|||
id: 18, |
|||
pid: 2, |
|||
name: '鲜花', |
|||
}, |
|||
{ |
|||
id: 19, |
|||
pid: 17, |
|||
name: '公益摆件', |
|||
picture: '/static/temp/cate7.jpg' |
|||
}, |
|||
{ |
|||
id: 20, |
|||
pid: 17, |
|||
name: '创意礼品', |
|||
picture: '/static/temp/cate8.jpg' |
|||
}, |
|||
{ |
|||
id: 21, |
|||
pid: 18, |
|||
name: '鲜花', |
|||
picture: '/static/temp/cate9.jpg' |
|||
}, |
|||
{ |
|||
id: 22, |
|||
pid: 18, |
|||
name: '每周一花', |
|||
picture: '/static/temp/cate10.jpg' |
|||
}, |
|||
{ |
|||
id: 23, |
|||
pid: 18, |
|||
name: '卡通花束', |
|||
picture: '/static/temp/cate11.jpg' |
|||
}, |
|||
{ |
|||
id: 24, |
|||
pid: 18, |
|||
name: '永生花', |
|||
picture: '/static/temp/cate12.jpg' |
|||
}, |
|||
{ |
|||
id: 25, |
|||
pid: 3, |
|||
name: '男装' |
|||
}, |
|||
{ |
|||
id: 26, |
|||
pid: 3, |
|||
name: '女装' |
|||
}, |
|||
{ |
|||
id: 27, |
|||
pid: 25, |
|||
name: '男士T恤', |
|||
picture: '/static/temp/cate13.jpg' |
|||
}, |
|||
{ |
|||
id: 28, |
|||
pid: 25, |
|||
name: '男士外套', |
|||
picture: '/static/temp/cate14.jpg' |
|||
}, |
|||
{ |
|||
id: 29, |
|||
pid: 26, |
|||
name: '裙装', |
|||
picture: '/static/temp/cate15.jpg' |
|||
}, |
|||
{ |
|||
id: 30, |
|||
pid: 26, |
|||
name: 'T恤', |
|||
picture: '/static/temp/cate16.jpg' |
|||
}, |
|||
{ |
|||
id: 31, |
|||
pid: 26, |
|||
name: '上装', |
|||
picture: '/static/temp/cate15.jpg' |
|||
}, |
|||
{ |
|||
id: 32, |
|||
pid: 26, |
|||
name: '下装', |
|||
picture: '/static/temp/cate16.jpg' |
|||
}, |
|||
{ |
|||
id: 33, |
|||
pid: 4, |
|||
name: '奶粉', |
|||
}, |
|||
{ |
|||
id: 34, |
|||
pid: 4, |
|||
name: '营养辅食', |
|||
}, |
|||
{ |
|||
id: 35, |
|||
pid: 4, |
|||
name: '童装', |
|||
}, |
|||
{ |
|||
id: 39, |
|||
pid: 4, |
|||
name: '喂养用品', |
|||
}, |
|||
{ |
|||
id: 36, |
|||
pid: 33, |
|||
name: '有机奶粉', |
|||
picture: '/static/temp/cate17.jpg' |
|||
}, |
|||
{ |
|||
id: 37, |
|||
pid: 34, |
|||
name: '果泥/果汁', |
|||
picture: '/static/temp/cate18.jpg' |
|||
}, |
|||
{ |
|||
id: 39, |
|||
pid: 34, |
|||
name: '面条/粥', |
|||
picture: '/static/temp/cate20.jpg' |
|||
}, |
|||
{ |
|||
id: 42, |
|||
pid: 35, |
|||
name: '婴童衣橱', |
|||
picture: '/static/temp/cate19.jpg' |
|||
}, |
|||
{ |
|||
id: 43, |
|||
pid: 39, |
|||
name: '吸奶器', |
|||
picture: '/static/temp/cate21.jpg' |
|||
}, |
|||
{ |
|||
id: 44, |
|||
pid: 39, |
|||
name: '儿童餐具', |
|||
picture: '/static/temp/cate22.jpg' |
|||
}, |
|||
{ |
|||
id: 45, |
|||
pid: 39, |
|||
name: '牙胶安抚', |
|||
picture: '/static/temp/cate23.jpg' |
|||
}, |
|||
{ |
|||
id: 46, |
|||
pid: 39, |
|||
name: '围兜', |
|||
picture: '/static/temp/cate24.jpg' |
|||
}, |
|||
] |
|||
|
|||
export default { |
|||
carouselList, |
|||
cartList, |
|||
detailData, |
|||
lazyLoadList, |
|||
userInfo, |
|||
shareList, |
|||
goodsList, |
|||
orderList, |
|||
cateList |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
# uniapp |
|||
https://blog.csdn.net/weixin_34337265/article/details/86030756 |
|||
https://blog.csdn.net/Neil_1993/article/details/85691295 |
|||
https://blog.csdn.net/qq_15764943/article/details/85837552 |
|||
#### Description |
|||
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} |
|||
|
|||
#### Software Architecture |
|||
Software architecture description |
|||
|
|||
#### Installation |
|||
|
|||
1. xxxx |
|||
2. xxxx |
|||
3. xxxx |
|||
|
|||
#### Instructions |
|||
|
|||
1. xxxx |
|||
2. xxxx |
|||
3. xxxx |
|||
|
|||
#### Contribution |
|||
|
|||
1. Fork the repository |
|||
2. Create Feat_xxx branch |
|||
3. Commit your code |
|||
4. Create Pull Request |
|||
|
|||
|
|||
#### Gitee Feature |
|||
|
|||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md |
|||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com) |
|||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) |
|||
4. The most valuable open source project [GVP](https://gitee.com/gvp) |
|||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) |
|||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) |
|||
@ -0,0 +1,75 @@ |
|||
<<<<<<< HEAD |
|||
# uniapp |
|||
======= |
|||
# orangemall多租户商城后台uni-app前端 |
|||
>>>>>>> d3c4db497ff0a14620ac8c253d9b194cbc87afae |
|||
|
|||
#### 介绍 |
|||
{**以下是码云平台说明,您可以替换此简介** |
|||
码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 |
|||
无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} |
|||
|
|||
#### 软件架构 |
|||
软件架构说明 |
|||
|
|||
|
|||
#### 安装教程 |
|||
<<<<<<< HEAD |
|||
qq 951449465 |
|||
1. 根目录下执行 npm install jweixin-module --save |
|||
|
|||
|
|||
#### 使用说明 |
|||
|
|||
1. xxxx |
|||
2. xxxx |
|||
3. xxxx |
|||
|
|||
#### 参与贡献 |
|||
|
|||
1. Fork 本仓库 |
|||
2. 新建 Feat_xxx 分支 |
|||
3. 提交代码 |
|||
4. 新建 Pull Request |
|||
|
|||
======= |
|||
|
|||
1. xxxx |
|||
2. xxxx |
|||
3. xxxx |
|||
|
|||
#### 使用说明 |
|||
|
|||
1. xxxx |
|||
2. xxxx |
|||
3. xxxx |
|||
|
|||
#### 参与贡献 |
|||
|
|||
1. Fork 本仓库 |
|||
2. 新建 Feat_xxx 分支 |
|||
3. 提交代码 |
|||
4. 新建 Pull Request |
|||
>>>>>>> d3c4db497ff0a14620ac8c253d9b194cbc87afae |
|||
|
|||
|
|||
#### 码云特技 |
|||
|
|||
<<<<<<< HEAD |
|||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md |
|||
2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) |
|||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 |
|||
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 |
|||
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) |
|||
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) |
|||
======= |
|||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md |
|||
2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) |
|||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 |
|||
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 |
|||
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) |
|||
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) |
|||
>>>>>>> d3c4db497ff0a14620ac8c253d9b194cbc87afae |
|||
|
|||
|
|||
现在的分销是 会员注册的时候 填写邀请码,然后我购买分销商品,并且支付成功后,给邀请码的用户反钱 |
|||
@ -0,0 +1,441 @@ |
|||
import store from '../store/index'; |
|||
export default { |
|||
// qq 237524947 wx15d4269d3210863d
|
|||
BASEURI: 'http://mall.yyundong.com/portalapi/api/', |
|||
// BASEURI: 'http://www.yyundong.com:8083/api/',
|
|||
ADMINURI: 'http://mall.yyundong.com/adminapi/', |
|||
ESURI: 'http://www.yyundong.com:8081/', |
|||
h5Appid: 'wxb4660f37187c0b8e', // h5微信登录的appId 暂时测试用
|
|||
source: 1, //1 weixinApplet 2 h5Source 3 pcSource 4 android 5ios
|
|||
es: { |
|||
simpleSearchList: 'esProduct/search/simple', //简单搜索
|
|||
search: 'esProduct/search', //综合搜索、筛选、排序
|
|||
}, |
|||
/** |
|||
* 接口名称 |
|||
*/ |
|||
index: { |
|||
sysInfo: 'single/home/sysInfo', |
|||
submitLocaltion: 'single/home/submitLocaltion', |
|||
getAppletOpenId: 'applet/getAppletOpenId', // 获取openId
|
|||
getWxPhone: 'applet/getWxPhone', // 获取手机号
|
|||
logout: 'single/home/logout', |
|||
appletLogin_by_weixin: 'applet/login_by_weixin1', // 登录(手机号:phone 密码:password)
|
|||
login: 'single/home/login', // 登录(手机号:phone 密码:password)
|
|||
appLogin: 'single/home/appLogin', |
|||
simpleReg: 'single/home/simpleReg', // 登录(手机号:phone 密码:password)
|
|||
home: 'single/home/content', //首页展示
|
|||
home1: 'single/home/content1', //首页展示
|
|||
homeFlashPromotionList: 'single/home/homeFlashPromotionList', // 秒杀列表
|
|||
bannerList: 'single/home/bannerList', // 首页banner
|
|||
updatePassword: 'single/home/updatePassword', // 修改密码
|
|||
loginByCode: 'single/home/loginByCode', // 手机和验证码登录
|
|||
reg: 'single/home/reg', // 注册
|
|||
sendCodes: 'single/home/sms/codes', // 获取验证码
|
|||
acceptCoupon: 'single/sms/add', // 获取优惠券
|
|||
listMemberCoupon: 'single/sms/listMemberCoupon', // 优惠券列表
|
|||
couponList: 'single/home/couponList', // 优惠券
|
|||
selectNotRecive: 'single/home/selectNotRecive', // 可领取的优惠券
|
|||
userInfo: 'single/home/userInfo', // 用户信息
|
|||
userSampleInfo: 'single/home/userSampleInfo', // 用户信息
|
|||
groupActivityDetail: 'single/sms/group.activity.getdetial', // 查询团购详情信息
|
|||
groupActivityList: 'single/sms/groupActivityList', // 查询商品团购列表
|
|||
logs: 'single/home/logs', // 记录日志
|
|||
diyDetail: 'single/sms/diyDetail', |
|||
homeNewProduct: 'single/sms/homeNewProduct/list', //首页新品推荐列表
|
|||
homeBrand: 'single/sms/homeBrand/list', //首页品牌推荐列表
|
|||
homeRecommendProduct: 'single/sms/homeRecommendProduct/list', //首页人气推荐列表
|
|||
homeRecommendSubject: 'single/sms/homeRecommendSubject/list', //首页专题推荐列表
|
|||
nearShopList: 'single/store/dis/shopList', //附近门店
|
|||
nearStoreList: 'single/store/dis/storeList', // 附近商户
|
|||
shoplist: 'single/store/shoplist', //查询门店管理
|
|||
shopDetail: 'single/store/shopDetail', // 门店详情
|
|||
storeClassList: 'single/store/storeClass/list', // 商户内部分类
|
|||
storeCommentList: 'single/store/storeComment/list', // 商户评论
|
|||
noticeList: 'single/home/notice/list', |
|||
noticeDetail: 'single/home/notice/detail', |
|||
}, |
|||
member: { |
|||
applyMember: 'single/user/applyMember', // 会员升级等级
|
|||
memberLevelList: 'single/user/memberLevel/list', // 查询会员等级列表
|
|||
getInviteData: 'single/user/getInviteData', |
|||
inviteUser: 'single/user/inviteUser', |
|||
inviteMoney: 'single/user/inviteMoney', |
|||
currentMember: 'single/user/currentMember', |
|||
updateMember: 'single/user/updateMember', |
|||
resetPassword: 'single/user/resetPassword', |
|||
schoolList: 'single/user/school/list', // 查询学校列表
|
|||
schoolDetail: 'single/user/schoolDetail', // 查询拼团商品详情信息
|
|||
getAreaByPid: 'single/user/getAreaByPid', // 根据pid查询区域
|
|||
bindSchool: 'single/user/bindSchool', // 会员绑定学校
|
|||
bindArea: 'single/user/bindArea', // 会员绑定区域
|
|||
applyStore: 'single/store/applyStore', // 商户入驻
|
|||
storeDetail: 'single/store/detail', // 商户详情
|
|||
storeDetail1: 'single/store/detail1', // 商户详情 带用户
|
|||
store: 'single/store/home', // 商户主页
|
|||
storeList: 'single/store/store/list', // 商户列表
|
|||
memberTagList: 'single/user/memberTag/list', // 商户列表
|
|||
addStoreComment: 'single/store/addStoreComment', // 商户addStoreComment
|
|||
memberBlanceLogList: 'single/user/memberBlanceLog/list', |
|||
}, |
|||
build: { |
|||
getBuildNoticeByPage: 'single/build/getBuildNoticeByPage', // 所有社区和房间
|
|||
getBuildWuyeCompanyByPage: 'single/build/getBuildWuyeCompanyByPage', // 所有社区和房间
|
|||
groupList: 'single/build/groupList', // 所有社区和房间
|
|||
communityList: 'single/build/communityList', // 所有社区和房间
|
|||
nearCommunityList: 'single/build/near/communityList', // 周边社区
|
|||
floorList: 'single/build/floorList', // 所有社区和房间
|
|||
allCommunity: 'single/build/allCommunity', // 所有社区和房间
|
|||
bindCommunity: 'single/build/bindCommunity', // 绑定小区和房间
|
|||
home: 'single/build/home', // 首页内容页信息展示
|
|||
applyCommunity: 'single/build/applyCommunity', // 社区入驻
|
|||
|
|||
|
|||
}, |
|||
goods: { |
|||
tagGoodsList: 'single/pms/tag/goods', // 查询标签商品
|
|||
goodsPromoto: 'single/sms/detail', // 单个商品的优惠详情
|
|||
secskillDetail: 'single/pms/secskill/detail', // 查询秒杀商品详情信息
|
|||
groupGoodsDetail: 'single/pms/goodsGroup/detail', // 查询拼团商品详情信息
|
|||
|
|||
groupHotGoodsList: 'single/pms/groupHotGoods/list', // 查询生效拼团商品列表
|
|||
giftDetail: 'single/pms/gift/detail', // 查询商品详情信息
|
|||
giftList: 'single/pms/gift/list', // 查询商品列表
|
|||
paiMaiDetail: 'single/pms/paimai/detail', // 查询商品详情信息
|
|||
updatePaiMai: 'single/pms/updatePaiMai', // 参与竞价
|
|||
typeGiftList: 'single/pms/typeGiftList', //查询商品类型下的商品列表
|
|||
addView: 'single/pms/addView', // 查询商品详情信息
|
|||
viewList: 'single/pms/viewList', // 查询商品列表
|
|||
|
|||
goodsDetail: 'single/pms/goods/detail', // 查询商品详情信息
|
|||
goodsList: 'single/pms/goods/list', // 查询商品列表
|
|||
productAttrCategoryList: 'single/pms/productAttrCategory/list', // 查询商品属性分类列表
|
|||
categoryList: 'single/pms/productCategory/list', // 查询商品分类列表
|
|||
createGoods: 'single/pms/createGoods', //创建商品
|
|||
brandList: 'single/pms/brand/list', // 根据条件查询所有品牌表列表
|
|||
consultList: 'single/pms/consult/list', // 取某个商品的评价
|
|||
categoryAndGoodsList: 'single/pms/categoryAndGoodsList/list', // 查询商品属性分类列表和商品
|
|||
typeGoodsList: 'single/pms/typeGoodsList', //查询商品类型下的商品列表
|
|||
typeGoodsList1: 'single/pms/typeGoodsList1', //查询商品类型下的商品列表
|
|||
areaGoodsList: 'single/pms/areaGoodsList', //查询商品类型下的商品列表
|
|||
typeList: 'single/pms/typeList', //查询商品类型下的商品列表
|
|||
|
|||
getGoodsTypes: 'single/pms/getGoodsTypes', // 查询分类
|
|||
|
|||
recommendBrand: 'single/pms/recommendBrand/list', // 查询首页推荐品牌
|
|||
newProductList: 'single/pms/newProductList/list', //查询首页新品
|
|||
hotProductList: 'single/pms/hotProductList/list', // 查询热销商品
|
|||
listCollect: 'collection/listCollect', // 显示关注列表
|
|||
deleteCollect: 'collection/delete', // 删除收藏中的某个商品
|
|||
favoriteSave: 'collection/favoriteSave', // 添加/商品收藏
|
|||
listAddress: 'address/list', // 显示所有收货地址
|
|||
deleteAddress: 'address/delete', // 删除
|
|||
addressSave: 'address/save', // 添加
|
|||
setDefaultAddress: 'address/address-set-default', // 设为默认地址
|
|||
getItemDefautl: 'address/getItemDefautl', // 显示默认收货地址
|
|||
|
|||
}, |
|||
order: { |
|||
getRefundReason: 'single/oms/order/getRefundReason', // 查询售后原因
|
|||
saveOmsOrderReturnApply: 'single/oms/saveOmsOrderReturnApply', // 添加售后
|
|||
aftersaleslist: 'single/oms/order/aftersaleslist', // 查询售后列表
|
|||
aftersalesinfo: 'single/oms/aftersalesinfo', // 查询售后详情
|
|||
addGroup: 'single/oms/addGroup', // 发起拼团
|
|||
acceptGroup: 'single/oms/acceptGroup', // 提交拼团
|
|||
sampleOrderList: 'single/oms/sampleOrderList', // 查询订单列表
|
|||
orderList: 'single/oms/order/list', // 查询订单列表
|
|||
orderDetail: 'single/oms/detail', // 查询订单列表
|
|||
preGroupActivityOrder: 'single/oms/preGroupActivityOrder', // 预览订单团购
|
|||
preOrder: 'single/oms/submitPreview', // 预览订单
|
|||
bookOrder: 'single/oms/generateOrder', // 生成订单
|
|||
submitStorePreview: 'single/oms/submitStorePreview', // 预览订单
|
|||
generateStoreOrder: 'single/oms/generateStoreOrder', // 生成订单
|
|||
closeOrder: 'single/oms/closeOrder', // 关闭订单
|
|||
confimDelivery: 'single/oms/confimDelivery', //确认收货
|
|||
applyRefund: 'single/oms/applyRefund', // 申请退款
|
|||
logisticbyapi: 'single/oms/logisticbyapi', // 查看物流
|
|||
orderevaluate: 'single/oms/orderevaluate', //订单评价
|
|||
addCart: 'cart/addCart', // 添加商品到购物车
|
|||
cartList: 'cart/list', // 获取某个会员的购物车列表
|
|||
promotionCartList: 'cart/list/promotion', // 获取某个会员的购物车列表,包括促销信息
|
|||
updateQuantity: 'cart/update/quantity', //修改购物车中某个商品的数量
|
|||
deleteCart: 'cart/delete', // 删除购物车中的某个商品
|
|||
clearCart: 'cart/clear', // 清空购物车
|
|||
|
|||
paymentlist: 'pay/paymentlist', // 查询订单列表
|
|||
|
|||
jifenPay: 'pay/jifenPay', // 积分兑换
|
|||
balancePay: 'pay/balancePay', // 余额支付
|
|||
weixinAppletPay: 'pay/weixinAppletPay', // 微信小程序支付
|
|||
//支付宝
|
|||
aliAppPay: 'aliPay/appPay', // 支付宝app支付
|
|||
aliWapPay: 'aliPay/wapPay', // 支付宝支付
|
|||
wapPayNoSdk: 'aliPay/wapPayNoSdk', // 支付宝支付
|
|||
pcPay: 'aliPay/pcPay', // 支付宝支付
|
|||
aliPay: 'aliPay/tradePay', // 支付宝支付 String authCode, String scene
|
|||
aliPrecreatePay: 'aliPay/tradePrecreatePay', // 支付宝扫码支付
|
|||
aliRefund: 'aliPay/tradePrecreatePay', // 支付宝退款
|
|||
//微信
|
|||
wapPay: 'wxPay/wapPay', //微信H5 支付 注意:必须再web页面中发起支付且域名已添加到开发配置中
|
|||
webPay: 'wxPay/webPay', //公众号支付
|
|||
scanCode1: 'wxPay/scanCode1', //扫码支付模式一 已测试
|
|||
scanCode2: 'wxPay/scanCode2', //扫码支付模式二 已测试
|
|||
appPay: 'wxPay/appPay', //微信APP支付
|
|||
micropay: 'wxPay/micropay', //微信刷卡支付
|
|||
miniAppPay: 'wxPay/miniAppPay', //微信小程序支付
|
|||
refund: 'wxPay/refund', //微信退款 String transactionId,String outTradeNo
|
|||
authCodeToOpenid: 'wxPay/authCodeToOpenid', //openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取
|
|||
|
|||
//银联支付
|
|||
frontConsume: 'unionPay/frontConsume', //PC网关支付 B2C跟B2B查询区别就在于bizType的不同
|
|||
frontConsume2: 'unionPay/frontConsume2', //B2B的网关支付 B2C跟B2B查询区别就在于bizType的不同
|
|||
wapConsume: 'unionPay/wapConsume', //WAP支付 请在手机paymentlist端访问此action
|
|||
appConsume: 'unionPay/appConsume', //APP支付获取tn
|
|||
frontrefund: 'unionPay/refund', //
|
|||
|
|||
//京东
|
|||
jdappPay: 'JDPay/appPay', //App 支付
|
|||
saveOrder: 'JDPay/saveOrder', //String payType PC H5 支付
|
|||
customerPay: 'JDPay/customerPay', //商户二维码支付
|
|||
fkmPay: 'JDPay/fkmPay', //刷卡支付 String token, String amount
|
|||
jdrefund: 'JDPay/refund', //微信APP支付
|
|||
|
|||
|
|||
}, |
|||
cms: { |
|||
subjectList: 'single/cms/subject/list', // 查询文章列表
|
|||
subjectCategoryList: 'single/cms/subjectCategory/list', // 查询文章分类列表
|
|||
subjectCommentList: 'single/cms/subjectComment/list', // 查询文章评论列表
|
|||
recommendSubjectList: 'single/cms/recommendSubjectList/list', //查询首页推荐文章
|
|||
topicList: 'single/cms/topic/list', // 查询专题列表
|
|||
topicDetail: 'single/cms/topic/detail', // 专题详情
|
|||
subjectDetail: 'single/cms/subject/detail', // 文章详情
|
|||
createSubject: 'single/cms/createSubject', // 创建文章
|
|||
}, |
|||
/** |
|||
商户端后台接口 |
|||
**/ |
|||
admin: { |
|||
|
|||
login: 'sys/sysUser/login', // 登录(手机号:phone 密码:password)
|
|||
orderStatic: 'home/orderStatic', // 订单统计
|
|||
goodsStatic: 'home/goodsStatic', // 商品统计
|
|||
userStatic: 'home/userStatic', //会员统计
|
|||
orderDayStatic: 'home/orderDayStatic', //订单日统计
|
|||
dayStatic: 'home/dayStatic', //订单日统计
|
|||
|
|||
bannerList: 'sms/SmsHomeAdvertise/list', // 首页banner
|
|||
memberList: 'ums/UmsMember/list', // 查询学校列表
|
|||
storeDetail: 'sys/SysStore/storeDetail', // 查询拼团商品详情信息
|
|||
schoolList: 'single/user/school/list', // 查询学校列表
|
|||
schoolDetail: 'single/user/schoolDetail', // 查询拼团商品详情信息
|
|||
getAreaByPid: 'single/user/getAreaByPid', // 根据pid查询区域
|
|||
bindSchool: 'single/user/bindSchool', // 会员绑定学校
|
|||
bindArea: 'single/user/bindArea', // 会员绑定区域
|
|||
goodsDetail: 'single/pms/goods/detail', // 查询商品详情信息
|
|||
goodsList: 'pms/PmsProduct/goods/list', // 查询商品列表
|
|||
updatePublishStatus: 'pms/PmsProduct/publishStatus', |
|||
updateReComStatus: 'pms/PmsProduct/updateReComStatus', |
|||
delivery: 'oms/OmsOrder/delivery', // 订单发货
|
|||
orderList: 'oms/OmsOrder/order/list', // 查询订单列表
|
|||
orderDetail: 'single/oms/detail', // 查询订单列表
|
|||
subjectList: 'single/cms/subject/list', // 查询文章列表
|
|||
}, |
|||
/** |
|||
* 封装请求(async await 封装uni.request) 对应portal 项目 |
|||
* method post/get |
|||
* endpoint 接口方法名 |
|||
* data 所需传递参数 |
|||
* load 是否需要loading |
|||
*/ |
|||
async apiCall(method, endpoint, data, load) { |
|||
if (load) { |
|||
uni.showLoading({ |
|||
title: '请稍候', |
|||
mask: true |
|||
}); |
|||
} |
|||
|
|||
let token = uni.getStorageSync('token') || ''; |
|||
let fullurl = this.BASEURI + endpoint; |
|||
console.log("fullurl",fullurl); |
|||
var contentType = 'application/x-www-form-urlencoded'; |
|||
|
|||
data.authorization = token; |
|||
//console.log(endpoint);
|
|||
let [error, res] = await uni.request({ |
|||
url: fullurl, |
|||
data: data, |
|||
method: method, |
|||
header: { |
|||
//'Content-Type': 'application/x-www-form-urlencoded',
|
|||
'content-type': contentType, |
|||
// 'authorization1': Authorization || ''
|
|||
}, |
|||
}); |
|||
if (load) { |
|||
uni.hideLoading(); |
|||
} |
|||
|
|||
if (undefined == res || 'undefined' == res) { |
|||
console.log('index'); |
|||
uni.navigateTo({ |
|||
url: `/pages/public/login` |
|||
}) |
|||
} |
|||
if (res.data.msg == 'User token expired!') { |
|||
console.log('User token expired'); |
|||
uni.showToast({ |
|||
title: '请先登录', |
|||
icon: 'none' |
|||
}); |
|||
uni.navigateTo({ |
|||
url: `/pages/public/login` |
|||
}) |
|||
} |
|||
if (res.data.msg == '请先登录' || res.data.code == 100) { |
|||
console.log("100=" + res.data); |
|||
uni.showToast({ |
|||
title: '请先登录', |
|||
icon: 'none' |
|||
}); |
|||
uni.navigateTo({ |
|||
url: `/pages/public/login` |
|||
}) |
|||
} |
|||
console.log(res.data); |
|||
console.log(fullurl); |
|||
console.log(res.data.data); |
|||
if (res.data.code == 200) { |
|||
console.log("===>>>"); |
|||
return res.data.data; |
|||
} else { |
|||
console.log(">>>>>="); |
|||
if (res.data) { |
|||
if (!res.data.msg) { |
|||
res.data.msg = res.data.data; |
|||
} |
|||
uni.showToast({ |
|||
title: res.data.msg, |
|||
icon: 'none' |
|||
}); |
|||
this.$api.msg(res.data.msg); |
|||
} |
|||
|
|||
} |
|||
}, |
|||
/** |
|||
* 封装请求(async await 封装uni.request) 对应admin 项目 |
|||
* method post/get |
|||
* endpoint 接口方法名 |
|||
* data 所需传递参数 |
|||
* load 是否需要loading |
|||
*/ |
|||
async apiAdminCall(method, endpoint, data, load) { |
|||
if (load) { |
|||
uni.showLoading({ |
|||
title: '请稍候', |
|||
mask: true |
|||
}); |
|||
} |
|||
|
|||
let token = uni.getStorageSync('adminToken') || ''; |
|||
let fullurl = this.ADMINURI + endpoint; |
|||
var contentType = 'application/json'; |
|||
|
|||
data.Authorization = token; |
|||
//console.log(endpoint);
|
|||
let [error, res] = await uni.request({ |
|||
url: fullurl, |
|||
data: data, |
|||
method: method, |
|||
header: { |
|||
//'Content-Type': 'application/x-www-form-urlencoded',
|
|||
'content-type': contentType, |
|||
// 'authorization1': Authorization || ''
|
|||
}, |
|||
}); |
|||
if (load) { |
|||
uni.hideLoading(); |
|||
} |
|||
console.log(res); |
|||
|
|||
if (undefined == res || 'undefined' == res) { |
|||
console.log('index'); |
|||
uni.navigateTo({ |
|||
url: `/pages/index/index` |
|||
}) |
|||
} |
|||
if (res.data.msg == 'User token expired!') { |
|||
console.log('User token expired'); |
|||
uni.showToast({ |
|||
title: '请先登录', |
|||
icon: 'none' |
|||
}); |
|||
uni.navigateTo({ |
|||
url: `/pages/public/login` |
|||
}) |
|||
} |
|||
if (res.data.msg == '请先登录' || res.data.code == 100) { |
|||
console.log("100=" + res.data); |
|||
uni.showToast({ |
|||
title: '请先登录', |
|||
icon: 'none' |
|||
}); |
|||
uni.navigateTo({ |
|||
url: `/pagesC/seller/login` |
|||
}) |
|||
} |
|||
|
|||
if (res.data.code == 200) { |
|||
console.log(res.data.data); |
|||
return res.data.data; |
|||
} else { |
|||
console.log(res.data); |
|||
if (res.data && res.data.msg) { |
|||
|
|||
uni.showToast({ |
|||
title: res.data.msg, |
|||
icon: 'none' |
|||
}); |
|||
this.$api.msg(res.data.msg); |
|||
} |
|||
|
|||
} |
|||
}, |
|||
/** |
|||
* 封装请求(async await 封装uni.request) 对应search 项目 |
|||
* method post/get |
|||
* endpoint 接口方法名 |
|||
* data 所需传递参数 |
|||
* load 是否需要loading |
|||
*/ |
|||
async apiEsCall(method, endpoint, data, load) { |
|||
if (!load) { |
|||
uni.showLoading({ |
|||
title: '请稍候', |
|||
mask: true |
|||
}); |
|||
} |
|||
|
|||
let fullurl = this.ESURI + endpoint; |
|||
//let fullurl = 'http://localhost:8085/api/' + endpoint;
|
|||
let Authorization = `${store.state.userInfo.tokenHead}${store.state.userInfo.token}`; |
|||
let [error, res] = await uni.request({ |
|||
url: fullurl, |
|||
data: data, |
|||
method: method, |
|||
header: { |
|||
'Content-Type': 'application/x-www-form-urlencoded', |
|||
// 'content-type': 'application/json',
|
|||
'Authorization': Authorization || '' |
|||
}, |
|||
}); |
|||
console.log(error); |
|||
if (!load) { |
|||
uni.hideLoading(); |
|||
} |
|||
return res; |
|||
|
|||
}, |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
module.exports = { |
|||
error:'', |
|||
isJSON : function (str){ |
|||
if (typeof str == 'string') { |
|||
try { |
|||
var obj=JSON.parse(str); |
|||
if(typeof obj == 'object' && obj ){ |
|||
return true; |
|||
}else{ |
|||
return false; |
|||
} |
|||
} catch(e) { |
|||
console.log('error:'+str+'!!!'+e); |
|||
return false; |
|||
} |
|||
} |
|||
}, |
|||
isNumber : function (checkVal){ |
|||
var reg = /^-?[1-9][0-9]?.?[0-9]*$/; |
|||
return reg.test(checkVal); |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,43 @@ |
|||
// date.js
|
|||
export function formatDate(date, fmt) { |
|||
if (/(y+)/.test(fmt)) { |
|||
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); |
|||
} |
|||
let o = { |
|||
'M+': date.getMonth() + 1, |
|||
'd+': date.getDate(), |
|||
'h+': date.getHours(), |
|||
'm+': date.getMinutes(), |
|||
's+': date.getSeconds() |
|||
}; |
|||
for (let k in o) { |
|||
if (new RegExp(`(${k})`).test(fmt)) { |
|||
let str = o[k] + ''; |
|||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str)); |
|||
} |
|||
} |
|||
return fmt; |
|||
} |
|||
|
|||
function padLeftZero(str) { |
|||
return ('00' + str).substr(str.length); |
|||
} |
|||
|
|||
export function str2Date(dateStr, separator) { |
|||
if (!separator) { |
|||
separator = "-"; |
|||
} |
|||
let dateArr = dateStr.split(separator); |
|||
let year = parseInt(dateArr[0]); |
|||
let month; |
|||
//处理月份为04这样的情况
|
|||
if (dateArr[1].indexOf("0") == 0) { |
|||
month = parseInt(dateArr[1].substring(1)); |
|||
} else { |
|||
month = parseInt(dateArr[1]); |
|||
} |
|||
let day = parseInt(dateArr[2]); |
|||
let date = new Date(year, month - 1, day); |
|||
return date; |
|||
} |
|||
|
|||
@ -0,0 +1,352 @@ |
|||
/* |
|||
* HTML5 Parser By Sam Blowes |
|||
* |
|||
* Designed for HTML5 documents |
|||
* |
|||
* Original code by John Resig (ejohn.org) |
|||
* http://ejohn.org/blog/pure-javascript-html-parser/
|
|||
* Original code by Erik Arvidsson, Mozilla Public License |
|||
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
|
|||
* |
|||
* ---------------------------------------------------------------------------- |
|||
* License |
|||
* ---------------------------------------------------------------------------- |
|||
* |
|||
* This code is triple licensed using Apache Software License 2.0, |
|||
* Mozilla Public License or GNU Public License |
|||
* |
|||
* ////////////////////////////////////////////////////////////////////////////
|
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not |
|||
* use this file except in compliance with the License. You may obtain a copy |
|||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* ////////////////////////////////////////////////////////////////////////////
|
|||
* |
|||
* The contents of this file are subject to the Mozilla Public License |
|||
* Version 1.1 (the "License"); you may not use this file except in |
|||
* compliance with the License. You may obtain a copy of the License at |
|||
* http://www.mozilla.org/MPL/
|
|||
* |
|||
* Software distributed under the License is distributed on an "AS IS" |
|||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|||
* License for the specific language governing rights and limitations |
|||
* under the License. |
|||
* |
|||
* The Original Code is Simple HTML Parser. |
|||
* |
|||
* The Initial Developer of the Original Code is Erik Arvidsson. |
|||
* Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights |
|||
* Reserved. |
|||
* |
|||
* ////////////////////////////////////////////////////////////////////////////
|
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, write to the Free Software |
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|||
* |
|||
* ---------------------------------------------------------------------------- |
|||
* Usage |
|||
* ---------------------------------------------------------------------------- |
|||
* |
|||
* // Use like so:
|
|||
* HTMLParser(htmlString, { |
|||
* start: function(tag, attrs, unary) {}, |
|||
* end: function(tag) {}, |
|||
* chars: function(text) {}, |
|||
* comment: function(text) {} |
|||
* }); |
|||
* |
|||
* // or to get an XML string:
|
|||
* HTMLtoXML(htmlString); |
|||
* |
|||
* // or to get an XML DOM Document
|
|||
* HTMLtoDOM(htmlString); |
|||
* |
|||
* // or to inject into an existing document/DOM node
|
|||
* HTMLtoDOM(htmlString, document); |
|||
* HTMLtoDOM(htmlString, document.body); |
|||
* |
|||
*/ |
|||
// Regular Expressions for parsing tags and attributes
|
|||
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/; |
|||
var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/; |
|||
var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
|
|||
|
|||
var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5
|
|||
// fixed by xxx 将 ins 标签从块级名单中移除
|
|||
|
|||
var block = makeMap('a,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,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
|
|||
|
|||
var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,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)
|
|||
|
|||
var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
|
|||
|
|||
var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything)
|
|||
|
|||
var special = makeMap('script,style'); |
|||
function HTMLParser(html, handler) { |
|||
var index; |
|||
var chars; |
|||
var match; |
|||
var stack = []; |
|||
var last = html; |
|||
|
|||
stack.last = function () { |
|||
return this[this.length - 1]; |
|||
}; |
|||
|
|||
while (html) { |
|||
chars = true; // Make sure we're not in a script or style element
|
|||
|
|||
if (!stack.last() || !special[stack.last()]) { |
|||
// Comment
|
|||
if (html.indexOf('<!--') == 0) { |
|||
index = html.indexOf('-->'); |
|||
|
|||
if (index >= 0) { |
|||
if (handler.comment) { |
|||
handler.comment(html.substring(4, index)); |
|||
} |
|||
|
|||
html = html.substring(index + 3); |
|||
chars = false; |
|||
} // end tag
|
|||
|
|||
} else 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('<'); |
|||
var text = index < 0 ? html : html.substring(0, index); |
|||
html = index < 0 ? '' : html.substring(index); |
|||
|
|||
if (handler.chars) { |
|||
handler.chars(text); |
|||
} |
|||
} |
|||
} else { |
|||
html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) { |
|||
text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2'); |
|||
|
|||
if (handler.chars) { |
|||
handler.chars(text); |
|||
} |
|||
|
|||
return ''; |
|||
}); |
|||
parseEndTag('', stack.last()); |
|||
} |
|||
|
|||
if (html == last) { |
|||
throw 'Parse Error: ' + html; |
|||
} |
|||
|
|||
last = html; |
|||
} // Clean up any remaining tags
|
|||
|
|||
|
|||
parseEndTag(); |
|||
|
|||
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) { |
|||
var attrs = []; |
|||
rest.replace(attr, function (match, name) { |
|||
var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : ''; |
|||
attrs.push({ |
|||
name: name, |
|||
value: value, |
|||
escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
|
|||
|
|||
}); |
|||
}); |
|||
|
|||
if (handler.start) { |
|||
handler.start(tagName, attrs, unary); |
|||
} |
|||
} |
|||
} |
|||
|
|||
function parseEndTag(tag, tagName) { |
|||
// If no tag name is provided, clean shop
|
|||
if (!tagName) { |
|||
var pos = 0; |
|||
} // Find the closest opened tag of the same type
|
|||
else { |
|||
for (var pos = stack.length - 1; pos >= 0; pos--) { |
|||
if (stack[pos] == tagName) { |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (pos >= 0) { |
|||
// Close all the open elements, up the stack
|
|||
for (var i = stack.length - 1; i >= pos; i--) { |
|||
if (handler.end) { |
|||
handler.end(stack[i]); |
|||
} |
|||
} // Remove the open elements from the stack
|
|||
|
|||
|
|||
stack.length = pos; |
|||
} |
|||
} |
|||
} |
|||
|
|||
function makeMap(str) { |
|||
var obj = {}; |
|||
var items = str.split(','); |
|||
|
|||
for (var i = 0; i < items.length; i++) { |
|||
obj[items[i]] = true; |
|||
} |
|||
|
|||
return obj; |
|||
} |
|||
|
|||
function removeDOCTYPE(html) { |
|||
return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, ''); |
|||
} |
|||
|
|||
function parseAttrs(attrs) { |
|||
return attrs.reduce(function (pre, attr) { |
|||
var value = attr.value; |
|||
var name = attr.name; |
|||
|
|||
if (pre[name]) { |
|||
pre[name] = pre[name] + " " + value; |
|||
} else { |
|||
pre[name] = value; |
|||
} |
|||
|
|||
return pre; |
|||
}, {}); |
|||
} |
|||
|
|||
function parseHtml(html) { |
|||
html = removeDOCTYPE(html); |
|||
var stacks = []; |
|||
var results = { |
|||
node: 'root', |
|||
children: [] |
|||
}; |
|||
HTMLParser(html, { |
|||
start: function start(tag, attrs, unary) { |
|||
var node = { |
|||
name: tag |
|||
}; |
|||
|
|||
if (attrs.length !== 0) { |
|||
node.attrs = parseAttrs(attrs); |
|||
} |
|||
|
|||
if (unary) { |
|||
var parent = stacks[0] || results; |
|||
|
|||
if (!parent.children) { |
|||
parent.children = []; |
|||
} |
|||
|
|||
parent.children.push(node); |
|||
} else { |
|||
stacks.unshift(node); |
|||
} |
|||
}, |
|||
end: function end(tag) { |
|||
var node = stacks.shift(); |
|||
if (node.name !== tag) console.error('invalid state: mismatch end tag'); |
|||
|
|||
if (stacks.length === 0) { |
|||
results.children.push(node); |
|||
} else { |
|||
var parent = stacks[0]; |
|||
|
|||
if (!parent.children) { |
|||
parent.children = []; |
|||
} |
|||
|
|||
parent.children.push(node); |
|||
} |
|||
}, |
|||
chars: function chars(text) { |
|||
var node = { |
|||
type: 'text', |
|||
text: text |
|||
}; |
|||
|
|||
if (stacks.length === 0) { |
|||
results.children.push(node); |
|||
} else { |
|||
var parent = stacks[0]; |
|||
|
|||
if (!parent.children) { |
|||
parent.children = []; |
|||
} |
|||
|
|||
parent.children.push(node); |
|||
} |
|||
}, |
|||
comment: function comment(text) { |
|||
var node = { |
|||
node: 'comment', |
|||
text: text |
|||
}; |
|||
var parent = stacks[0]; |
|||
|
|||
if (!parent.children) { |
|||
parent.children = []; |
|||
} |
|||
|
|||
parent.children.push(node); |
|||
} |
|||
}); |
|||
return results.children; |
|||
} |
|||
|
|||
export default parseHtml; |
|||
@ -0,0 +1,32 @@ |
|||
const listData = [{ |
|||
content: "好评", |
|||
create_time: "2019-04-12", |
|||
header_img: "http://cs.zhangkaixing.com/face/face_2.jpg", |
|||
user_name: "测试1", |
|||
rate:5, |
|||
imgs:[] |
|||
}, |
|||
{ |
|||
content: "中评", |
|||
create_time: "2019-04-12", |
|||
header_img: "http://cs.zhangkaixing.com/face/face_12.jpg", |
|||
user_name: "测试2", |
|||
rate:4, |
|||
imgs:[ |
|||
'http://cs.zhangkaixing.com/face/face.jpg', |
|||
'http://cs.zhangkaixing.com/face/p10.jpg', |
|||
'http://cs.zhangkaixing.com/face/face_14.jpg', |
|||
'http://cs.zhangkaixing.com/face/face.jpg', |
|||
'http://cs.zhangkaixing.com/face/p10.jpg', |
|||
] |
|||
}, |
|||
{ |
|||
content: "", |
|||
create_time: "2019-04-12", |
|||
header_img: "http://cs.zhangkaixing.com/face/face_15.jpg", |
|||
user_name: "测试3", |
|||
rate:2, |
|||
imgs:[] |
|||
}] |
|||
|
|||
export default listData |
|||
@ -0,0 +1,71 @@ |
|||
//#ifdef H5
|
|||
/** clipboard.js v2.0.4**/ |
|||
!function(t,e){try{window.ClipboardJS=e();}catch(e){};"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports} |
|||
return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}} |
|||
return function(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}}(),a=o(n(1)),c=o(n(3)),u=o(n(4));function o(t){return t&&t.__esModule?t:{default:t}} |
|||
var l=function(t){function o(t,e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,o);var n=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}(this,(o.__proto__||Object.getPrototypeOf(o)).call(this));return n.resolveOptions(e),n.listenClick(t),n} |
|||
return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(o,c.default),i(o,[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===r(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=(0,u.default)(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new a.default({action:this.action(e),target:this.target(e),text:this.text(e),container:this.container,trigger:e,emitter:this})}},{key:"defaultAction",value:function(t){return s("action",t)||'copy'}},{key:"defaultTarget",value:function(t){var e=s("target",t);if(e){return document.querySelector(e)}}},{key:"defaultText",value:function(t){return s("text",t)||this.text}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:["copy","cut"],e="string"==typeof t?[t]:t,n=!!document.queryCommandSupported;return e.forEach(function(t){n=n&&!!document.queryCommandSupported(t)}),n}}]),o}();function s(t,e){var n="data-clipboard-"+t;let isFun=e&&typeof e.hasAttribute==='function';if(isFun&&e.hasAttribute(n)){return e.getAttribute(n)}} |
|||
t.exports=l},function(t,e,n){"use strict";var o,r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}} |
|||
return function(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}}(),a=n(2),c=(o=a)&&o.__esModule?o:{default:o};var u=function(){function e(t){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),this.resolveOptions(t),this.initSelection()} |
|||
return i(e,[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.container=t.container,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var t=this,e="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[e?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,c.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,c.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1} |
|||
this.handleResult(e)}},{key:"handleResult",value:function(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(t){if(void 0!==t){if(!t||"object"!==(void 0===t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function(){return this._target}}]),e}();t.exports=u},function(t,e){t.exports=function(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),r=document.createRange();r.selectNodeContents(t),o.removeAllRanges(),o.addRange(r),e=o.toString()} |
|||
return e}},function(t,e){function n(){} |
|||
n.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var o=this;function r(){o.off(t,r),e.apply(n,arguments)} |
|||
return r._=e,this.on(t,r,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;o<r;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,a=o.length;i<a;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},t.exports=n},function(t,e,n){var d=n(5),h=n(6);t.exports=function(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!d.string(e))throw new TypeError("Second argument must be a String");if(!d.fn(n))throw new TypeError("Third argument must be a Function");if(d.node(t))return s=e,f=n,(l=t).addEventListener(s,f),{destroy:function(){l.removeEventListener(s,f)}};if(d.nodeList(t))return a=t,c=e,u=n,Array.prototype.forEach.call(a,function(t){t.addEventListener(c,u)}),{destroy:function(){Array.prototype.forEach.call(a,function(t){t.removeEventListener(c,u)})}};if(d.string(t))return o=t,r=e,i=n,h(document.body,o,r,i);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList");var o,r,i,a,c,u,l,s,f}},function(t,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},function(t,e,n){var a=n(7);function i(t,e,n,o,r){var i=function(e,n,t,o){return function(t){t.delegateTarget=a(t.target,n),t.delegateTarget&&o.call(e,t)}}.apply(this,arguments);return t.addEventListener(n,i,r),{destroy:function(){t.removeEventListener(n,i,r)}}} |
|||
t.exports=function(t,e,n,o,r){return"function"==typeof t.addEventListener?i.apply(null,arguments):"function"==typeof n?i.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return i(t,e,n,o,r)}))}},function(t,e){if("undefined"!=typeof Element&&!Element.prototype.matches){var n=Element.prototype;n.matches=n.matchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector||n.webkitMatchesSelector} |
|||
t.exports=function(t,e){for(;t&&9!==t.nodeType;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}}])});let Types={isFunction:function(obj){var type=Object.prototype.toString.call(obj) |
|||
return type=='[object Function]'},isObject:function(obj){var type=Object.prototype.toString.call(obj) |
|||
return type=='[object Object]'},isString:function(obj){var type=Object.prototype.toString.call(obj) |
|||
return type=='[object String]'}} |
|||
uni.setClipboardData=function(options){let emptyFun=function(){} |
|||
let config={data:null,event:null,success:emptyFun,fail:emptyFun,complete:emptyFun} |
|||
if(options&&Types.isObject(options)){config=Object.assign({},config,options)} |
|||
if(options&&Types.isString(options)){config=Object.assign({},config,{data:options})} |
|||
let data=config.data |
|||
let success=config.success||emptyFun |
|||
let fail=config.fail||emptyFun |
|||
let complete=config.complete||emptyFun |
|||
let e=config.event||window.event||{} |
|||
let cb=new ClipboardJS('.null',{text:()=>data}) |
|||
cb.on('success',function(res){ |
|||
window.__clipboard__=data; |
|||
success&&Types.isFunction(success)&&success({data:res.text}) |
|||
complete&&Types.isFunction(complete)&&complete() |
|||
cb.off('error') |
|||
cb.off('success') |
|||
cb.destroy()}) |
|||
cb.on('error',function(err){fail&&Types.isFunction(fail)&&fail(err) |
|||
complete&&Types.isFunction(complete)&&complete() |
|||
cb.off('error') |
|||
cb.off('success') |
|||
cb.destroy()}) |
|||
cb.onClick(e)}; |
|||
uni.getClipboardData=function(options){let emptyFun=function(){} |
|||
let config={data:null,event:null,success:emptyFun,fail:emptyFun,complete:emptyFun} |
|||
if(options&&Types.isObject(options)){config=Object.assign({},config,options)} |
|||
let success=config.success||emptyFun |
|||
let fail=config.fail||emptyFun |
|||
let complete=config.complete||emptyFun |
|||
if(window.__clipboard__!==undefined){success&&Types.isFunction(success)&&success({data:window.__clipboard__})}else{fail&&Types.isFunction(fail)&&fail({data:null})} |
|||
complete&&Types.isFunction(complete)&&complete()}; |
|||
function fileDownLoad(data){var linkElement=document.createElement('a') |
|||
linkElement.setAttribute('href',data.blob) |
|||
linkElement.setAttribute('downLoad',data.name) |
|||
linkElement.click()} |
|||
uni.saveImageToPhotosAlbum=uni.saveVideoToPhotosAlbum=function(options){let emptyFun=function(){} |
|||
let config={filePath:null,success:emptyFun,fail:emptyFun,complete:emptyFun} |
|||
if(options&&Types.isObject(options)){config=Object.assign({},config,options)} |
|||
if(options&&Types.isString(options)){config=Object.assign({},config,{filePath:options})} |
|||
let filePath=config.filePath |
|||
let success=config.success||emptyFun |
|||
let fail=config.fail||emptyFun |
|||
let complete=config.complete||emptyFun |
|||
if(!filePath){fail&&Types.isFunction(fail)&&fail({msg:'no File'}) |
|||
complete&&Types.isFunction(complete)&&complete() |
|||
return} |
|||
let names=filePath.split('/') |
|||
let name=names[names.length-1] |
|||
uni.downloadFile({url:filePath,success:function(res){let tempFilePath=res.tempFilePath |
|||
fileDownLoad({name:name,blob:tempFilePath}) |
|||
success&&Types.isFunction(success)&&success({filePath:filePath})},fail:function(err){fail&&Types.isFunction(fail)&&fail({msg:err})},complete:function(){complete&&Types.isFunction(complete)&&complete()}})} |
|||
//#endif
|
|||
@ -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,190 @@ |
|||
<template> |
|||
<view class="coupon-item"> |
|||
<view class="coupon-money"> |
|||
<view class="nick">{{item.name}}</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="useCoupon(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 { |
|||
types: false |
|||
} |
|||
}, |
|||
props: { |
|||
item: { |
|||
type: Object |
|||
}, |
|||
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) { |
|||
this.types =!this.types |
|||
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(); |
|||
|
|||
}, |
|||
async useCoupon(item){ |
|||
uni.showLoading({ |
|||
title: '请稍后' |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
</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> |
|||
@ -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} |
|||
@ -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} |
|||
@ -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> |
|||
File diff suppressed because one or more lines are too long
@ -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; |
|||
@ -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; |
|||
@ -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; |
|||
@ -0,0 +1,12 @@ |
|||
/* 商家模块 */ |
|||
var merchant = function(){}; |
|||
merchant.prototype = { |
|||
|
|||
constructor : merchant, |
|||
|
|||
//收银员的订单列表是否需要刷新
|
|||
cashierOrderListRefresh : false |
|||
|
|||
}; |
|||
|
|||
export default merchant; |
|||
@ -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; |
|||
@ -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; |
|||
@ -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; |
|||
File diff suppressed because it is too large
@ -0,0 +1,3 @@ |
|||
// 版本控制文件
|
|||
var version='0.0.12'; |
|||
export default version; |
|||
@ -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> |
|||
@ -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; |
|||
@ -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; |
|||
@ -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, |
|||
}; |
|||
@ -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; |
|||
} |
|||
@ -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> |
|||
@ -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> |
|||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
|
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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,71 @@ |
|||
<template> |
|||
<view class="icons" @click.stop="likeTab"> |
|||
<uni-icons size="20" color="#f07373" :type="like?'heart-filled':'heart'" ></uni-icons> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props:{ |
|||
item:{ |
|||
type:Object, |
|||
default(){ |
|||
return {} |
|||
} |
|||
}, |
|||
types:{ |
|||
type:String, |
|||
default:'' |
|||
} |
|||
}, |
|||
watch:{ |
|||
item(newVal){ |
|||
this.like = this.item.is_like |
|||
} |
|||
}, |
|||
created() { |
|||
this.like = this.item.is_like |
|||
}, |
|||
data() { |
|||
return { |
|||
like:false |
|||
}; |
|||
}, |
|||
methods:{ |
|||
likeTab(){ |
|||
this.like = !this.like; |
|||
this.updateLikes(); |
|||
}, |
|||
updateLikes(){ |
|||
uni.showLoading(); |
|||
this.$api.update_likes({ |
|||
user_id:'5f3d11c03d11c60001141e5f', |
|||
article_id:this.item._id |
|||
}).then(res=>{ |
|||
uni.hideLoading(); |
|||
console.log(res); |
|||
uni.showToast({ |
|||
title:this.like?"收藏成功":"取消收藏", |
|||
icon:'none' |
|||
}) |
|||
uni.$emit('update_article',this.types) |
|||
}).catch(()=>{ |
|||
uni.hideLoading(); |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.icons { |
|||
position: absolute; |
|||
right: 0; |
|||
top: 0; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
width: 20px; |
|||
height: 20px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,36 @@ |
|||
<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{ |
|||
width: 100%; |
|||
position: absolute; |
|||
bottom: 0; |
|||
justify-self: center; |
|||
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> |
|||
@ -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> |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
File diff suppressed because one or more lines are too long
@ -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> |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue