Compare commits

1 Commits

Author SHA1 Message Date
e263a616f6 tmp: 部分代码与UnishopV5结合,但是代码有严重缺陷 2025-12-20 15:30:39 +08:00
183 changed files with 31316 additions and 18590 deletions

13
App.vue
View File

@@ -40,7 +40,7 @@
// #endif // #endif
// #ifdef H5 // #ifdef H5
if (uni.getSystemInfoSync().platform == 'ios') { if (uni.getDeviceInfo().platform == 'ios') {
uni.setStorageSync('initUrl', location.href); uni.setStorageSync('initUrl', location.href);
} }
// #endif // #endif
@@ -151,7 +151,6 @@
onShow: function(options) { onShow: function(options) {
// #ifdef MP // #ifdef MP
// 自动授权登录 // 自动授权登录
this.getAuthInfo();
if (this.$store.state.token) { if (this.$store.state.token) {
this.$api.sendRequest({ this.$api.sendRequest({
url: '/api/member/info', url: '/api/member/info',
@@ -161,6 +160,8 @@
} }
} }
}); });
}else{
this.getAuthInfo();
} }
// #endif // #endif
@@ -177,8 +178,7 @@
// #ifdef H5 // #ifdef H5
if (this.$util.isWeiXin()) { if (this.$util.isWeiXin()) {
this.$util.getUrlCode(urlParams => { this.$util.getUrlCode(urlParams => {
if (urlParams.source_member) uni.setStorageSync('source_member', urlParams if (urlParams.source_member) uni.setStorageSync('source_member', urlParams.source_member);
.source_member);
if (urlParams.code == undefined) { if (urlParams.code == undefined) {
this.$api.sendRequest({ this.$api.sendRequest({
@@ -204,8 +204,7 @@
let data = {}; let data = {};
if (res.data.openid) data.wx_openid = res.data.openid; if (res.data.openid) data.wx_openid = res.data.openid;
if (res.data.unionid) data.wx_unionid = res.data.unionid; if (res.data.unionid) data.wx_unionid = res.data.unionid;
if (res.data.userinfo) Object.assign(data, res.data if (res.data.userinfo) Object.assign(data, res.data.userinfo);
.userinfo);
this.authLogin(data); this.authLogin(data);
} }
} }
@@ -301,7 +300,7 @@
this.shareConfig(); this.shareConfig();
} }
}, },
// 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法 // 代表在watch里声明了firstName这个方法之后立即先去执行handler方法
immediate: true immediate: true
} }
} }

View File

@@ -1,234 +1,305 @@
.collectPopupWindow { .collectPopupWindow {
position: relative; position: relative;
height: 113rpx; height: 113rpx;
width: 510rpx; width: 510rpx;
margin-left: calc(100% - 530rpx); margin-left: calc(100% - 530rpx);
image { image {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
text { text {
color: #ff4544 !important; color: #ff4544 !important;
font-size: 24rpx !important; font-size: 24rpx !important;
position: absolute; position: absolute;
top: 48rpx; top: 48rpx;
right: 25rpx; right: 25rpx;
} }
} }
.zhezhao { .zhezhao {
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
background-color: transparent; background-color: transparent;
} }
image { image {
max-width: 100% !important; max-width: 100% !important;
max-height: 100% !important; max-height: 100% !important;
} }
.diy-wrap { .diy-wrap {
/* #ifdef H5 */ /* #ifdef H5 */
height: calc(100vh - 88rpx); height: calc(100vh - 88rpx);
/* #endif */ /* #endif */
/* #ifdef MP-WEIXIN */ /* #ifdef MP-WEIXIN */
height: 100vh; height: 100vh;
/* #endif */ /* #endif */
} }
.page-img { .page-img {
background-size: contain !important; background-size: contain !important;
background-repeat: no-repeat !important; background-repeat: no-repeat !important;
} }
.page-header { .page-header {
background-size: 100% !important; background-size: 100% !important;
background-repeat: no-repeat !important; background-repeat: no-repeat !important;
background-position: top center; background-position: top center;
background-attachment: fixed; background-attachment: fixed;
} }
.bg-index { .bg-index {
width: 100%; width: 100%;
height: 100%; height: 100%;
box-sizing: border-box; box-sizing: border-box;
background-size: 100% !important; background-size: 100% !important;
background-repeat: no-repeat !important; background-repeat: no-repeat !important;
} }
.wap-floating { .wap-floating {
text { text {
display: block; display: block;
font-size: 60rpx; font-size: 60rpx;
color: #ffffff; color: #ffffff;
text-align: center; text-align: center;
} }
} }
.wap-floating-collect .uni-popup__mask { .wap-floating-collect .uni-popup__mask {
background: transparent; background: transparent;
} }
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 0; width: 0;
height: 0; height: 0;
color: transparent; color: transparent;
} }
.popup-box { .popup-box {
width: 450rpx; width: 450rpx;
background: #ffffff; background: #ffffff;
border-radius: $border-radius; border-radius: $border-radius;
overflow: hidden; overflow: hidden;
.close_title { .close_title {
width: 100%; width: 100%;
text-align: center; text-align: center;
height: 70rpx; height: 70rpx;
line-height: 70rpx; line-height: 70rpx;
font-size: $font-size-base; font-size: $font-size-base;
} }
.close_content { .close_content {
width: 100%; width: 100%;
max-height: 500rpx; max-height: 500rpx;
padding: $padding; padding: $padding;
box-sizing: border-box; box-sizing: border-box;
} }
.close_content_box { .close_content_box {
width: 100%; width: 100%;
max-height: 460rpx; max-height: 460rpx;
line-height: 1.3; line-height: 1.3;
} }
} }
.noStore-text { .noStore-text {
color: #000000 !important; color: #000000 !important;
} }
.isStore-top { .isStore-top {
margin-bottom: 10rpx; margin-bottom: 10rpx;
} }
.keep-on-record { .keep-on-record {
text-align: center; text-align: center;
padding-bottom: 20rpx; padding-bottom: 20rpx;
image { image {
width: 150rpx; width: 150rpx;
height: 60rpx; height: 60rpx;
} }
} }
.padding-bottom { .padding-bottom {
padding-bottom: 40rpx !important; padding-bottom: 40rpx !important;
} }
.choose-store { .choose-store {
/deep/ .uni-popup__wrapper{ /deep/ .uni-popup__wrapper{
background: none!important; background: none!important;
} }
} }
.choose-store-popup { .choose-store-popup {
padding: 30rpx; padding: 30rpx;
background-color: #fff; background-color: #fff;
.head-wrap { .head-wrap {
font-weight: bold; font-weight: bold;
font-size: $font-size-toolbar; font-size: $font-size-toolbar;
text-align: center; text-align: center;
margin-bottom: 20rpx; margin-bottom: 20rpx;
color: #202021; color: #202021;
} }
.position-wrap { .position-wrap {
display: flex; display: flex;
color: #202021; color: #202021;
align-items: center; align-items: center;
margin-bottom: 20rpx; margin-bottom: 20rpx;
.icon-dizhi { .icon-dizhi {
font-weight: bold; font-weight: bold;
font-size: $font-size-tag; font-size: $font-size-tag;
margin-right: 10rpx; margin-right: 10rpx;
} }
.address { .address {
font-weight: bold; font-weight: bold;
font-size: $font-size-tag; font-size: $font-size-tag;
margin-right: 10rpx; margin-right: 10rpx;
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
-o-text-overflow: ellipsis; -o-text-overflow: ellipsis;
} }
.reposition { .reposition {
display: flex; display: flex;
align-items: center; align-items: center;
.iconfont { .iconfont {
font-size: $font-size-base; font-size: $font-size-base;
margin-right: 6rpx; margin-right: 6rpx;
} }
text { text {
font-size: $font-size-tag; font-size: $font-size-tag;
color: #fd463e; color: #fd463e;
} }
} }
} }
.store-wrap { .store-wrap {
border: 1px solid $base-color; border: 1px solid $base-color;
border-radius: 16rpx; border-radius: 16rpx;
padding: 20rpx 30rpx; padding: 20rpx 30rpx;
margin-bottom: 30rpx; margin-bottom: 30rpx;
.tag { .tag {
background-color: #fee9ea; background-color: #fee9ea;
color: #fd463e; color: #fd463e;
font-size: $font-size-activity-tag; font-size: $font-size-activity-tag;
display: inline-block; display: inline-block;
border-radius: 6rpx; border-radius: 6rpx;
padding: 4rpx 12rpx; padding: 4rpx 12rpx;
// #ifdef H5 // #ifdef H5
transform: scale(0.8); transform: scale(0.8);
margin-left: -10rpx; margin-left: -10rpx;
// #endif // #endif
} }
.store-name { .store-name {
margin: 10rpx 0; margin: 10rpx 0;
font-weight: bold; font-weight: bold;
color: #202021; color: #202021;
font-size: $font-size-toolbar; font-size: $font-size-toolbar;
} }
.address { .store-close-desc{
color: #5f6067; color: red;
font-size: $font-size-tag; font-size: $font-size-tag;
margin-bottom: 10rpx; margin-bottom: 10rpx;
} }
.distance { .address {
display: flex; color: #5f6067;
align-items: center; font-size: $font-size-tag;
color: #5f6067; margin-bottom: 10rpx;
font-size: $font-size-tag; }
.iconfont { .distance {
font-size: $font-size-base; display: flex;
margin-right: 10rpx; align-items: center;
} color: #5f6067;
} font-size: $font-size-tag;
} .iconfont {
font-size: $font-size-base;
button { margin-right: 10rpx;
border-radius: 40rpx; }
} }
}
.other-store {
display: flex; button {
align-items: center; border-radius: 40rpx;
color: #5e6066; }
font-weight: bold;
justify-content: center; .other-store {
margin-top: 20rpx; display: flex;
margin-bottom: 20rpx; align-items: center;
.iconfont { color: #5e6066;
margin-left: 10rpx; font-weight: bold;
font-size: $font-size-tag; justify-content: center;
} margin-top: 20rpx;
} margin-bottom: 20rpx;
} .iconfont {
.page-bottom { margin-left: 10rpx;
margin-top: 20rpx; font-size: $font-size-tag;
} }
}
}
.page-bottom {
margin-top: 20rpx;
}
.chain-stores{
.chain-store-popup{
background-color: #fff;
border-top-left-radius: 24rpx;
border-top-right-radius: 24rpx;
overflow: hidden;
.title{
font-size: 36rpx;
line-height: 104rpx;
text-align: center;
color: #000;
font-weight: bold;
}
.body{
padding: 20rpx 30rpx;
background-color: #F4F4F4;
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom)) !important;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom)) !important;
.center{
background-color: #fff;
box-shadow: 4rpx 4rpx 12rpx 4rpx rgba(0,0,0,0.02);
border-radius: 24rpx;
padding-top: 60rpx;
padding-bottom: 23rpx;
.image{
display: flex;
justify-content: center;
}
.text-top{
margin-top: 44rpx;
font-size: 30rpx;
font-weight: bold;
color: #000;
line-height: 42rpx;
text-align: center;
}
.text-bottom{
margin-top: 20rpx;
padding: 0 57rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #999;
text-align: center;
}
.footer{
display: flex;
margin-top: 20rpx;
padding: 0 24rpx;
button{
margin: 0 !important;
box-sizing: border-box;
height: 84rpx;
line-height: 84rpx;
border-radius: 62rpx;
font-size: 30rpx;
flex:1;
}
button.btn-right{
margin-left: 20rpx !important;
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,103 +1,100 @@
export default { export default {
data() { data() {
return { return {
authInfo: {} authInfo: {}
} }
}, },
methods: { methods: {
/** /**
* 获取用户登录凭证code * 获取用户登录凭证code
*/ */
getCode(callback) { getCode(callback) {
// 微信小程序 // 微信小程序
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
uni.login({ uni.login({
provider: 'weixin', provider: 'weixin',
timeout: 3000, timeout: 3000,
success: res => { success: res => {
if (res.code) { if (res.code) {
this.$api.sendRequest({ this.$api.sendRequest({
url: '/weapp/api/weapp/authcodetoopenid', url: '/weapp/api/weapp/authcodetoopenid',
data: { data: {
code: res.code code: res.code
}, },
success: res => { success: res => {
if (res.code >= 0) { if (res.code >= 0) {
if (res.data.openid) this.authInfo.weapp_openid = res.data if (res.data.openid) this.authInfo.weapp_openid = res.data.openid;
.openid; if (res.data.unionid) this.authInfo.wx_unionid = res.data.unionid;
if (res.data.unionid) this.authInfo.wx_unionid = res.data typeof callback == 'function' && callback(this.authInfo);
.unionid; } else {
typeof callback == 'function' && callback(this.authInfo); this.$util.showToast({
} else { title: res.message ? res.message : '小程序配置错误'
this.$util.showToast({ });
title: res.message ? res.message : '小程序配置错误' }
}); }
} })
} }
}) },
} fail: (res) => {
}, // #ifdef MP-WEIXIN
fail: (res) => { let scene = wx.getLaunchOptionsSync().scene;
// #ifdef MP-WEIXIN if ([1154, 1155].indexOf(scene) == -1) {
let scene = wx.getLaunchOptionsSync().scene; this.$util.showToast({
if ([1154, 1155].indexOf(scene) == -1) { title: res.errMsg
this.$util.showToast({ });
title: res.errMsg }
}); // #endif
} }
// #endif })
} // #endif
})
// #endif // #ifdef MP-ALIPAY
uni.login({
// #ifdef MP-ALIPAY timeout: 3000,
uni.login({ success: res => {
timeout: 3000, if (res.code) {
success: res => { this.$api.sendRequest({
if (res.code) { url: '/aliapp/api/aliapp/authcodetouserid',
this.$api.sendRequest({ data: {
url: '/aliapp/api/aliapp/authcodetouserid', code: res.code
data: { },
code: res.code success: res => {
}, if (res.code >= 0) {
success: res => { if (res.data.user_id) this.authInfo.ali_openid = res.data.user_id;
if (res.code >= 0) { typeof callback == 'function' && callback(this.authInfo);
if (res.data.user_id) this.authInfo.ali_openid = res.data } else {
.user_id; this.$util.showToast({
typeof callback == 'function' && callback(this.authInfo); title: res.message ? res.message : '小程序配置错误'
} else { });
this.$util.showToast({ }
title: res.message ? res.message : '小程序配置错误' }
}); })
} }
} },
}) fail: (res) => {
} this.$util.showToast({
}, title: res.errMsg
fail: (err) => { });
this.$util.showToast({ }
title: res.errMsg })
}); // #endif
}
}) // #ifdef H5
// #endif if (this.$util.isWeiXin()) {
this.$api.sendRequest({
// #ifdef H5 url: '/wechat/api/wechat/authcode',
if (this.$util.isWeiXin()) { data: {
this.$api.sendRequest({ redirect_url: location.href,
url: '/wechat/api/wechat/authcode', scopes: 'snsapi_userinfo'
data: { },
redirect_url: location.href, success: res => {
scopes: 'snsapi_userinfo' if (res.code >= 0) {
}, location.href = res.data;
success: res => { }
if (res.code >= 0) { }
location.href = res.data; });
} }
} // #endif
}); }
} }
// #endif
}
}
} }

View File

@@ -1,7 +1,14 @@
import WxMap from 'common/js/map-wx-jssdk.js'; import { QQMapWX } from 'common/js/map-wx-jssdk.js';
import Config from '@/common/js/config.js'; import Config from '@/common/js/config.js';
let systemInfo = uni.getSystemInfoSync(); let systemInfo = {};
try {
// 合并设备信息和窗口信息
systemInfo = {...uni.getDeviceInfo(), ...uni.getWindowInfo()};
} catch (e) {
// 兼容旧版本
systemInfo = uni.getSystemInfoSync();
}
export default { export default {
data() { data() {
return { return {
@@ -35,6 +42,7 @@ export default {
latitude: null, // 纬度 latitude: null, // 纬度
longitude: null, // 经度 longitude: null, // 经度
currentPosition: '', // 当前位置 currentPosition: '', // 当前位置
currentStore: null,//当前门店
nearestStore: null, // 离自己最近的门店 nearestStore: null, // 离自己最近的门店
storeTimeOut: null, // 没有获取到定位,则获取默认门店 storeTimeOut: null, // 没有获取到定位,则获取默认门店
@@ -43,19 +51,26 @@ export default {
diyRoute: '', // 页面路由 diyRoute: '', // 页面路由
openBottomNav: false, openBottomNav: false,
isShowCopyRight: false, isShowCopyRight: false,
option: null,
firstDiy: true,
//启动广告 //启动广告
adv:{}, adv: {},
}; };
}, },
onLoad(option) { onLoad(option) {
this.option = option;
uni.hideTabBar(); uni.hideTabBar();
// 支付宝小程序传参处理
// #ifdef MP-ALIPAY
let aliapp_option = my.getLaunchOptionsSync();
aliapp_option.query && Object.assign(option, aliapp_option.query);
// #endif
if (option.source_member) uni.setStorageSync('source_member', option.source_member); // 处理分享人数据
if (option.source_member) uni.setStorageSync('source_member', option.source_member);// 分享链接进入
// 小程序扫码进入 if (option.scene) {// 小程序扫码进入
if (option.scene) {
var sceneParams = decodeURIComponent(option.scene); var sceneParams = decodeURIComponent(option.scene);
sceneParams = sceneParams.split('&'); sceneParams = sceneParams.split('&');
if (sceneParams.length) { if (sceneParams.length) {
@@ -65,64 +80,36 @@ export default {
} }
} }
// H5地图选择位置回调
// #ifdef H5 // #ifdef H5
// H5地图选择位置回调数据 // H5地图选择位置回调数据
if (option.module && option.module == 'locationPicker') { if (option.module && option.module == 'locationPicker') {
option.name = ''; // 清空地址 option.name = ''; // 自定义页面传参id和name防止获取地址时变量混淆
this.locationModule = option.module; this.locationModule = option.module;
this.latitude = option.latng.split(',')[0]; this.latitude = option.latng.split(',')[0];
this.longitude = option.latng.split(',')[1]; this.longitude = option.latng.split(',')[1];
} }
// #endif // #endif
//自定义页面的id和名称
this.id = option.id || 0; this.id = option.id || 0;
this.name = option.name || ''; this.name = option.name || '';
uni.removeStorageSync('manual_store_info'); // 清除手动切换门店缓存 //获取当前门店信息 必须是首页且不是手动切换操作
uni.removeStorageSync('manual_change_store'); // 清楚手动切换门店标识 let current_route = this.$util.getCurrentRoute();
let manualChangeStore = uni.getStorageSync('manual_change_store'); // 手动切换门店
// H5才会执行 if (current_route.path.indexOf('/pages/index/index') > -1 && !manualChangeStore) {
if (this.locationModule == 'locationPicker') { this.getCurrentStore(option);
// H5地图选址后的回调
this.getNearestStore();
this.getCurrentLocation();
} else if (this.mapConfig.wap_is_open == 1) {
// 每次都要定位,获取当前位置
/*this.$util.getLocation({
fail: (res) => {
// 拒绝定位,进入默认总店
this.enterDefaultStore();
}
});*/
// 如果3秒没有获取到定位则获取默认门店H5使用
// #ifdef H5
this.storeTimeOut = setTimeout(() => {
this.enterDefaultStore();
}, 1000 * 3);
// #endif
} else {
// 关闭定位
this.enterDefaultStore();
} }
}, },
onShow() { async onShow() {
if (this.firstDiy) {
this.init(); this.firstDiy = false;
await this.getDiyMethod();
}
await this.onShowMethod();
}, },
onHide() { onHide() {
if (this.storeTimeOut) {
clearTimeout(this.storeTimeOut);
}
// 跳转页面要关闭门店弹出框
this.closeChooseStorePopup();
// 清除限时秒杀定时器 // 清除限时秒杀定时器
this.$store.commit('setDiySeckillInterval', 0); this.$store.commit('setDiySeckillInterval', 0);
}, },
@@ -149,7 +136,7 @@ export default {
return str; return str;
}, },
backgroundUrl() { backgroundUrl() {
var str = this.diyData.global.bgUrl && this.diyData.global.bgUrl != 'transparent' ? 'url(' + this.$util.img(this.diyData.global.bgUrl) + ') ' : ''; var str = this.diyData.global?.bgUrl && this.diyData.global?.bgUrl != 'transparent' ? 'url(' + this.$util.img(this.diyData.global?.bgUrl) + ') ' : '';
return str; return str;
}, },
textNavColor() { textNavColor() {
@@ -187,30 +174,34 @@ export default {
} }
}, },
watch: { watch: {
location: function (nVal) { /* location: function (nVal) {
if (nVal) { if (nVal && !this.latitude && !this.longitude) {
this.latitude = nVal.latitude; this.latitude = nVal.latitude;
this.longitude = nVal.longitude; this.longitude = nVal.longitude;
this.getNearestStore(); this.getStoreInfoByLocation();
this.getCurrentLocation();
} }
}, */
initStatus: function (val) {
if (!this.option.store_id) this.getLocation();
} }
}, },
methods: { methods: {
play(){ async getDiyMethod() {
console.log(123) await this.getDiyInfo();
this.$store.commit('setDiySeckillInterval', 1);
this.$store.commit('setComponentRefresh');
}, },
async init() { async onShowMethod() {
// 定位信息过期后,重新获取定位 // 定位信息过期后,重新获取定位
if(this.mapConfig.wap_is_open == 1 && this.locationStorage && this.locationStorage.is_expired) { // if (this.mapConfig.wap_is_open == 1 && this.locationStorage && this.locationStorage.is_expired) {
this.$util.getLocation({ // this.$util.getLocation({
fail: (res) => { // fail: (res) => {
// 拒绝定位,进入默认总店 // // 失败了不需要做任何处理,保持之前的门店选择即可
this.enterDefaultStore(); // }
} // });
}); // }
}
if (this.storeToken) { if (this.storeToken) {
//记录分享关系 //记录分享关系
@@ -225,17 +216,15 @@ export default {
this.$store.commit('setDiySeckillInterval', 1); this.$store.commit('setDiySeckillInterval', 1);
//小程序分享
// #ifdef MP-WEIXIN
this.$util.getMpShare().then(res => {
this.mpShareData = res;
});
// #endif
let manualChangeStore = uni.getStorageSync('manual_change_store'); // 手动切换门店 let manualChangeStore = uni.getStorageSync('manual_change_store'); // 手动切换门店
if (manualChangeStore) { if (manualChangeStore) {
uni.removeStorageSync('manual_change_store'); uni.removeStorageSync('manual_change_store');
let manualStoreInfo = uni.getStorageSync('manual_store_info'); // 手动选择门店
uni.removeStorageSync('manual_store_info');
if (manualStoreInfo) {
this.currentStore = manualStoreInfo;
}
this.closeGetLocationFailPopup();
// 滚动至顶部 // 滚动至顶部
uni.pageScrollTo({ uni.pageScrollTo({
duration: 200, duration: 200,
@@ -267,8 +256,14 @@ export default {
query.select('.page-header').boundingClientRect(data => { query.select('.page-header').boundingClientRect(data => {
if (data && data.height) { if (data && data.height) {
// 从状态栏高度开始算 // 从状态栏高度开始算
this.paddingTop = data.height + 'px'; if (!this.diyData.global.topNavBg) {
this.marginTop = -data.height + 'px'; this.paddingTop = 0;
this.marginTop = 0;
} else {
this.paddingTop = data.height + 'px';
this.marginTop = -data.height + 'px';
}
clearInterval(time); clearInterval(time);
} }
}).exec(); }).exec();
@@ -276,7 +271,7 @@ export default {
}, 50); }, 50);
// #endif // #endif
}, },
async getDiyAdv(){ async getDiyAdv() {
//启动广告 //启动广告
let res = await this.$api.sendRequest({ let res = await this.$api.sendRequest({
url: '/api/diyview/getstartadv', url: '/api/diyview/getstartadv',
@@ -285,13 +280,13 @@ export default {
}); });
this.adv = res.value this.adv = res.value
// 弹框形式,首次弹出 1每次弹出 0 // 弹框形式,首次弹出 1每次弹出 0
if(this.adv.advshow == 1){ if (this.adv.advshow == 1) {
setTimeout(() => { setTimeout(() => {
if (res.value.advtype == 1) { if (res.value.advtype == 1) {
var popwindow_count = uni.getStorageSync(this.id + this.name + '_popwindow_count'); var popwindow_count = uni.getStorageSync(this.id + this.name + '_popwindow_count');
if ((this.$refs.uniPopupWindow && popwindow_count == '') || ( if ((this.$refs.uniPopupWindow && popwindow_count == '') || (
this.$refs.uniPopupWindow && popwindow_count == 1)) { this.$refs.uniPopupWindow && popwindow_count == 1)) {
this.$refs.uniPopupWindow.open(); this.$refs.uniPopupWindow.open();
uni.setStorageSync(this.id + this.name + '_popwindow_count', 1); uni.setStorageSync(this.id + this.name + '_popwindow_count', 1);
} }
@@ -301,7 +296,7 @@ export default {
} }
}, 500); }, 500);
} }
}, },
async getDiyInfo() { async getDiyInfo() {
let res = await this.$api.sendRequest({ let res = await this.$api.sendRequest({
@@ -309,7 +304,7 @@ export default {
data: { data: {
id: this.id, id: this.id,
name: this.name, name: this.name,
en_type:uni.getStorageSync("lang"),//获取语言底部 en_type: uni.getStorageSync("lang"),//获取语言底部
}, },
async: false async: false
}); });
@@ -337,7 +332,7 @@ export default {
this.$langConfig.title(this.diyData.global.title); this.$langConfig.title(this.diyData.global.title);
this.mpCollect = this.diyData.global.mpCollect; this.mpCollect = this.diyData.global.mpCollect;
this.setPublicShare(); this.setPublicShare();
/* if (this.diyData.global.popWindow && this.diyData.global.popWindow.imageUrl) { if (this.diyData.global.popWindow && this.diyData.global.popWindow.imageUrl) {
// 弹框形式,首次弹出 1每次弹出 0 // 弹框形式,首次弹出 1每次弹出 0
setTimeout(() => { setTimeout(() => {
if (this.diyData.global.popWindow.count == 1) { if (this.diyData.global.popWindow.count == 1) {
@@ -352,7 +347,7 @@ export default {
uni.setStorageSync(this.id + this.name + '_popwindow_count', 0); uni.setStorageSync(this.id + this.name + '_popwindow_count', 0);
} }
}, 500); }, 500);
}*/ }
// 修改diy数据结构排序 // 修改diy数据结构排序
let searchIndex = -1; let searchIndex = -1;
@@ -375,14 +370,15 @@ export default {
this.diyData.value.splice(topCategoryIndex, 1); this.diyData.value.splice(topCategoryIndex, 1);
this.diyData.value.splice(0, 0, ...topCategoryData); this.diyData.value.splice(0, 0, ...topCategoryData);
this.diyData.value.splice(1, 0, ...searchData); this.diyData.value.splice(1, 0, ...searchData);
} else } else {
this.diyData.value.splice(0, 0, ...searchData); this.diyData.value.splice(0, 0, ...searchData);
}
} else if (searchIndex != -1 && topCategoryIndex == -1) { } else if (searchIndex != -1 && topCategoryIndex == -1) {
let searchData = this.diyData.value.slice(searchIndex, searchIndex + 1); let searchData = this.diyData.value.slice(searchIndex, searchIndex + 1);
this.diyData.value.splice(searchIndex, 1); this.diyData.value.splice(searchIndex, 1);
this.diyData.value.splice(0, 0, ...searchData); this.diyData.value.splice(0, 0, ...searchData);
} }
this.topIndexValue = null;
for (var i = 0; i < this.diyData.value.length; i++) { for (var i = 0; i < this.diyData.value.length; i++) {
// 分类导航组件 // 分类导航组件
if (this.diyData.value[i].componentName == 'TopCategory') { if (this.diyData.value[i].componentName == 'TopCategory') {
@@ -402,7 +398,6 @@ export default {
} }
} }
// #ifdef MP // #ifdef MP
//小程序收藏 //小程序收藏
if (!uni.getStorageSync('isCollect') && this.diyData.global.mpCollect) { if (!uni.getStorageSync('isCollect') && this.diyData.global.mpCollect) {
@@ -416,6 +411,45 @@ export default {
this.openBottomNav = this.diyData.global.openBottomNav; this.openBottomNav = this.diyData.global.openBottomNav;
} }
this.isShowCopyRight = true; this.isShowCopyRight = true;
//小程序分享
// #ifdef MP-WEIXIN
let path = this.$util.getCurrentRoute().path;
if (path == '/pages/member/index') {
this.mpShareData = {};
return;
}
let share_path = path;
if (this.$store.state.memberInfo && this.$store.state.memberInfo.member_id) {
share_path = this.$util.getCurrentShareRoute(this.$store.state.memberInfo.member_id).path
}
let appMessageData = {
title: this.diyData.global.weappShareTitle,
path: share_path,
imageUrl: this.$util.img(this.diyData.global.weappShareImage),
success: res => { },
fail: res => { }
}
let timeLineData = {
title: this.diyData.global.weappShareTitle,
query: share_path,
imageUrl: this.$util.img(this.diyData.global.weappShareImage),
}
this.mpShareData = {
appMessage: appMessageData,
timeLine: timeLineData
};
//console.log(this.mpShareData, 'this.mpShareData');
var store_info = this.$store.state.globalStoreInfo;
if (store_info) {
this.mpShareData.appMessage.path += (this.mpShareData.appMessage.path.indexOf('?') > -1 ? '&' : '?') + 'store_id=' + store_info.store_id;
this.mpShareData.timeLine.query += (this.mpShareData.timeLine.query.indexOf('?') > -1 ? '&' : '?') + 'store_id=' + store_info.store_id;
}
//朋友圈不需要页面路径,只要要后面的参数就行
this.mpShareData.timeLine.query = this.mpShareData.timeLine.query.split('?')[1] || '';
// #endif
} }
}, },
closePopupWindow() { closePopupWindow() {
@@ -430,44 +464,131 @@ export default {
this.$util.diyRedirectTo(this.diyData.global.popWindow.link); this.$util.diyRedirectTo(this.diyData.global.popWindow.link);
this.closePopupWindow(); this.closePopupWindow();
}, },
openChooseStorePopup() { /******************************************** 获取门店相关 START ***************************************************/
if (this.globalStoreConfig && this.globalStoreConfig.confirm_popup_control == 1) { /**
let storeInfo = this.globalStoreInfo; * 1、分享携带门店id
* 门店id正确 进入门店
// 首次进入门店,没有门店信息 || 当前位置的门店和缓存门店不一致要弹框 * 门店id错误 通过定位获取门店
if (!storeInfo || storeInfo && this.nearestStore && storeInfo.store_id != this.nearestStore.store_id) { * 2、通过定位获取门店
if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.open(); * 开启获取定位
* 同意获取定位 获取最近门店 进入门店
* 拒绝获取定位
* 平台运营模式 进入默认门店
* 连锁门店模式 提示获取定位失败,手动选择门店或引导去开启定位
* 关闭获取定位
* 平台运营模式 进入默认门店
* 连锁门店模式 提示获取定位失败,手动选择门店
*/
getCurrentStore(option) {
if (option.store_id && !isNaN(parseInt(option.store_id))) {
this.getStoreInfoByShare(option.store_id);
} else {
this.getLocation();
}
},
getStoreInfoByShare(store_id) {
this.$api.sendRequest({
url: '/api/store/info',
data: { store_id },
success: res => {
if (res.code >= 0 && res.data) {
this.changeCurrentStore(res.data);
} else {
this.getLocation();
}
},
fail: res => {
this.getLocation();
}
});
},
getLocation() {
if (!this.latitude && !this.longitude && this.initStatus) {
if (this.mapConfig.wap_is_open == 1) {
this.$util.getLocation({
complete: (res) => {
if (res.latitude && res.longitude) {
this.closeGetLocationFailPopup();
this.latitude = res.latitude;
this.longitude = res.longitude;
this.getStoreInfoByLocation();
} else {
let is_h5 = false;
// #ifdef H5
is_h5 = true;
// #endif
if (is_h5) {
//H5同意了也会进入失败所以直接进入默认门店
this.enterDefaultStore();
} else {
this.getLocationFail();
}
}
}
});
// #ifdef H5
//H5有的机型可能根本不会触发getLocation的任何执行包括successfailcompletele
//所以这里如果等待一定时间后还是没有获取到当前门店则进入默认门店
setTimeout(() => {
let current_route = this.$util.getCurrentRoute();
if (this.mapConfig.wap_is_open == 1 && !this.currentStore && current_route.path == '/pages/index/index') {
this.enterDefaultStore();
}
}, 5000);
// #endif
} else {
this.getLocationFail();
} }
} }
},
let manualStoreInfo = uni.getStorageSync('manual_store_info'); // 手动选择门店 getStoreInfoByLocation() {
if (manualStoreInfo) { if (this.latitude && this.longitude) {
this.nearestStore = manualStoreInfo; this.getNearestStore();
this.getCurrentLocation();
}
},
changeCurrentStore(store_info) {
this.currentStore = store_info;
this.changeStore(store_info);
this.openChooseStorePopup();
},
getLocationFail() {
if (this.globalStoreConfig.store_business == 'shop') {
this.enterDefaultStore();
} else {
this.openGetLocationFailPopup();
}
},
openGetLocationFailPopup() {
if (this.$refs.getLocationFailRef) this.$refs.getLocationFailRef.open();
},
closeGetLocationFailPopup() {
if (this.$refs.getLocationFailRef) this.$refs.getLocationFailRef.close();
},
openChooseStorePopup() {
let globalStoreInfo = this.globalStoreInfo;
if (this.globalStoreConfig && this.globalStoreConfig.confirm_popup_control == 1) {
this.currentStore.show_address = this.currentStore.full_address.replace(/,/g, ' ') + ' ' + this.currentStore.address;
if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.open();
} }
this.changeStore(this.nearestStore); // 切换门店数据
}, },
closeChooseStorePopup() { closeChooseStorePopup() {
if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.close(); if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.close();
}, },
// 确认进入门店
enterStore() {
this.closeChooseStorePopup();
},
// 选择其他门店 // 选择其他门店
chooseOtherStore() { chooseOtherStore() {
this.$util.redirectTo('/pages_tool/store/list'); this.$util.redirectTo('/pages_tool/store/list');
this.closeChooseStorePopup(); this.closeChooseStorePopup();
}, },
// 打开地图重新选择位置 // 打开地图重新选择位置
reposition() { reGetLocation() {
// #ifdef MP // #ifdef MP
/*uni.chooseLocation({ uni.chooseLocation({
success: res => { success: res => {
this.latitude = res.latitude; this.latitude = res.latitude;
this.longitude = res.longitude; this.longitude = res.longitude;
this.currentPosition = res.name; this.currentPosition = res.name;
this.getNearestStore(); this.getStoreInfoByLocation();
this.getCurrentLocation();
}, },
fail(res) { fail(res) {
uni.getSetting({ uni.getSetting({
@@ -492,8 +613,7 @@ export default {
this.latitude = res.latitude; this.latitude = res.latitude;
this.longitude = res.longitude; this.longitude = res.longitude;
this.currentPosition = res.name; this.currentPosition = res.name;
this.getNearestStore(); this.getStoreInfoByLocation();
this.getCurrentLocation();
} }
}); });
}, 1000); }, 1000);
@@ -511,7 +631,7 @@ export default {
} }
}); });
} }
});*/ });
// #endif // #endif
// #ifdef H5 // #ifdef H5
@@ -532,9 +652,7 @@ export default {
data: data, data: data,
success: res => { success: res => {
if (res.code == 0 && res.data) { if (res.code == 0 && res.data) {
this.nearestStore = res.data; this.changeCurrentStore(res.data);
this.nearestStore.show_address = this.nearestStore.full_address.replace(/,/g, ' ') + ' ' + this.nearestStore.address;
this.openChooseStorePopup();
} }
} }
}); });
@@ -547,7 +665,6 @@ export default {
data.latitude = this.latitude; data.latitude = this.latitude;
data.longitude = this.longitude; data.longitude = this.longitude;
} }
this.$api.sendRequest({ this.$api.sendRequest({
url: '/api/store/getLocation', url: '/api/store/getLocation',
data: data, data: data,
@@ -563,26 +680,42 @@ export default {
// 定位失败,进入默认门店 // 定位失败,进入默认门店
enterDefaultStore() { enterDefaultStore() {
if (this.defaultStoreInfo) { if (this.defaultStoreInfo) {
if (!this.nearestStore) { this.changeCurrentStore(this.defaultStoreInfo);
this.nearestStore = this.defaultStoreInfo;
this.nearestStore.show_address = this.nearestStore.full_address.replace(/,/g, ' ') + ' ' + this.nearestStore.address;
}
if (this.currentPosition == '') this.currentPosition = '未获取到定位';
this.openChooseStorePopup();
} }
}, },
//连锁门店未定位选择门店
chooseStore() {
this.$util.redirectTo('/pages_tool/store/list');
},
//打开手机设置重新定位
openSetting() {
uni.openSetting({
success: res => {
this.getLocation();
}
})
},
/******************************************** 获取门店相关 END ***************************************************/
// 设置公众号分享 // 设置公众号分享
setPublicShare() { setPublicShare() {
let shareUrl = this.$config.h5Domain + this.diyRoute; let shareUrl = this.$config.h5Domain + this.diyRoute;
if (this.id) shareUrl += '?id=' + this.id; var store_info = this.$store.state.globalStoreInfo;
else if (this.name) shareUrl += '?name=' + this.name; //if (store_info) shareUrl += '?store_id=' + store_info.store_id;
if (shareUrl.indexOf('?') > 0) {
shareUrl += '&';
} else {
shareUrl += '?';
}
if (this.id) shareUrl += 'id=' + this.id;
else if (this.name) shareUrl += 'name=' + this.name;
// alert('diydiydiy')
this.$util.setPublicShare({ this.$util.setPublicShare({
title: this.diyData.global.title, title: this.diyData.global.wechatShareTitle || this.diyData.global.title,
desc: '', desc: this.diyData.global.wechatShareDesc,
link: shareUrl, link: shareUrl,
imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : '' imgUrl: this.diyData.global.wechatShareImage ? this.$util.img(this.diyData.global.wechatShareImage) : this.$util.img(this.siteInfo.logo_square)
}); });
} },
}, },
onPageScroll(e) { onPageScroll(e) {
this.scrollTop = e.scrollTop; this.scrollTop = e.scrollTop;
@@ -597,6 +730,7 @@ export default {
// 下拉刷新 // 下拉刷新
onPullDownRefresh() { onPullDownRefresh() {
this.$store.commit('setComponentRefresh'); this.$store.commit('setComponentRefresh');
this.getDiyMethod();
setTimeout(() => { setTimeout(() => {
uni.stopPullDownRefresh(); uni.stopPullDownRefresh();
}, 50); }, 50);

View File

@@ -1,371 +1,382 @@
// 商品详情业务 // 商品详情业务
import htmlParser from '@/common/js/html-parser'; import htmlParser from '@/common/js/html-parser';
export default { export default {
data() { data() {
return { return {
skuId: 0, skuId: 0,
goodsId: 0, goodsId: 0,
// 商品详情 // 商品详情
goodsSkuDetail: { goodsSkuDetail: {
goods_id: 0, goods_id: 0,
goods_service: [] goods_service: []
}, },
preview: 0, //是否开启预览0不开启1开启 preview: 0, //是否开启预览0不开启1开启
//评价 //评价
contactData: { contactData: {
title: '', title: '',
path: '', path: '',
img: '' img: ''
}, },
shareQuery: '', // 分享参数 shareQuery: '', // 分享参数
shareUrl: '', // 分享链接 shareUrl: '', // 分享链接
source_member: 0, //分享人的id source_member: 0, //分享人的id
chatRoomParams: {}, // 联系客服参数 chatRoomParams: {}, // 联系客服参数
isIphoneX: false, //判断手机是否是iphoneX以上 isIphoneX: false, //判断手机是否是iphoneX以上
whetherCollection: 0, whetherCollection: 0,
posterParams: {}, //海报所需参数 posterParams: {}, //海报所需参数
shareImg: '', shareImg: '',
navbarData: { navbarData: {
title: '', title: '',
topNavColor: "#ffffff", topNavColor: "#ffffff",
topNavBg: false, topNavBg: false,
navBarSwitch: true, // 导航栏是否显示 navBarSwitch: true, // 导航栏是否显示
textNavColor: "#333333", textNavColor: "#333333",
moreLink: { moreLink: {
name: "" name: ""
}, },
navStyle: 1, navStyle: 1,
bgUrl: '', bgUrl: '',
textImgPosLink: 'left' textImgPosLink: 'left'
}, },
} goodsFormVal: []
}, }
onLoad(data) { },
//刷新多语言 onLoad(data) {
this.$langConfig.refresh(); //刷新多语言
// #ifdef MP-ALIPAY this.$langConfig.refresh();
let options = my.getLaunchOptionsSync(); // #ifdef MP-ALIPAY
options.query && Object.assign(data, options.query); let options = my.getLaunchOptionsSync();
// #endif options.query && Object.assign(data, options.query);
// #endif
this.preview = data.preview || 0;
this.isIphoneX = this.$util.uniappIsIPhoneX(); this.preview = data.preview || 0;
this.isIphoneX = this.$util.uniappIsIPhoneX();
if (data.source_member) {
uni.setStorageSync('source_member', data.source_member); if (data.source_member) {
this.source_member = data.source_member; uni.setStorageSync('source_member', data.source_member);
} this.source_member = data.source_member;
//记录分享关系 }
if (this.storeToken && uni.getStorageSync('source_member')) { //记录分享关系
this.$util.onSourceMember(uni.getStorageSync('source_member')); if (this.storeToken && uni.getStorageSync('source_member')) {
} this.$util.onSourceMember(uni.getStorageSync('source_member'));
}
// 小程序扫码进入
if (data.scene) { // 小程序扫码进入
var sceneParams = decodeURIComponent(data.scene); if (data.scene) {
sceneParams = sceneParams.split('&'); var sceneParams = decodeURIComponent(data.scene);
if (sceneParams.length) { sceneParams = sceneParams.split('&');
sceneParams.forEach(item => { if (sceneParams.length) {
if (item.indexOf('m') != -1) uni.setStorageSync('source_member', item.split('-')[1]); sceneParams.forEach(item => {
if (item.indexOf('is_test') != -1) uni.setStorageSync('is_test', 1); if (item.indexOf('m') != -1) uni.setStorageSync('source_member', item.split('-')[1]);
}); if (item.indexOf('is_test') != -1) uni.setStorageSync('is_test', 1);
} });
} }
}, }
onShow() { },
}, onShow() {
methods: { },
// 处理商品详情数据 methods: {
handleGoodsSkuData() { detailChangeVal(data) {
// this.navbarData.title = this.goodsSkuDetail.goods_name.length > 9 ? this.goodsSkuDetail.goods_name.substr(0, 9) + "..." : this.goodsSkuDetail.goods_name; this.goodsFormVal = data;
//设置标题 },
// this.$langConfig.title(this.navbarData.title); // 处理商品详情数据
if (this.goodsSkuDetail.config) { handleGoodsSkuData() {
this.navbarData.navBarSwitch = this.goodsSkuDetail.config.nav_bar_switch; this.navbarData.title = this.goodsSkuDetail.goods_name.length > 9 ? this.goodsSkuDetail.goods_name.substr(0, 9) + "..." : this.goodsSkuDetail.goods_name;
} this.$langConfig.title(this.navbarData.title);
if (this.goodsSkuDetail.config) {
this.whetherCollection = this.goodsSkuDetail.is_collect; // 用户关注商品状态 this.navbarData.navBarSwitch = this.goodsSkuDetail.config.nav_bar_switch;
}
this.modifyGoodsInfo();
this.whetherCollection = this.goodsSkuDetail.is_collect; // 用户关注商品状态
// 初始化商品详情视图数据
if (this.$refs.goodsDetailView) this.$refs.goodsDetailView.init({ this.modifyGoodsInfo();
sku_id: this.skuId,
goods_id: this.goodsSkuDetail.goods_id, // 初始化商品详情视图数据
preview: this.preview, if (this.$refs.goodsDetailView) this.$refs.goodsDetailView.init({
source_member: this.source_member, sku_id: this.skuId,
posterParams: this.posterParams, goods_id: this.goodsSkuDetail.goods_id,
posterApi: this.posterApi, preview: this.preview,
shareUrl: this.shareUrl, source_member: this.source_member,
goodsRoute: this.goodsRoute, posterParams: this.posterParams,
isVirtual: this.goodsSkuDetail.is_virtual, posterApi: this.posterApi,
deliveryType: this.goodsSkuDetail.express_type, shareUrl: this.shareUrl,
whetherCollection: this.goodsSkuDetail.is_collect, goodsRoute: this.goodsRoute,
evaluateConfig: this.goodsSkuDetail.evaluate_config, isVirtual: this.goodsSkuDetail.is_virtual,
evaluateList: this.goodsSkuDetail.evaluate_list, deliveryType: this.goodsSkuDetail.express_type,
evaluateCount: this.goodsSkuDetail.evaluate_count whetherCollection: this.goodsSkuDetail.is_collect,
}); evaluateConfig: this.goodsSkuDetail.evaluate_config,
evaluateList: this.goodsSkuDetail.evaluate_list,
//媒体 evaluateCount: this.goodsSkuDetail.evaluate_count,
if (this.goodsSkuDetail.video_url) this.switchMedia = "video"; goods_class : this.goodsSkuDetail.goods_class,
sale_store: this.goodsSkuDetail.sale_store
if (!Array.isArray(this.goodsSkuDetail.sku_images)) { });
if (this.goodsSkuDetail.sku_images) this.goodsSkuDetail.sku_images = this.goodsSkuDetail.sku_images.split(",");
else this.goodsSkuDetail.sku_images = []; //媒体
} if (this.goodsSkuDetail.video_url) this.switchMedia = "video";
// 多规格时合并主图 if (!Array.isArray(this.goodsSkuDetail.sku_images)) {
if (this.goodsSkuDetail.goods_spec_format && this.goodsSkuDetail.goods_image) { if (this.goodsSkuDetail.sku_images) this.goodsSkuDetail.sku_images = this.goodsSkuDetail.sku_images.split(",");
else this.goodsSkuDetail.sku_images = [];
if (!Array.isArray(this.goodsSkuDetail.goods_image)) this.goodsSkuDetail.goods_image = this.goodsSkuDetail.goods_image.split(","); }
this.goodsSkuDetail.sku_images = this.goodsSkuDetail.goods_image.concat(this.goodsSkuDetail.sku_images); // 多规格时合并主图
} if (this.goodsSkuDetail.goods_spec_format && this.goodsSkuDetail.goods_image) {
let maxHeight = ''; if (!Array.isArray(this.goodsSkuDetail.goods_image)) this.goodsSkuDetail.goods_image = this.goodsSkuDetail.goods_image.split(",");
let systemInfo = uni.getSystemInfoSync();
this.goodsSkuDetail.goods_image_list.forEach((item, index) => { this.goodsSkuDetail.sku_images = this.goodsSkuDetail.goods_image.concat(this.goodsSkuDetail.sku_images);
if (typeof item.pic_spec == "string") }
item.pic_spec = item.pic_spec.split('*');
let maxHeight = '';
let ratio = item.pic_spec[0] / systemInfo.windowWidth; let systemInfo = uni.getSystemInfoSync();
item.pic_spec[0] = item.pic_spec[0] / ratio; this.goodsSkuDetail.goods_image_list.forEach((item, index) => {
item.pic_spec[1] = item.pic_spec[1] / ratio; if (typeof item.pic_spec == "string")
item.pic_spec = item.pic_spec.split('*');
if (!maxHeight || maxHeight > item.pic_spec[1]) {
maxHeight = item.pic_spec[1]; let ratio = item.pic_spec[0] / systemInfo.windowWidth;
} item.pic_spec[0] = item.pic_spec[0] / ratio;
}); item.pic_spec[1] = item.pic_spec[1] / ratio;
this.goodsSkuDetail.swiperHeight = maxHeight + 'px';
if (!maxHeight || maxHeight > item.pic_spec[1]) {
this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件"; maxHeight = item.pic_spec[1];
}
// 当前商品SKU规格 });
if (this.goodsSkuDetail.sku_spec_format) this.goodsSkuDetail.sku_spec_format = JSON.parse(this.goodsSkuDetail.sku_spec_format); this.goodsSkuDetail.swiperHeight = maxHeight + 'px';
// 商品属性 this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件";
if (this.goodsSkuDetail.goods_attr_format) {
let goods_attr_format = JSON.parse(this.goodsSkuDetail.goods_attr_format); // 当前商品SKU规格
this.goodsSkuDetail.goods_attr_format = this.$util.unique(goods_attr_format, "attr_id"); if (this.goodsSkuDetail.sku_spec_format) this.goodsSkuDetail.sku_spec_format = JSON.parse(this.goodsSkuDetail.sku_spec_format);
for (var i = 0; i < this.goodsSkuDetail.goods_attr_format.length; i++) {
for (var j = 0; j < goods_attr_format.length; j++) { // 商品属性
if (this.goodsSkuDetail.goods_attr_format[i].attr_id == goods_attr_format[j].attr_id && this.goodsSkuDetail.goods_attr_format[i].attr_value_id != goods_attr_format[j].attr_value_id) { if (this.goodsSkuDetail.goods_attr_format) {
this.goodsSkuDetail.goods_attr_format[i].attr_value_name += "、" + goods_attr_format[j].attr_value_name; let goods_attr_format = JSON.parse(this.goodsSkuDetail.goods_attr_format);
} this.goodsSkuDetail.goods_attr_format = this.$util.unique(goods_attr_format, "attr_id");
} for (var i = 0; i < this.goodsSkuDetail.goods_attr_format.length; i++) {
} for (var j = 0; j < goods_attr_format.length; j++) {
} if (this.goodsSkuDetail.goods_attr_format[i].attr_id == goods_attr_format[j].attr_id && this.goodsSkuDetail.goods_attr_format[i].attr_value_id != goods_attr_format[j].attr_value_id) {
this.goodsSkuDetail.goods_attr_format[i].attr_value_name += "、" + goods_attr_format[j].attr_value_name;
// 商品SKU格式 }
if (this.goodsSkuDetail.goods_spec_format) this.goodsSkuDetail.goods_spec_format = JSON.parse(this.goodsSkuDetail.goods_spec_format); }
}
// 商品详情 }
if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = (this.goodsSkuDetail.goods_content);
console.log(this.goodsSkuDetail.goods_content) // 商品SKU格式
// if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = htmlParser(this.goodsSkuDetail.goods_content); if (this.goodsSkuDetail.goods_spec_format) this.goodsSkuDetail.goods_spec_format = JSON.parse(this.goodsSkuDetail.goods_spec_format);
//商品服务 // 商品详情
if (this.goodsSkuDetail.goods_service) { if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = (this.goodsSkuDetail.goods_content);
for (let i in this.goodsSkuDetail.goods_service) { console.log(this.goodsSkuDetail.goods_content)
this.goodsSkuDetail.goods_service[i]['icon'] = this.goodsSkuDetail.goods_service[i]['icon'] ? JSON.parse(this.goodsSkuDetail.goods_service[i]['icon']) : ''; // if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = htmlParser(this.goodsSkuDetail.goods_content);
}
} //商品服务
if (this.goodsSkuDetail.goods_service) {
this.contactData = { for (let i in this.goodsSkuDetail.goods_service) {
title: this.goodsSkuDetail.sku_name, this.goodsSkuDetail.goods_service[i]['icon'] = this.goodsSkuDetail.goods_service[i]['icon'] ? JSON.parse(this.goodsSkuDetail.goods_service[i]['icon']) : '';
path: this.shareUrl, }
img: this.$util.img(this.goodsSkuDetail.sku_image, { }
size: 'big'
}) this.contactData = {
}; title: this.goodsSkuDetail.sku_name,
if (this.$refs.goodsPromotion) this.$refs.goodsPromotion.refresh(this.goodsSkuDetail.goods_promotion); path: this.shareUrl,
img: this.$util.img(this.goodsSkuDetail.sku_image, {
if (this.goodsRoute != '/pages/goods/detail') this.setPublicShare(); size: 'big'
})
// this.getBarrageData(); };
if (this.addonIsExist.form) { if (this.$refs.goodsPromotion) this.$refs.goodsPromotion.refresh(this.goodsSkuDetail.goods_promotion);
this.getGoodsForm();
} this.setPublicShare();
}, // if (this.goodsRoute != '/pages/goods/detail') this.setPublicShare();
/**
* 刷新商品详情数据 this.getBarrageData();
* @param {Object} data if (this.addonIsExist.form) {
*/ this.getGoodsForm();
refreshGoodsSkuDetail(data) { }
this.goodsSkuDetail = Object.assign({}, this.goodsSkuDetail, data); },
if (this.$refs.goodsPromotion) this.$refs.goodsPromotion.refresh(this.goodsSkuDetail.goods_promotion); /**
if (this.$refs.goodsDetailView) { * 刷新商品详情数据
* @param {Object} data
// 初始化商品详情视图数据 */
this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件"; refreshGoodsSkuDetail(data) {
this.goodsSkuDetail = Object.assign({}, this.goodsSkuDetail, data);
// 解决轮播图数量不一致时,切换到第一个 if (this.$refs.goodsPromotion) this.$refs.goodsPromotion.refresh(this.goodsSkuDetail.goods_promotion);
if (this.swiperCurrent > this.goodsSkuDetail.sku_images.length) { if (this.$refs.goodsDetailView) {
this.swiperAutoplay = true;
this.swiperCurrent = 1; // 初始化商品详情视图数据
setTimeout(() => { this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件";
this.swiperAutoplay = false;
}, 40); // 解决轮播图数量不一致时,切换到第一个
} if (this.swiperCurrent > this.goodsSkuDetail.sku_images.length) {
this.swiperAutoplay = true;
} this.swiperCurrent = 1;
this.navbarData.title = this.goodsSkuDetail.goods_name.length > 9 ? this.goodsSkuDetail.goods_name.substr(0, 9) + "..." : this.goodsSkuDetail.goods_name; setTimeout(() => {
this.$langConfig.title(this.navbarData.title); this.swiperAutoplay = false;
}, 40);
if (this.goodsSkuDetail.membercard) { }
this.membercard = this.goodsSkuDetail.membercard;
} }
}, this.navbarData.title = this.goodsSkuDetail.goods_name.length > 9 ? this.goodsSkuDetail.goods_name.substr(0, 9) + "..." : this.goodsSkuDetail.goods_name;
goodsDetailViewInit() { this.$langConfig.title(this.navbarData.title);
// 初始化商品详情视图数据
if (this.$refs.goodsDetailView) this.$refs.goodsDetailView.init({ if (this.goodsSkuDetail.membercard) {
sku_id: this.skuId, this.membercard = this.goodsSkuDetail.membercard;
goods_id: this.goodsSkuDetail.goods_id, }
preview: this.preview, },
source_member: this.source_member, goodsDetailViewInit() {
posterParams: this.posterParams, // 初始化商品详情视图数据
posterApi: this.posterApi, if (this.$refs.goodsDetailView) this.$refs.goodsDetailView.init({
shareUrl: this.shareUrl, sku_id: this.skuId,
goodsRoute: this.goodsRoute, goods_id: this.goodsSkuDetail.goods_id,
isVirtual: this.goodsSkuDetail.is_virtual, preview: this.preview,
deliveryType: this.goodsSkuDetail.express_type, source_member: this.source_member,
whetherCollection: this.goodsSkuDetail.is_collect, posterParams: this.posterParams,
evaluateConfig: this.goodsSkuDetail.evaluate_config, posterApi: this.posterApi,
evaluateList: this.goodsSkuDetail.evaluate_list, shareUrl: this.shareUrl,
evaluateCount: this.goodsSkuDetail.evaluate_count goodsRoute: this.goodsRoute,
}); isVirtual: this.goodsSkuDetail.is_virtual,
}, deliveryType: this.goodsSkuDetail.express_type,
goHome() { whetherCollection: this.goodsSkuDetail.is_collect,
if (this.preview) return; // 开启预览,禁止任何操作和跳转 evaluateConfig: this.goodsSkuDetail.evaluate_config,
this.$util.redirectTo('/pages/index/index'); evaluateList: this.goodsSkuDetail.evaluate_list,
}, evaluateCount: this.goodsSkuDetail.evaluate_count
goCart() { });
if (this.preview) return; // 开启预览,禁止任何操作和跳转 },
this.$util.redirectTo('/pages/goods/cart'); goHome() {
}, if (this.preview) return; // 开启预览,禁止任何操作和跳转
//-------------------------------------关注------------------------------------- this.$util.redirectTo('/pages/index/index');
//更新商品信息 },
modifyGoodsInfo() { goCart() {
if (this.preview) return; // 开启预览,禁止任何操作和跳转 if (this.preview) return; // 开启预览,禁止任何操作和跳转
//更新商品点击量 this.$util.redirectTo('/pages/goods/cart');
this.$api.sendRequest({ },
url: "/api/goods/modifyclicks", //-------------------------------------关注-------------------------------------
data: { //更新商品信息
sku_id: this.skuId modifyGoodsInfo() {
}, if (this.preview) return; // 开启预览,禁止任何操作和跳转
success: res => { //更新商品点击量
} this.$api.sendRequest({
}); url: "/api/goods/modifyclicks",
data: {
//添加足迹 sku_id: this.skuId
this.$api.sendRequest({ },
url: "/api/goodsbrowse/add", success: res => {
data: { }
goods_id: this.goodsSkuDetail.goods_id, });
sku_id: this.skuId
}, //添加足迹
success: res => { this.$api.sendRequest({
} url: "/api/goodsbrowse/add",
}); data: {
}, goods_id: this.goodsSkuDetail.goods_id,
//-------------------------------------关注------------------------------------- sku_id: this.skuId
async editCollection() { },
if (this.$refs.goodsDetailView) { success: res => {
this.whetherCollection = await this.$refs.goodsDetailView.collection(); }
} });
}, },
openSharePopup() { //-------------------------------------关注-------------------------------------
if (this.$refs.goodsDetailView) { async editCollection() {
this.$refs.goodsDetailView.openSharePopup(); if (this.$refs.goodsDetailView) {
} this.whetherCollection = await this.$refs.goodsDetailView.collection();
}, }
//弹幕 },
getBarrageData() { openSharePopup() {
this.$api.sendRequest({ if (this.$refs.goodsDetailView) {
url: '/api/goods/goodsbarrage', this.$refs.goodsDetailView.openSharePopup();
data: { }
goods_id: this.goodsSkuDetail.goods_id },
}, //弹幕
success: res => { getBarrageData() {
if (res.code == 0 && res.data) { this.$api.sendRequest({
let barrageData = []; url: '/api/goods/goodsbarrage',
for (let i in res.data.list) { data: {
if (res.data.list[i]['title']) { goods_id: this.goodsSkuDetail.goods_id
let title = res.data.list[i]['title'].substr(0, 1) + '*' + res.data.list[i]['title'].substr(res.data.list[i]['title'].length - 1, 1) },
barrageData.push({ success: res => {
img: res.data.list[i]['img'] ? res.data.list[i]['img'] : this.$util.getDefaultImage().head, if (res.code == 0 && res.data) {
title: title + '已下单' let barrageData = [];
}); for (let i in res.data.list) {
} if (res.data.list[i]['title']) {
} let title = res.data.list[i]['title'].substr(0, 1) + '*' + res.data.list[i]['title'].substr(res.data.list[i]['title'].length - 1, 1)
this.goodsSkuDetail.barrageData = barrageData; barrageData.push({
} img: res.data.list[i]['img'] ? res.data.list[i]['img'] : this.$util.getDefaultImage().head,
} title: title + '已下单'
}); });
}, }
/** }
* 设置公众号分享 this.goodsSkuDetail.barrageData = barrageData;
*/ }
setPublicShare() { }
let shareUrl = this.$config.h5Domain + this.shareUrl; });
if (this.memberInfo && this.memberInfo.member_id) shareUrl += '&source_member=' + this.memberInfo.member_id; },
/**
this.$util.setPublicShare({ * 设置公众号分享
title: this.goodsSkuDetail.goods_name, */
desc: '', setPublicShare() {
link: shareUrl, let shareUrl = this.$config.h5Domain + this.shareUrl;
imgUrl: typeof this.goodsSkuDetail.goods_image == 'object' ? this.goodsSkuDetail.goods_image[0] : this.goodsSkuDetail.goods_image.split(',')[0] if (this.memberInfo && this.memberInfo.member_id) shareUrl += '&source_member=' + this.memberInfo.member_id;
}) var store_info = this.$store.state.globalStoreInfo;
}, if (store_info) shareUrl+= '&store_id=' + store_info.store_id;
/** this.$util.setPublicShare({
* 获取商品表单 title: this.goodsSkuDetail.goods_name,
*/ desc: '',
getGoodsForm() { link: shareUrl,
this.$api.sendRequest({ imgUrl: typeof this.goodsSkuDetail.goods_image == 'object' ? this.goodsSkuDetail.goods_image[0] : this.goodsSkuDetail.goods_image.split(',')[0]
url: "/form/api/form/goodsform", })
data: { },
goods_id: this.goodsSkuDetail.goods_id /**
}, * 获取商品表单
success: res => { */
if (res.code == 0 && res.data) this.$set(this.goodsSkuDetail, 'goods_form', res.data); getGoodsForm() {
} this.$api.sendRequest({
}); url: "/form/api/form/goodsform",
} data: {
}, goods_id: this.goodsSkuDetail.goods_id
/** },
* 自定义分享内容 success: res => {
* @param {Object} res if (res.code == 0 && res.data) this.$set(this.goodsSkuDetail, 'goods_form', res.data);
*/ }
onShareAppMessage(res) { });
var path = this.shareUrl; }
if (this.memberInfo && this.memberInfo.member_id) path += '&source_member=' + this.memberInfo.member_id; },
return { /**
title: this.goodsSkuDetail.sku_name, * 自定义分享内容
imageUrl: this.shareImg ? this.$util.img(this.shareImg) : this.$util.img(this.goodsSkuDetail.sku_image, { * @param {Object} res
size: 'big' */
}), onShareAppMessage(res) {
path: path, var path = this.shareUrl;
success: res => { var store_info = this.$store.state.globalStoreInfo;
}, if (store_info) path+= '&store_id=' + store_info.store_id;
fail: res => { if (this.memberInfo && this.memberInfo.member_id) path += '&source_member=' + this.memberInfo.member_id;
} return {
}; title: this.goodsSkuDetail.sku_name,
}, imageUrl: this.shareImg ? this.$util.img(this.shareImg) : this.$util.img(this.goodsSkuDetail.sku_image, {
// 分享到微信朋友圈 size: 'big'
// #ifdef MP-WEIXIN }),
onShareTimeline() { path: path,
let query = this.shareQuery; success: res => {
if (this.memberInfo && this.memberInfo.member_id) query += '&source_member=' + this.memberInfo.member_id; },
return { fail: res => {
title: this.goodsSkuDetail.sku_name, }
query: query, };
imageUrl: this.$util.img(this.goodsSkuDetail.sku_image, { },
size: 'big' // 分享到微信朋友圈
}) // #ifdef MP-WEIXIN
}; onShareTimeline() {
} let query = this.shareQuery;
// #endif var store_info = this.$store.state.globalStoreInfo;
if (store_info) query+= '&store_id=' + store_info.store_id;
if (this.memberInfo && this.memberInfo.member_id) query += '&source_member=' + this.memberInfo.member_id;
return {
title: this.goodsSkuDetail.sku_name,
query: query,
imageUrl: this.$util.img(this.goodsSkuDetail.sku_image, {
size: 'big'
})
};
}
// #endif
} }

View File

@@ -1,440 +1,440 @@
import util from './util.js' import util from './util.js'
/* /*
* HTML5 Parser By Sam Blowes * HTML5 Parser By Sam Blowes
* *
* Designed for HTML5 documents * Designed for HTML5 documents
* *
* Original code by John Resig (ejohn.org) * Original code by John Resig (ejohn.org)
* http://ejohn.org/blog/pure-javascript-html-parser/ * http://ejohn.org/blog/pure-javascript-html-parser/
* Original code by Erik Arvidsson, Mozilla Public License * Original code by Erik Arvidsson, Mozilla Public License
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* License * License
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
* This code is triple licensed using Apache Software License 2.0, * This code is triple licensed using Apache Software License 2.0,
* Mozilla Public License or GNU Public License * Mozilla Public License or GNU Public License
* *
* //////////////////////////////////////////////////////////////////////////// * ////////////////////////////////////////////////////////////////////////////
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not * 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 * 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 * of the License at http://www.apache.org/licenses/LICENSE-2.0
* *
* //////////////////////////////////////////////////////////////////////////// * ////////////////////////////////////////////////////////////////////////////
* *
* The contents of this file are subject to the Mozilla Public License * 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 * 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 * compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/ * http://www.mozilla.org/MPL/
* *
* Software distributed under the License is distributed on an "AS IS" * Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations * License for the specific language governing rights and limitations
* under the License. * under the License.
* *
* The Original Code is Simple HTML Parser. * The Original Code is Simple HTML Parser.
* *
* The Initial Developer of the Original Code is Erik Arvidsson. * The Initial Developer of the Original Code is Erik Arvidsson.
* Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights * Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
* Reserved. * Reserved.
* *
* //////////////////////////////////////////////////////////////////////////// * ////////////////////////////////////////////////////////////////////////////
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* Usage * Usage
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
* // Use like so: * // Use like so:
* HTMLParser(htmlString, { * HTMLParser(htmlString, {
* start: function(tag, attrs, unary) {}, * start: function(tag, attrs, unary) {},
* end: function(tag) {}, * end: function(tag) {},
* chars: function(text) {}, * chars: function(text) {},
* comment: function(text) {} * comment: function(text) {}
* }); * });
* *
* // or to get an XML string: * // or to get an XML string:
* HTMLtoXML(htmlString); * HTMLtoXML(htmlString);
* *
* // or to get an XML DOM Document * // or to get an XML DOM Document
* HTMLtoDOM(htmlString); * HTMLtoDOM(htmlString);
* *
* // or to inject into an existing document/DOM node * // or to inject into an existing document/DOM node
* HTMLtoDOM(htmlString, document); * HTMLtoDOM(htmlString, document);
* HTMLtoDOM(htmlString, document.body); * HTMLtoDOM(htmlString, document.body);
* *
*/ */
// Regular Expressions for parsing tags and attributes // Regular Expressions for parsing tags and attributes
var startTag = var startTag =
/^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/; /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/; var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
var attr = var attr =
/([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5 /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
var empty = makeMap( var empty = makeMap(
'area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr' 'area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'
); // Block Elements - HTML 5 ); // Block Elements - HTML 5
// fixed by xxx 将 ins 标签从块级名单中移除 // fixed by xxx 将 ins 标签从块级名单中移除
var block = makeMap( 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' '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 ); // Inline Elements - HTML 5
var inline = makeMap( 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' '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 ); // Elements that you can, intentionally, leave open
// (and which close themselves) // (and which close themselves)
var closeSelf = makeMap( var closeSelf = makeMap(
'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled" 'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
var fillAttrs = makeMap( var fillAttrs = makeMap(
'checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected' 'checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'
); // Special Elements (can contain anything) ); // Special Elements (can contain anything)
var special = makeMap('script,style'); var special = makeMap('script,style');
function HTMLParser(html, handler) { function HTMLParser(html, handler) {
var index; var index;
var chars; var chars;
var match; var match;
var stack = []; var stack = [];
var last = html; var last = html;
stack.last = function() { stack.last = function() {
return this[this.length - 1]; return this[this.length - 1];
}; };
while (html) { while (html) {
chars = true; // Make sure we're not in a script or style element chars = true; // Make sure we're not in a script or style element
if (!stack.last() || !special[stack.last()]) { if (!stack.last() || !special[stack.last()]) {
// Comment // Comment
if (html.indexOf('<!--') == 0) { if (html.indexOf('<!--') == 0) {
index = html.indexOf('-->'); index = html.indexOf('-->');
if (index >= 0) { if (index >= 0) {
if (handler.comment) { if (handler.comment) {
handler.comment(html.substring(4, index)); handler.comment(html.substring(4, index));
} }
html = html.substring(index + 3); html = html.substring(index + 3);
chars = false; chars = false;
} // end tag } // end tag
} else if (html.indexOf('</') == 0) { } else if (html.indexOf('</') == 0) {
match = html.match(endTag); match = html.match(endTag);
if (match) { if (match) {
html = html.substring(match[0].length); html = html.substring(match[0].length);
match[0].replace(endTag, parseEndTag); match[0].replace(endTag, parseEndTag);
chars = false; chars = false;
} // start tag } // start tag
} else if (html.indexOf('<') == 0) { } else if (html.indexOf('<') == 0) {
match = html.match(startTag); match = html.match(startTag);
if (match) { if (match) {
html = html.substring(match[0].length); html = html.substring(match[0].length);
match[0].replace(startTag, parseStartTag); match[0].replace(startTag, parseStartTag);
chars = false; chars = false;
} }
} }
if (chars) { if (chars) {
index = html.indexOf('<'); index = html.indexOf('<');
var text = index < 0 ? html : html.substring(0, index); var text = index < 0 ? html : html.substring(0, index);
html = index < 0 ? '' : html.substring(index); html = index < 0 ? '' : html.substring(index);
if (handler.chars) { if (handler.chars) {
handler.chars(text); handler.chars(text);
} }
} }
} else { } else {
html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function(all, text) { html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function(all, text) {
text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2'); text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
if (handler.chars) { if (handler.chars) {
handler.chars(text); handler.chars(text);
} }
return ''; return '';
}); });
parseEndTag('', stack.last()); parseEndTag('', stack.last());
} }
if (html == last) { if (html == last) {
throw 'Parse Error: ' + html; throw 'Parse Error: ' + html;
} }
last = html; last = html;
} // Clean up any remaining tags } // Clean up any remaining tags
parseEndTag(); parseEndTag();
function parseStartTag(tag, tagName, rest, unary) { function parseStartTag(tag, tagName, rest, unary) {
tagName = tagName.toLowerCase(); tagName = tagName.toLowerCase();
if (block[tagName]) { if (block[tagName]) {
while (stack.last() && inline[stack.last()]) { while (stack.last() && inline[stack.last()]) {
parseEndTag('', stack.last()); parseEndTag('', stack.last());
} }
} }
if (closeSelf[tagName] && stack.last() == tagName) { if (closeSelf[tagName] && stack.last() == tagName) {
parseEndTag('', tagName); parseEndTag('', tagName);
} }
unary = empty[tagName] || !!unary; unary = empty[tagName] || !!unary;
if (!unary) { if (!unary) {
stack.push(tagName); stack.push(tagName);
} }
if (handler.start) { if (handler.start) {
var attrs = []; var attrs = [];
rest.replace(attr, function(match, name) { rest.replace(attr, function(match, name) {
var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ?
arguments[4] : fillAttrs[ arguments[4] : fillAttrs[
name] ? name : ''; name] ? name : '';
attrs.push({ attrs.push({
name: name, name: name,
value: value, value: value,
escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // " escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
}); });
}); });
if (handler.start) { if (handler.start) {
handler.start(tagName, attrs, unary); handler.start(tagName, attrs, unary);
} }
} }
} }
function parseEndTag(tag, tagName) { function parseEndTag(tag, tagName) {
// If no tag name is provided, clean shop // If no tag name is provided, clean shop
if (!tagName) { if (!tagName) {
var pos = 0; var pos = 0;
} // Find the closest opened tag of the same type } // Find the closest opened tag of the same type
else { else {
for (var pos = stack.length - 1; pos >= 0; pos--) { for (var pos = stack.length - 1; pos >= 0; pos--) {
if (stack[pos] == tagName) { if (stack[pos] == tagName) {
break; break;
} }
} }
} }
if (pos >= 0) { if (pos >= 0) {
// Close all the open elements, up the stack // Close all the open elements, up the stack
for (var i = stack.length - 1; i >= pos; i--) { for (var i = stack.length - 1; i >= pos; i--) {
if (handler.end) { if (handler.end) {
handler.end(stack[i]); handler.end(stack[i]);
} }
} // Remove the open elements from the stack } // Remove the open elements from the stack
stack.length = pos; stack.length = pos;
} }
} }
} }
function makeMap(str) { function makeMap(str) {
var obj = {}; var obj = {};
var items = str.split(','); var items = str.split(',');
for (var i = 0; i < items.length; i++) { for (var i = 0; i < items.length; i++) {
obj[items[i]] = true; obj[items[i]] = true;
} }
return obj; return obj;
} }
function removeDOCTYPE(html) { function removeDOCTYPE(html) {
return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, ''); return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
} }
/** /**
* 忽略注释 * 忽略注释
* @param {Object} html * @param {Object} html
*/ */
function replaceAnnotation(html) { function replaceAnnotation(html) {
var html = html.replace(/<!--[\s\S]*-->/gi, ''); var html = html.replace(/<!--[\s\S]*-->/gi, '');
return html; return html;
} }
/** /**
* 替换图片 * 替换图片
* @param {Object} html * @param {Object} html
*/ */
function replaceImage(html) { function replaceImage(html) {
// #ifdef MP // #ifdef MP
let info = uni.getSystemInfoSync(); let info = uni.getWindowInfo();
var screenWidth = info.windowWidth; var screenWidth = info.windowWidth;
screenWidth -= 20; screenWidth -= 20;
screenWidth += 'px'; screenWidth += 'px';
// #endif // #endif
// #ifdef H5 // #ifdef H5
var screenWidth = '100%'; var screenWidth = '100%';
// #endif // #endif
let rep = `<img style="width:100% !important;display:block;max-width: ${screenWidth} !important;"`; let rep = `<img style="width:100% !important;display:block;max-width: ${screenWidth} !important;"`;
var html = html.replace(/\\/g, '').replace(/<img/g, rep); var html = html.replace(/\\/g, '').replace(/<img/g, rep);
html = html.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, capture) => { html = html.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, capture) => {
return rep + ' src="' + util.img(capture) + '"/>'; return rep + ' src="' + util.img(capture) + '"/>';
}); });
return html; return html;
} }
function replaceVideo(html){ function replaceVideo(html){
// #ifdef MP // #ifdef MP
let info = uni.getSystemInfoSync(); let info = uni.getWindowInfo();
var screenWidth = info.windowWidth; var screenWidth = info.windowWidth;
screenWidth -= 20; screenWidth -= 20;
screenWidth += 'px'; screenWidth += 'px';
// #endif // #endif
// #ifdef H5 // #ifdef H5
var screenWidth = '100%'; var screenWidth = '100%';
// #endif // #endif
let rep = `<video style="width:100% !important;display:block;max-width: ${screenWidth} !important;"`; let rep = `<video style="width:100% !important;display:block;max-width: ${screenWidth} !important;"`;
var html = html.replace(/\\/g, '').replace(/<video/g, rep); var html = html.replace(/\\/g, '').replace(/<video/g, rep);
console.log(html) console.log(html)
html = html.replace(/<video [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, capture) => { html = html.replace(/<video [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, capture) => {
return rep + ' src="' + util.img(capture) + '"/>'; return rep + ' src="' + util.img(capture) + '"/>';
}); });
// console.log(html) // console.log(html)
return html; return html;
} }
/** /**
* 将style属性中的双引号改为单引号 * 将style属性中的双引号改为单引号
* @param {Object} html * @param {Object} html
*/ */
function replaceStyleQuotes(html) { function replaceStyleQuotes(html) {
var html = html.replace(/style\s*=\s*["][^>]*;[^"]?/gi, (match, capture) => { var html = html.replace(/style\s*=\s*["][^>]*;[^"]?/gi, (match, capture) => {
match = match.replace(/[:](\s?)[\s\S]*/gi, (a, b) => { match = match.replace(/[:](\s?)[\s\S]*/gi, (a, b) => {
return a.replace(/"/g, "'"); return a.replace(/"/g, "'");
}); });
return match; return match;
}); });
return html; return html;
} }
function parseAttrs(attrs) { function parseAttrs(attrs) {
return attrs.reduce(function(pre, attr) { return attrs.reduce(function(pre, attr) {
var value = attr.value; var value = attr.value;
var name = attr.name; var name = attr.name;
if (pre[name]) { if (pre[name]) {
pre[name] = pre[name] + " " + value; pre[name] = pre[name] + " " + value;
} else { } else {
pre[name] = value; pre[name] = value;
} }
return pre; return pre;
}, {}); }, {});
} }
function parseHtml(html) { function parseHtml(html) {
html = removeDOCTYPE(html); html = removeDOCTYPE(html);
html = replaceAnnotation(html); //忽略注释 html = replaceAnnotation(html); //忽略注释
html = replaceImage(html); //替换图片 html = replaceImage(html); //替换图片
html = replaceStyleQuotes(html); //将style属性中的双引号改为单引号 html = replaceStyleQuotes(html); //将style属性中的双引号改为单引号
html = replaceVideo(html); //替换视频链接 html = replaceVideo(html); //替换视频链接
var stacks = []; var stacks = [];
var results = { var results = {
node: 'root', node: 'root',
children: [] children: []
}; };
HTMLParser(html, { HTMLParser(html, {
start: function start(tag, attrs, unary) { start: function start(tag, attrs, unary) {
var node = { var node = {
name: tag name: tag
}; };
if (attrs.length !== 0) { if (attrs.length !== 0) {
node.attrs = parseAttrs(attrs); node.attrs = parseAttrs(attrs);
} }
if (unary) { if (unary) {
var parent = stacks[0] || results; var parent = stacks[0] || results;
if (!parent.children) { if (!parent.children) {
parent.children = []; parent.children = [];
} }
parent.children.push(node); parent.children.push(node);
} else { } else {
stacks.unshift(node); stacks.unshift(node);
} }
}, },
end: function end(tag) { end: function end(tag) {
var node = stacks.shift(); var node = stacks.shift();
if (node.name !== tag) console.error('invalid state: mismatch end tag'); if (node.name !== tag) console.error('invalid state: mismatch end tag');
if (stacks.length === 0) { if (stacks.length === 0) {
results.children.push(node); results.children.push(node);
} else { } else {
var parent = stacks[0]; var parent = stacks[0];
if (!parent.children) { if (!parent.children) {
parent.children = []; parent.children = [];
} }
parent.children.push(node); parent.children.push(node);
} }
}, },
chars: function chars(text) { chars: function chars(text) {
var node = { var node = {
type: 'text', type: 'text',
text: text text: text
}; };
if (stacks.length === 0) { if (stacks.length === 0) {
results.children.push(node); results.children.push(node);
} else { } else {
var parent = stacks[0]; var parent = stacks[0];
if (!parent.children) { if (!parent.children) {
parent.children = []; parent.children = [];
} }
parent.children.push(node); parent.children.push(node);
} }
}, },
comment: function comment(text) { comment: function comment(text) {
var node = { var node = {
node: 'comment', node: 'comment',
text: text text: text
}; };
var parent = stacks[0]; var parent = stacks[0];
if (!parent.children) { if (!parent.children) {
parent.children = []; parent.children = [];
} }
parent.children.push(node); parent.children.push(node);
} }
}); });
return results.children; return results.children;
} }
export default parseHtml; export default parseHtml;

View File

@@ -1,255 +1,289 @@
import Config from './config.js' import Config from './config.js'
import Util from './util.js' import Util from './util.js'
import store from '@/store/index.js' import store from '@/store/index.js'
import { Utils } from 'common/js/map-wx-jssdk.js';
// #ifdef H5
const app_type = Util.isWeiXin() ? 'wechat' : 'h5'; // #ifdef H5
const app_type_name = Util.isWeiXin() ? '微信公众号' : 'H5'; const app_type = Util.isWeiXin() ? 'wechat' : 'h5';
// #endif const app_type_name = Util.isWeiXin() ? '微信公众号' : 'H5';
// #endif
// #ifdef MP-WEIXIN
const app_type = 'weapp'; // #ifdef MP-WEIXIN
const app_type_name = '微信小程序'; const app_type = 'weapp';
// #endif const app_type_name = '微信小程序';
// #endif
// #ifdef MP-ALIPAY
const app_type = 'aliapp'; // #ifdef MP-ALIPAY
const app_type_name = '支付宝小程序'; const app_type = 'aliapp';
// #endif const app_type_name = '支付宝小程序';
// #endif
// #ifdef MP-BAIDU
const app_type = 'baiduapp'; // #ifdef MP-BAIDU
const app_type_name = '百度小程序'; const app_type = 'baiduapp';
// #endif const app_type_name = '百度小程序';
// #endif
// #ifdef MP-TOUTIAO
const app_type = 'MP-TOUTIAO'; // #ifdef MP-TOUTIAO
const app_type_name = '头条小程序'; const app_type = 'MP-TOUTIAO';
// #endif const app_type_name = '头条小程序';
// #endif
// #ifdef MP-QQ
const app_type = 'MP-QQ'; // #ifdef MP-QQ
const app_type_name = 'QQ小程序'; const app_type = 'MP-QQ';
// #endif const app_type_name = 'QQ小程序';
// #endif
// #ifdef APP-PLUS
const app_type = 'app'; // #ifdef APP-PLUS
const app_type_name = 'APP'; const app_type = 'app';
// #endif const app_type_name = 'APP';
// #endif
export default {
sendRequest(params) { export default {
if (!Config.baseUrl) { sendRequest(params) {
uni.showToast({ if (!Config.baseUrl) {
title: '未配置请求域名', uni.showToast({
'icon': 'none', title: '未配置请求域名',
duration: 10000 'icon': 'none',
}); duration: 10000
return; });
} return;
}
var method = params.data != undefined ? 'POST' : 'GET', // 请求方式
url = Config.baseUrl + params.url, // 请求路径 var method = params.data != undefined ? 'POST' : 'GET', // 请求方式
data = { url = Config.baseUrl + params.url, // 请求路径
app_type, data = {
app_type_name app_type,
}; app_type_name
};
// token
data.token = store.state.token || ''; // token
data.uniacid = Config.uniacid data.token = store.state.token || '';
// 门店id data.uniacid = Config.uniacid
var default_store_info = store.state.defaultStoreInfo; // 门店id
if (default_store_info) { var default_store_info = store.state.defaultStoreInfo;
data.store_id = default_store_info.store_id; if (default_store_info) {
} data.store_id = default_store_info.store_id;
}
var store_info = store.state.globalStoreInfo;
var store_info = store.state.globalStoreInfo;
if (store_info) data.store_id = store_info.store_id;
if (store_info) data.store_id = store_info.store_id;
// 参数
if (params.data != undefined) Object.assign(data, params.data); // 参数
if (params.data != undefined) Object.assign(data, params.data);
if (params.async === false) {
//同步 if (params.async === false) {
return new Promise((resolve, reject) => { //同步
uni.request({ return new Promise((resolve, reject) => {
url: url, uni.request({
method: method, url: url,
data: data, method: method,
header: params.header || { data: data,
// 'Accept': 'application/json', header: params.header || {
'content-type': 'application/x-www-form-urlencoded;application/json' // 'Accept': 'application/json',
}, 'content-type': 'application/x-www-form-urlencoded;application/json'
dataType: params.dataType || 'json', },
responseType: params.responseType || 'text', dataType: params.dataType || 'json',
success: (res) => { responseType: params.responseType || 'text',
// try { success: (res) => {
// res.data = JSON.parse(res.data); // try {
// } catch (e) { // res.data = JSON.parse(res.data);
// //TODO handle the exception // } catch (e) {
// console.log('api error', e); // //TODO handle the exception
// } // console.log('api error', e);
if (res.data.code == -3 && store.state.siteState > 0) { // }
store.commit('setSiteState', -3); if (res.data.code == -3 && store.state.siteState > 0) {
Util.redirectTo('/pages_tool/storeclose/storeclose', {}, 'reLaunch'); store.commit('setSiteState', -3);
return; Util.redirectTo('/pages_tool/storeclose/storeclose', {}, 'reLaunch');
} return;
if (res.data.refreshtoken) { }
store.commit('setToken', res.data.refreshtoken); if (res.data.refreshtoken) {
} store.commit('setToken', res.data.refreshtoken);
if (res.data.code == -10009 || res.data.code == -10010) { }
store.commit('setToken', ''); if (res.data.code == -10009 || res.data.code == -10010) {
store.commit('setMemberInfo', ''); store.commit('setToken', '');
} store.commit('setMemberInfo', '');
resolve(res.data); }
}, resolve(res.data);
fail: (res) => { },
if (res.errMsg && res.errMsg == 'request:fail url not in domain list') { fail: (res) => {
uni.showToast({ if (res.errMsg && res.errMsg == 'request:fail url not in domain list') {
title: Config.baseUrl + '不在request 合法域名列表中', uni.showToast({
'icon': 'none', title: Config.baseUrl + '不在request 合法域名列表中',
duration: 10000 'icon': 'none',
}); duration: 10000
return; });
} return;
reject(res); }
}, reject(res);
complete: (res) => { },
if ((res.errMsg && res.errMsg != "request:ok") || (res.statusCode && [200, 500].indexOf(res.statusCode) == -1)) { complete: (res) => {
uni.showToast({ if ((res.errMsg && res.errMsg != "request:ok") || (res.statusCode && [200, 500].indexOf(res.statusCode) == -1)) {
title: Config.baseUrl + '请求失败', uni.showToast({
'icon': 'none', title: Config.baseUrl + '请求失败',
duration: 10000 'icon': 'none',
}); duration: 10000
return; });
} return;
reject(res.data); }
} reject(res.data);
}); }
}); });
} else { });
//异步 } else {
uni.request({ //异步
url: url, uni.request({
method: method, url: url,
data: data, method: method,
header: params.header || { data: data,
// 'Accept': 'application/json', header: params.header || {
'content-type': 'application/x-www-form-urlencoded;application/json' // 'Accept': 'application/json',
}, 'content-type': 'application/x-www-form-urlencoded;application/json'
dataType: params.dataType || 'json', },
responseType: params.responseType || 'text', dataType: params.dataType || 'json',
success: (res) => { responseType: params.responseType || 'text',
// try { success: (res) => {
// res.data = JSON.parse(res.data); // try {
// } catch (e) { // res.data = JSON.parse(res.data);
// //TODO handle the exception // } catch (e) {
// console.log('api error', e); // //TODO handle the exception
// } // console.log('api error', e);
if (res.data.code == -3 && store.state.siteState > 0) { // }
store.commit('setSiteState', -3); if (res.data.code == -3 && store.state.siteState > 0) {
Util.redirectTo('/pages_tool/storeclose/storeclose', {}, 'reLaunch'); store.commit('setSiteState', -3);
return; Util.redirectTo('/pages_tool/storeclose/storeclose', {}, 'reLaunch');
} return;
if (res.data.refreshtoken) { }
store.commit('setToken', res.data.refreshtoken); if (res.data.refreshtoken) {
} store.commit('setToken', res.data.refreshtoken);
if (res.data.code == -10009 || res.data.code == -10010) { }
store.commit('setToken', ''); if (res.data.code == -10009 || res.data.code == -10010) {
store.commit('setMemberInfo', ''); store.commit('setToken', '');
} store.commit('setMemberInfo', '');
typeof params.success == 'function' && params.success(res.data); }
}, typeof params.success == 'function' && params.success(res.data);
fail: (res) => { },
if (res.errMsg && res.errMsg == 'request:fail url not in domain list') { fail: (res) => {
uni.showToast({ if (res.errMsg && res.errMsg == 'request:fail url not in domain list') {
title: Config.baseUrl + '不在request 合法域名列表中', uni.showToast({
'icon': 'none', title: Config.baseUrl + '不在request 合法域名列表中',
duration: 10000 'icon': 'none',
}); duration: 10000
return; });
} return;
typeof params.fail == 'function' && params.fail(res); }
}, typeof params.fail == 'function' && params.fail(res);
complete: (res) => { },
if ((res.errMsg && res.errMsg != "request:ok") || (res.statusCode && [200, 500].indexOf(res.statusCode) == -1)) { complete: (res) => {
uni.showToast({ if ((res.errMsg && res.errMsg != "request:ok") || (res.statusCode && [200, 500].indexOf(res.statusCode) == -1)) {
title: Config.baseUrl + '请求失败', uni.showToast({
'icon': 'none', title: Config.baseUrl + '请求失败',
duration: 10000 'icon': 'none',
}); duration: 10000
return; });
} return;
typeof params.complete == 'function' && params.complete(res.data); }
} typeof params.complete == 'function' && params.complete(res.data);
}); }
} });
}, }
uploadBase64(params) { },
uni.request({ needMd5Fn(params,callback) {
url: Config.baseUrl + '/api/upload/headimgBase64', uni.request({
method: 'POST', url: Config.baseUrl + '/api/config/getApiConfig',
header: { method: 'POST',
'content-type': 'application/x-www-form-urlencoded;application/json' header: {
}, 'content-type': 'application/x-www-form-urlencoded;application/json'
data: { },
app_type, data: {
app_type_name, app_type,
images: params.base64 app_type_name,
}, },
dataType: 'json', dataType: 'json',
responseType: 'text', responseType: 'text',
success: res => { success: res => {
typeof params.success == 'function' && params.success(res.data); var sign_str = Utils.hexMD5('key=' + res.data.data.key+'&time='+res.data.data.time)
}, typeof callback == 'function' && callback(sign_str,res.data.data.time);
fail: () => { },
typeof params.fail == 'function' && params.fail(res); fail: () => {
} typeof params.fail == 'function' && params.fail(res);
}); }
}, });
pullImage(params) { },
uni.request({ uploadBase64(params) {
url: Config.baseUrl + '/api/upload/headimgPull', this.needMd5Fn(params,(sign_str,time)=>{
method: 'POST', uni.request({
header: { url: Config.baseUrl + '/api/upload/headimgBase64',
'content-type': 'application/x-www-form-urlencoded;application/json' method: 'POST',
}, header: {
data: { 'content-type': 'application/x-www-form-urlencoded;application/json'
app_type, },
app_type_name, data: {
path: params.path app_type,
}, app_type_name,
dataType: 'json', images: params.base64,
responseType: 'text', token: store.state.token || '',
success: res => { sign: sign_str,
typeof params.success == 'function' && params.success(res.data); time: time
}, },
fail: () => { dataType: 'json',
typeof params.fail == 'function' && params.fail(res); responseType: 'text',
} success: res => {
}); typeof params.success == 'function' && params.success(res.data);
}, },
upload(params) { fail: () => {
uni.uploadFile({ typeof params.fail == 'function' && params.fail(res);
url: Config.baseUrl + params.url, }
filePath: params.filePath, });
name: params.name || 'file', })
fileType: params.fileType || 'image', },
formData: { pullImage(params) {
app_type, this.needMd5Fn(params,(sign_str,time)=>{
app_type_name, uni.request({
}, url: Config.baseUrl + '/api/upload/headimgPull',
header: { method: 'POST',
'content-type': 'application/x-www-form-urlencoded;application/json' header: {
}, 'content-type': 'application/x-www-form-urlencoded;application/json'
success: (res) => { },
typeof params.success == 'function' && params.success(JSON.parse(res.data)); data: {
}, app_type,
fail: (res) => { app_type_name,
typeof params.fail == 'function' && params.fail(res); path: params.path,
} token: store.state.token || '',
}); sign: sign_str,
} time: time
},
dataType: 'json',
responseType: 'text',
success: res => {
typeof params.success == 'function' && params.success(res.data);
},
fail: () => {
typeof params.fail == 'function' && params.fail(res);
}
});
})
},
upload(params) {
uni.uploadFile({
url: Config.baseUrl + params.url,
filePath: params.filePath,
name: params.name || 'file',
fileType: params.fileType || 'image',
formData: {
app_type,
app_type_name,
token: store.state.token || ''
},
header: {
'content-type': 'application/x-www-form-urlencoded;application/json'
},
success: (res) => {
typeof params.success == 'function' && params.success(JSON.parse(res.data));
},
fail: (res) => {
typeof params.fail == 'function' && params.fail(res);
}
});
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,107 +1,107 @@
import TransformCoordinate from './transformCoordinate.js' import TransformCoordinate from './transformCoordinate.js'
function openMapByDefault(latitude, longitude, name) { function openMapByDefault(latitude, longitude, name) {
uni.openLocation({ uni.openLocation({
latitude: latitude, latitude: latitude,
longitude: longitude, longitude: longitude,
name: name, name: name,
fail: (e) => { fail: (e) => {
uni.showModal({ uni.showModal({
content: '打开地图失败,请稍后重试' content: '打开地图失败,请稍后重试'
}) })
}, },
}) })
} }
function openMapByAndroid(latitude, longitude, name) { function openMapByAndroid(latitude, longitude, name) {
let url = ''; // 回调地址 let url = ''; // 回调地址
let identity = ''; // 程序名称 let identity = ''; // 程序名称
if (plus.runtime.isApplicationExist({ if (plus.runtime.isApplicationExist({
pname: 'com.baidu.BaiduMap' pname: 'com.baidu.BaiduMap'
})) { })) {
url = url = `baidumap://map/marker?location=${latitude},${longitude}&title=${name}&coord_type=gcj02&src=andr.baidu.openAPIdemo`;
`baidumap://map/marker?location=${latitude},${longitude}&title=${name}&coord_type=gcj02&src=andr.baidu.openAPIdemo` identity = 'com.baidu.BaiduMap';
identity = 'com.baidu.BaiduMap' openURL(url, identity)
openURL(url, identity) } else if (plus.runtime.isApplicationExist({
} else if (plus.runtime.isApplicationExist({ pname: 'com.autonavi.minimap'
pname: 'com.autonavi.minimap' })) {
})) { // 高德 // 高德
url = `androidamap://viewMap?sourceApplication=appname&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0` url = `androidamap://viewMap?sourceApplication=appname&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`;
identity = 'com.autonavi.minimap' identity = 'com.autonavi.minimap';
openURL(url, identity) openURL(url, identity)
} else { } else {
openMapByDefault(latitude, longitude, name) openMapByDefault(latitude, longitude, name)
} }
} }
function openMapByIos(latitude, longitude, name) { function openMapByIos(latitude, longitude, name) {
let url = ''; // 回调地址 let url = ''; // 回调地址
let errorCB = ''; // url失败的回调地址 let errorCB = ''; // url失败的回调地址
let identity = ''; // 程序名称 let identity = ''; // 程序名称
if (plus.runtime.isApplicationExist({ if (plus.runtime.isApplicationExist({
action: 'baidumap://' action: 'baidumap://'
})) { })) {
url = url = `baidumap://map/marker?location=${latitude},${longitude}&title=${name}&content=${name}&src=ios.baidu.openAPIdemo&coord_type=gcj02`;
`baidumap://map/marker?location=${latitude},${longitude}&title=${name}&content=${name}&src=ios.baidu.openAPIdemo&coord_type=gcj02`; openURL(url, identity)
openURL(url, identity) } else if (plus.runtime.isApplicationExist({
} else if (plus.runtime.isApplicationExist({ action: 'iosamap://'
action: 'iosamap://' })) {
})) { // 高德 // 高德
url = `iosamap://viewMap?sourceApplication=applicationName&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0` url = `iosamap://viewMap?sourceApplication=applicationName&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`;
openURL(url, identity) openURL(url, identity)
} else { } else {
openMapByDefault(latitude, longitude, name) openMapByDefault(latitude, longitude, name)
} }
} }
function openURL(url, identity) { function openURL(url, identity) {
let newurl = encodeURI(url); let newurl = encodeURI(url);
plus.runtime.openURL(newurl, function(res) { plus.runtime.openURL(newurl, function(res) {
uni.showModal({ uni.showModal({
content: res.message content: res.message
}) })
}, identity); }, identity);
} }
function getCoordByType(longitude, latitude, coord_type) { function getCoordByType(longitude, latitude, coord_type) {
switch (coord_type) { switch (coord_type) {
case 'gcj02': case 'gcj02':
return [longitude, latitude] return [longitude, latitude]
break; break;
case 'bd09': case 'bd09':
return TransformCoordinate.bd09togcj02(longitude, latitude) return TransformCoordinate.bd09togcj02(longitude, latitude)
break; break;
case 'wgs84': case 'wgs84':
return TransformCoordinate.wgs84togcj02(longitude, latitude) return TransformCoordinate.wgs84togcj02(longitude, latitude)
break; break;
default: default:
return [longitude, latitude] return [longitude, latitude]
break; break;
} }
} }
export default { export default {
/* 打开地图 */ /* 打开地图 */
openMap(latitude, longitude, name, coord_type = 'gcj02') { openMap(latitude, longitude, name, coord_type = 'gcj02') {
let arr = getCoordByType(longitude, latitude, coord_type) let arr = getCoordByType(longitude, latitude, coord_type)
// #ifdef APP-PLUS // #ifdef APP-PLUS
switch (uni.getSystemInfoSync().platform) { switch (uni.getSystemInfoSync().platform) {
case 'android': case 'android':
console.log('运行Android上') console.log('运行Android上')
openMapByAndroid(arr[1], arr[0], name) openMapByAndroid(arr[1], arr[0], name)
break; break;
case 'ios': case 'ios':
console.log('运行iOS上') console.log('运行iOS上')
openMapByIos(arr[1], arr[0], name) openMapByIos(arr[1], arr[0], name)
break; break;
default: default:
openMapByDefault(arr[1], arr[0], name) openMapByDefault(arr[1], arr[0], name)
console.log('运行在开发者工具上') console.log('运行在开发者工具上')
break; break;
} }
// #endif // #endif
// #ifndef APP-PLUS // #ifndef APP-PLUS
openMapByDefault(arr[1], arr[0], name) openMapByDefault(arr[1], arr[0], name)
// #endif // #endif
} }
} }

View File

@@ -1,207 +1,215 @@
import config from './config.js' import config from './config.js'
export default { export default {
data() { data() {
return { return {
timeoutObj: null, //ping定时器 timeoutObj: null, //ping定时器
servicer_id: null, //绑定 servicer_id: null, //绑定
pingInterval: config.pingInterval //本地端主动给服务器ping的时间, 0 则不开启 pingInterval: config.pingInterval //本地端主动给服务器ping的时间, 0 则不开启
} }
}, },
onLoad() { onLoad() {
let that = this; let that = this;
// 因为图片上传所以不能onhide关闭长链接但是每次打开客服都会有重复请求所以优先关闭再去打开长链接 // 因为图片上传所以不能onhide关闭长链接但是每次打开客服都会有重复请求所以优先关闭再去打开长链接
uni.closeSocket(); uni.closeSocket();
// .判断是否已连接 // .判断是否已连接
that.checkOpenSocket(); that.checkOpenSocket();
// uni.onSocketClose(function(res) { // uni.onSocketClose(function(res) {
// console.log('WebSocket 已关闭!'); // console.log('WebSocket 已关闭!');
// }); // });
}, },
methods: { methods: {
// 判断是否已连接 // 判断是否已连接
checkOpenSocket() { checkOpenSocket() {
console.log('判断是否已连接'); console.log('判断是否已连接');
// alert('判断是否已连接') // alert('判断是否已连接')
let self = this; let self = this;
uni.sendSocketMessage({ uni.sendSocketMessage({
data: 'ping', data: 'ping',
success: (res) => { success: (res) => {
console.log('连接成功,检查'); console.log('连接成功,检查');
// alert('连接成功,检查') // alert('连接成功,检查')
// self.getChatList(); // self.getChatList();
}, },
fail: (err) => { // 未连接打开websocket连接 fail: (err) => { // 未连接打开websocket连接
console.log('连接失败'); console.log('连接失败');
// alert('连接失败') // alert('连接失败')
self.openConnection(); self.openConnection();
} }
}); });
}, },
openConnection() { // 打开连接 openConnection() { // 打开连接
console.log('打开连接'); console.log('打开连接');
// alert('打开连接') // alert('打开连接')
// uni.closeSocket(); // 确保已经关闭后再重新打开 // uni.closeSocket(); // 确保已经关闭后再重新打开
uni.connectSocket({
url: config.webSocket, uni.connectSocket({
method: 'POST', url: config.webSocket,
success(res) { method: 'POST',
console.log('连接成功 connectSocket=', res); success(res) {
// alert('连接成功 connectSocket=', res); console.log('连接成功 connectSocket=', res);
}, // alert('连接成功 connectSocket=', res);
fail(err) { },
console.log('连接失败 connectSocket=', err); fail(err) {
} console.log('连接失败 connectSocket=', err);
}); }
// uni.onSocketOpen((res) => { });
// console.log('连接成功', res); // 监听 WebSocket 连接错误事件
// }); uni.onSocketError((res)=>{
this.onSocketMessage(); // 打开成功监听服务器返回的消息 console.error('WebSocket 连接失败:', res.errMsg);
}, this.chatListInit();
// 打开成功监听服务器返回的消息 this.getChatList();
onSocketMessage() { // 消息 });
console.log("开始监听"); // uni.onSocketOpen((res) => {
// console.log('连接成功', res);
let that = this; // });
this.pingInterval = config.pingInterval; this.onSocketMessage(); // 打开成功监听服务器返回的消息
this.timeoutObj = null; },
uni.onSocketMessage((res) => { //type:init,connect,close,string,order,goods // 打开成功监听服务器返回的消息
let msg = JSON.parse(res.data); onSocketMessage() { // 消息
console.log("监听该服务器消息", res); console.log("开始监听");
if (msg.type == 'close') {
clearInterval(that.timeoutObj); let that = this;
that.timeoutObj = null; this.pingInterval = config.pingInterval;
uni.closeSocket(); if(this.timeoutObj) clearInterval(this.timeoutObj);
return; this.timeoutObj = null;
} uni.onSocketMessage((res) => { //type:init,connect,close,string,order,goods
this.reset(); let msg = JSON.parse(res.data);
this.getSocketMsg(res.data); // 监听到有新服务器消息 console.log("监听该服务器消息", res);
}); if (msg.type == 'close') {
}, clearInterval(that.timeoutObj);
// 监听到有新服务器消息 that.timeoutObj = null;
getSocketMsg(reData) { // 监听到服务器消息 uni.closeSocket();
let that = this; return;
// console.log(reData) }
let giveMsg = JSON.parse(reData); this.reset();
let data = { this.getSocketMsg(res.data); // 监听到有新服务器消息
isItMe: false, });
}; },
data.contentType = giveMsg.type; // 监听到有新服务器消息
// alert(data.contentType) getSocketMsg(reData) { // 监听到服务器消息
if (giveMsg.type == 'init') { let that = this;
// alert(123) let giveMsg = JSON.parse(reData);
that.$api.sendRequest({ let data = {
url: '/servicer/api/chat/bind', isItMe: false,
data: { };
client_id: giveMsg.data.client_id, data.contentType = giveMsg.type;
site_id: that.siteId // alert(data.contentType)
}, if (giveMsg.type == 'init') {
success(res) { // alert(123)
if (res.code == 0) { that.$api.sendRequest({
that.servicer_id = res.data.servicer_id; url: '/servicer/api/chat/bind',
} else { data: {
that.servicer_id = 0; client_id: giveMsg.data.client_id,
} site_id: that.siteId
that.getChatList(); },
} success(res) {
}) if (res.code == 0) {
} else if (giveMsg.type == 'connect') { that.servicer_id = res.data.servicer_id;
// that.servicer_id = giveMsg.data.servicer_id; } else {
// let NewArr = that.messageList; that.servicer_id = 0;
// let index = null; }
// for (let i = 0; i < NewArr.length; i++) { that.chatListInit();
// if (NewArr[i].contentType == 'online' || NewArr[i].contentType == 'noline') { that.getChatList();
// index = i; }
// } })
// } } else if (giveMsg.type == 'connect') {
// NewArr.splice(index, 1) // that.servicer_id = giveMsg.data.servicer_id;
// that.messageList = NewArr; // let NewArr = that.messageList;
// let obj = {} // let index = null;
// if (that.servicer_id > 0) { // for (let i = 0; i < NewArr.length; i++) {
// obj.contentType = 'online'; // if (NewArr[i].contentType == 'online' || NewArr[i].contentType == 'noline') {
// } else if (that.servicer_id == 0) { // index = i;
// obj.contentType = 'noline'; // }
// } // }
// that.messageList.push(obj); // NewArr.splice(index, 1)
return false; // that.messageList = NewArr;
} else if (giveMsg.type == 'string') { // let obj = {}
data.content = giveMsg.data.servicer_say; // if (that.servicer_id > 0) {
} else if (giveMsg.type == 'image') { // obj.contentType = 'online';
data.image = giveMsg.data.servicer_say; // } else if (that.servicer_id == 0) {
} else if (giveMsg.type == 'order') { // obj.contentType = 'noline';
data.order_id = giveMsg.data.order_id; // }
} else if (giveMsg.type == 'goodssku') { // that.messageList.push(obj);
data.sku_id = giveMsg.data.goods_sku_id; return false;
} } else if (giveMsg.type == 'string') {
if (giveMsg.type == 'init') return; data.content = giveMsg.data.servicer_say;
that.messageList.push(data); } else if (giveMsg.type == 'image') {
that.$nextTick(() => { data.image = giveMsg.data.servicer_say;
that.setPageScrollTo() } else if (giveMsg.type == 'order') {
}) data.order_id = giveMsg.data.order_id;
}, } else if (giveMsg.type == 'goodssku') {
// 检测心跳reset data.sku_id = giveMsg.data.goods_sku_id;
reset() { }
console.log("检测心跳"); if (giveMsg.type == 'init') return;
clearInterval(this.timeoutObj); that.messageList.push(data);
this.start(); // 启动心跳 that.$nextTick(() => {
}, that.setPageScrollTo()
// 启动心跳 start })
start() { },
console.log("启动心跳"); // 检测心跳reset
let self = this; reset() {
this.timeoutObj = setInterval(function () { console.log("检测心跳");
uni.sendSocketMessage({ clearInterval(this.timeoutObj);
data: 'ping', this.start(); // 启动心跳
success: (res) => { },
console.log('连接中....'); // 启动心跳 start
}, start() {
fail: (err) => { console.log("启动心跳");
console.log('连接失败重新连接....'); let self = this;
self.openConnection(); this.timeoutObj = setInterval(function () {
} uni.sendSocketMessage({
}); data: 'ping',
}, this.pingInterval); success: (res) => {
} console.log('连接中....');
}, },
// onHide() { fail: (err) => {
// // alert("关闭") console.log('连接失败重新连接....');
// // 改之前的 self.openConnection();
// // console.log("我出发了") }
// // this.checkOpenSocket(); });
// clearInterval(this.timeoutObj); }, this.pingInterval);
// this.timeoutObj = null; }
// this.$api.sendRequest({ },
// url: '/servicer/api/chat/bye', // onHide() {
// data: { // // alert("关闭")
// servicer_id: this.servicer_id, // // 改之前的
// site_id: this.siteId // // console.log("我出发了")
// }, // // this.checkOpenSocket();
// success(res) { // clearInterval(this.timeoutObj);
// uni.closeSocket(); // this.timeoutObj = null;
// }, // this.$api.sendRequest({
// fail: (err) => { // url: '/servicer/api/chat/bye',
// uni.closeSocket(); // data: {
// } // servicer_id: this.servicer_id,
// }); // site_id: this.siteId
// }, // },
onUnload() { // success(res) {
// alert("关闭") // uni.closeSocket();
clearInterval(this.timeoutObj); // },
this.timeoutObj = null; // fail: (err) => {
this.$api.sendRequest({ // uni.closeSocket();
url: '/servicer/api/chat/bye', // }
data: { // });
servicer_id: this.servicer_id, // },
site_id: this.siteId onUnload() {
}, // alert("关闭")
success(res) { clearInterval(this.timeoutObj);
// alert("关闭1") this.timeoutObj = null;
uni.closeSocket(); this.$api.sendRequest({
}, url: '/servicer/api/chat/bye',
fail: (err) => { data: {
// alert("关闭2") servicer_id: this.servicer_id,
uni.closeSocket(); site_id: this.siteId
} },
}); success(res) {
} // alert("关闭1")
} uni.closeSocket();
},
fail: (err) => {
// alert("关闭2")
uni.closeSocket();
}
});
}
}

View File

@@ -8,15 +8,15 @@ import {
export default { export default {
/** /**
* 页面跳转 * 页面跳转
* @param {string} to 跳转链接 /pages/idnex/index * @param {string} to 跳转链接 /pages/index/index
* @param {Object} param 参数 {key : value, ...} * @param {Object} param 参数 {key : value, ...}
* @param {string} mode 模式 * @param {string} mode 模式
*/ */
redirectTo(to, param, mode) { redirectTo(to, param, mode) {
let url = to; let url = to;
let tabbarList = ['/pages/index/index', '/pages/goods/category', '/pages/vr/index', '/pages/contact/contact', '/pages/member/index']; let tabbarList = ['/pages/index/index', '/pages/goods/category', '/pages/goods/cart', '/pages/member/index'];
if (param != undefined) { if (param != undefined) {
Object.keys(param).forEach(function (key) { Object.keys(param).forEach(function(key) {
if (url.indexOf('?') != -1) { if (url.indexOf('?') != -1) {
url += "&" + key + "=" + param[key]; url += "&" + key + "=" + param[key];
} else { } else {
@@ -26,6 +26,8 @@ export default {
} }
for (let i = 0; i < tabbarList.length; i++) { for (let i = 0; i < tabbarList.length; i++) {
if (url.indexOf(tabbarList[i]) == 0) { if (url.indexOf(tabbarList[i]) == 0) {
if(url.split('?')[1]) uni.setStorageSync('tabBarParams',url.split('?')[1]);
else uni.removeStorageSync('tabBarParams')
uni.switchTab({ uni.switchTab({
url url
}); });
@@ -64,8 +66,6 @@ export default {
* @param {Object} params 参数针对商品、相册里面的图片区分大中小size: big、mid、small * @param {Object} params 参数针对商品、相册里面的图片区分大中小size: big、mid、small
*/ */
img(img_path, params) { img(img_path, params) {
var path = ""; var path = "";
if (img_path != undefined && img_path != "") { if (img_path != undefined && img_path != "") {
if (img_path.split(',').length > 1) { if (img_path.split(',').length > 1) {
@@ -78,19 +78,17 @@ export default {
arr.pop(); arr.pop();
arr[arr.length - 1] = arr[arr.length - 1] + "_" + params.size.toUpperCase(); arr[arr.length - 1] = arr[arr.length - 1] + "_" + params.size.toUpperCase();
arr.push(suffix); arr.push(suffix);
// if(img_path.indexOf('attachment') == -1){ img_path = arr.join(".");
// img_path = arr.join(".");
// }
} }
if (img_path.indexOf("http://") == -1 && img_path.indexOf("https://") == -1) { if (img_path.indexOf("http://") == -1 && img_path.indexOf("https://") == -1) {
path = Config.imgDomain + "/" + img_path; path = Config.imgDomain + "/" + img_path;
} else { } else {
// console.log(img_path)
path = img_path; path = img_path;
} }
if (Config.h5Domain.indexOf('https://') != -1) {
path = path.replace('http://', 'https://');
}
} }
// path += '?t=' + parseInt(new Date().getTime() / 1000); // path += '?t=' + parseInt(new Date().getTime() / 1000);
return path; return path;
}, },
@@ -98,7 +96,7 @@ export default {
* 时间戳转日期格式 * 时间戳转日期格式
* @param {Object} timeStamp * @param {Object} timeStamp
*/ */
timeStampTurnTime(timeStamp, type = "") { timeStampTurnTime(timeStamp, format = "Y-m-d H:i:s") {
if (timeStamp != undefined && timeStamp != "" && timeStamp > 0) { if (timeStamp != undefined && timeStamp != "" && timeStamp > 0) {
var date = new Date(); var date = new Date();
date.setTime(timeStamp * 1000); date.setTime(timeStamp * 1000);
@@ -113,14 +111,15 @@ export default {
var second = date.getSeconds(); var second = date.getSeconds();
minute = minute < 10 ? ('0' + minute) : minute; minute = minute < 10 ? ('0' + minute) : minute;
second = second < 10 ? ('0' + second) : second; second = second < 10 ? ('0' + second) : second;
if (type) {
if (type == 'yearMonthDay') { format = format.replace('Y', y);
return y + '年' + m + '' + d + '日'; format = format.replace('m', m);
} format = format.replace('d', d);
return y + '-' + m + '-' + d; format = format.replace('H', h);
} else { format = format.replace('i', minute);
return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second; format = format.replace('s', second);
}
return format;
} else { } else {
return ""; return "";
} }
@@ -187,19 +186,19 @@ export default {
* @param {Object} elem * @param {Object} elem
* @param {Object} arr * @param {Object} arr
*/ */
inArray: function (elem, arr) { inArray: function(elem, arr) {
return arr == null ? -1 : arr.indexOf(elem); return arr == null ? -1 : arr.indexOf(elem);
}, },
/** /**
* 获取某天日期 * 获取某天日期
* @param {Object} day * @param {Object} day
*/ */
getDay: function (day) { getDay: function(day) {
var today = new Date(); var today = new Date();
var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day; var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day;
today.setTime(targetday_milliseconds); today.setTime(targetday_milliseconds);
const doHandleMonth = function (month) { const doHandleMonth = function(month) {
var m = month; var m = month;
if (month.toString().length == 1) { if (month.toString().length == 1) {
m = "0" + month; m = "0" + month;
@@ -231,7 +230,7 @@ export default {
* @param callback * @param callback
* @param url * @param url
*/ */
upload: function (num, params, callback, url) { upload: function(num, params, callback, url) {
// #ifdef H5 // #ifdef H5
var app_type = this.isWeiXin() ? 'wechat' : 'h5'; var app_type = this.isWeiXin() ? 'wechat' : 'h5';
var app_type_name = this.isWeiXin() ? '微信公众号' : 'H5'; var app_type_name = this.isWeiXin() ? '微信公众号' : 'H5';
@@ -275,7 +274,7 @@ export default {
count: imgs_num, count: imgs_num,
sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有 sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], //从相册或者拍照 sourceType: ['album', 'camera'], //从相册或者拍照
success: async function (res) { success: async (res) => {
const tempFilePaths = res.tempFilePaths; const tempFilePaths = res.tempFilePaths;
var _data = data; var _data = data;
var imgs = []; var imgs = [];
@@ -283,9 +282,16 @@ export default {
title: '图片上传中' title: '图片上传中'
}) })
for (var i = 0; i < tempFilePaths.length; i++) { for (var i = 0; i < tempFilePaths.length; i++) {
var path = await _self.upload_file_server(tempFilePaths[i], _data, params.path, try {
url); var path = await _self.upload_file_server(tempFilePaths[i], _data, params.path,
imgs.push(path); url);
imgs.push(path);
} catch (e) {
this.showToast({
title: e,
});
break;
}
if (imgs.length == tempFilePaths.length) { if (imgs.length == tempFilePaths.length) {
uni.hideLoading() uni.hideLoading()
uni.showToast({ uni.showToast({
@@ -297,11 +303,12 @@ export default {
} }
}, },
fail: err => { fail: err => {
uni.hideLoading() if (err.errMsg != 'chooseImage:fail cancel') {
uni.showToast({ uni.showToast({
title: '上传失败', title: '上传失败',
icon: 'none' icon: 'none'
}) })
}
} }
}); });
}, },
@@ -319,13 +326,25 @@ export default {
name: 'file', name: 'file',
fileType: data.fileType || 'image', fileType: data.fileType || 'image',
formData: data, formData: data,
success: function (res) { success: (res) => {
var path_str = JSON.parse(res.data); var path_str = JSON.parse(res.data);
if (path_str.code >= 0) { if (path_str.code >= 0) {
resolve(path_str.data.pic_path); resolve(path_str.data.pic_path);
typeof callback == 'function' && callback(path_str.data.pic_path);
} else { } else {
reject("error"); reject(path_str.message);
}
uni.hideLoading();
},
fail: (res) => {
if (res.statusCode != 200) {
reject(res.errMsg || '上传错误');
uni.hideLoading();
}
},
complete: (res) => {
if (res.statusCode != 200) {
reject('服务器发生错误');
uni.hideLoading();
} }
} }
}); });
@@ -395,7 +414,7 @@ export default {
* 检测苹果X以上的手机 * 检测苹果X以上的手机
*/ */
isIPhoneX() { isIPhoneX() {
let res = uni.getSystemInfoSync(); let res = uni.getDeviceInfo();
if (res.model.search('iPhone X') != -1) { if (res.model.search('iPhone X') != -1) {
return true; return true;
} }
@@ -403,7 +422,7 @@ export default {
}, },
//判断安卓还是iOS //判断安卓还是iOS
isAndroid() { isAndroid() {
let platform = uni.getSystemInfoSync().platform let platform = uni.getDeviceInfo().platform
if (platform == 'ios') { if (platform == 'ios') {
return false; return false;
} else if (platform == 'android') { } else if (platform == 'android') {
@@ -415,7 +434,7 @@ export default {
* @param {Object} obj * @param {Object} obj
*/ */
deepClone(obj) { deepClone(obj) {
const isObject = function (obj) { const isObject = function(obj) {
return typeof obj == 'object'; return typeof obj == 'object';
} }
@@ -431,7 +450,6 @@ export default {
} }
return cloneObj return cloneObj
}, },
/** /**
* 打开微信企业客服 * 打开微信企业客服
* @param {Function} fallbackFunc 降级处理函数 * @param {Function} fallbackFunc 降级处理函数
@@ -464,11 +482,11 @@ export default {
* @param {Object} link * @param {Object} link
*/ */
diyRedirectTo(link) { diyRedirectTo(link) {
if (link == null || Object.keys(link).length == 1) return;
//if (link == null || Object.keys(link).length == 1) return;
// 外部链接 // 外部链接
if (link.wap_url && link.wap_url.indexOf('http') != -1 || link.wap_url && link.wap_url.indexOf('http') != -1) { if (link.wap_url && link.wap_url.indexOf('http') != -1 || link.wap_url && link.wap_url.indexOf('https') != -1) {
// #ifdef H5 // #ifdef H5
window.location.href = link.wap_url; window.location.href = link.wap_url;
// #endif // #endif
@@ -492,10 +510,8 @@ export default {
uni.makePhoneCall({ uni.makePhoneCall({
phoneNumber: link.mobile, phoneNumber: link.mobile,
success: (res) => { success: (res) => {},
}, fail: (res) => {}
fail: (res) => {
}
}); });
} else if (link.name == 'MEMBER_CONTACT') { } else if (link.name == 'MEMBER_CONTACT') {
@@ -585,9 +601,12 @@ export default {
*/ */
uniappIsIPhoneX() { uniappIsIPhoneX() {
let isIphoneX = false; let isIphoneX = false;
let systemInfo = uni.getSystemInfoSync(); let deviceInfo = uni.getDeviceInfo();
let windowInfo = uni.getWindowInfo();
// #ifdef MP // #ifdef MP
if (systemInfo.model.search('iPhone X') != -1 || systemInfo.model.search('iPhone 11') != -1 || systemInfo.model.search('iPhone 12') != -1 || systemInfo.model.search('iPhone 13') != -1) { if (deviceInfo.model.search('iPhone X') != -1 || deviceInfo.model.search('iPhone 11') != -1 || deviceInfo.model
.search('iPhone 12') != -1 || deviceInfo.model.search('iPhone 13') != -1 || parseInt(deviceInfo.model.split(
'iPhone')[1]) > 13) {
isIphoneX = true; isIphoneX = true;
} }
// #endif // #endif
@@ -596,11 +615,11 @@ export default {
var u = navigator.userAgent; var u = navigator.userAgent;
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if (isIOS) { if (isIOS) {
if (systemInfo.screenWidth == 375 && systemInfo.screenHeight == 812 && systemInfo.pixelRatio == 3) { if (windowInfo.screenWidth == 375 && windowInfo.screenHeight == 812 && deviceInfo.pixelRatio == 3) {
isIphoneX = true; isIphoneX = true;
} else if (systemInfo.screenWidth == 414 && systemInfo.screenHeight == 896 && systemInfo.pixelRatio == 3) { } else if (windowInfo.screenWidth == 414 && windowInfo.screenHeight == 896 && deviceInfo.pixelRatio == 3) {
isIphoneX = true; isIphoneX = true;
} else if (systemInfo.screenWidth == 414 && systemInfo.screenHeight == 896 && systemInfo.pixelRatio == 2) { } else if (windowInfo.screenWidth == 414 && windowInfo.screenHeight == 896 && deviceInfo.pixelRatio == 2) {
isIphoneX = true; isIphoneX = true;
} }
} }
@@ -612,9 +631,9 @@ export default {
*/ */
uniappIsIPhone11() { uniappIsIPhone11() {
let isIphone11 = false; let isIphone11 = false;
let systemInfo = uni.getSystemInfoSync(); let deviceInfo = uni.getDeviceInfo();
// #ifdef MP // #ifdef MP
if (systemInfo.model.search('iPhone 11') != -1) { if (deviceInfo.model.search('iPhone 11') != -1) {
isIphone11 = true; isIphone11 = true;
} }
// #endif // #endif
@@ -623,7 +642,6 @@ export default {
// #ifdef H5 // #ifdef H5
//判断该浏览器是否为safaria浏览器 //判断该浏览器是否为safaria浏览器
isSafari() { isSafari() {
let res = uni.getSystemInfoSync();
var ua = navigator.userAgent.toLowerCase(); var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf('applewebkit') > -1 && ua.indexOf('mobile') > -1 && ua.indexOf('safari') > -1 && if (ua.indexOf('applewebkit') > -1 && ua.indexOf('mobile') > -1 && ua.indexOf('safari') > -1 &&
ua.indexOf('linux') === -1 && ua.indexOf('android') === -1 && ua.indexOf('chrome') === -1 && ua.indexOf('linux') === -1 && ua.indexOf('android') === -1 && ua.indexOf('chrome') === -1 &&
@@ -670,7 +688,6 @@ export default {
} }
}, },
/** /**
*
* @param val 转化时间字符串 (转化时分秒) * @param val 转化时间字符串 (转化时分秒)
* @returns {string} * @returns {string}
*/ */
@@ -689,7 +706,7 @@ export default {
* 获取定位信息 * 获取定位信息
*/ */
getLocation(param = {}) { getLocation(param = {}) {
/*uni.getLocation({ uni.getLocation({
type: param.type ?? 'gcj02', type: param.type ?? 'gcj02',
success: res => { success: res => {
store.commit('setLocation', res); store.commit('setLocation', res);
@@ -701,7 +718,7 @@ export default {
complete: res => { complete: res => {
typeof param.complete == 'function' && param.complete(res); typeof param.complete == 'function' && param.complete(res);
} }
});*/ });
}, },
// 计算两个经纬度之间的距离 // 计算两个经纬度之间的距离
getDistance(lat1, lng1, lat2, lng2) { getDistance(lat1, lng1, lat2, lng2) {
@@ -709,8 +726,8 @@ export default {
var radLat2 = lat2 * Math.PI / 180.0; var radLat2 = lat2 * Math.PI / 180.0;
var a = radLat1 - radLat2; var a = radLat1 - radLat2;
var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0; var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(
Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))); Math.sin(b / 2), 2)));
s = s * 6378.137; // EARTH_RADIUS; s = s * 6378.137; // EARTH_RADIUS;
s = Math.round(s * 10000) / 10000; s = Math.round(s * 10000) / 10000;
return s; return s;
@@ -737,7 +754,7 @@ export default {
/** /**
* 微信订阅消息 * 微信订阅消息
*/ */
subscribeMessage(keywords) { subscribeMessage(keywords, callback) {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
let url = '/weapp/api/weapp/messagetmplids'; let url = '/weapp/api/weapp/messagetmplids';
// #endif // #endif
@@ -759,6 +776,9 @@ export default {
}, },
fail: (res) => { fail: (res) => {
console.log('fail', res) console.log('fail', res)
},
complete: (res) => {
typeof callback == 'function' && callback();
} }
}) })
// #endif // #endif
@@ -771,10 +791,18 @@ export default {
}, },
fail: res => { fail: res => {
console.log('fail', res) console.log('fail', res)
},
complete: (res) => {
typeof callback == 'function' && callback();
} }
}); });
// #endif // #endif
} else {
typeof callback == 'function' && callback();
} }
},
fail: res => {
typeof callback == 'function' && callback();
} }
}) })
}, },
@@ -807,10 +835,8 @@ export default {
title: shareConfig.title, title: shareConfig.title,
path: shareConfig.path, path: shareConfig.path,
imageUrl: shareConfig.imageUrl, imageUrl: shareConfig.imageUrl,
success: res => { success: res => {},
}, fail: res => {}
fail: res => {
}
} }
//分享到朋友圈 //分享到朋友圈
let query = ''; let query = '';
@@ -846,8 +872,7 @@ export default {
Http.sendRequest({ Http.sendRequest({
url: '/wechat/api/wechat/jssdkconfig', url: '/wechat/api/wechat/jssdkconfig',
data: { data: {
url: uni.getSystemInfoSync().platform == 'ios' ? uni.getStorageSync('initUrl') : window.location url: uni.getDeviceInfo().platform == 'ios' ? uni.getStorageSync('initUrl') : window.location.href
.href
}, },
success: res => { success: res => {
if (res.code == 0) { if (res.code == 0) {
@@ -870,7 +895,7 @@ export default {
//获取当前路由 //获取当前路由
getCurrentRoute() { getCurrentRoute() {
let currentRoutes = getCurrentPages(); // 获取当前打开过的页面路由数组 let currentRoutes = getCurrentPages(); // 获取当前打开过的页面路由数组
let currentRoute = currentRoutes[currentRoutes.length - 1].route //获取当前页面路由 let currentRoute = currentRoutes[currentRoutes.length - 1].route; //获取当前页面路由
let currentParam = currentRoutes[currentRoutes.length - 1].options; //获取路由参数 let currentParam = currentRoutes[currentRoutes.length - 1].options; //获取路由参数
// 拼接参数 // 拼接参数
let param = []; let param = [];
@@ -950,12 +975,10 @@ export default {
var points_D = []; var points_D = [];
var points_E = []; var points_E = [];
const DIST_AB = Math.sqrt(Math.pow(points[1]['x'] - points[0]['x'], 2) + Math.pow(points[1]['y'] - points[0][ const DIST_AB = Math.sqrt(Math.pow(points[1]['x'] - points[0]['x'], 2) + Math.pow(points[1]['y'] - points[0][
'y' 'y'], 2));
], 2));
// 邻控制BC点间距 // 邻控制BC点间距
const DIST_BC = Math.sqrt(Math.pow(points[2]['x'] - points[1]['x'], 2) + Math.pow(points[2]['y'] - points[1][ const DIST_BC = Math.sqrt(Math.pow(points[2]['x'] - points[1]['x'], 2) + Math.pow(points[2]['y'] - points[1][
'y' 'y'], 2));
], 2));
// D每次在AB方向上移动的距离 // D每次在AB方向上移动的距离
if (points[0]['x'] > points[2]['x']) { if (points[0]['x'] > points[2]['x']) {
var EACH_MOVE_AD = -(DIST_AB / times); var EACH_MOVE_AD = -(DIST_AB / times);
@@ -1017,5 +1040,157 @@ export default {
verifyMobile(mobile) { verifyMobile(mobile) {
var parse = /^\d{11}$/.test(mobile); var parse = /^\d{11}$/.test(mobile);
return parse; return parse;
},
// 获取缓存key
getStorageKey(key) {
return Config.storagePrefix + key;
},
// 重写uni缓存方法
rewriteUniStorageMethod() {
const setStorageSync = uni.setStorageSync;
const setStorage = uni.setStorage;
const getStorage = uni.getStorage;
const getStorageSync = uni.getStorageSync;
const removeStorage = uni.removeStorage;
const removeStorageSync = uni.removeStorageSync;
uni.setStorage = (options) => {
options.key = this.getStorageKey(options.key);
setStorage(options)
};
uni.setStorageSync = (key, data) => {
setStorageSync(this.getStorageKey(key), data)
};
uni.getStorage = (options) => {
options.key = this.getStorageKey(options.key);
getStorage(options)
};
uni.getStorageSync = (key) => {
return getStorageSync(this.getStorageKey(key))
};
uni.removeStorage = (options) => {
options.key = this.getStorageKey(options.key);
removeStorage(options)
};
uni.removeStorageSync = (key) => {
return removeStorageSync(this.getStorageKey(key))
}
},
//生成唯一id
generateUUID() {
var d = new Date().getTime(); //Timestamp
var d2 = (performance && performance.now && (performance.now() * 1000)) ||
0; //Time in microseconds since page-load or 0 if unsupported
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16; //random number between 0 and 16
if (d > 0) { //Use timestamp until depleted
r = (d + r) % 16 | 0;
d = Math.floor(d / 16);
} else { //Use microseconds since page-load if supported
r = (d2 + r) % 16 | 0;
d2 = Math.floor(d2 / 16);
}
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
},
// 获取弹新人礼弹框页面
openRegisterRewardPath(back) {
return uni.getStorageSync('initiateLogin') || back;
},
// 登录完成后返回页面
loginComplete(back, mode) {
let url = uni.getStorageSync('initiateLogin') || back;
uni.removeStorageSync('initiateLogin')
let jump = true;
let arr = getCurrentPages().reverse();
for (let i = 0; i < arr.length; i++) {
if (url.indexOf(arr[i].route) != -1) {
jump = false;
uni.navigateBack({
delta: i
});
break;
}
}
if (jump) {
this.redirectTo(url, {}, 'redirectTo')
}
},
// 微信提现收款
merchantTransfer(data,withdrawInfo,callback) {
Http.sendRequest({
url: '/wechatpay/api/transfer/transfer',
data: data,
success: res => {
if (res.code == 0) {
uni.hideLoading();
// #ifdef MP-WEIXIN
if (wx.canIUse('requestMerchantTransfer')) {
wx.requestMerchantTransfer({
mchId: withdrawInfo.mch_id,
appId: withdrawInfo.app_id,
package: res.data.package_info,
success: (res) => {
typeof callback == 'function' && callback(res);
},
fail: (res) => {
typeof callback == 'function' && callback(res);
},
});
} else {
wx.showModal({
content: '你的微信版本过低,请更新至最新版本。',
showCancel: false,
});
}
// #endif
// #ifdef H5
if (this.isWeiXin()) {
if (uni.getDeviceInfo().platform == 'ios') {
var url = uni.getStorageSync('initUrl');
} else {
var url = location.href;
}
// 获取jssdk配置
Http.sendRequest({
url: '/wechat/api/wechat/jssdkconfig',
data: {
url: url
},
success: jssdkRes => {
var wxJS = new Weixin();
wxJS.init(jssdkRes.data);
wxJS.withdrawWechat({
mch_id: withdrawInfo.mch_id,
wechat_appid: withdrawInfo.app_id,
package_info: res.data.package_info
},
res => {
typeof callback == 'function' && callback(res);
},
);
}
})
}
// #endif
} else {
this.showToast({
title: res.message,
});
}
},
fail: err => {
this.showToast({
title: err.message,
});
}
})
} }
} }

View File

@@ -1,119 +1,142 @@
/** /**
* 微信jssdk调用 * 微信jssdk调用
*/ */
let Weixin = function () { let Weixin = function () {
var wx = require('jweixin-module'); var wx = require('jweixin-module');
this.weixin = wx; this.weixin = wx;
this.init = function (params) { this.init = function (params) {
wx.config({ wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来若要查看传入的参数可以在pc端打开参数信息会通过log打出仅在pc端时才会打印。 debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来若要查看传入的参数可以在pc端打开参数信息会通过log打出仅在pc端时才会打印。
appId: params.appId, // 必填,公众号的唯一标识 appId: params.appId, // 必填,公众号的唯一标识
timestamp: params.timestamp, // 必填,生成签名的时间戳 timestamp: params.timestamp, // 必填,生成签名的时间戳
nonceStr: params.nonceStr, // 必填,生成签名的随机串 nonceStr: params.nonceStr, // 必填,生成签名的随机串
signature: params.signature, // 必填,签名 signature: params.signature, // 必填,签名
jsApiList: ['chooseWXPay', 'openAddress', 'updateAppMessageShareData', jsApiList: ['chooseWXPay', 'openAddress', 'updateAppMessageShareData',
'updateTimelineShareData', 'scanQRCode', 'hideMenuItems' 'updateTimelineShareData', 'scanQRCode', 'hideMenuItems'
] // 必填需要使用的JS接口列表 ] // 必填需要使用的JS接口列表
}); });
} }
/** /**
* 发起支付 * 发起支付
* @param jsApiParame * @param jsApiParame
* @param callback * @param callback
* @param cancel * @param cancel
*/ */
this.pay = function (jsApiParame, callback, cancel) { this.pay = function (jsApiParame, callback, cancel) {
wx.ready(function () { wx.ready(function () {
wx.chooseWXPay({ wx.chooseWXPay({
timestamp: jsApiParame timestamp: jsApiParame
.timestamp, // 支付签名时间戳注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 .timestamp, // 支付签名时间戳注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: jsApiParame.nonceStr, // 支付签名随机串,不长于 32 位 nonceStr: jsApiParame.nonceStr, // 支付签名随机串,不长于 32 位
package: jsApiParame.package, // 统一支付接口返回的prepay_id参数值提交格式如prepay_id=\*\*\* package: jsApiParame.package, // 统一支付接口返回的prepay_id参数值提交格式如prepay_id=\*\*\*
signType: jsApiParame.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5' signType: jsApiParame.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: jsApiParame.paySign, // 支付签名 paySign: jsApiParame.paySign, // 支付签名
success: function (res) { success: function (res) {
typeof callback == 'function' && callback(res); typeof callback == 'function' && callback(res);
}, },
cancel: function (res) { cancel: function (res) {
typeof cancel == 'function' && cancel(res); typeof cancel == 'function' && cancel(res);
} }
}); });
}) })
} }
/** /**
* 获取收货地址 * 获取收货地址
* @param {Object} callback * @param {Object} callback
*/ */
this.openAddress = function (callback) { this.openAddress = function (callback) {
wx.ready(function () { wx.ready(function () {
wx.openAddress({ wx.openAddress({
success: function (res) { success: function (res) {
typeof callback == 'function' && callback(res); typeof callback == 'function' && callback(res);
}, },
fail: (res) => { fail: (res) => {
console.log('获取收货地址 fail',res); console.log('获取收货地址 fail',res);
alert(JSON.stringify(res)) alert(JSON.stringify(res))
} }
}); });
}) })
} }
/** /**
* 分享给好友 * 分享给好友
* @param {Object} params * @param {Object} params
* @param {Object} callback * @param {Object} callback
*/ */
this.setShareData = function (params, callback) { this.setShareData = function (params, callback) {
wx.ready(function () { wx.ready(function () {
// 自定义“分享给朋友”及“分享到QQ”按钮的分享内容 // 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
wx.updateAppMessageShareData({ wx.updateAppMessageShareData({
title: params.title || '', // 分享标题 title: params.title || '', // 分享标题
desc: params.desc || '', // 分享描述 desc: params.desc || '', // 分享描述
link: params.link || '', // 分享链接该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 link: params.link || '', // 分享链接该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: params.imgUrl || '', // 分享图标 imgUrl: params.imgUrl || '', // 分享图标
success: function (res) { success: function (res) {
typeof callback == 'function' && callback(res); typeof callback == 'function' && callback(res);
}, },
fail: function (err) { fail: function (err) {
} }
}) })
// 自定义“分享到朋友圈”及“分享到QQ空间”按钮的分享内容 // 自定义“分享到朋友圈”及“分享到QQ空间”按钮的分享内容
wx.updateTimelineShareData({ wx.updateTimelineShareData({
title: params.title || '', // 分享标题 title: params.title || '', // 分享标题
link: params.link || '', // 分享链接该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 link: params.link || '', // 分享链接该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: params.imgUrl || '', // 分享图标 imgUrl: params.imgUrl || '', // 分享图标
success: function (res) { success: function (res) {
typeof callback == 'function' && callback(res); typeof callback == 'function' && callback(res);
} }
}) })
}); });
} }
/** /**
* 扫一扫 * 扫一扫
* @param {Object} callback * @param {Object} callback
*/ */
this.scanQRCode = function (callback) { this.scanQRCode = function (callback) {
wx.ready(function () { wx.ready(function () {
wx.scanQRCode({ wx.scanQRCode({
needResult: 1, needResult: 1,
scanType: ["qrCode"], scanType: ["qrCode"],
success: function (res) { success: function (res) {
typeof callback == 'function' && callback(res); typeof callback == 'function' && callback(res);
} }
}); });
}) })
} }
} // 提现
this.withdrawWechat = function (data,callback) {
export { wx.ready(function () {
Weixin wx.checkJsApi({
jsApiList: ['requestMerchantTransfer'],
success: function (res) {
if (res.checkResult['requestMerchantTransfer']) {
WeixinJSBridge.invoke('requestMerchantTransfer', {
mchId: data.mch_id,
appId: data.wechat_appid,
package: data.package_info,
},
function (res) {
typeof callback == 'function' && callback(res);
}
);
} else {
alert('你的微信版本过低,请更新至最新版本。');
}
},
});
});
}
}
export {
Weixin
} }

View File

@@ -1,638 +0,0 @@
<template>
<view class="order-container" :class="{ 'safe-area': isIphoneX }">
<!-- #ifdef MP-WEIXIN -->
<view class="payment-navbar" :style="{ 'padding-top': menuButtonBounding.top + 'px', height: menuButtonBounding.height + 'px' }">
<view class="nav-wrap">
<text class="iconfont icon-back_light" @click="back"></text>
<view class="navbar-title">确认订单</view>
</view>
</view>
<view class="payment-navbar-block" :style="{ height: menuButtonBounding.bottom + 'px' }"></view>
<!-- #endif -->
<scroll-view scroll-y="true" class="order-scroll-container">
<view class="payment-navbar-block"></view>
<template v-if="paymentData">
<template v-if="paymentData.is_virtual">
<!-- 虚拟商品联系方式 -->
<view class="mobile-wrap">
<view class="tips color-base-text">
<text class="iconfont icongantanhao"></text>
购买虚拟类商品需填写手机号方便商家与您联系
</view>
<view class="form-group">
<text class="icon">
<image :src="$util.img('public/uniapp/order/icon-mobile.png')" mode="widthFix"></image>
</text>
<text class="text">手机号码</text>
<input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" />
</view>
</view>
</template>
<template v-else>
<!-- 配送方式 -->
<view class="delivery-mode" v-if="goodsData.delivery.express_type.length > 1">
<view class="action">
<view :class="{ active: item.name == orderCreateData.delivery.delivery_type }" v-for="(item, index) in goodsData.delivery.express_type" :key="index" @click="selectDeliveryType(item)">
{{ item.title }}
<!-- 外圆角 -->
<view class="out-radio"></view>
</view>
</view>
</view>
<view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'express'">
<view class="info-wrap" v-if="memberAddress" @click="selectAddress">
<view class="content">
<text class="name">{{ memberAddress.name ? memberAddress.name : '' }}</text>
<text class="mobile">{{ memberAddress.mobile ? memberAddress.mobile : '' }}</text>
<view class="desc-wrap">
{{ memberAddress.full_address ? memberAddress.full_address : '' }}
{{ memberAddress.address ? memberAddress.address : '' }}
</view>
</view>
<text class="cell-more iconfont icon-right"></text>
</view>
<view class="empty-wrap" v-else @click="selectAddress">
<view class="info">请设置收货地址</view>
<view class="cell-more">
<view class="iconfont icon-right"></view>
</view>
</view>
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image>
</view>
<view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'local'">
<view v-if="localMemberAddress">
<block v-if="storeList && Object.keys(storeList).length > 1">
<view class="local-delivery-store" v-if="storeInfo" @click="openPopup('deliveryPopup')">
<view class="info">
<text class="store-name">{{ storeInfo.store_name }}</text>
提供配送
</view>
<view class="cell-more">
<text>点击切换</text>
<text class="iconfont icon-right"></text>
</view>
</view>
<view v-else class="local-delivery-store">
<view class="info">
<text class="store-name">您的附近没有可配送的门店请选择其他配送方式</text>
</view>
</view>
</block>
<view class="info-wrap local" @click="selectAddress">
<view class="content">
<text class="name">{{ localMemberAddress.name ? localMemberAddress.name : '' }}
</text>
<text class="mobile">{{ localMemberAddress.mobile ? localMemberAddress.mobile : '' }}
</text>
<view class="desc-wrap">
{{ localMemberAddress.full_address ? localMemberAddress.full_address : '' }}
{{ localMemberAddress.address ? localMemberAddress.address : '' }}
</view>
</view>
<text class="cell-more iconfont icon-right"></text>
</view>
<view class="local-box" v-if="calculateGoodsData.config.local && calculateGoodsData.delivery.local.info.time_is_open == 1">
<view class="pick-block" @click="localtime('')">
<view class="title font-size-base">送达时间</view>
<view class="time-picker">
<text :class="{ 'color-tip': !deliveryTime }">{{ deliveryTime ? deliveryTime : '请选择送达时间' }}</text>
<text class="iconfont icon-right cell-more"></text>
</view>
</view>
</view>
</view>
<view class="empty-wrap" v-else @click="selectAddress">
<view class="info">请设置收货地址</view>
<view class="cell-more">
<view class="iconfont icon-right"></view>
</view>
</view>
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image>
</view>
<!-- 门店信息 -->
<view class="store-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'store'">
<block v-if="storeInfo">
<view @click="openPopup('deliveryPopup')" class="store-info">
<view class="store-address-info">
<view class="info-wrap">
<view class="title">
<text>{{ storeInfo.store_name }}</text>
</view>
<view class="store-detail">
<view v-if="storeInfo.open_date">营业时间{{ storeInfo.open_date }}</view>
<view class="address">{{ storeInfo.full_address }} {{ storeInfo.address }}
</view>
</view>
</view>
<view class="cell-more iconfont icon-right" v-if="storeList && Object.keys(storeList).length > 1"></view>
</view>
</view>
<view class="mobile-wrap store-mobile" v-if="orderCreateData.member_address">
<view class="form-group">
<text class="text">姓名</text>
<input type="text" placeholder-class="color-tip placeholder" class="input" disabled v-model="orderCreateData.member_address.name" />
</view>
</view>
<view class="mobile-wrap store-mobile" v-if="orderCreateData.member_address">
<view class="form-group">
<text class="text">预留手机</text>
<input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" />
</view>
</view>
<view class="store-time" @click="storetime('')">
<view class="left">提货时间</view>
<view class="right">
{{ deliveryTime }}
<text class="iconfont icon-right"></text>
</view>
</view>
</block>
<view v-else class="empty">当前无自提门店请选择其它配送方式</view>
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image>
</view>
</template>
<!-- 店铺 -->
<view class="site-wrap order-goods" v-if="calculateGoodsData">
<view class="site-header">
<view class="iconfont icon-dianpu"></view>
<text class="site-name">门店</text>
</view>
<view class="site-body">
<!-- 商品 -->
<view class="goods-item" v-for="(goodsItem, goodsIndex) in calculateGoodsData.goods_list" :key="goodsIndex">
<view class="goods-wrap">
<view class="goods-img" @click="$util.redirectTo('/pages/goods/detail', { goods_id: goodsItem.goods_id })">
<image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" mode="aspectFill"/>
</view>
<view class="goods-info">
<view class="top-wrap">
<view @click="$util.redirectTo('/pages/goods/detail', { goods_id: goodsItem.goods_id })" class="goods-name">{{ goodsItem.sku_name }}</view>
<view class="sku" v-if="goodsItem.sku_spec_format">
<view class="goods-spec">
<block v-for="(x, i) in goodsItem.sku_spec_format" :key="i">
<view>{{ x.spec_value_name }}</view>
</block>
</view>
</view>
<block v-if="goodsItem.is_virtual == 0">
<view class="error-tips" v-if="orderCreateData.delivery &&
orderCreateData.delivery.delivery_type &&
goodsItem.support_trade_type &&
goodsItem.support_trade_type.indexOf(orderCreateData.delivery.delivery_type) == -1
">
<text class="iconfont icon-gantanhao"></text>
<text>该商品不支持{{ orderCreateData.delivery.delivery_type_name }}</text>
</view>
</block>
<view class="error-tips" v-if="goodsItem.error && goodsItem.error.message">
<text class="iconfont icon-gantanhao"></text>
<text>{{ goodsItem.error.message }}</text>
</view>
</view>
<view class="goods-sub-section">
<view class="color-base-text">
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
<text class="goods-price price-style large">{{ parseFloat(goodsItem.price).toFixed(2).split('.')[0] }}</text>
<text class="unit price-style small">.{{ parseFloat(goodsItem.price).toFixed(2).split('.')[1] }}</text>
</view>
<view>
<text class="font-size-tag">x</text>
<text class="font-size-base">{{ goodsItem.num }}</text>
</view>
</view>
</view>
</view>
<view class="member-goods-card order-cell" v-if="calculateGoodsData.goods_list[goodsIndex].member_card_list" @click="selectMemberGoodsCard(goodsIndex)">
<text class="tit">次卡抵扣</text>
<view class="box text-overflow">
<block v-if="calculateGoodsData.goods_list[goodsIndex].card_promotion_money">
<text class="text">次卡抵扣{{ calculateGoodsData.goods_list[goodsIndex].card_use_num }}张/{{ calculateGoodsData.goods_list[goodsIndex].card_use_num }}次</text>
<text class="price-font">-¥{{ calculateGoodsData.goods_list[goodsIndex].card_promotion_money | moneyFormat }}</text>
</block>
<text class="color-tip" v-else>请选择次卡</text>
</view>
<text class="iconfont icon-right"></text>
</view>
<view class="goods-form" v-if="goodsData.goods_list[goodsIndex].goods_form" @click="editForm(goodsIndex)">
<ns-form :data="goodsData.goods_list[goodsIndex].goods_form.json_data" ref="goodsForm" :custom-attr="{ sku_id: goodsItem.sku_id, form_id: goodsData.goods_list[goodsIndex].goods_form.id }"/>
<text class="cell-more iconfont icon-right"></text>
<view class="shade"></view>
</view>
</view>
</view>
</view>
<view class="site-wrap buyer-message">
<view class="order-cell">
<text class="tit">买家留言</text>
<view class="box text-overflow " @click="openPopup('buyerMessagePopup')">
<text v-if="orderCreateData.buyer_message">{{ orderCreateData.buyer_message }}</text>
<text class="color-sub" v-else>无留言</text>
</view>
<text class="iconfont icon-right"></text>
</view>
</view>
<view v-if="paymentData.system_form" class="system-form-wrap">
<view class="order-cell">
<text class="tit">{{ paymentData.system_form.form_name }}</text>
</view>
<ns-form :data="paymentData.system_form.json_data" ref="form"/>
</view>
<view class="site-wrap" v-if="calculateGoodsData || promotionInfo || (calculateGoodsData && calculateGoodsData.max_usable_point > 0) || goodsData.invoice">
<view class="site-footer">
<view class="order-cell coupon" v-if="modules.indexOf('coupon') != -1">
<text class="tit">优惠券</text>
<view class="box text-overflow" @click="openPopup('couponPopup')">
<template v-if="orderCreateData.coupon && orderCreateData.coupon.coupon_id">
<text>已使用优惠券,优惠</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ (calculateData && calculateData.coupon_money ? calculateData.coupon_money : 0) | moneyFormat }}</text>
</template>
<text v-else>不使用优惠券</text>
</view>
<text class="iconfont icon-right"></text>
</view>
<view class="order-cell" v-if="promotionInfo">
<text class="tit">活动优惠</text>
<view class="box text-overflow" @click="openPopup('promotionPopup')">
<text>{{ promotionInfo.title }}</text>
</view>
<text class="iconfont icon-right"></text>
</view>
<view class="order-cell point" v-if="calculateGoodsData && calculateGoodsData.max_usable_point > 0">
<text class="tit">
<text>使用{{ parseInt(calculateGoodsData.max_usable_point) }}积分可抵扣</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.point_money | moneyFormat }}</text>
</text>
<view class="box"></view>
<ns-switch class="balance-switch" @change="usePoint" :checked="orderCreateData.is_point == 1"/>
</view>
<view class="order-cell order-invoice-cell" v-if="goodsData.invoice.invoice_status == 1">
<text class="tit">发票</text>
<view class="box text-overflow" @click="openPopup('invoicePopup')">
<text v-if="orderCreateData.is_invoice == 1">{{ orderCreateData.invoice_type == 1 ? '纸质' : '电子' }}发票({{ orderCreateData.invoice_content }})</text>
<text v-else>无需发票</text>
</view>
<text class="iconfont icon-right"></text>
</view>
</view>
</view>
<view class="site-wrap box member-card-wrap" v-if="paymentData.recommend_member_card && Object.keys(paymentData.recommend_member_card).length > 0">
<view class="head" @click="selectMemberCard">
<text class="iconfont icon-huiyuan"></text>
<view class="info">
开通{{ paymentData.recommend_member_card.level_name }}
<text>本单预计可省</text>
<text class="price-color">{{ paymentData.recommend_member_card.discount_money | moneyFormat }}</text>
<text>元</text>
</view>
<text class="iconfont" :class="orderCreateData.is_open_card == 1 ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></text>
</view>
<view class="body" v-if="orderCreateData.is_open_card">
<view class="item" :class="{ 'active color-base-border': item.key == orderCreateData.member_card_unit }" v-for="(item, index) in cardChargeType" :key="index" @click="selectMembercardUnit(item.key)">
<view class="title">{{ item.title }}</view>
<view class="price price-font">{{ $lang('common.currencySymbol') }}{{ parseFloat(item.value) }}/{{ item.unit }}</view>
<text class="iconfont icon-icon color-base-text price-font identify" v-if="item.key == orderCreateData.member_card_unit"></text>
</view>
</view>
</view>
<!-- 订单金额 -->
<template v-if="calculateData">
<view class="order-money">
<view class="order-cell">
<text class="tit">商品金额</text>
<view class="box">
<text class="unit color-title price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money color-title price-font">{{ calculateData.goods_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="calculateData.is_virtual == 0 && calculateData.delivery_money > 0">
<text class="tit">运费</text>
<view class="box color-base-text">
<text class="operator">+</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.delivery_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_money > 0">
<text class="tit">
<text>税费</text>
<text class="color-base-text font-bold price-font">({{ goodsData.invoice.invoice_rate }}%)</text>
</text>
<view class="box color-base-text">
<text class="operator">+</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.invoice_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_delivery_money > 0">
<text class="tit">发票邮寄费</text>
<view class="box color-base-text">
<text class="operator">+</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.invoice_delivery_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="calculateData.promotion_money > 0">
<text class="tit">优惠</text>
<view class="box color-base-text">
<text class="operator">-</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.promotion_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="calculateData.coupon_money">
<text class="tit">优惠券</text>
<view class="box color-base-text">
<text class="operator">-</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.coupon_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="calculateData.point_money > 0">
<text class="tit">积分抵扣</text>
<view class="box color-base-text">
<text class="operator">-</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.point_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="calculateData.member_card_money > 0">
<text class="tit">会员卡</text>
<view class="box color-base-text">
<text class="operator">+</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.member_card_money | moneyFormat }}
</text>
</view>
</view>
</view>
<view v-if="transactionAgreement.title && transactionAgreement.content" class="agreement">购买前请先阅读<text @click="$refs.agreementPopup.open()">《{{ transactionAgreement.title }}》</text>,下单即代表同意该协议</view>
<view class="order-submit bottom-safe-area">
<view class="order-settlement-info">
<text class="font-size-base color-tip margin-right">共{{ calculateData.goods_num }}件</text>
<text class="font-size-base">合计:</text>
<text class=" unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class=" money price-font">{{ parseFloat(calculateData.pay_money).toFixed(2).split('.')[0] }}</text>
<text class=" unit price-font">.{{ parseFloat(calculateData.pay_money).toFixed(2).split('.')[1] }}</text>
</view>
<view class="submit-btn">
<button type="primary" class="mini" size="mini" @click="create()" v-if="!surplusStartMoney()">提交订单</button>
<button v-else class="no-submit mini" size="mini">差{{ surplusStartMoney() | moneyFormat }}起送</button>
</view>
</view>
<view class="order-submit-block"></view>
<payment ref="choosePaymentPopup" @close="payClose" v-if="calculateData"></payment>
</template>
<!-- 活动优惠弹窗 -->
<uni-popup ref="promotionPopup" type="bottom" v-if="promotionInfo">
<view class="promotion-popup popup">
<view class="popup-header">
<text class="tit">活动优惠</text>
<text class="iconfont icon-close" @click="closePopup('promotionPopup')"></text>
</view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view class="order-cell" style="align-items: baseline;">
<view class="tit">
<text class="promotion-mark ns-gradient-promotionpages-payment">{{ promotionInfo.title }}
</text>
</view>
<view class="promotion-content">
<view class="tit tit-content" style="white-space: pre-line;" v-html="promotionInfo.content"></view>
</view>
</view>
</scroll-view>
<view class="popup-footer" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg" @click="closePopup('promotionPopup')">确定</view>
</view>
</view>
</uni-popup>
<!-- 门店列表弹窗 -->
<uni-popup ref="deliveryPopup" type="bottom">
<view class="delivery-popup popup">
<view class="popup-header">
<text class="tit">已为您甄选出附近所有相关门店</text>
<text class="iconfont icon-close" @click="closePopup('deliveryPopup')"></text>
</view>
<view class="popup-body store-popup" :class="{ 'safe-area': isIphoneX }">
<mescroll-uni @getData="getStore" ref="mescroll" top="50px">
<block slot="list">
<view class="delivery-content">
<block v-if="storeData">
<view class="item-wrap" v-for="(item, index) in storeData" :key="index" @click="selectPickupPoint(item)">
<view class="detail">
<view class="name" :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''">
<text>{{ item.store_name }}</text>
<text v-if="item.distance">({{ item.distance }}km)</text>
</view>
<view class="info">
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">营业时间:{{ item.open_date }}</view>
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">地址:{{ item.full_address }}{{ item.address }}</view>
</view>
</view>
<view class="icon" v-if="item.store_id == orderCreateData.delivery.store_id">
<text class="iconfont icon-yuan_checked color-base-text"></text>
</view>
</view>
</block>
<view v-else class="empty-wrap">
<ns-empty text="所选择收货地址附近没有可以自提的门店" :isIndex="false"></ns-empty>
</view>
</view>
</block>
</mescroll-uni>
</view>
</view>
</uni-popup>
<!-- 留言弹窗 -->
<uni-popup ref="buyerMessagePopup" type="bottom">
<view style="height: auto;" class="buyermessag-popup popup" @touchmove.prevent.stop>
<view class="popup-header">
<text class="tit">买家留言</text>
<text class="iconfont icon-close" @click="closePopup('buyerMessagePopup')"></text>
</view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view>
<view class="buyermessag-cell">
<view class="buyermessag-form-group">
<textarea type="text" maxlength="100" placeholder="留言前建议先与商家协调一致" placeholder-class="color-tip" v-model="orderCreateData.buyer_message"/>
</view>
</view>
</view>
</scroll-view>
<view class="popup-footer" @click="saveBuyerMessage" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg">确定</view>
</view>
</view>
</uni-popup>
<!-- 优惠券弹窗 -->
<uni-popup ref="couponPopup" type="bottom" v-if="calculateGoodsData" :mask-click="false">
<view class="coupon-popup popup" @touchmove.prevent.stop>
<view class="popup-header">
<text class="tit">优惠券</text>
<text class="iconfont icon-close" @click="closePopup('couponPopup')"></text>
</view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view v-if="coupon_list.length > 0">
<view class="coupon-item" v-for="(couponItem, couponIndex) in coupon_list" :key="couponIndex" @click="selectCoupon(couponItem)">
<view class="coupon-info" :style="{ backgroundColor: 'var(--main-color-shallow)' }">
<view class="info-wrap">
<image class="coupon-line" mode="heightFix" :src="$util.img('public/uniapp/coupon/coupon_line.png')"/>
<view class="coupon-money">
<template v-if="couponItem.type == 'divideticket'">
<text class="unit">{{ $lang('common.currencySymbol') }}</text>
<text class="money">{{ parseFloat(couponItem.money) }}</text>
</template>
<template v-else-if="couponItem.type == 'reward'">
<text class="unit">{{ $lang('common.currencySymbol') }}</text>
<text class="money">{{ parseFloat(couponItem.money) }}</text>
</template>
<template v-else-if="couponItem.type == 'discount'">
<text class="money">{{ parseFloat(couponItem.discount) }}</text>
<text class="unit">折</text>
</template>
<view class="at-least">
<template v-if="couponItem.at_least > 0">
满{{ couponItem.at_least }}可用
</template>
<template v-else>
无门槛
</template>
</view>
</view>
</view>
<view class="desc-wrap">
<view class="coupon-name">{{ couponItem.coupon_name }}</view>
<view v-if="couponItem.type == 'discount' && couponItem.discount_limit > 0" class="limit">最多可抵¥{{ couponItem.discount_limit }}</view>
<view class="time font-size-goods-tag">有效期:{{ couponItem.end_time ? $util.timeStampTurnTime(couponItem.end_time) : '长期有效' }}</view>
</view>
<view class="iconfont" :class="orderCreateData.coupon.coupon_id == couponItem.coupon_id ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></view>
</view>
</view>
</view>
<view v-else class="coupon-empty">暂无可用的优惠券</view>
</scroll-view>
<view class="popup-footer" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg" @click="useCpopon">确定</view>
</view>
</view>
</uni-popup>
<!-- 交易协议 -->
<view @touchmove.prevent>
<uni-popup ref="agreementPopup" type="center" :maskClick="false">
<view class="agreement-conten-box">
<view class="close">
<text class="iconfont icon-close" @click="$refs.agreementPopup.close()"></text>
</view>
<view class="title">{{ transactionAgreement.title }}</view>
<view class="con">
<scroll-view scroll-y="true" class="con">
<rich-text :nodes="transactionAgreement.content"></rich-text>
</scroll-view>
</view>
</view>
</uni-popup>
</view>
<!-- 表单修改弹窗 -->
<uni-popup ref="editFormPopup" type="bottom">
<view style="height: auto;" class="form-popup popup" @touchmove.prevent.stop>
<view class="popup-header">
<text class="tit">买家信息</text>
<text class="iconfont icon-close" @click="$refs.editFormPopup.close()"></text>
</view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<ns-form v-if="tempFormData" :data="tempFormData.json_data" ref="tempForm"></ns-form>
</scroll-view>
<view class="popup-footer" @click="saveForm" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg">确定</view>
</view>
</view>
</uni-popup>
<uni-popup ref="memberGoodsCardPopup" type="bottom">
<view class="member-card-popup popup" @touchmove.prevent.stop>
<view class="popup-header">
<text class="tit">选择次卡</text>
<text class="iconfont icon-close" @click="$refs.memberGoodsCardPopup.close()"></text>
</view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view v-for="(item, index) in selectGoodsCard.cardList" class="card-item" @click="selectGoodsCard.click(item.item_id)">
<view class="content">
<view class="title">{{ item.goods_name }}</view>
<view class="info">
<text v-if="item.card_type == 'timecard'">不限次数</text>
<text v-if="item.card_type == 'oncecard'">剩余{{ item.num - item.use_num }}次</text>
<text v-if="item.card_type == 'commoncard'">剩余{{ item.total_num - item.total_use_num }}次</text>
<text>|</text>
<text>{{ item.end_time ? $util.timeStampTurnTime(item.end_time) : '长期有效' }}</text>
</view>
</view>
<view class="iconfont" :class="selectGoodsCard.itemId == item.item_id ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></view>
</view>
</scroll-view>
<view class="popup-footer" @click="saveMemberGoodsCard" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg">确定</view>
</view>
</view>
</uni-popup>
</template>
</scroll-view>
<!-- 门店自提时间 -->
<ns-select-time @selectTime="selectPickupTime" ref="timePopup"></ns-select-time>
<ns-login ref="login"></ns-login>
<loading-cover ref="loadingCover"></loading-cover>
</view>
</template>
<script>
import payment from './payment.js';
export default {
name: 'common-payment',
data() {
return {};
},
props: {
api: Object,
createDataKey: String
},
mixins: [payment]
};
</script>
<style lang="scss">
@import '@/common/css/order_parment.scss';
.order-cell .promotion-content {
flex: 1;
}
</style>

View File

@@ -64,30 +64,27 @@
<view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'local'"> <view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'local'">
<view v-if="localMemberAddress"> <view v-if="localMemberAddress">
<block v-if="storeList && Object.keys(storeList).length > 1"> <block v-if="storeList && Object.keys(storeList).length > 0">
<view class="local-delivery-store" v-if="storeInfo" @click="openPopup('deliveryPopup')"> <view class="local-delivery-store">
<view class="info"> <view class="info" v-if="storeInfo">
<text class="store-name">{{ storeInfo.store_name }}</text> <text class="store-name">{{ storeInfo.store_name }}</text>
提供配送 提供配送
<view>营业时间{{ storeInfo.open_date }}</view>
</view> </view>
<view class="cell-more"> <view class="info" v-else>
<text class="store-name">超出配送范围请选择其他门店</text>
</view>
<view class="cell-more" v-if="Object.keys(storeList).length > 1" @click="openPopup('deliveryPopup')">
<text>点击切换</text> <text>点击切换</text>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
</view> </view>
</view> </view>
<view v-else class="local-delivery-store">
<view class="info">
<text class="store-name">您的附近没有可配送的门店请选择其他配送方式</text>
</view>
</view>
</block> </block>
<view class="info-wrap local" @click="selectAddress"> <view class="info-wrap local" @click="selectAddress">
<view class="content"> <view class="content">
<text class="name">{{ localMemberAddress.name ? localMemberAddress.name : '' }} <text class="name">{{ localMemberAddress.name ? localMemberAddress.name : '' }}</text>
</text> <text class="mobile">{{ localMemberAddress.mobile ? localMemberAddress.mobile : '' }}</text>
<text class="mobile">{{ localMemberAddress.mobile ? localMemberAddress.mobile : '' }}
</text>
<view class="desc-wrap"> <view class="desc-wrap">
{{ localMemberAddress.full_address ? localMemberAddress.full_address : '' }} {{ localMemberAddress.full_address ? localMemberAddress.full_address : '' }}
{{ localMemberAddress.address ? localMemberAddress.address : '' }} {{ localMemberAddress.address ? localMemberAddress.address : '' }}
@@ -125,9 +122,9 @@
<text>{{ storeInfo.store_name }}</text> <text>{{ storeInfo.store_name }}</text>
</view> </view>
<view class="store-detail"> <view class="store-detail">
<view class="close-desc" v-if="storeInfo.status == 0 && storeInfo.close_desc">{{ storeInfo.close_desc }}</view>
<view v-if="storeInfo.open_date">营业时间{{ storeInfo.open_date }}</view> <view v-if="storeInfo.open_date">营业时间{{ storeInfo.open_date }}</view>
<view class="address">{{ storeInfo.full_address }} {{ storeInfo.address }} <view class="address">{{ storeInfo.full_address }} {{ storeInfo.address }}</view>
</view>
</view> </view>
</view> </view>
<view class="cell-more iconfont icon-right" v-if="storeList && Object.keys(storeList).length > 1"></view> <view class="cell-more iconfont icon-right" v-if="storeList && Object.keys(storeList).length > 1"></view>
@@ -145,7 +142,14 @@
<input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" /> <input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" />
</view> </view>
</view> </view>
<view class="store-time" @click="storetime('')"> <view class="store-time" v-if="goodsData.jielong_id">
<view class="left">提货时间</view>
<view class="right">
{{ $util.timeStampTurnTime(goodsData.jielong_info.take_start_time,'Y/m/d') }} ~ {{ $util.timeStampTurnTime(goodsData.jielong_info.take_end_time,'Y/m/d') }}
</view>
</view>
<view class="store-time" @click="storetime('')" v-else>
<view class="left">提货时间</view> <view class="left">提货时间</view>
<view class="right"> <view class="right">
{{ deliveryTime }} {{ deliveryTime }}
@@ -159,15 +163,10 @@
</template> </template>
<!-- 店铺 --> <!-- 店铺 -->
<view class="site-wrap order-goods" v-if="calculateGoodsData">
<view class="site-wrap order-goods" v-for="(calculateGoodsData, siteIndex) in shop_goods_list" :key="siteIndex">
<view class="site-header">
<view class="iconfont icon-dianpu"></view>
<text class="site-name">{{calculateGoodsData.site_name}}</text>
</view>
<view class="site-body"> <view class="site-body">
<!-- 商品 --> <!-- 商品 -->
<view class="goods-item" v-for="(goodsItem, goodsIndex) in goodsSpecFormat(calculateGoodsData.goods_list)" :key="goodsIndex"> <view class="goods-item" v-for="(goodsItem, goodsIndex) in calculateGoodsData.goods_list" :key="goodsIndex">
<view class="goods-wrap"> <view class="goods-wrap">
<view class="goods-img" @click="$util.redirectTo('/pages/goods/detail', { goods_id: goodsItem.goods_id })"> <view class="goods-img" @click="$util.redirectTo('/pages/goods/detail', { goods_id: goodsItem.goods_id })">
<image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" mode="aspectFill"/> <image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" mode="aspectFill"/>
@@ -210,6 +209,17 @@
</view> </view>
</view> </view>
</view> </view>
<view class="member-goods-card order-cell" v-if="calculateGoodsData.goods_list[goodsIndex].member_card_list" @click="selectMemberGoodsCard(goodsIndex)">
<text class="tit">次卡抵扣</text>
<view class="box text-overflow">
<block v-if="calculateGoodsData.goods_list[goodsIndex].card_promotion_money">
<text class="text">次卡抵扣{{ calculateGoodsData.goods_list[goodsIndex].card_use_num }}张/{{ calculateGoodsData.goods_list[goodsIndex].card_use_num }}次</text>
<text class="price-font">-¥{{ calculateGoodsData.goods_list[goodsIndex].card_promotion_money | moneyFormat }}</text>
</block>
<text class="color-tip" v-else>请选择次卡</text>
</view>
<text class="iconfont icon-right"></text>
</view>
<view class="goods-form" v-if="goodsData.goods_list[goodsIndex].goods_form" @click="editForm(goodsIndex)"> <view class="goods-form" v-if="goodsData.goods_list[goodsIndex].goods_form" @click="editForm(goodsIndex)">
<ns-form :data="goodsData.goods_list[goodsIndex].goods_form.json_data" ref="goodsForm" :custom-attr="{ sku_id: goodsItem.sku_id, form_id: goodsData.goods_list[goodsIndex].goods_form.id }"/> <ns-form :data="goodsData.goods_list[goodsIndex].goods_form.json_data" ref="goodsForm" :custom-attr="{ sku_id: goodsItem.sku_id, form_id: goodsData.goods_list[goodsIndex].goods_form.id }"/>
<text class="cell-more iconfont icon-right"></text> <text class="cell-more iconfont icon-right"></text>
@@ -217,48 +227,18 @@
</view> </view>
</view> </view>
</view> </view>
</view>
<view class="site-wrap buyer-message">
<view class="site-wrap buyer-message">
</view> <view class="order-cell">
<text class="tit">买家留言</text>
<view class="order-money" style="margin: 0;"> <view class="box text-overflow " @click="openPopup('buyerMessagePopup')">
<view class="order-cell"> <text v-if="orderCreateData.buyer_message">{{ orderCreateData.buyer_message }}</text>
<text class="tit">买家留言</text> <text class="color-sub" v-else>无留言</text>
<view class="box text-overflow " @click="openPopup('buyerMessagePopup')">
<text v-if="orderCreateData.buyer_message">{{ orderCreateData.buyer_message[calculateGoodsData.merch_id] }}</text>
<text class="color-sub" v-else>无留言</text>
</view>
<text class="iconfont icon-right"></text>
</view>
<view class="order-cell coupon" v-if="modules.indexOf('coupon') != -1">
<text class="tit">优惠券</text>
<view class="box text-overflow"@click="openSiteCoupon(calculateGoodsData.merch_id)">
<template v-if="orderCreateData.coupon[calculateGoodsData.merch_id].coupon_id">
<text class="money price-font" style="max-width: 100%;">已选择1张优惠券</text>
<!-- <text class="unit price-font">优惠</text>
<text class="money price-font">{{ (calculateData && calculateData.coupon_money ? calculateData.coupon_money : 0) | moneyFormat }}</text> -->
</template>
<text v-else>不使用优惠券</text>
</view>
<text class="iconfont icon-right"></text>
</view>
</view>
<view class="site-wrap buyer-message">
<view class="order-cell">
<view class="box shop-item">
<text class="color-tip goods-num">共{{ calculateGoodsData.goods_num }}件</text>
<text class="font-size-base">小计:</text>
<text class="color-base-text unit">{{ $lang('common.currencySymbol') }}</text>
<text class="color-base-text money">{{ calculateGoodsData.goods_money | moneyFormat }}</text>
</view>
</view> </view>
<text class="iconfont icon-right"></text>
</view> </view>
</view> </view>
<view v-if="paymentData.system_form" class="system-form-wrap"> <view v-if="paymentData.system_form" class="system-form-wrap">
<view class="order-cell"> <view class="order-cell">
@@ -267,7 +247,7 @@
<ns-form :data="paymentData.system_form.json_data" ref="form"/> <ns-form :data="paymentData.system_form.json_data" ref="form"/>
</view> </view>
<!-- <view class="site-wrap" v-if="calculateGoodsData || promotionInfo || (calculateGoodsData && calculateGoodsData.max_usable_point > 0) || goodsData.invoice"> <view class="site-wrap" v-if="calculateGoodsData || promotionInfo || (calculateGoodsData && calculateGoodsData.max_usable_point > 0) || goodsData.invoice">
<view class="site-footer"> <view class="site-footer">
<view class="order-cell coupon" v-if="modules.indexOf('coupon') != -1"> <view class="order-cell coupon" v-if="modules.indexOf('coupon') != -1">
<text class="tit">优惠券</text> <text class="tit">优惠券</text>
@@ -306,8 +286,8 @@
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
</view> </view>
</view> </view>
</view> --> </view>
<view class="site-wrap box member-card-wrap" v-if="paymentData.recommend_member_card && Object.keys(paymentData.recommend_member_card).length > 0"> <view class="site-wrap box member-card-wrap" v-if="paymentData.recommend_member_card && Object.keys(paymentData.recommend_member_card).length > 0">
<view class="head" @click="selectMemberCard"> <view class="head" @click="selectMemberCard">
<text class="iconfont icon-huiyuan"></text> <text class="iconfont icon-huiyuan"></text>
@@ -320,7 +300,7 @@
<text class="iconfont" :class="orderCreateData.is_open_card == 1 ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></text> <text class="iconfont" :class="orderCreateData.is_open_card == 1 ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></text>
</view> </view>
<view class="body" v-if="orderCreateData.is_open_card"> <view class="body" v-if="orderCreateData.is_open_card">
<view class="item" :class="{ 'active color-base-border': item.key == orderCreateData.member_card_unit }" v-for="(item, index) in cardChargeType" :key="index" @click="selectMembercardUnit(item.key)"> <view class="item" :class="{ 'active color-base-border': item.key == orderCreateData.member_card_unit }" v-for="(item, index) in cardChargeType" :key="index" @click="selectMemberCardUnit(item.key)">
<view class="title">{{ item.title }}</view> <view class="title">{{ item.title }}</view>
<view class="price price-font">{{ $lang('common.currencySymbol') }}{{ parseFloat(item.value) }}/{{ item.unit }}</view> <view class="price price-font">{{ $lang('common.currencySymbol') }}{{ parseFloat(item.value) }}/{{ item.unit }}</view>
<text class="iconfont icon-icon color-base-text price-font identify" v-if="item.key == orderCreateData.member_card_unit"></text> <text class="iconfont icon-icon color-base-text price-font identify" v-if="item.key == orderCreateData.member_card_unit"></text>
@@ -346,7 +326,7 @@
<text class="money price-font">{{ calculateData.delivery_money | moneyFormat }}</text> <text class="money price-font">{{ calculateData.delivery_money | moneyFormat }}</text>
</view> </view>
</view> </view>
<!-- <view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_money > 0"> <view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_money > 0">
<text class="tit"> <text class="tit">
<text>税费</text> <text>税费</text>
<text class="color-base-text font-bold price-font">({{ goodsData.invoice.invoice_rate }}%)</text> <text class="color-base-text font-bold price-font">({{ goodsData.invoice.invoice_rate }}%)</text>
@@ -356,15 +336,15 @@
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text> <text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.invoice_money | moneyFormat }}</text> <text class="money price-font">{{ calculateData.invoice_money | moneyFormat }}</text>
</view> </view>
</view> --> </view>
<!-- <view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_delivery_money > 0"> <view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_delivery_money > 0">
<text class="tit">发票邮寄费</text> <text class="tit">发票邮寄费</text>
<view class="box color-base-text"> <view class="box color-base-text">
<text class="operator">+</text> <text class="operator">+</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text> <text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.invoice_delivery_money | moneyFormat }}</text> <text class="money price-font">{{ calculateData.invoice_delivery_money | moneyFormat }}</text>
</view> </view>
</view> --> </view>
<view class="order-cell" v-if="calculateData.promotion_money > 0"> <view class="order-cell" v-if="calculateData.promotion_money > 0">
<text class="tit">优惠</text> <text class="tit">优惠</text>
<view class="box color-base-text"> <view class="box color-base-text">
@@ -389,7 +369,7 @@
<text class="money price-font">{{ calculateData.point_money | moneyFormat }}</text> <text class="money price-font">{{ calculateData.point_money | moneyFormat }}</text>
</view> </view>
</view> </view>
<!-- <view class="order-cell" v-if="calculateData.member_card_money > 0"> <view class="order-cell" v-if="calculateData.member_card_money > 0">
<text class="tit">会员卡</text> <text class="tit">会员卡</text>
<view class="box color-base-text"> <view class="box color-base-text">
<text class="operator">+</text> <text class="operator">+</text>
@@ -397,7 +377,7 @@
<text class="money price-font">{{ calculateData.member_card_money | moneyFormat }} <text class="money price-font">{{ calculateData.member_card_money | moneyFormat }}
</text> </text>
</view> </view>
</view> --> </view>
</view> </view>
<view v-if="transactionAgreement.title && transactionAgreement.content" class="agreement">购买前请先阅读<text @click="$refs.agreementPopup.open()">《{{ transactionAgreement.title }}》</text>,下单即代表同意该协议</view> <view v-if="transactionAgreement.title && transactionAgreement.content" class="agreement">购买前请先阅读<text @click="$refs.agreementPopup.open()">《{{ transactionAgreement.title }}》</text>,下单即代表同意该协议</view>
@@ -412,14 +392,76 @@
</view> </view>
<view class="submit-btn"> <view class="submit-btn">
<button type="primary" class="mini" size="mini" @click="create()" v-if="!surplusStartMoney()">提交订单</button> <button type="primary" class="mini" size="mini" @click="create()" v-if="!surplusStartMoney()">提交订单</button>
<!-- <button v-else class="no-submit mini" size="mini">差{{ surplusStartMoney() | moneyFormat }}起送</button> --> <button v-else class="no-submit mini" size="mini">差{{ surplusStartMoney() | moneyFormat }}起送</button>
</view> </view>
</view> </view>
<view class="order-submit-block"></view> <view class="order-submit-block"></view>
<payment ref="choosePaymentPopup" @close="payClose" v-if="calculateData"></payment> <payment ref="choosePaymentPopup" @close="payClose" v-if="calculateData"></payment>
</template> </template>
<!-- 发票弹窗 -->
<uni-popup ref="invoicePopup" type="bottom" :mask-click="false">
<view :style="orderCreateData.is_invoice == 1 ? 'height: 83vh;' : 'height: 48vh;'" class="invoice-popup popup" @touchmove.prevent.stop>
<view class="popup-header">
<text class="tit">发票</text>
<text class="iconfont icon-close" @click="closePopup('invoicePopup')"></text>
</view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view>
<view class="invoice-cell" v-if="goodsData.invoice">
<text class="tit">需要发票</text>
<view class="option-grpup">
<view class="option-item" :class="{ 'color-base-bg active': orderCreateData.is_invoice == 0 }" @click="changeIsInvoice">不需要</view>
<view class="option-item" :class="{ 'color-base-bg active': orderCreateData.is_invoice == 1 }" @click="changeIsInvoice">需要</view>
</view>
</view>
<block v-if="orderCreateData.is_invoice == 1">
<view class="invoice-cell">
<text class="tit">发票类型</text>
<view class="option-grpup">
<view class="option-item" :class="{ 'color-base-bg active': orderCreateData.invoice_type == item }" @click="changeInvoiceType(item)" v-for="(item, index) in goodsData.invoice.invoice_type.split(',')" :key="index">
{{ item == 1 ? '纸质' : '电子' }}
</view>
</view>
</view>
<view class="invoice-cell">
<text class="tit">抬头类型</text>
<view class="option-grpup">
<view class="option-item" :class="{ 'color-base-bg active': orderCreateData.invoice_title_type == 1 }" @click="changeInvoiceTitleType(1)">
个人
</view>
<view class="option-item" :class="{ 'color-base-bg active': orderCreateData.invoice_title_type == 2 }" @click="changeInvoiceTitleType(2)">
企业
</view>
</view>
</view>
<view class="invoice-cell">
<text class="tit">发票信息</text>
<view class="invoice-form-group">
<input type="text" placeholder="请填写抬头名称" v-model.trim="orderCreateData.invoice_title" />
<input v-if="orderCreateData.invoice_title_type == 2" type="text" placeholder="请填写纳税人识别号" v-model.trim="orderCreateData.taxpayer_number" />
<input type="text" placeholder="请填写邮寄地址" v-model.trim="orderCreateData.invoice_full_address" v-if="orderCreateData.invoice_type == 1" />
<input type="text" placeholder="请填写邮箱" v-model.trim="orderCreateData.invoice_email" v-if="orderCreateData.invoice_type == 2" />
</view>
</view>
<view class="invoice-cell">
<text class="tit">发票内容</text>
<view class="option-grpup">
<view :key="index" v-for="(item, index) in goodsData.invoice.invoice_content_array" :class="{ 'color-base-bg active': item == orderCreateData.invoice_content }" @click="changeInvoiceContent(item)" class="option-item content">
{{ item }}
</view>
</view>
</view>
</block>
<view class="invoice-tops">发票内容将以根据税法调整,具体请以展示为准,发票内容显示详细商品名 称及价格信息</view>
</view>
</scroll-view>
<view class="popup-footer" @click="saveInvoice" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg">确定</view>
</view>
</view>
</uni-popup>
<!-- 活动优惠弹窗 --> <!-- 活动优惠弹窗 -->
<uni-popup ref="promotionPopup" type="bottom" v-if="promotionInfo"> <uni-popup ref="promotionPopup" type="bottom" v-if="promotionInfo">
@@ -431,8 +473,7 @@
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }"> <scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view class="order-cell" style="align-items: baseline;"> <view class="order-cell" style="align-items: baseline;">
<view class="tit"> <view class="tit">
<text class="promotion-mark ns-gradient-promotionpages-payment">{{ promotionInfo.title }} <text class="promotion-mark ns-gradient-promotionpages-payment">{{ promotionInfo.title }}</text>
</text>
</view> </view>
<view class="promotion-content"> <view class="promotion-content">
<view class="tit tit-content" style="white-space: pre-line;" v-html="promotionInfo.content"></view> <view class="tit tit-content" style="white-space: pre-line;" v-html="promotionInfo.content"></view>
@@ -465,6 +506,7 @@
<text v-if="item.distance">({{ item.distance }}km)</text> <text v-if="item.distance">({{ item.distance }}km)</text>
</view> </view>
<view class="info"> <view class="info">
<view v-if="item.status == 0 && item.close_desc" class="close-desc">{{ item.close_desc }}</view>
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">营业时间:{{ item.open_date }}</view> <view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">营业时间:{{ item.open_date }}</view>
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">地址:{{ item.full_address }}{{ item.address }}</view> <view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">地址:{{ item.full_address }}{{ item.address }}</view>
</view> </view>
@@ -478,6 +520,33 @@
<ns-empty text="所选择收货地址附近没有可以自提的门店" :isIndex="false"></ns-empty> <ns-empty text="所选择收货地址附近没有可以自提的门店" :isIndex="false"></ns-empty>
</view> </view>
</view> </view>
<!-- <block v-if="storeList">
<view class="item-wrap" v-for="(item, index) in storeList" :key="index"
@click="selectPickupPoint(item)">
<view class="detail">
<view class="name"
:class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''">
<text>{{ item.store_name }}</text>
<text v-if="item.distance">({{ item.distance }}km)</text>
</view>
<view class="info">
<view
:class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''"
class="font-size-goods-tag">
营业时间:{{ item.open_date }}
</view>
<view
:class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''"
class="font-size-goods-tag">
地址:{{ item.full_address }}{{ item.address }}
</view>
</view>
</view>
<view class="icon" v-if="item.store_id == orderCreateData.delivery.store_id">
<text class="iconfont icon-yuan_checked color-base-text"></text>
</view>
</view>
</block> -->
</block> </block>
</mescroll-uni> </mescroll-uni>
@@ -509,7 +578,7 @@
</uni-popup> </uni-popup>
<!-- 优惠券弹窗 --> <!-- 优惠券弹窗 -->
<uni-popup ref="couponPopup" type="bottom" :mask-click="false"> <uni-popup ref="couponPopup" type="bottom" v-if="calculateGoodsData" :mask-click="false">
<view class="coupon-popup popup" @touchmove.prevent.stop> <view class="coupon-popup popup" @touchmove.prevent.stop>
<view class="popup-header"> <view class="popup-header">
<text class="tit">优惠券</text> <text class="tit">优惠券</text>
@@ -517,8 +586,8 @@
</view> </view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }"> <scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view v-if="merchCoupon.data.length > 0"> <view v-if="coupon_list.length > 0">
<view class="coupon-item" v-for="(couponItem, couponIndex) in merchCoupon.data" :key="couponIndex" @click="selectCoupon(couponItem,merchCoupon.merch_id)"> <view class="coupon-item" v-for="(couponItem, couponIndex) in coupon_list" :key="couponIndex" @click="selectCoupon(couponItem)">
<view class="coupon-info" :style="{ backgroundColor: 'var(--main-color-shallow)' }"> <view class="coupon-info" :style="{ backgroundColor: 'var(--main-color-shallow)' }">
<view class="info-wrap"> <view class="info-wrap">
<image class="coupon-line" mode="heightFix" :src="$util.img('public/uniapp/coupon/coupon_line.png')"/> <image class="coupon-line" mode="heightFix" :src="$util.img('public/uniapp/coupon/coupon_line.png')"/>
@@ -536,12 +605,8 @@
<text class="unit">折</text> <text class="unit">折</text>
</template> </template>
<view class="at-least"> <view class="at-least">
<template v-if="couponItem.at_least > 0"> <template v-if="couponItem.at_least > 0">满{{ couponItem.at_least }}可用</template>
满{{ couponItem.at_least }}可用 <template v-else>无门槛</template>
</template>
<template v-else>
无门槛
</template>
</view> </view>
</view> </view>
</view> </view>
@@ -550,7 +615,7 @@
<view v-if="couponItem.type == 'discount' && couponItem.discount_limit > 0" class="limit">最多可抵¥{{ couponItem.discount_limit }}</view> <view v-if="couponItem.type == 'discount' && couponItem.discount_limit > 0" class="limit">最多可抵¥{{ couponItem.discount_limit }}</view>
<view class="time font-size-goods-tag">有效期:{{ couponItem.end_time ? $util.timeStampTurnTime(couponItem.end_time) : '长期有效' }}</view> <view class="time font-size-goods-tag">有效期:{{ couponItem.end_time ? $util.timeStampTurnTime(couponItem.end_time) : '长期有效' }}</view>
</view> </view>
<view class="iconfont" :class="selectCouponId == couponItem.coupon_id ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></view> <view class="iconfont" :class="orderCreateData.coupon.coupon_id == couponItem.coupon_id ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></view>
</view> </view>
</view> </view>
</view> </view>
@@ -558,7 +623,7 @@
</scroll-view> </scroll-view>
<view class="popup-footer" :class="{ 'bottom-safe-area': isIphoneX }"> <view class="popup-footer" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg" @click="useCpopon">确定</view> <view class="confirm-btn color-base-bg" @click="useCoupon">确定</view>
</view> </view>
</view> </view>
</uni-popup> </uni-popup>
@@ -573,7 +638,7 @@
<view class="title">{{ transactionAgreement.title }}</view> <view class="title">{{ transactionAgreement.title }}</view>
<view class="con"> <view class="con">
<scroll-view scroll-y="true" class="con"> <scroll-view scroll-y="true" class="con">
<rich-text :nodes="transactionAgreement.content"></rich-text> <ns-mp-html :content="transactionAgreement.content"></ns-mp-html>
</scroll-view> </scroll-view>
</view> </view>
</view> </view>
@@ -588,7 +653,7 @@
<text class="iconfont icon-close" @click="$refs.editFormPopup.close()"></text> <text class="iconfont icon-close" @click="$refs.editFormPopup.close()"></text>
</view> </view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }"> <scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<ns-form v-if="tempFormData" :data="tempFormData.json_data" ref="tempForm"></ns-form> <ns-form v-if="tempFormData" :data="tempFormData.json_data" ref="tempForm" />
</scroll-view> </scroll-view>
<view class="popup-footer" @click="saveForm" :class="{ 'bottom-safe-area': isIphoneX }"> <view class="popup-footer" @click="saveForm" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg">确定</view> <view class="confirm-btn color-base-bg">确定</view>
@@ -603,7 +668,7 @@
<text class="iconfont icon-close" @click="$refs.memberGoodsCardPopup.close()"></text> <text class="iconfont icon-close" @click="$refs.memberGoodsCardPopup.close()"></text>
</view> </view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }"> <scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view v-for="(item, index) in selectGoodsCard.cardList" class="card-item" @click="selectGoodsCard.click(item.item_id)"> <view v-for="(item, index) in selectGoodsCard.cardList" class="card-item" @click="selectGoodsCard.click(item.item_id)" :key="item.item_id">
<view class="content"> <view class="content">
<view class="title">{{ item.goods_name }}</view> <view class="title">{{ item.goods_name }}</view>
<view class="info"> <view class="info">
@@ -655,4 +720,4 @@
.order-cell .promotion-content { .order-cell .promotion-content {
flex: 1; flex: 1;
} }
</style> </style>

View File

@@ -1,26 +1,27 @@
<template> <template>
<x-skeleton data-component-name="diy-article" type="list" :loading="loading" :configs="skeletonConfig"> <view :style="value.pageStyle" v-if="loading || (list && list.length)">
<view class="article-wrap" :style="warpCss"> <x-skeleton type="list" :loading="loading" :configs="skeletonConfig">
<view :class="['list-wrap', value.style]" :style="warpCss"> <view class="article-wrap" :style="warpCss">
<view :class="['item', value.ornament.type]" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :style="itemCss"> <view :class="['list-wrap', value.style]" :style="warpCss">
<view class="article-img"> <view :class="['item', value.ornament.type]" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :style="itemCss">
<image class="cover-img" :src="$util.img(item.cover_img)" mode="widthFix" @error="imgError(index)" /> <view class="article-img">
</view> <image class="cover-img" :src="$util.img(item.cover_img)" mode="widthFix" @error="imgError(index)" />
<view class="info-wrap"> </view>
<text class="title">{{ item.article_title }}</text> <view class="info-wrap">
<text class="desc" style="color:#888;font-size: 24rpx; display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2;overflow: hidden;text-overflow: ellipsis;">{{ item.article_abstract }}</text> <text class="title">{{ item.article_title }}</text>
<view class="read-wrap"> <view class="read-wrap">
<block v-if="item.category_name"> <block v-if="item.category_name">
<text class="category-icon"></text> <text class="category-icon"></text>
<text>{{ item.category_name }}</text> <text>{{ item.category_name }}</text>
</block> </block>
<text class="date">{{ $util.timeStampTurnTime(item.create_time, 'date') }}</text> <text class="date">{{ $util.timeStampTurnTime(item.create_time, 'Y-m-d') }}</text>
</view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </x-skeleton>
</x-skeleton> </view>
</template> </template>
<script> <script>
@@ -29,7 +30,10 @@
name: 'diy-article', name: 'diy-article',
props: { props: {
value: { value: {
type: Object type: Object,
default: () => {
return {};
}
} }
}, },
data() { data() {

View File

@@ -1,4 +1,5 @@
<template> <template>
<view :style="value.pageStyle" v-if="loading || (list && list.length)">
<x-skeleton data-component-name="diy-bargain" :type="skeletonType" :loading="loading" :configs="skeletonConfig"> <x-skeleton data-component-name="diy-bargain" :type="skeletonType" :loading="loading" :configs="skeletonConfig">
<view class="diy-bargain" :class="[value.template, value.style]" :style="warpCss"> <view class="diy-bargain" :class="[value.template, value.style]" :style="warpCss">
@@ -123,6 +124,7 @@
</view> </view>
</x-skeleton> </x-skeleton>
</view>
</template> </template>
<script> <script>
@@ -130,7 +132,10 @@
name: 'diy-bargain', name: 'diy-bargain',
props: { props: {
value: { value: {
type: Object type: Object,
default: () => {
return {};
}
} }
}, },
data() { data() {

View File

@@ -33,14 +33,13 @@
</block> </block>
<block v-if="type == 'goods'"> <block v-if="type == 'goods'">
<view class="categoty-goods-wrap" v-if="loadType == 'part'" <view class="categoty-goods-wrap" v-if="loadType == 'part'" :style="'padding-top:' + (value.search ? 0 : '20rpx')">
:style="'padding-top:' + (value.search ? 0 : '20rpx')">
<!-- 分类筛选 --> <!-- 分类筛选 -->
<block v-if="category.child_list && value.goodsLevel == 2"> <block v-if="category.child_list && value.goodsLevel == 2">
<view class="screen-category-wrap"> <view class="screen-category-wrap">
<scroll-view scroll-x="true" class="screen-category" :class="{ 'screen-category-4': value.template == 4 }" :scroll-with-animation="true" :scroll-into-view="scrollIntoView"> <scroll-view scroll-x="true" class="screen-category" :class="{ 'screen-category-4': value.template == 4 }" :scroll-with-animation="true" :scroll-into-view="scrollIntoView">
<view class="item" id="category-2--1" :class="{ selected: categoryId == -1 }" @click="selectCategoey(-1)">全部</view> <view class="item" id="category-2--1" :class="{ selected: categoryId == -1 }" @click="selectCategory(-1)">全部</view>
<view class="item" :id="'category-2-' + oneIndex" :class="{ selected: categoryId == oneIndex }" @click="selectCategoey(oneIndex)" v-for="(one, oneIndex) in category.child_list" :key="oneIndex"> <view class="item" :id="'category-2-' + oneIndex" :class="{ selected: categoryId == oneIndex }" @click="selectCategory(oneIndex)" v-for="(one, oneIndex) in category.child_list" :key="oneIndex">
{{ one.category_name }} {{ one.category_name }}
</view> </view>
</scroll-view> </scroll-view>
@@ -50,14 +49,14 @@
<view class="screen-category-popup" @click="$refs.screenCategoryPopup.close()"> <view class="screen-category-popup" @click="$refs.screenCategoryPopup.close()">
<scroll-view scroll-y="true" class="screen-category" :class="{ 'screen-category-4': value.template == 4 }"> <scroll-view scroll-y="true" class="screen-category" :class="{ 'screen-category-4': value.template == 4 }">
<view class="title">全部</view> <view class="title">全部</view>
<view class="item" :class="{ selected: categoryId == oneIndex }" @click="selectCategoey(oneIndex)" v-for="(one, oneIndex) in category.child_list" :key="oneIndex"> <view class="item" :class="{ selected: categoryId == oneIndex }" @click="selectCategory(oneIndex)" v-for="(one, oneIndex) in category.child_list" :key="oneIndex">
{{ one.category_name }} {{ one.category_name }}
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
</uni-popup> </uni-popup>
</block> </block>
<!---->
<scroll-view scroll-y="true" class="scroll-goods-view" lower-threshold="300" :scroll-top="scrollTop" @scrolltolower="scrolltolower" @touchstart="touchstart" @touchend="touchend" @scroll="listenScroll"> <scroll-view scroll-y="true" class="scroll-goods-view" lower-threshold="300" :scroll-top="scrollTop" @scrolltolower="scrolltolower" @touchstart="touchstart" @touchend="touchend" @scroll="listenScroll">
<!--一级分类展示商品显示--> <!--一级分类展示商品显示-->
@@ -70,6 +69,9 @@
<view class="goods-img" @click="toDetail(item)"> <view class="goods-img" @click="toDetail(item)">
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"/> <image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"/>
<view class="color-base-bg goods-tag" v-if="item.label_name">{{ item.label_name }}</view> <view class="color-base-bg goods-tag" v-if="item.label_name">{{ item.label_name }}</view>
<view class="sell-out" v-if="item.goods_stock <= 0">
<text class="iconfont icon-shuqing"></text>
</view>
</view> </view>
<view class="info-wrap"> <view class="info-wrap">
<view class="name-wrap" @click="toDetail(item)"> <view class="name-wrap" @click="toDetail(item)">
@@ -293,7 +295,7 @@
oneCategorySelect: function() { oneCategorySelect: function() {
this.scrollTop = -1; this.scrollTop = -1;
this.goodsList = []; this.goodsList = [];
this.selectCategoey(-1); this.selectCategory(-1);
}, },
select: function() { select: function() {
if (this.index == this.select) { if (this.index == this.select) {
@@ -607,7 +609,7 @@
} }
this.$emit('selectsku', data); this.$emit('selectsku', data);
}, },
selectCategoey(index) { selectCategory(index) {
this.categoryId = index; this.categoryId = index;
this.pageIndex = 0; this.pageIndex = 0;
this.totalPage = 1; this.totalPage = 1;
@@ -667,7 +669,7 @@
this.$emit('switch', index); this.$emit('switch', index);
} else { } else {
let index = this.categoryId - 1; let index = this.categoryId - 1;
this.selectCategoey(index); this.selectCategory(index);
} }
} else { } else {
if (this.categoryId == -1 || (this.category.child_list && this.categoryId == this.category.child_list.length - 1)) { if (this.categoryId == -1 || (this.category.child_list && this.categoryId == this.category.child_list.length - 1)) {
@@ -675,7 +677,7 @@
this.$emit('switch', index); this.$emit('switch', index);
} else { } else {
let index = this.categoryId + 1; let index = this.categoryId + 1;
this.selectCategoey(index); this.selectCategory(index);
} }
} }
}, },
@@ -995,7 +997,27 @@
height: 100%; height: 100%;
} }
} }
.sell-out{
position: absolute;
z-index: 1;
width: 180rpx;
height: 180rpx;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.5);
border-radius: $border-radius;
text{
color: #fff;
font-size: 150rpx;
position: absolute;
left:50%;
top:50%;
transform: translateX(-50%) translateY(-50%);
}
}
.info-wrap { .info-wrap {
flex: 1; flex: 1;
display: flex; display: flex;
@@ -1171,10 +1193,28 @@
height: auto; height: auto;
margin-right: 0; margin-right: 0;
line-height: 1; line-height: 1;
position: relative;
image { image {
border-radius: 8rpx; border-radius: 8rpx;
} }
.sell-out{
position: absolute;
z-index: 1;
width: 100%;
height: auto;
top: 0;
left: 0;
bottom:0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.5);
border-radius: $border-radius;
text{
color: #fff;
font-size: 240rpx;
}
}
} }
.select-sku { .select-sku {
@@ -1200,7 +1240,7 @@
.screen-category-wrap { .screen-category-wrap {
display: flex; display: flex;
padding-top: 20rpx;
.icon-unfold { .icon-unfold {
font-size: 24rpx; font-size: 24rpx;
color: #999; color: #999;

View File

@@ -2,20 +2,20 @@
<view data-component-name="diy-category" :class="['category-page-wrap', 'category-template-' + value.template]" <view data-component-name="diy-category" :class="['category-page-wrap', 'category-template-' + value.template]"
:style="{height: 'calc(100vh - '+ tabBarHeight +')' }"> :style="{height: 'calc(100vh - '+ tabBarHeight +')' }">
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<!-- <block v-if="value.template == 4"> <block v-if="value.template == 4">
<view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="navbarInnerStyle"> <view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="navbarInnerStyle">
<view class="search-content"> <view class="search-content">
<input type="text" class="uni-input font-size-tag" maxlength="50" :placeholder="$lang('search')" confirm-type="search" disabled="true" /> <input type="text" class="uni-input font-size-tag" maxlength="50" :placeholder="$lang('search')" confirm-type="search" readonly="true" disabled="true" />
<text class="iconfont icon-sousuo3"></text> <text class="iconfont icon-sousuo3"></text>
</view> </view>
</view> </view>
<view :style="navbarInnerStyle" v-if="!value.search">商品分类</view> <view :style="navbarInnerStyle" v-if="!value.search">商品分类</view>
</block> --> </block>
<block v-if="value.template != 4"> <block v-if="value.template != 4">
<!-- <view :style="navbarInnerStyle">商品分类</view> --> <view :style="navbarInnerStyle">商品分类</view>
<view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="wxSearchHeight"> <view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="wxSearchHeight">
<view class="search-content"> <view class="search-content">
<input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')" confirm-type="search" disabled="true" /> <input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')" confirm-type="search" readonly="true" disabled="true" />
<text class="iconfont icon-sousuo3"></text> <text class="iconfont icon-sousuo3"></text>
</view> </view>
</view> </view>
@@ -24,11 +24,12 @@
<!-- #ifdef H5 --> <!-- #ifdef H5 -->
<view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')"> <view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')">
<view class="search-content"> <view class="search-content">
<input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')" confirm-type="search" disabled="true" /> <input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')" confirm-type="search" readonly="true" disabled="true" />
<text class="iconfont icon-sousuo3"></text> <text class="iconfont icon-sousuo3"></text>
</view> </view>
</view> </view>
<!-- #endif --> <!-- #endif -->
<view class="template-four wx" v-if="value.template == 4"> <view class="template-four wx" v-if="value.template == 4">
<scroll-view scroll-x="true" class="template-four-wrap" :scroll-with-animation="true" :scroll-into-view="'category-one-' + oneCategorySelect" enable-flex="true"> <scroll-view scroll-x="true" class="template-four-wrap" :scroll-with-animation="true" :scroll-into-view="'category-one-' + oneCategorySelect" enable-flex="true">
<view class="category-item" :id="'category-one-' + index" v-for="(item, index) in templateFourData" :key="index" :class="{ select: oneCategorySelect == index }" @click="templateFourOneFn(index)"> <view class="category-item" :id="'category-one-' + index" v-for="(item, index) in templateFourData" :key="index" :class="{ select: oneCategorySelect == index }" @click="templateFourOneFn(index)">
@@ -71,12 +72,13 @@
{ 'border-bottom': value.template == 4 && select + 1 === index }, { 'border-bottom': value.template == 4 && select + 1 === index },
{ 'border-top': value.template == 4 && select - 1 === index } { 'border-top': value.template == 4 && select - 1 === index }
]" @click="switchOneCategory(index)"> ]" @click="switchOneCategory(index)">
<view class="">{{ item.category_name }}</view> <view>{{ item.category_name }}</view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
<view class="right-flex-wrap"> <view class="right-flex-wrap">
<scroll-view scroll-y="true" class="content-wrap" v-if="value.template == 1 || loadType == 'all'" <scroll-view scroll-y="true" class="content-wrap" v-if="value.template == 1 || loadType == 'all'"
ref="contentWrap" :scroll-into-view="categoryId" :scroll-with-animation="true" ref="contentWrap" :scroll-into-view="categoryId" :scroll-with-animation="true"
@scroll="listenScroll" @touchstart="touchStart" :refresher-enabled="true" @scroll="listenScroll" @touchstart="touchStart" :refresher-enabled="true"
@@ -113,8 +115,8 @@
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix"></image> <image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix"></image>
<view class="tips">暂时没有分类哦</view> <view class="tips">暂时没有分类哦</view>
</view> </view>
<view class="cart-bottom-block" v-if="(value.template == 2 || value.template == 4) && value.quickBuy && storeToken && categoryTree && categoryTree.length"></view>
<!-- <view class="cart-box" v-if="(value.template == 2 || value.template == 4) && value.quickBuy && storeToken && categoryTree && categoryTree.length"> <view class="cart-box" v-if="(value.template == 2 || value.template == 4) && value.quickBuy && storeToken && categoryTree && categoryTree.length" :style="{ bottom: tabBarHeight }" :class="{ active: isIphoneX }">
<view class="left-wrap"> <view class="left-wrap">
<view class="cart-icon" ref="cartIcon" :animation="cartAnimation" @click="$util.redirectTo('/pages/goods/cart')"> <view class="cart-icon" ref="cartIcon" :animation="cartAnimation" @click="$util.redirectTo('/pages/goods/cart')">
<text class="iconfont icon-ziyuan1"></text> <text class="iconfont icon-ziyuan1"></text>
@@ -127,9 +129,10 @@
<text class="unit font-size-tag price-font">.{{ cartTotalMoney[1] ? cartTotalMoney[1] : '00' }}</text> <text class="unit font-size-tag price-font">.{{ cartTotalMoney[1] ? cartTotalMoney[1] : '00' }}</text>
</view> </view>
</view> </view>
<view class="right-wrap"><button type="primary" class="settlement-btn" @click="settlement">去结算</button> <view class="right-wrap">
<button type="primary" class="settlement-btn" @click="settlement">去结算</button>
</view> </view>
</view> --> </view>
<view class="cart-point" :style="{ left: item.left + 'px', top: item.top + 'px' }" :key="index" v-for="(item, index) in carIconList"></view> <view class="cart-point" :style="{ left: item.left + 'px', top: item.top + 'px' }" :key="index" v-for="(item, index) in carIconList"></view>
@@ -176,34 +179,27 @@
cartAnimation: {}, cartAnimation: {},
loadType: '', loadType: '',
templateFourData: [], templateFourData: [],
isIphoneX: false, //判断手机是否是iphoneX以上,
lang:uni.getStorageSync("lang")//en-us 英文 lang:uni.getStorageSync("lang")//en-us 英文
}; };
}, },
created() { created() {
this.isIphoneX = this.$util.uniappIsIPhoneX();
this.getCategoryTree(); this.getCategoryTree();
this.loadType = this.value.goodsLevel == 1 && this.value.loadType == 'all' ? 'all' : 'part'; this.loadType = this.value.goodsLevel == 1 && this.value.loadType == 'all' ? 'all' : 'part';
}, },
mounted() { mounted() {
query = uni.createSelectorQuery().in(this); query = uni.createSelectorQuery().in(this);
query query.select('.content-wrap').boundingClientRect(data => {
.select('.content-wrap') if (data) contentWrapHeight = data.height;
.boundingClientRect(data => { }).exec();
if (data) contentWrapHeight = data.height;
})
.exec();
setTimeout(() => { setTimeout(() => {
query query.select('.end-tips').boundingClientRect(data => {
.select('.end-tips') if (data && data.top > contentWrapHeight) this.endTips = 1;
.boundingClientRect(data => { }).exec();
if (data && data.top > contentWrapHeight) this.endTips = 1; query.select('.cart-icon').boundingClientRect(data => {
}) if (data) cartPosition = data;
.exec(); }).exec();
query
.select('.cart-icon')
.boundingClientRect(data => {
if (data) cartPosition = data;
})
.exec();
if (this.value.template == 1) this.getHeightArea(-1); if (this.value.template == 1) this.getHeightArea(-1);
}, 500); }, 500);
}, },
@@ -250,7 +246,7 @@
style += 'padding-top:' + this.navbarHeight + 'px;'; style += 'padding-top:' + this.navbarHeight + 'px;';
style += 'text-align: center;'; style += 'text-align: center;';
style += 'line-height:' + menuButtonInfo.height * 2 + 'rpx;'; style += 'line-height:' + menuButtonInfo.height * 2 + 'rpx;';
style += 'font-size: 14px;'; style += 'font-size: 16px;';
style += 'padding-bottom: 10rpx;'; style += 'padding-bottom: 10rpx;';
} }
return style; return style;
@@ -282,27 +278,48 @@
pageShow() { pageShow() {
this.$store.dispatch('getCartNumber'); this.$store.dispatch('getCartNumber');
if (!this.heightArea.length) this.getHeightArea(-1); if (!this.heightArea.length) this.getHeightArea(-1);
this.dealCategoryData()
},
dealCategoryData() {
if (uni.getStorageSync('tabBarParams')) {
if (this.value.template != 4) {
this.categoryTree.forEach((item,index) => {
if(item.category_id == uni.getStorageSync('tabBarParams').split('=')[1]) {
this.select = index;
this.categoryId = 'category-' + index;
// 阻止切换分类之后滚动事件也立即执行
}
})
} else {
this.templateFourData.forEach((item,index) => {
if(item.category_id == uni.getStorageSync('tabBarParams').split('=')[1]) {
this.oneCategorySelect = index;
this.categoryId = 'category-' + index;
// 阻止切换分类之后滚动事件也立即执行
this.categoryTree = this.templateFourData[index].child_list || [];
this.select = 0;
}
})
}
uni.removeStorageSync('tabBarParams')
}
}, },
/** /**
* 获取高度区间 * 获取高度区间
*/ */
getHeightArea(index) { getHeightArea(index) {
let heightArea = []; let heightArea = [];
query query.selectAll('.content-wrap .child-category').boundingClientRect(data => {
.selectAll('.content-wrap .child-category') if (data && data.length) {
.boundingClientRect(data => { data.forEach((item, index) => {
if (data && data.length) { if (index == 0) heightArea.push([0, item.height]);
data.forEach((item, index) => { else heightArea.push([heightArea[index - 1][1], heightArea[index - 1][1] + item.height]);
if (index == 0) heightArea.push([0, item.height]); });
else heightArea.push([heightArea[index - 1][1], heightArea[index - 1][1] + }
item.height }).exec();
]);
});
}
})
.exec();
this.heightArea = heightArea; this.heightArea = heightArea;
if (index != -1 && index < this.categoryTree.length - 1) this.$refs.categoryItem[index + 1].getGoodsList(); if (index != -1 && index < this.categoryTree.length - 1) this.$refs.categoryItem[index + 1].getGoodsList();
this.refreshData();
}, },
/** /**
* 获取全部分类 * 获取全部分类
@@ -332,6 +349,7 @@
return item; return item;
}); });
} }
this.dealCategoryData()
} }
} }
}); });
@@ -364,8 +382,7 @@
break; break;
} }
} }
if (this.value.template != 1 && this.value.loadType == 'all' && this.heightArea[this.select][1] - if (this.value.template != 1 && this.value.loadType == 'all' && this.heightArea[this.select][1] - scrollTop - contentWrapHeight < 300) {
scrollTop - contentWrapHeight < 300) {
this.$refs.categoryItem[this.select].getGoodsList(); this.$refs.categoryItem[this.select].getGoodsList();
} }
} }
@@ -433,6 +450,37 @@
}); });
}, },
settlement() { settlement() {
// 是否有商品库存不足 不足最小购买数 超过最大购买数
var no_buy = false;
for (let k in this.cartList) {
let item = this.cartList[k];
for (let sku in item) {
if (item.max_buy && item.num > item.max_buy){
no_buy = true;
this.$util.showToast({title: '商品' + item.goods_name+'商品最多可购买'+item.max_buy+'件'})
break;
}
if (typeof item[sku] == 'object') {
if (item[sku].num > item[sku].stock){
no_buy = true;
this.$util.showToast({title: '商品' + item.goods_name+'库存不足'})
break;
}
if (item[sku].min_buy && item[sku].num < item[sku].min_buy){
no_buy = true;
this.$util.showToast({title: '商品' + item.goods_name+'商品最少要购买'+item[sku].min_buy+'件'})
break;
}
}
}
}
if(no_buy) return;
if (!this.cartIds.length || this.isSub) return; if (!this.cartIds.length || this.isSub) return;
this.isSub = true; this.isSub = true;
@@ -520,7 +568,7 @@
}, },
// 操作多规格商品弹框后,刷新商品数据 // 操作多规格商品弹框后,刷新商品数据
refreshData() { refreshData() {
this.$refs.categoryItem[this.select].loadGoodsCartNum(true); if(this.$refs.categoryItem) this.$refs.categoryItem[this.select].loadGoodsCartNum(true);
} }
} }
}; };
@@ -529,7 +577,8 @@
<style lang="scss"> <style lang="scss">
.category-page-wrap { .category-page-wrap {
width: 100vw; width: 100vw;
// height: calc(100vh - var(--tab-bar-height, 0)); height: 100vh;
box-sizing: border-box;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background-color: #fff; background-color: #fff;
@@ -584,10 +633,16 @@
view { view {
color: #222222; color: #222222;
width: 100%; width: 100%;
white-space: nowrap; // white-space: nowrap;
text-overflow: ellipsis; // text-overflow: ellipsis;
line-height: 1.3;
overflow: hidden; overflow: hidden;
text-align: center; text-align: center;
// display: -webkit-box;
// -webkit-line-clamp: 2;
// -webkit-box-orient: vertical;
word-break: break-all;
max-height: 100rpx;
} }
&.border-top { &.border-top {
@@ -667,6 +722,11 @@
.cart-box { .cart-box {
height: 100rpx; height: 100rpx;
width: 100%; width: 100%;
position: fixed;
left: 0;
bottom: var(--tab-bar-height, 0);
// bottom: calc( constant(safe-area-inset-bottom) + 110rpx );
// bottom: calc( env(safe-area-inset-bottom) + 110rpx );
background: #fff; background: #fff;
border-top: 1px solid #f5f5f5; border-top: 1px solid #f5f5f5;
box-sizing: border-box; box-sizing: border-box;
@@ -739,6 +799,11 @@
} }
} }
.cart-box.active {
bottom: calc(constant(safe-area-inset-bottom) + 110rpx) !important;
bottom: calc(env(safe-area-inset-bottom) + 110rpx) !important;
}
.cart-point { .cart-point {
width: 26rpx; width: 26rpx;
height: 26rpx; height: 26rpx;
@@ -785,7 +850,7 @@
} }
.cart-box { .cart-box {
position: relative; // position: relative;
z-index: 2; z-index: 2;
} }
@@ -865,15 +930,30 @@
} }
.text { .text {
padding: 2rpx 16rpx; padding: 2rpx 0;
border-radius: 40rpx; border-radius: 40rpx;
font-size: $font-size-tag; font-size: $font-size-tag;
box-sizing: border-box;
width: 100%;
box-sizing: border-box;
text-align: center;
overflow: hidden;
}
.ellipsis {
// text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
} }
&.selected { &.selected {
.text { .text {
background-color: $base-color; background-color: $base-color;
color: var(--btn-text-color); color: var(--btn-text-color);
line-height: 1.3;
border: 4rpx solid transparent;
border-color: $base-color;
} }
} }
} }
@@ -1004,4 +1084,7 @@
border-bottom-right-radius: 8rpx; border-bottom-right-radius: 8rpx;
} }
} }
.cart-bottom-block {
height: 100rpx;
}
</style> </style>

View File

@@ -1,5 +1,7 @@
<template> <template>
<view data-component-name="diy-comp-extend"></view> <view data-component-name="diy-comp-extend" :style="value.pageStyle">
<view></view>
</view>
</template> </template>
<script> <script>
@@ -8,7 +10,10 @@ export default {
name: 'diy-comp-extend', name: 'diy-comp-extend',
props: { props: {
value: { value: {
type: Object type: Object,
default: () => {
return {};
}
} }
}, },
data() { data() {

View File

@@ -1,23 +1,91 @@
<template> <template>
<x-skeleton data-component-name="diy-coupon" type="banner" :loading="loading" :configs="skeletonConfig"> <view :style="value.pageStyle" v-if="loading || (computedCouponList && computedCouponList.length)">
<view class="coupon-wrap" :class="'coupon-box-' + value.style" :style="[ <x-skeleton type="banner" :loading="loading" :configs="skeletonConfig">
value.couponType == 'img' && { backgroundImage: 'url(' + $util.img(value.couponBgUrl) + ')' }, <view class="coupon-wrap" :class="'coupon-box-' + value.style" :style="[
value.couponType == 'color' && { backgroundColor: value.couponBgColor } value.couponType == 'img' && { backgroundImage: 'url(' + $util.img(value.couponBgUrl) + ')' },
]"> value.couponType == 'color' && { backgroundColor: value.couponBgColor }
]">
<template v-if="value.style == '1'"> <template v-if="value.style == '1'">
<swiper class="coupon-style-one" circular> <swiper class="coupon-style-one" circular>
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box"> <swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
<view v-for="(item, index) in computedCouponList" class="coupon-item" <view v-for="(item, index) in computedCouponList" class="coupon-item" v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{ color: value.moneyColor,
color: value.moneyColor, backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style1-bg.png') + ')',
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style1-bg.png') + ')', marginRight: couponItemHeight + 'px',
marginRight: couponItemHeight + 'px', marginLeft: couponItemHeight + 'px'
marginLeft: couponItemHeight + 'px' }" @click="couponAction(item, index)">
}" @click="couponAction(item, index)">
<view class="coupon-info"> <view class="coupon-info">
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
<text class="font-size-tag coupon-sign"></text>
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
</view>
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else>
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
<text class="font-size-tag coupon-sign"></text>
</view>
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }">
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}
</view>
</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text }}</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
</view>
</swiper-item>
</swiper>
</template>
<template v-if="value.style == '2'">
<swiper class="coupon-style-two" circular>
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index"
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_bg1.png') + ')',
marginRight: couponItemHeight + 'px',
marginLeft: couponItemHeight + 'px'
}" @click="couponAction(item, index)">
<view class="coupon-info">
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
<text class="font-size-tag coupon-sign"></text>
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
</view>
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else>
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
<text class="font-size-tag coupon-sign"></text>
</view>
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }">
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}
</view>
</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text || '领取' }}</view>
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
</view>
</swiper-item>
</swiper>
</template>
<template v-if="value.style == '3'">
<swiper class="coupon-style-three" circular>
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index"
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_shu.png') + ')',
marginRight: couponItemHeight + 'px',
marginLeft: couponItemHeight + 'px'
}" @click="couponAction(item, index)">
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)"> <view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
<text class="font-size-tag coupon-sign"></text> <text class="font-size-tag coupon-sign"></text>
<text class="coupon-size">{{ item.money | moneyConduct }}</text> <text class="coupon-size">{{ item.money | moneyConduct }}</text>
@@ -26,125 +94,188 @@
<text class="coupon-size">{{ item.discount | moneyConduct }}</text> <text class="coupon-size">{{ item.discount | moneyConduct }}</text>
<text class="font-size-tag coupon-sign"></text> <text class="font-size-tag coupon-sign"></text>
</view> </view>
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }"> <view class="coupon-type font-size-tag">
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }} <text :style="{ color: value.limitColor }">{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}</text>
<view class="item-text">{{item.goods_type_name}}</view>
</view> </view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text || '领取' }}</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
</view> </view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0"> </swiper-item>
{{ value.btnStyle.text }} </swiper>
</view> </template>
<view class="coupon-get" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用</view>
</view>
</swiper-item> <template v-if="value.style == '4'">
</swiper> <swiper class="coupon-style-four" circular>
</template> <swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index"
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style4_bg.png') + ')',
marginRight: couponItemHeight + 'px',
marginLeft: couponItemHeight + 'px'
}" @click="couponAction(item, index)">
<view class="coupon-info">
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
<text class="font-size-tag coupon-sign"></text>
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
</view>
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else>
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
<text class="font-size-tag coupon-sign"></text>
</view>
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }">
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}
</view>
</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text || '立即领取' }}</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
</view>
</swiper-item>
</swiper>
</template>
<template v-if="value.style == '2'"> <template v-if="value.style == '5'">
<swiper class="coupon-style-two" circular> <view class="coupon-style-five">
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box"> <view class="coupon-all">
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index" <view class="coupon-box">
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{ <view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index" @click="couponAction(item, index)">
color: value.moneyColor, <image :src="$util.img('public/uniapp/coupon/style5_bg.png')"></image>
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_bg1.png') + ')', <view class="coupon">
marginRight: couponItemHeight + 'px', <view class="coupon-info">
marginLeft: couponItemHeight + 'px' <view class="coupon-num" v-if="item.discount == '0.00'" :style="{ color: value.moneyColor }">
}" @click="couponAction(item, index)"> <text class="coupon-size">{{ item.money | moneyConduct }}</text>
<view class="coupon-info"> <text class="font-size-tag coupon-sign"></text>
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)"> </view>
<text class="font-size-tag coupon-sign"></text> <view class="coupon-num" v-else :style="{ color: value.moneyColor }">
<text class="coupon-size">{{ item.money | moneyConduct }}</text> <text class="coupon-size">{{ item.discount | moneyConduct }}</text>
<text class="font-size-tag coupon-sign"></text>
</view>
</view>
<view class="coupon-line"></view>
<view class="coupon-content">
<view class="coupon-type">
<view class="coupon-name" :style="{ color: value.nameColor }">{{ item.coupon_name }}</view>
<text class="coupon-least" :style="{ color: value.limitColor }" v-if="item.at_least > 0">{{ Number(item.at_least) }}元可用</text>
<text class="coupon-least" :style="{ color: value.limitColor }" v-else>无门槛优惠券</text>
</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text || '立即领取' }}</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
</view>
</view>
</view> </view>
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else>
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
<text class="font-size-tag coupon-sign"></text>
</view>
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }">
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}
</view>
</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0">
{{ value.btnStyle.text || '领取' }}
</view>
<view class="coupon-get use" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用
</view> </view>
</view> </view>
</swiper-item> </view>
</swiper> </template>
</template>
<template v-if="value.style == '3'"> <template v-if="value.style == '6'">
<swiper class="coupon-style-three" circular> <swiper class="coupon-style-six" circular>
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box"> <swiper-item class="style-six-wrap" v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex">
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index" <view class="coupon" v-for="(item, index) in computedCouponList" :key="index"
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{ v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
color: value.moneyColor, color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_shu.png') + ')', backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-1.png') + ')',
marginRight: couponItemHeight + 'px', marginRight: couponItemHeight + 'px',
marginLeft: couponItemHeight + 'px' marginLeft: couponItemHeight + 'px'
}" @click="couponAction(item, index)"> }" @click="couponAction(item, index)">
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)"> <view class="coupon-content">
<text class="font-size-tag coupon-sign"></text> <view class="price-wrap">
<text class="coupon-size">{{ item.money | moneyConduct }}</text> <text class="price" :style="{ color: value.moneyColor }">{{ (item.discount == '0.00' ? item.money : item.discount) | moneyConduct }}</text>
</view> <text class="unit">{{ item.discount == '0.00' ? '元' : '折' }}</text>
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else> </view>
<text class="coupon-size">{{ item.discount | moneyConduct }}</text> <text class="text">优惠券</text>
<text class="font-size-tag coupon-sign"></text>
</view>
<view class="coupon-type font-size-tag">
<text :style="{ color: value.limitColor }">{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}</text>
<view class="item-text" v-if="item.goods_type == 1">所有商品可用</view>
<view class="item-text" v-else-if="item.goods_type == 2">指定商品可用</view>
<view class="item-text" v-else-if="item.goods_type == 3">指定商品不可用</view>
</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0">
{{ value.btnStyle.text || '领取' }}
</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用</view>
</view>
</swiper-item>
</swiper>
</template>
<template v-if="value.style == '4'">
<swiper class="coupon-style-four" circular>
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index"
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style4_bg.png') + ')',
marginRight: couponItemHeight + 'px',
marginLeft: couponItemHeight + 'px'
}" @click="couponAction(item, index)">
<view class="coupon-info">
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
<text class="font-size-tag coupon-sign"></text>
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
</view>
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else>
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
<text class="font-size-tag coupon-sign"></text>
</view>
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }">
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}
</view> </view>
<!-- <text class="btn" v-if="item.useState == 0" :style="{
color: value.btnStyle.textColor,
backgroundColor: value.btnStyle.bgColor,
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}">
<text class="btn-content">{{ value.btnStyle.text }}</text>
</text>
<text class="btn" v-if="parseInt(item.useState)" :style="{
color: value.btnStyle.textColor,
backgroundColor: value.btnStyle.bgColor,
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}">
<text class="btn-content">去使用</text>
</text> -->
<text class="btn" v-if="item.useState == 0" :style="{
color: value.btnStyle.textColor,
backgroundColor: value.btnStyle.bgColor,
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}">
<text class="btn-content">{{ value.btnStyle.text }}</text>
</text>
<text class="btn to-use" v-if="item.useState == 1" :style="{
color: value.btnStyle.textColor,
backgroundColor: value.btnStyle.bgColor,
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}">
<text class="btn-content">去使用</text>
</text>
<text class="btn disabled" v-if="item.useState == 2" :style="{
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}">
<text class="btn-content">已抢光</text>
</text>
<text class="btn disabled" v-if="item.useState == 3" :style="{
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}">
<text class="btn-content">已失效</text>
</text>
<text class="btn disabled" v-if="item.useState == 4" :style="{
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}">
<text class="btn-content">已使用</text>
</text>
<text class="limit" :style="{ color: value.limitColor }" v-if="parseFloat(item.at_least) > 0">{{ item.at_least | moneyConduct }}元使用</text>
<text class="limit" :style="{ color: value.limitColor }" v-else>无门槛使用</text>
</view> </view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0">
{{ value.btnStyle.text || '立即使用' }}
</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用</view>
</view>
</swiper-item>
</swiper>
</template>
<template v-if="value.style == '5'"> <div v-if="computedCouponList.length <= 2" @click="$util.redirectTo('/pages/goods/category')"
<view class="coupon-style-five"> class="coupon coupon-null" :style="{
<view class="coupon-all"> color: value.moneyColor,
<view class="coupon-box"> backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-2.png') + ')',
marginRight: couponItemHeight + 'px',
marginLeft: couponItemHeight + 'px'
}">
<div class="coupon-content" :style="{ color: value.moneyColor }">
<span class="price">+</span>
<span class="text">暂无优惠券</span>
</div>
<span class="limit" :style="{ color: value.limitColor }">去逛逛</span>
</div>
</swiper-item>
</swiper>
</template>
<template v-if="value.style == '7'">
<scroll-view class="coupon-style-seven" scroll-x="true">
<view class="wrap">
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index" @click="couponAction(item, index)"> <view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index" @click="couponAction(item, index)">
<image :src="$util.img('public/uniapp/coupon/style5_bg.png')"></image> <image :src="$util.img('public/uniapp/coupon/style7_bg.png')"></image>
<view class="coupon"> <view class="coupon">
<view class="coupon-info"> <view class="coupon-info">
<view class="coupon-num" v-if="item.discount == '0.00'" :style="{ color: value.moneyColor }"> <view class="coupon-num" v-if="item.discount == '0.00'" :style="{ color: value.moneyColor }">
@@ -156,115 +287,32 @@
<text class="font-size-tag coupon-sign"></text> <text class="font-size-tag coupon-sign"></text>
</view> </view>
</view> </view>
<view class="coupon-type">
<text class="coupon-name" :style="{ color: value.limitColor }" v-if="item.at_least > 0">{{ Number(item.at_least) }}元可用</text>
<text class="coupon-name" :style="{ color: value.limitColor }" v-else>无门槛优惠券</text>
<view class="coupon-least" v-if="item.validity_type == 0" :style="{ color: value.limitColor }">有效期至{{ $util.timeStampTurnTime(item.end_time, 'Y-m-d') }}</view>
<view class="coupon-least" v-else-if="item.validity_type == 1" :style="{ color: value.limitColor }">领取后{{ item.fixed_term }}天有效</view>
<view class="coupon-least" v-else :style="{ color: value.limitColor }">领取后长期有效</view>
</view>
<view class="coupon-line"></view> <view class="coupon-line"></view>
<view class="coupon-content">
<view class="coupon-type"> <view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text || '立即领取' }}</view>
<view class="coupon-name" :style="{ color: value.nameColor }">{{ item.coupon_name }}</view> <view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
<text class="coupon-least" :style="{ color: value.limitColor }" v-if="item.at_least > 0">{{ Number(item.at_least) }}元可用</text> <view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
<text class="coupon-least" :style="{ color: value.limitColor }" v-else>无门槛优惠券</text> <view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
</view> <view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0">{{ value.btnStyle.text || '立即领取' }}</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用</view>
</view>
</view> </view>
</view> </view>
</view> </view>
</view> </scroll-view>
</view> </template>
</template>
<template v-if="value.style == '6'"> <ns-login ref="login"></ns-login>
<swiper class="coupon-style-six" circular>
<swiper-item class="style-six-wrap" v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex">
<view class="coupon" v-for="(item, index) in computedCouponList" :key="index"
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-1.png') + ')',
marginRight: couponItemHeight + 'px',
marginLeft: couponItemHeight + 'px'
}" @click="couponAction(item, index)">
<view class="coupon-content">
<view class="price-wrap">
<text class="price" :style="{ color: value.moneyColor }">{{ (item.discount == '0.00' ? item.money : item.discount) | moneyConduct }}</text>
<text class="unit">{{ item.discount == '0.00' ? '元' : '折' }}</text>
</view>
<text class="text">优惠券</text>
</view>
<text class="btn" v-if="item.useState == 0" :style="{
color: value.btnStyle.textColor,
backgroundColor: value.btnStyle.bgColor,
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}">
<text class="btn-content">{{ value.btnStyle.text }}</text>
</text>
<text class="btn" v-if="parseInt(item.useState)" :style="{
color: value.btnStyle.textColor,
backgroundColor: value.btnStyle.bgColor,
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}">
<text class="btn-content">去使用</text>
</text>
<text class="limit" :style="{ color: value.limitColor }" v-if="parseFloat(item.at_least) > 0">{{ item.at_least | moneyConduct }}元使用</text>
<text class="limit" :style="{ color: value.limitColor }" v-else>无门槛使用</text>
</view>
<div v-if="computedCouponList.length <= 2" @click="$util.redirectTo('/pages/goods/category')" </view>
class="coupon coupon-null" :style="{
color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-2.png') + ')',
marginRight: couponItemHeight + 'px',
marginLeft: couponItemHeight + 'px'
}">
<div class="coupon-content" :style="{ color: value.moneyColor }">
<span class="price">+</span>
<span class="text">暂无优惠券</span>
</div>
<span class="limit" :style="{ color: value.limitColor }">去逛逛</span>
</div>
</swiper-item>
</swiper>
</template>
<template v-if="value.style == '7'"> </x-skeleton>
<scroll-view class="coupon-style-seven" scroll-x="true"> </view>
<view class="wrap">
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index" @click="couponAction(item, index)">
<image :src="$util.img('public/uniapp/coupon/style7_bg.png')"></image>
<view class="coupon">
<view class="coupon-info">
<view class="coupon-num" v-if="item.discount == '0.00'" :style="{ color: value.moneyColor }">
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
<text class="font-size-tag coupon-sign"></text>
</view>
<view class="coupon-num" v-else :style="{ color: value.moneyColor }">
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
<text class="font-size-tag coupon-sign"></text>
</view>
</view>
<view class="coupon-type">
<text class="coupon-name" :style="{ color: value.limitColor }" v-if="item.at_least > 0">{{ Number(item.at_least) }}元可用</text>
<text class="coupon-name" :style="{ color: value.limitColor }" v-else>无门槛优惠券</text>
<view class="coupon-least" :style="{ color: value.limitColor }">有效期至{{ $util.timeStampTurnTime(item.end_time, 'yearmonthday') }}</view>
</view>
<view class="coupon-line"></view>
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0">
{{ value.btnStyle.text || '立即领取' }}
</view>
<view class="coupon-get" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用
</view>
</view>
</view>
</view>
</scroll-view>
</template>
<ns-login ref="login"></ns-login>
</view>
</x-skeleton>
</template> </template>
<script> <script>
@@ -313,17 +361,11 @@
couponItemHeight() { couponItemHeight() {
var width = ''; var width = '';
const screenWidth = uni.getSystemInfoSync().windowWidth; const screenWidth = uni.getSystemInfoSync().windowWidth;
if (this.value.style == '1') width = [screenWidth - this.rpxUpPx(210) * 3 - this.rpxUpPx(this.value.margin if (this.value.style == '1') width = [screenWidth - this.rpxUpPx(210) * 3 - this.rpxUpPx(this.value.margin.both * 2) * 2] / 6;
.both * 2) * 2] / 6; else if (this.value.style == '2') width = [screenWidth - this.rpxUpPx(210) * 3 - this.rpxUpPx(this.value.margin.both * 2) * 2] / 6;
else if (this.value.style == '2') width = [screenWidth - this.rpxUpPx(210) * 3 - this.rpxUpPx(this.value else if (this.value.style == '3') width = [screenWidth - this.rpxUpPx(24) * 2 - this.rpxUpPx(194) * 3 - this.rpxUpPx(this.value.margin.both * 2) * 2] / 6;
.margin.both * 2) * 2] / 6; else if (this.value.style == '4') width = [screenWidth - this.rpxUpPx(206) * 3 - this.rpxUpPx(this.value.margin.both * 2) * 2] / 6;
else if (this.value.style == '3') width = [screenWidth - this.rpxUpPx(24) * 2 - this.rpxUpPx(194) * 3 - else if (this.value.style == '6') width = [screenWidth - this.rpxUpPx(208) * 3 - this.rpxUpPx(this.value.margin.both * 2) * 2] / 6;
this.rpxUpPx(this.value.margin.both * 2) * 2
] / 6;
else if (this.value.style == '4') width = [screenWidth - this.rpxUpPx(206) * 3 - this.rpxUpPx(this.value
.margin.both * 2) * 2] / 6;
else if (this.value.style == '6') width = [screenWidth - this.rpxUpPx(208) * 3 - this.rpxUpPx(this.value
.margin.both * 2) * 2] / 6;
return width; return width;
}, },
@@ -357,12 +399,18 @@
if (data != null) { if (data != null) {
this.couponList = data; this.couponList = data;
this.couponList.forEach(v => { this.couponList.forEach(v => {
if (v.max_fetch != 0 && v.member_coupon_num && v.member_coupon_num >= v // if (v.count == v.lead_count) v.useState = 2;
.max_fetch) { // else if (v.max_fetch != 0 && v.member_coupon_num && v.member_coupon_num >= v.max_fetch) v.useState = 1;
v.useState = 1; // else v.useState = 0;
} else { // if(v.received_type && v.received_type == 'expire'){
v.useState = 0; // v.useState = 2;
} // }
if (v.count == v.lead_count) v.useState = 2;
else if (v.max_fetch == 0 || (v.max_fetch != 0 && !v.member_coupon_num) || (v.max_fetch != 0 && v.member_coupon_num && v.max_fetch > v.member_coupon_num)) v.useState = 0;
else if (v.wait_coupon_num) v.useState = 1
else if (v.lose_coupon_num) v.useState = 3;
else if (v.use_coupon_num) v.useState = 4;
}); });
} }
this.loading = false; this.loading = false;
@@ -372,18 +420,34 @@
couponAction(item, index) { couponAction(item, index) {
if (item.useState == 0) { if (item.useState == 0) {
this.receiveCoupon(item, index); this.receiveCoupon(item, index);
} else if (parseInt(item.useState)) { } else {
this.couponTap(item, index); this.couponTap(item, index);
} }
// if(item.received_type == 'out'){
// this.$util.showToast({
// title: '该优惠券已抢光'
// });
// }else if(item.received_type == 'expire'){
// this.$util.showToast({
// title: '该优惠券已过期'
// });
// }else if(item.received_type == 'limit'){
// this.$util.showToast({
// title: '该优惠券领取已达上限'
// });
// }
}, },
couponTap(item, index) { couponTap(item, index) {
if (item.count == item.lead_count) { if(item.useState == 2){
this.$util.showToast({ this.$util.showToast({
title: '该优惠券已抢光' title: '该优惠券已抢光'
}); });
return; return;
} }
if (item.useState == 0) this.receiveCoupon(item, index); if (item.useState == 0) this.receiveCoupon(item, index);
else if (item.useState == 3 || item.useState == 4) this.$util.redirectTo('/pages_tool/member/coupon',{state: item.useState == 4 ? 2 : item.useState})
else this.toGoodsList(item); else this.toGoodsList(item);
}, },
// 领取优惠券 // 领取优惠券
@@ -527,17 +591,21 @@
.coupon-get { .coupon-get {
position: relative; position: relative;
top: 2rpx; top: 0;
right: 12rpx; right: 12rpx;
font-size: 24rpx; font-size: 24rpx;
letter-spacing: 16rpx; letter-spacing: 16rpx;
width: 26rpx; width: 26rpx;
&.use { &.use {
top: 0; top: 0;
right: 4rpx; right: 4rpx;
letter-spacing: 4rpx; letter-spacing: 4rpx;
} }
&.three-text {
line-height: 1.2;
}
} }
.coupon-info { .coupon-info {
@@ -873,6 +941,12 @@
line-height: 1; line-height: 1;
transform: scale(0.8); transform: scale(0.8);
} }
&.disabled {
background-color: #eee;
color: #909399;
}
} }
.coupon-content { .coupon-content {
@@ -1045,6 +1119,11 @@
font-size: $font-size-tag; font-size: $font-size-tag;
box-sizing: border-box; box-sizing: border-box;
flex-shrink: 0; flex-shrink: 0;
&.three-text {
writing-mode: vertical-rl;
}
} }
} }
} }

View File

@@ -0,0 +1,276 @@
<template>
<view :style="componentStyle">
<scroll-view
:class="['graphic-nav', value.showStyle == 'fixed' ? 'fixed-layout' : value.showStyle]"
:scroll-x="value.showStyle == 'singleSlide'"
>
<view class="uni-scroll-view-content">
<view
v-for="(item, index) in value.list"
:key="index"
:class="['graphic-nav-item', value.mode, value.mode === 'text' ? 'newright' : '']"
:style="{ width: (100 / value.rowCount + '%') + ';' }"
>
<view style="display:flex;">
<view :style="{
'line-height': '1.2;',
'font-size': (value.font.titlesize * 2 + 'rpx') + ';',
'font-weight': '600;',
'color': value.font.titlecolor + ';'
}">
<uv-count-to
:ref="`countTo-${index}`"
:autoplay="true"
:startVal="30"
:endVal="item.title"
:decimals="getvalue(item.title)"
decimal="."
></uv-count-to>
<text :style="{
'margin-left': '4rpx;',
'font-size': (value.font.unitsize * 2 + 'rpx') + ';',
'font-weight': value.font.weight + ';',
'color': value.font.unitcolor + ';'
}">{{ item.unit }}</text>
</view>
</view>
<view class="graphic-text">
<text :style="{
'font-size': (value.font.descsize * 2 + 'rpx') + ';',
'font-weight': value.font.weight + ';',
'color': value.font.desccolor + ';'
}">{{ item.desc }}</text>
</view>
</view>
</view>
</scroll-view>
<ns-login ref="login"></ns-login>
</view>
</template>
<script>
import uvCountTo from '@/components/uv-count-to/uv-count-to.vue'
import nsLogin from '@/components/ns-login/ns-login.vue'
export default {
name: 'diy-digit',
components: {
uvCountTo,
nsLogin
},
props: {
value: {
type: Object,
default: () => ({})
}
},
data() {
return {
pageWidth: '',
indicatorDots: false,
swiperCurrent: 0
}
},
created() {
// 组件创建时的逻辑
},
watch: {
componentRefresh(newValue) {
// 监听组件刷新
}
},
computed: {
componentStyle() {
let style = '';
style += 'background-image:url(' + this.$util.img(this.value.imageUrl) + ');background-size:100% 100%;';
if (this.value.componentAngle == 'round') {
style += 'border-top-left-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
style += 'border-top-right-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
style += 'border-bottom-left-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
style += 'border-bottom-right-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
}
style += 'box-shadow:' + (this.value.ornament.type == 'shadow' ? '0 0 10rpx ' + this.value.ornament.color : '') + ';';
style += 'border:' + (this.value.ornament.type == 'stroke' ? '2rpx solid ' + this.value.ornament.color : '') + ';';
return style;
}
},
methods: {
// 获取小数位数
getvalue(value) {
return value % 1 !== 0 ? 2 : 0;
},
// 页面跳转
redirectTo(item) {
if (!item.wap_url || this.$util.getCurrRoute() != 'pages/member/index' || this.storeToken) {
console.log(item);
this.$util.diyRedirectTo(item);
} else {
this.$refs.login.open(item.wap_url);
}
},
// 轮播切换
swiperChange(event) {
this.swiperCurrent = event.detail.current;
}
}
}
</script>
<style lang="scss" scoped>
.graphic-nav {
padding: 16rpx;
box-sizing: border-box;
&.fixed-layout {
.uni-scroll-view-content {
display: flex;
flex-wrap: wrap;
}
}
&.singleSlide {
.uni-scroll-view-content {
display: flex;
}
.graphic-nav-item {
flex-shrink: 0;
}
}
&.pageSlide {
position: relative;
.uni-swiper-dots-horizontal {
bottom: 0rpx;
}
&.straightLine {
.uni-swiper-dot {
width: 30rpx;
border-radius: 0;
height: 8rpx;
}
}
&.circle {
.uni-swiper-dot {
width: 14rpx;
height: 14rpx;
}
}
}
.graphic-nav-wrap {
display: flex;
flex-wrap: wrap;
width: 100%;
height: 100%;
}
.graphic-nav-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 14rpx 0;
box-sizing: border-box;
.graphic-text {
line-height: 1.3;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: 100%;
text-align: center;
&.alone {
padding-top: 0;
}
}
&.text {
.graphic-text {
padding-top: 0;
}
}
.graphic-img {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100rpx;
height: 100rpx;
font-size: 90rpx;
.tag {
position: absolute;
top: -10rpx;
right: -24rpx;
color: #fff;
border-radius: 24rpx;
border-bottom-left-radius: 0;
-webkit-transform: scale(0.8);
transform: scale(0.8);
padding: 8rpx 16rpx;
line-height: 1;
font-size: 24rpx;
}
.icon {
font-size: 50rpx;
color: #606266;
}
}
}
&.pageSlide {
.graphic-nav-item {
flex-shrink: 0;
}
}
}
.newright {
margin-right: 16rpx;
}
.swiper-dot-box {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: -20rpx;
padding-bottom: 8rpx;
.swiper-dot {
background-color: rgba(0, 0, 0, 0.3);
margin: 8rpx;
&.active {
background-color: #000;
}
}
&.straightLine {
.swiper-dot {
width: 30rpx;
border-radius: 0;
height: 8rpx;
}
}
&.circle {
.swiper-dot {
width: 15rpx;
border-radius: 50%;
height: 15rpx;
}
}
}
</style>

View File

@@ -1,48 +1,48 @@
<template> <template>
<view data-component-name="diy-fenxiao-goods-list" class="diy-fenxiao" v-if="list.length" :class="['goods-list', value.template, value.style]" :style="goodsListWarpCss"> <view :style="value.pageStyle" v-if="list && list.length">
<view class="goods-item" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss"> <view class="diy-fenxiao" v-if="list.length" :class="['goods-list', value.template, value.style]" :style="goodsListWarpCss">
<view class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="goods-item" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)"/> <view class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
</view> <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)"/>
<view class="info-wrap" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
<view class="name-wrap">
<view v-if="value.goodsNameStyle.control" class="goods-name"
:style="{ color: value.theme == 'diy' ? value.goodsNameStyle.color : '', fontWeight: value.goodsNameStyle.fontWeight ? 'bold' : '' }"
:class="[{ 'using-hidden': value.nameLineMode == 'single' }, { 'multi-hidden': value.nameLineMode == 'multiple' }]"
>
{{ item.goods_name }}
</view>
</view> </view>
<view class="pro-info"> <view class="info-wrap" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
<view class="discount-price"> <view class="name-wrap">
<view class="price-wrap" v-if="value.priceStyle.mainControl"> <view v-if="value.goodsNameStyle.control" class="goods-name"
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }"> </text> :style="{ color: value.theme == 'diy' ? value.goodsNameStyle.color : '', fontWeight: value.goodsNameStyle.fontWeight ? 'bold' : '' }"
<text class="price price-style large" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">{{ item.commission_money.split('.')[0] }}</text> :class="[{ 'using-hidden': value.nameLineMode == 'single' }, { 'multi-hidden': value.nameLineMode == 'multiple' }]"
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">{{ '.' + item.commission_money.split('.')[1] }}</text>
</view>
<view class="sale-btn" v-if="value.btnStyle.control && item.is_collect == 0"
:style="{
background: value.btnStyle.theme == 'diy' ? 'linear-gradient(to right,' + value.btnStyle.bgColorStart + ',' + value.btnStyle.bgColorEnd + ')' : '',
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}"
@click.stop="followGoods(item, index)"
> >
关注 {{ item.goods_name }}
</view>
<view class="sale-btn" v-if="value.btnStyle.control && item.is_collect == 1"
:style="{
background: value.btnStyle.theme == 'diy' ? 'linear-gradient(to right,' + value.btnStyle.bgColorStart + ',' + value.btnStyle.bgColorEnd + ')' : '',
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}"
@click.stop="delFollowTip(item, index)"
>
取消关注
</view> </view>
</view> </view>
<view class="delete-price" v-if="value.priceStyle.lineControl" :style="{ color: value.theme == 'diy' ? value.priceStyle.lineColor : '' }"> <view class="pro-info">
{{ item.discount_price }} <view class="discount-price">
<view class="price-wrap" v-if="value.priceStyle.mainControl">
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }"> </text>
<text class="price price-style large" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">{{ item.commission_money.split('.')[0] }}</text>
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">{{ '.' + item.commission_money.split('.')[1] }}</text>
</view>
<view class="sale-btn" v-if="value.btnStyle.control && item.is_collect == 0"
:style="{
background: value.btnStyle.theme == 'diy' ? 'linear-gradient(to right,' + value.btnStyle.bgColorStart + ',' + value.btnStyle.bgColorEnd + ')' : '',
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}"
@click.stop="followGoods(item, index)">
关注
</view>
<view class="sale-btn" v-if="value.btnStyle.control && item.is_collect == 1"
:style="{
background: value.btnStyle.theme == 'diy' ? 'linear-gradient(to right,' + value.btnStyle.bgColorStart + ',' + value.btnStyle.bgColorEnd + ')' : '',
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
}"
@click.stop="delFollowTip(item, index)">
取消关注
</view>
</view>
<view class="delete-price" v-if="value.priceStyle.lineControl" :style="{ color: value.theme == 'diy' ? value.priceStyle.lineColor : '' }">
{{ item.discount_price }}
</view>
</view> </view>
</view> </view>
</view> </view>
@@ -55,7 +55,10 @@ export default {
name: 'diy-fenxiao-goods-list', name: 'diy-fenxiao-goods-list',
props: { props: {
value: { value: {
type: Object type: Object,
default: () => {
return {};
}
} }
}, },
data() { data() {

View File

@@ -1,12 +1,13 @@
<template> <template>
<view data-component-name="diy-float-btn" class="float-btn" :class="{ left_top: value.bottomPosition == 1, right_top: value.bottomPosition == 2, left_bottom: value.bottomPosition == 3, right_bottom: value.bottomPosition == 4 }" :style="style"> <view :style="value.pageStyle">
<block v-for="(item, index) in value.list" :key="index"> <view class="float-btn" :class="{ left_top: value.bottomPosition == 1, right_top: value.bottomPosition == 2, left_bottom: value.bottomPosition == 3, right_bottom: value.bottomPosition == 4 }" :style="style">
<view class="button-box" @click="$util.diyRedirectTo(item.link)" :style="{ width: value.imageSize + 'px', height: value.imageSize + 'px', fontSize: value.imageSize + 'px' }"> <block v-for="(item, index) in value.list" :key="index">
<image v-if="!item.iconType || item.iconType == 'img'" :src="$util.img(item.imageUrl)" mode="aspectFit" :show-menu-by-longpress="true"/> <view class="button-box" @click="$util.diyRedirectTo(item.link)" :style="{ width: value.imageSize + 'px', height: value.imageSize + 'px', fontSize: value.imageSize + 'px' }">
<diy-icon v-else-if="item.iconType && item.iconType == 'icon'" :icon="item.icon" <image v-if="!item.iconType || item.iconType == 'img'" :src="$util.img(item.imageUrl)" mode="aspectFit" :show-menu-by-longpress="true"/>
:value="item.style ? item.style : null"></diy-icon> <diy-icon v-else-if="item.iconType && item.iconType == 'icon'" :icon="item.icon" :value="item.style ? item.style : null"></diy-icon>
</view> </view>
</block> </block>
</view>
</view> </view>
</template> </template>

View File

@@ -1,7 +1,9 @@
<template> <template>
<!-- #ifdef MP --> <!-- #ifdef MP -->
<view data-component-name="diy-follow-official-account" v-if="value.isShow"> <view :style="value.pageStyle">
<official-account></official-account> <view v-if="value.isShow">
<official-account></official-account>
</view>
</view> </view>
<!--#endif --> <!--#endif -->
</template> </template>
@@ -12,7 +14,10 @@
name: 'diy-follow-official-account', name: 'diy-follow-official-account',
props: { props: {
value: { value: {
type: Object type: Object,
default: () => {
return {};
}
} }
}, },
data() { data() {

View File

@@ -1,17 +1,18 @@
<template> <template>
<x-skeleton data-component-name="diy-goods-brand" type="waterfall" :loading="loading" :configs="skeletonConfig"> <view :style="value.pageStyle" v-if="loading || (list && list.length)">
<view :class="['brand-wrap', value.ornament.type]" :style="warpCss"> <x-skeleton type="waterfall" :loading="loading" :configs="skeletonConfig">
<view :class="[value.style]"> <view :class="['brand-wrap', value.ornament.type]" :style="warpCss">
<view class="title-wrap" v-show="value.title" :style="{ color: value.textColor, fontWeight: value.fontWeight ? 'bold' : '' }">{{ value.title }} <view :class="[value.style]">
</view> <view class="title-wrap" v-show="value.title" :style="{ color: value.textColor, fontWeight: value.fontWeight ? 'bold' : '' }">{{ value.title }}</view>
<view class="ul-wrap"> <view class="ul-wrap">
<view class="li-item" v-for="(item, index) in list" :key="index"> <view class="li-item" v-for="(item, index) in list" :key="index">
<image class="brand-pic" :src="$util.img(item.image_url)" mode="aspectFit" @click="handlerClick(item)" @tap="handlerClick(item)" @error="imgError(index)" :style="itemCss"/> <image class="brand-pic" :src="$util.img(item.image_url)" mode="aspectFit" @click="toDetail(item)" @error="imgError(index)" :style="itemCss"/>
</view>
</view> </view>
</view> </view>
</view> </view>
</view> </x-skeleton>
</x-skeleton> </view>
</template> </template>
<script> <script>
@@ -25,7 +26,10 @@
name: 'diy-goods-brand', name: 'diy-goods-brand',
props: { props: {
value: { value: {
type: Object type: Object,
default: () => {
return {};
}
} }
}, },
components: { components: {

View File

@@ -3,7 +3,7 @@
<block v-if="value.showStyle == 'pageSlide'"> <block v-if="value.showStyle == 'pageSlide'">
<swiper :class="['graphic-nav', 'pageSlide', value.carousel.type]" circular :indicator-dots="false" :style="swiperHeight" @change="swiperChange"> <swiper :class="['graphic-nav', 'pageSlide', value.carousel.type]" circular :indicator-dots="false" :style="swiperHeight" @change="swiperChange">
<swiper-item class="graphic-nav-wrap" <swiper-item class="graphic-nav-wrap"
v-for="(numItem, numIndex) in Math.ceil(value.list.length / (value.pageCount * value.rowCount))"> v-for="(numItem, numIndex) in Math.ceil(value.list.length / (value.pageCount * value.rowCount))" :key="numIndex">
<!-- #ifdef MP --> <!-- #ifdef MP -->
<view class="graphic-nav-item" :class="[value.mode]" v-for="(item, index) in value.list" <view class="graphic-nav-item" :class="[value.mode]" v-for="(item, index) in value.list"
:key="index" :key="index"

View File

@@ -0,0 +1,290 @@
<template>
<view :style="componentStyle">
<scroll-view
:class="['image-nav', value.showStyle == 'fixed' ? 'fixed-layout' : value.showStyle]"
:scroll-x="value.showStyle == 'singleSlide'"
>
<view class="uni-scroll-view-content">
<view
v-for="(item, index) in value.list"
:key="index"
:class="['image-nav-item', value.mode]"
style="margin-right: 28rpx;"
>
<!-- 图片部分 -->
<view v-if="value.mode != 'text'" class="image-img" :style="{
'font-size': (value.imageSize * 2 + 'rpx') + ';',
'width': (item.imgWidth / 2 + 'rpx') + ';',
'height': (item.imgHeight / 2 + 'rpx') + ';'
}">
<image
v-if="item.link.wap_url"
:style="{
'width': (item.imgWidth / 2 + 'rpx') + ';',
'height': (item.imgHeight / 2 + 'rpx') + ';'
}"
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
:show-menu-by-longpress="true"
@tap="redirectTo(item.link)"
></image>
<image
v-else
:style="{
'width': (item.imgWidth / 2 + 'rpx') + ';',
'height': (item.imgHeight / 2 + 'rpx') + ';'
}"
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
:show-menu-by-longpress="true"
@tap="previewImg(item.imageUrl)"
></image>
</view>
<!-- 文字部分 -->
<text class="image-text" :style="{
'width': (item.imgWidth / 2 + 'rpx') + ';',
'font-size': (value.font.size * 2 + 'rpx') + ';',
'font-weight': value.font.weight + ';',
'color': value.font.color + ';'
}">{{ item.title }}</text>
</view>
</view>
</scroll-view>
<ns-login ref="login"></ns-login>
</view>
</template>
<script>
import nsLogin from '@/components/ns-login/ns-login.vue'
export default {
name: 'diy-image-nav',
components: {
nsLogin
},
props: {
value: {
type: Object,
default: () => ({})
}
},
data() {
return {
pageWidth: '',
indicatorDots: false,
swiperCurrent: 0
}
},
created() {
// 组件创建时的逻辑
},
watch: {
componentRefresh(newValue) {
// 监听组件刷新
}
},
computed: {
componentStyle() {
let style = '';
style += 'background-color:' + this.value.componentBgColor + ';';
if (this.value.componentAngle == 'round') {
style += 'border-top-left-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
style += 'border-top-right-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
style += 'border-bottom-left-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
style += 'border-bottom-right-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
}
style += 'box-shadow:' + (this.value.ornament.type == 'shadow' ? '0 0 10rpx ' + this.value.ornament.color : '') + ';';
style += 'border:' + (this.value.ornament.type == 'stroke' ? '2rpx solid ' + this.value.ornament.color : '') + ';';
return style;
},
swiperHeight() {
let height = 0;
if (this.value.mode == 'graphic') {
height = (49 + this.value.imageSize) * this.value.pageCount;
} else if (this.value.mode == 'img') {
height = (22 + this.value.imageSize) * this.value.pageCount;
} else if (this.value.mode == 'text') {
height = 43 * this.value.pageCount;
}
return 'height:' + (2 * height) + 'rpx';
},
isIndicatorDots() {
return this.value.carousel.type != 'hide' &&
1 != Math.ceil(this.value.list.length / (this.value.pageCount * this.value.rowCount));
}
},
methods: {
// 预览图片
previewImg(imageUrl) {
uni.previewImage({
current: 0,
urls: [this.$util.img(imageUrl)],
success: (res) => {},
fail: (res) => {},
complete: (res) => {}
});
},
// 页面跳转
redirectTo(link) {
if (!link.wap_url || this.$util.getCurrRoute() != 'pages/member/index' || this.storeToken) {
this.$util.diyRedirectTo(link);
} else {
this.$refs.login.open(link.wap_url);
}
},
// 轮播切换
swiperChange(event) {
this.swiperCurrent = event.detail.current;
}
}
}
</script>
<style lang="scss" scoped>
.image-nav {
padding: 16rpx;
box-sizing: border-box;
&.fixed-layout {
.uni-scroll-view-content {
display: flex;
flex-wrap: wrap;
}
}
&.singleSlide {
.uni-scroll-view-content {
display: flex;
}
.image-nav-item {
flex-shrink: 0;
}
}
&.pageSlide {
position: relative;
.uni-swiper-dots-horizontal {
bottom: 0rpx;
}
&.straightLine {
.uni-swiper-dot {
width: 30rpx;
border-radius: 0;
height: 8rpx;
}
}
&.circle {
.uni-swiper-dot {
width: 14rpx;
height: 14rpx;
}
}
}
.image-nav-wrap {
display: flex;
flex-wrap: wrap;
width: 100%;
height: 100%;
}
.image-nav-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 14rpx 0;
box-sizing: border-box;
.image-text {
padding-top: 12rpx;
line-height: 1.5;
text-overflow: ellipsis;
overflow: hidden;
text-align: center;
&.alone {
padding-top: 0;
}
}
&.text {
.image-text {
padding-top: 0;
}
}
.image-img {
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-size: 90rpx;
.tag {
position: absolute;
top: -10rpx;
right: -24rpx;
color: #fff;
border-radius: 24rpx;
border-bottom-left-radius: 0;
-webkit-transform: scale(0.8);
transform: scale(0.8);
padding: 8rpx 16rpx;
line-height: 1;
font-size: 24rpx;
}
.icon {
font-size: 50rpx;
color: #606266;
}
}
}
}
.swiper-dot-box {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: -20rpx;
padding-bottom: 8rpx;
.swiper-dot {
background-color: rgba(0, 0, 0, 0.3);
margin: 8rpx;
&.active {
background-color: #000;
}
}
&.straightLine {
.swiper-dot {
width: 30rpx;
border-radius: 0;
height: 8rpx;
}
}
&.circle {
.swiper-dot {
width: 15rpx;
border-radius: 50%;
height: 15rpx;
}
}
}
</style>

View File

@@ -268,7 +268,7 @@
.exec(); .exec();
}); });
this.setModuleLocatinoFn(); this.setModuleLocationFn();
}, },
methods: { methods: {
initPageIndex() { initPageIndex() {
@@ -415,7 +415,7 @@
this.isUnfold = !this.isUnfold; this.isUnfold = !this.isUnfold;
}, },
// 向vuex中的diyIndexPositionObj增加分类导航组件定位位置 // 向vuex中的diyIndexPositionObj增加分类导航组件定位位置
setModuleLocatinoFn() { setModuleLocationFn() {
const query = uni.createSelectorQuery().in(this); const query = uni.createSelectorQuery().in(this);
query.select('.nav-top-category') query.select('.nav-top-category')
.boundingClientRect(data => { .boundingClientRect(data => {

View File

@@ -1,6 +1,6 @@
<template> <template>
<view data-component-name="diy-kefu" class="diy-kefu" :style="style"> <view data-component-name="diy-kefu" class="diy-kefu" :style="style">
<view class="fui-list-group merchgroup" v-for="(item,index) in value.list"> <view class="fui-list-group merchgroup" v-for="(item,index) in value.list" :key="index">
<view class="fui-list jump" v-if="index == 0"> <view class="fui-list jump" v-if="index == 0">
<view class="fui-list-media"> <view class="fui-list-media">
<image class="round" :src="$util.img(item.imageUrl)" style="border-radius:6rpx"></image> <image class="round" :src="$util.img(item.imageUrl)" style="border-radius:6rpx"></image>

View File

@@ -3,7 +3,7 @@
<view class="fui-cell-group"> <view class="fui-cell-group">
<!-- <image mode="widthFix" style="width: 100%;" :src="$util.img(item.imageUrl)"></image> --> <!-- <image mode="widthFix" style="width: 100%;" :src="$util.img(item.imageUrl)"></image> -->
<view v-for="(item,index) in value.list" @click="redirectTo(item.link)" class="fui-cell" :class="item.iconType == 'img'?'img-cell':''"> <view v-for="(item,index) in value.list" @click="redirectTo(item.link)" class="fui-cell" :class="item.iconType == 'img'?'img-cell':''" :key="index">
<view class="fui-cell-icon" style="color:diyitem.style.iconcolo"> <view class="fui-cell-icon" style="color:diyitem.style.iconcolo">
<diy-icon v-if="item.iconType == 'icon'" :icon="item.icon" <diy-icon v-if="item.iconType == 'icon'" :icon="item.icon"
:value="item.style ? item.style : null" :value="item.style ? item.style : null"

View File

@@ -1,6 +1,6 @@
<template> <template>
<view data-component-name="diy-map" class="diy-map" :style="style"> <view data-component-name="diy-map" class="diy-map" :style="style">
<view class="fui-list-group merchgroup" style="margin-top:0" v-for="(item,index) in value.list"> <view class="fui-list-group merchgroup" style="margin-top:0" v-for="(item,index) in value.list" :key="index">
<map <map
id="map" id="map"
style="width: 100%; height:600rpx" style="width: 100%; height:600rpx"

View File

@@ -1,7 +1,7 @@
<template> <template>
<view data-component-name="diy-picture" class="diy-picture" :style="style"> <view data-component-name="diy-picture" class="diy-picture" :style="style">
<view class="fui-picture"> <view class="fui-picture">
<view v-for="(item,index) in value.list" style="line-height: 0;"> <view v-for="(item,index) in value.list" style="line-height: 0;" :key="index">
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-if="item.link.wap_url" @click="handlerClick(item)" @tap="handlerClick(item)"></image> <image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-if="item.link.wap_url" @click="handlerClick(item)" @tap="handlerClick(item)"></image>
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-else @click="handlerClick(item)" @tap="handlerClick(item)"></image> <image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-else @click="handlerClick(item)" @tap="handlerClick(item)"></image>
</view> </view>

View File

@@ -173,7 +173,7 @@
if (this.value.ornament.type == 'stroke') { if (this.value.ornament.type == 'stroke') {
obj += 'border:' + '2rpx solid ' + this.value.ornament.color + ';'; obj += 'border:' + '2rpx solid ' + this.value.ornament.color + ';';
} }
const screenWidth = uni.getSystemInfoSync().windowWidth; const screenWidth = uni.getWindowInfo().windowWidth;
if (this.value.template == 'horizontal-slide') { if (this.value.template == 'horizontal-slide') {
var width = ""; var width = "";
if (this.value.slideMode == 'scroll' && this.value.goodsMarginType == 'diy') if (this.value.slideMode == 'scroll' && this.value.goodsMarginType == 'diy')
@@ -217,7 +217,7 @@
} }
}, },
rpxUpPx(res) { rpxUpPx(res) {
const screenWidth = uni.getSystemInfoSync().windowWidth; const screenWidth = uni.getWindowInfo().windowWidth;
var data = screenWidth * parseInt(res) / 750; var data = screenWidth * parseInt(res) / 750;
return Math.floor(data); return Math.floor(data);
}, },

View File

@@ -1,4 +1,5 @@
<template> <template>
<view :style="value.pageStyle">
<view data-component-name="diy-search" class="diy-search"> <view data-component-name="diy-search" class="diy-search">
<view class="diy-search-wrap" :class="value.positionWay" :style="fixedCss"> <view class="diy-search-wrap" :class="value.positionWay" :style="fixedCss">
<view :class="['search-box','search-box-'+value.searchStyle]" :style="searchWrapCss" @click="handlerSearchClick" @tap="handlerSearchClick"> <view :class="['search-box','search-box-'+value.searchStyle]" :style="searchWrapCss" @click="handlerSearchClick" @tap="handlerSearchClick">
@@ -33,11 +34,19 @@
<view v-if="value.positionWay == 'fixed'" class="u-navbar-placeholder" :style="{ width: '100%', paddingTop: moduleHeight }"></view> <view v-if="value.positionWay == 'fixed'" class="u-navbar-placeholder" :style="{ width: '100%', paddingTop: moduleHeight }"></view>
<ns-login ref="login"></ns-login> <ns-login ref="login"></ns-login>
</view> </view>
</view>
</template> </template>
<script> <script>
// 获取系统状态栏的高度 // 获取系统状态栏的高度
let systemInfo = uni.getSystemInfoSync(); let systemInfo = {};
try {
// 合并设备信息和窗口信息
systemInfo = {...uni.getDeviceInfo(), ...uni.getWindowInfo()};
} catch (e) {
// 兼容旧版本
systemInfo = uni.getSystemInfoSync();
}
let menuButtonInfo = {}; let menuButtonInfo = {};
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API尚未兼容) // 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API尚未兼容)
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ // #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
@@ -125,7 +134,7 @@
}, },
fixedTop() { fixedTop() {
let diyPositionObj = this.$store.state.diyGroupPositionObj; let diyPositionObj = this.$store.state.diyGroupPositionObj;
let data = 0 let data = 0;
if (diyPositionObj.diySearch && diyPositionObj.diyIndexPage && diyPositionObj.nsNavbar) { if (diyPositionObj.diySearch && diyPositionObj.diyIndexPage && diyPositionObj.nsNavbar) {
if (diyPositionObj.diySearch.moduleIndex > diyPositionObj.diyIndexPage.moduleIndex) { if (diyPositionObj.diySearch.moduleIndex > diyPositionObj.diyIndexPage.moduleIndex) {
data = diyPositionObj.nsNavbar.originalVal + diyPositionObj.diyIndexPage.originalVal; data = diyPositionObj.nsNavbar.originalVal + diyPositionObj.diyIndexPage.originalVal;
@@ -175,7 +184,7 @@
}, },
mounted() { mounted() {
if (this.value.positionWay == 'fixed') if (this.value.positionWay == 'fixed')
this.setModuleLocatinoFn(); this.setModuleLocationFn();
}, },
methods: { methods: {
search() { search() {
@@ -204,7 +213,7 @@
}); });
}, },
// 向vuex中的diyIndexPositionObj增加搜索组件定位位置 // 向vuex中的diyIndexPositionObj增加搜索组件定位位置
setModuleLocatinoFn() { setModuleLocationFn() {
this.$nextTick(() => { this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this); const query = uni.createSelectorQuery().in(this);
query.select('.diy-search-wrap') query.select('.diy-search-wrap')

View File

@@ -258,7 +258,7 @@
if (this.value.ornament.type == 'stroke') { if (this.value.ornament.type == 'stroke') {
obj += 'border:' + '2rpx solid ' + this.value.ornament.color + ';'; obj += 'border:' + '2rpx solid ' + this.value.ornament.color + ';';
} }
const screenWidth = uni.getSystemInfoSync().windowWidth; const screenWidth = uni.getWindowInfo().windowWidth;
if (this.value.template == 'horizontal-slide') { if (this.value.template == 'horizontal-slide') {
var width = ''; var width = '';
if (this.value.slideMode == 'scroll' && this.value.goodsMarginType == 'diy') width = this.rpxUpPx(this.value.goodsMarginNum * 2); if (this.value.slideMode == 'scroll' && this.value.goodsMarginType == 'diy') width = this.rpxUpPx(this.value.goodsMarginNum * 2);
@@ -312,7 +312,7 @@
} }
}, },
rpxUpPx(res) { rpxUpPx(res) {
const screenWidth = uni.getSystemInfoSync().screenWidth; const screenWidth = uni.getWindowInfo().screenWidth;
var data = (screenWidth * parseInt(res)) / 750; var data = (screenWidth * parseInt(res)) / 750;
return Math.floor(data); return Math.floor(data);
}, },

View File

@@ -1,9 +1,10 @@
<template> <template>
<view :style="value.pageStyle">
<x-skeleton data-component-name="diy-store-label" type="banner" :loading="loading" :configs="skeletonConfig"> <x-skeleton data-component-name="diy-store-label" type="banner" :loading="loading" :configs="skeletonConfig">
<view class="diy-store-label"> <view class="diy-store-label">
<block v-if="businessConfig.store_business == 'store'"> <block v-if="businessConfig.store_business == 'store'">
<scroll-view scroll-x="true" :class="[value.contentStyle, { between: list.length == 3 }]" :style="storeLabelWrapCss" :enable-flex="true"> <scroll-view scroll-x="true" :class="[value.contentStyle, { between: list.length == 3 }]" :style="storeLabelWrapCss" :enable-flex="true">
<view v-for="(item, index) in storeLabel" :class="['item']"> <view v-for="(item, index) in storeLabel" :class="['item']" :key="index">
<diy-icon v-if="value.icon" class="icon-box" :icon="value.icon" :value="value.style ? value.style : 'null'"></diy-icon> <diy-icon v-if="value.icon" class="icon-box" :icon="value.icon" :value="value.style ? value.style : 'null'"></diy-icon>
<text class="label-name" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx', fontWeight: value.fontWeight }">{{ item }}</text> <text class="label-name" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx', fontWeight: value.fontWeight }">{{ item }}</text>
</view> </view>
@@ -11,7 +12,7 @@
</block> </block>
<block v-else> <block v-else>
<scroll-view scroll-x="true" :class="[value.contentStyle, { between: list.length == 3 }]" :style="storeLabelWrapCss" :enable-flex="true"> <scroll-view scroll-x="true" :class="[value.contentStyle, { between: list.length == 3 }]" :style="storeLabelWrapCss" :enable-flex="true">
<view v-for="(item, index) in list" :class="['item']"> <view v-for="(item, index) in list" :class="['item']" :key="item.label_id || index">
<diy-icon v-if="value.icon" class="icon-box" :icon="value.icon" :value="value.style ? value.style : 'null'"></diy-icon> <diy-icon v-if="value.icon" class="icon-box" :icon="value.icon" :value="value.style ? value.style : 'null'"></diy-icon>
<text class="label-name" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx', fontWeight: value.fontWeight }">{{ item.label_name }}</text> <text class="label-name" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx', fontWeight: value.fontWeight }">{{ item.label_name }}</text>
</view> </view>
@@ -19,6 +20,7 @@
</block> </block>
</view> </view>
</x-skeleton> </x-skeleton>
</view>
</template> </template>
<script> <script>
// 门店标签 // 门店标签
@@ -26,7 +28,10 @@
name: 'diy-store-label', name: 'diy-store-label',
props: { props: {
value: { value: {
type: Object type: Object,
default: () => {
return {};
}
} }
}, },
data() { data() {

View File

@@ -1,4 +1,5 @@
<template> <template>
<view :style="value.pageStyle">
<view data-component-name="diy-store" class="store-wrap"> <view data-component-name="diy-store" class="store-wrap">
<block v-if="value.style == 1"> <block v-if="value.style == 1">
<view class="store-box store-one"> <view class="store-box store-one">
@@ -65,6 +66,7 @@
</view> </view>
</block> </block>
</view> </view>
</view>
</template> </template>
<script> <script>
@@ -74,7 +76,10 @@ export default {
name: 'diy-store', name: 'diy-store',
props: { props: {
value: { value: {
type: Object type: Object,
default: () => {
return {};
}
} }
}, },
data() { data() {

View File

@@ -1,4 +1,5 @@
<template> <template>
<view :style="value.pageStyle">
<view data-component-name="diy-text" class="diy-text" @click="handlerClick(value.link)" @tap="handlerClick(value.link)" :style="warpCss"> <view data-component-name="diy-text" class="diy-text" @click="handlerClick(value.link)" @tap="handlerClick(value.link)" :style="warpCss">
<view :class="value.style == 'style-8' ? 'title2' : 'title'" :style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor }"> <view :class="value.style == 'style-8' ? 'title2' : 'title'" :style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor }">
<block v-if="value.style == 'style-0'" style="height: 40rpx; line-height: 40rpx;"> <block v-if="value.style == 'style-0'" style="height: 40rpx; line-height: 40rpx;">
@@ -254,6 +255,7 @@
</view> </view>
</view> </view>
</view> </view>
</view>
</template> </template>
<script> <script>
@@ -263,7 +265,10 @@ export default {
name: 'diy-text', name: 'diy-text',
props: { props: {
value: { value: {
type: Object type: Object,
default: () => {
return {};
}
} }
}, },
data() { data() {

View File

@@ -0,0 +1,704 @@
<template>
<view :style="componentStyle">
<!-- 固定布局模式 -->
<view v-if="value.showStyle == 'fixed'" :class="['goods-list', 'row1-of' + value.rowCount]" style="padding:20rpx;">
<view
v-for="(item, index) in value.list"
:key="index"
class="goods-item"
@tap="showVideo(item)"
>
<view class="goods-img-wrap">
<image
class="goods-img"
style="border-radius:10rpx 10rpx 0 0;"
:src="$util.img(item.imageUrl)"
mode="widthFix"
@error="imgError(index)"
></image>
<view style="position:absolute;top:10rpx;right:10rpx;">
<image style="width:30rpx;" :src="$util.img('addon/personnel/shop/view/enterprise/play.png')" mode="widthFix"></image>
</view>
</view>
<view class="info-wrap">
<view
class="goods-name"
:style="{
'font-size': (value.font.size * 2 + 'rpx') + ';',
'font-weight': value.font.weight + ';',
'color': value.font.color + ';'
}"
>{{ item.title }}</view>
</view>
</view>
</view>
<!-- 其他布局模式 -->
<scroll-view
v-else
:class="['video-nav', value.showStyle == 'fixed' ? 'fixed-layout' : value.showStyle]"
:scroll-x="value.showStyle == 'singleSlide'"
>
<view class="uni-scroll-view-content">
<view
v-for="(item, index) in value.list"
:key="index"
:class="['video-nav-item', value.mode]"
:style="{ width: (100 / value.rowCount + '%') + ';' }"
@tap="showVideo(item)"
>
<view class="video-img">
<image
v-if="item.iconType == 'img'"
:style="{
'max-width': '200rpx;',
'max-height': '200rpx;',
'border-radius': '8rpx;'
}"
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
mode="widthFix"
:show-menu-by-longpress="true"
></image>
<view style="position:absolute;top:10rpx;right:10rpx;">
<image style="width:30rpx;" :src="$util.img('addon/personnel/shop/view/enterprise/play.png')" mode="widthFix"></image>
</view>
</view>
<view
class="video-text"
:style="{
'margin-left': '16rpx;',
'font-size': (value.font.size * 2 + 'rpx') + ';',
'font-weight': value.font.weight + ';',
'color': value.font.color + ';'
}"
>{{ item.title }}</view>
</view>
</view>
</scroll-view>
<!-- 视频播放弹窗 -->
<uni-popup
ref="videoPopup"
type="center"
style="background:transparent;width:100%;height:100%;"
>
<view class="video-container" style="position:fixed;top:30%;width:100%;left:0;">
<video
class="adaptive-video"
:autoPauseIfNavigate="true"
:autoPauseIfOpenNative="true"
:autoplay="false"
:enableAutoRotation="true"
id="myVideo"
:src="video_url"
:controls="true"
></video>
</view>
</uni-popup>
</view>
</template>
<script>
import uniPopup from '@/components/uni-popup/uni-popup.vue'
export default {
name: 'diy-video-list',
components: {
uniPopup
},
props: {
value: {
type: Object,
default: () => ({})
}
},
data() {
return {
pageWidth: '',
indicatorDots: false,
swiperCurrent: 0,
video_url: ''
}
},
created() {
// 组件创建时的逻辑
},
watch: {
componentRefresh(newValue) {
// 监听组件刷新
}
},
computed: {
componentStyle() {
let style = '';
style += 'background-color:' + this.value.componentBgColor + ';';
if (this.value.componentAngle == 'round') {
style += 'border-top-left-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
style += 'border-top-right-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
style += 'border-bottom-left-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
style += 'border-bottom-right-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
}
style += 'box-shadow:' + (this.value.ornament.type == 'shadow' ? '0 0 10rpx ' + this.value.ornament.color : '') + ';';
style += 'border:' + (this.value.ornament.type == 'stroke' ? '2rpx solid ' + this.value.ornament.color : '') + ';';
console.log(this.value);
return style;
},
swiperHeight() {
let height = 0;
if (this.value.mode == 'graphic') {
height = (49 + this.value.imageSize) * this.value.pageCount;
} else if (this.value.mode == 'img') {
height = (22 + this.value.imageSize) * this.value.pageCount;
} else if (this.value.mode == 'text') {
height = 43 * this.value.pageCount;
}
return 'height:' + (2 * height) + 'rpx';
},
isIndicatorDots() {
return this.value.carousel.type != 'hide' &&
1 != Math.ceil(this.value.list.length / (this.value.pageCount * this.value.rowCount));
}
},
methods: {
// 显示视频播放弹窗
showVideo(item) {
this.video_url = item.videoUrl;
this.$refs.videoPopup.open();
},
// 图片加载错误处理
imgError(index) {
// 图片加载失败的处理逻辑
console.log('图片加载失败:', index);
}
}
}
</script>
<style lang="scss" scoped>
.goods-name {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.goods-list {
&.row1-of3 {
display: flex;
flex-wrap: wrap;
.goods-item {
position: relative;
display: flex;
flex-direction: column;
margin-top: 20rpx;
width: calc(33.3333333% - 14rpx);
box-sizing: border-box;
&:nth-child(3n + 3) {
width: calc(33.33% - 15rpx);
}
&:nth-of-type(1), &:nth-of-type(2), &:nth-of-type(3) {
margin-top: 0;
}
&:nth-child(3n) {
width: calc(33.3333333% - 15rpx);
}
&:nth-child(3n-1) {
margin-left: 20rpx;
margin-right: 20rpx;
}
&.shadow {
width: calc(33.3333333% - 18rpx);
&:nth-of-type(1), &:nth-of-type(2), &:nth-of-type(3) {
margin-top: 8rpx;
}
&:nth-child(1n) {
margin-left: 8rpx;
}
&:nth-child(3n-1) {
margin-left: 20rpx;
margin-right: 20rpx;
}
&:nth-child(3n) {
margin-right: 0;
margin-left: 0;
}
}
.goods-img-wrap {
position: relative;
overflow: hidden;
height: 220rpx;
}
.goods-img {
width: 100%;
}
.info-wrap {
display: flex;
flex-direction: column;
flex: 1;
.pro-info {
margin-top: auto;
display: flex;
flex-direction: column;
justify-content: space-between;
.discount-price {
display: flex;
justify-content: space-between;
align-items: center;
.price-wrap {
white-space: nowrap;
.unit {
font-size: 24rpx !important;
}
.price {
font-size: 32rpx;
text {
font-weight: 700;
}
}
}
}
.delete-price {
text-decoration: line-through;
flex: 1;
line-height: 28rpx;
color: #909399;
font-size: 20rpx;
}
}
}
}
&.style-1 {
.pro-info {
.price-wrap {
line-height: 1;
}
.discount-price {
justify-content: unset !important;
align-items: baseline !important;
flex-wrap: wrap;
}
.delete-price {
margin-left: 10rpx;
}
}
}
&.style-2 {
.pro-info {
position: relative;
flex-direction: row !important;
align-items: center;
.price-wrap {
line-height: 1;
}
.discount-price {
align-items: flex-end !important;
flex-wrap: wrap;
justify-content: unset !important;
}
.delete-price {
margin: 20rpx 0;
flex-basis: 100% !important;
}
.buy-btn {
min-width: 112rpx;
height: 52rpx;
padding: 0 20rpx;
line-height: 52rpx;
text-align: center;
box-sizing: border-box;
}
}
}
.sell-out {
text {
font-size: 150rpx;
}
}
}
&.row1-of2 {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.goods-item {
position: relative;
margin-top: 20rpx;
width: calc(50% - 10rpx);
display: flex;
flex-direction: column;
box-sizing: border-box;
&:nth-child(2n) {
margin-right: 0 !important;
}
&:nth-of-type(1), &:nth-of-type(2) {
margin-top: 0;
}
&.shadow {
width: calc(50% - 18rpx);
&:nth-child(2n-1) {
margin-left: 8rpx;
}
&:nth-child(2n) {
margin-right: 8rpx !important;
}
&:nth-of-type(1), &:nth-of-type(2) {
margin-top: 8rpx;
}
}
.goods-img-wrap {
position: relative;
overflow: hidden;
height: 340rpx;
}
.goods-img {
width: 100%;
}
.info-wrap {
display: flex;
flex-direction: column;
flex: 1;
.sale {
flex-basis: 100%;
}
.pro-info {
margin-top: auto;
display: flex;
flex-direction: row;
justify-content: space-between;
.discount-price {
.price-wrap {
white-space: nowrap;
.unit {
font-weight: 700;
font-size: 24rpx !important;
}
.price {
font-weight: 700;
font-size: 32rpx !important;
}
}
}
.delete-price {
text-decoration: line-through;
flex: 1;
line-height: 28rpx;
color: #909399;
font-size: 20rpx;
}
}
}
}
&.style-1 {
.pro-info {
.discount-price {
display: flex;
flex-wrap: wrap;
align-items: baseline;
.price-wrap {
display: inline-block;
text {
font-weight: 700;
}
line-height: 1;
}
}
.delete-price {
margin-top: 6rpx;
flex-basis: 100% !important;
}
}
}
&.style-2 {
.pro-info {
position: relative;
align-items: center;
.price-wrap {
line-height: 1;
}
.discount-price {
display: flex;
flex-wrap: wrap;
align-items: baseline;
}
.delete-price {
margin-top: 4rpx;
flex-basis: 100% !important;
}
.sale {
line-height: 1;
margin-top: 10rpx;
}
.buy-btn {
min-width: 140rpx;
height: 52rpx;
padding: 0 20rpx;
line-height: 52rpx;
text-align: center;
box-sizing: border-box;
}
}
}
&.style-3 {
.pro-info {
.member-price {
margin-right: auto;
align-self: flex-end;
margin-bottom: 4rpx;
}
.sale {
line-height: 1;
align-self: center;
margin-top: 8rpx;
}
.discount-price {
display: flex;
flex-wrap: wrap;
flex: 1;
align-content: center;
.price-wrap {
display: flex;
align-items: baseline;
line-height: 1;
align-self: center;
}
}
}
.swiper {
padding: 20rpx 0;
}
}
.sell-out {
text {
font-size: 250rpx;
}
}
}
}
.video-container {
width: 100%;
height: 300px;
position: relative;
}
.adaptive-video {
width: 100%;
height: 100%;
object-fit: contain;
position: absolute;
top: 0;
left: 0;
}
.video-nav {
padding: 16rpx;
box-sizing: border-box;
&.fixed-layout {
.uni-scroll-view-content {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
}
&.singleSlide {
.uni-scroll-view-content {
display: flex;
}
.video-nav-item {
flex-shrink: 0;
}
}
&.pageSlide {
position: relative;
.uni-swiper-dots-horizontal {
bottom: 0rpx;
}
&.straightLine {
.uni-swiper-dot {
width: 30rpx;
border-radius: 0;
height: 8rpx;
}
}
&.circle {
.uni-swiper-dot {
width: 14rpx;
height: 14rpx;
}
}
}
.video-nav-wrap {
display: flex;
flex-wrap: wrap;
width: 100%;
height: 100%;
}
.video-nav-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 14rpx 0;
box-sizing: border-box;
.video-text {
padding-top: 12rpx;
line-height: 1.5;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: 100%;
text-align: center;
&.alone {
padding-top: 0;
}
}
&.text {
.video-text {
padding-top: 0;
}
}
.video-img {
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-size: 90rpx;
.tag {
position: absolute;
top: -10rpx;
right: -24rpx;
color: #fff;
border-radius: 24rpx;
border-bottom-left-radius: 0;
-webkit-transform: scale(0.8);
transform: scale(0.8);
padding: 8rpx 16rpx;
line-height: 1;
font-size: 24rpx;
}
.icon {
font-size: 50rpx;
color: #606266;
}
}
}
}
.swiper-dot-box {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: -20rpx;
padding-bottom: 8rpx;
.swiper-dot {
background-color: rgba(0, 0, 0, 0.3);
margin: 8rpx;
&.active {
background-color: #000;
}
}
&.straightLine {
.swiper-dot {
width: 30rpx;
border-radius: 0;
height: 8rpx;
}
}
&.circle {
.swiper-dot {
width: 15rpx;
border-radius: 50%;
height: 15rpx;
}
}
}
</style>

View File

@@ -1,5 +1,7 @@
<template> <template>
<view :style="value.pageStyle">
<video data-component-name="diy-video" class="diy-video" :src="$util.img(value.videoUrl)" :poster="$util.img(value.imageUrl)" :style="videoWarpCss" objectFit="cover" @click="handlerClick(value.videoUrl)" @tap="handlerClick(value.videoUrl)"></video> <video data-component-name="diy-video" class="diy-video" :src="$util.img(value.videoUrl)" :poster="$util.img(value.imageUrl)" :style="videoWarpCss" objectFit="cover" @click="handlerClick(value.videoUrl)" @tap="handlerClick(value.videoUrl)"></video>
</view>
</template> </template>
<script> <script>
@@ -9,7 +11,10 @@
name: 'diy-video', name: 'diy-video',
props: { props: {
value: { value: {
type: Object type: Object,
default: () => {
return {};
}
} }
}, },
data() { data() {

View File

@@ -64,7 +64,10 @@ export default {
longitude: null, // 经度 longitude: null, // 经度
evaluateCount: 0, // 商品评论数量 evaluateCount: 0, // 商品评论数量
deliveryType: null, // 配送方式 deliveryType: null, // 配送方式
isVirtual: 0 //是否为虚拟商品 isVirtual: 0 ,//是否为虚拟商品
hasGlobalStore:false,
saleStore:'all',
isInitStoreData:false,
} }
}, },
created() { created() {
@@ -73,10 +76,7 @@ export default {
if (this.location) { if (this.location) {
this.latitude = this.location.latitude; this.latitude = this.location.latitude;
this.longitude = this.location.longitude; this.longitude = this.location.longitude;
} else {
this.$util.getLocation();
} }
this.getStoreData();
}, },
watch: { watch: {
location: function (nVal) { location: function (nVal) {
@@ -95,26 +95,24 @@ export default {
this.source_member = params.source_member; this.source_member = params.source_member;
this.whetherCollection = params.whetherCollection; this.whetherCollection = params.whetherCollection;
this.posterParams = params.posterParams; this.posterParams = params.posterParams;
this.shareUrl = params.shareUrl; this.shareUrl = params.shareUrl;
this.goodsRoute = params.goodsRoute; this.goodsRoute = params.goodsRoute;
this.posterApi = params.posterApi; this.posterApi = params.posterApi;
this.isVirtual = params.isVirtual; this.isVirtual = params.isVirtual;
this.deliveryType = params.deliveryType; this.deliveryType = params.deliveryType;
this.evaluateConfig = params.evaluateConfig; this.evaluateConfig = params.evaluateConfig;
this.saleStore = params.sale_store;
if (this.evaluateConfig.evaluate_show == 1) { if (this.evaluateConfig.evaluate_show == 1) {
//商品评论 //商品评论
this.getGoodsEvaluate(params.evaluateList); this.getGoodsEvaluate(params.evaluateList);
this.evaluateCount = params.evaluateCount; this.evaluateCount = params.evaluateCount;
} }
if( params.goods_class != 2 && params.goods_class !=3) this.isShowStore = true;
for (let k in this.deliveryType) { if(!this.isInitStoreData){
if (k == 'store') { this.isInitStoreData = true;
this.isShowStore = true; this.getStoreData();
}
} }
this.getService(); this.getService();
this.videoContext = uni.createVideoContext('goodsVideo'); this.videoContext = uni.createVideoContext('goodsVideo');
@@ -144,11 +142,12 @@ export default {
closeStoreListPopup() { closeStoreListPopup() {
this.$refs.storeListPopup.close(); this.$refs.storeListPopup.close();
}, },
getStoreData() { getStoreData(){
//门店列表 //门店列表
let data = { let data = {
page: this.storeList.page, page: this.storeList.page,
page_size: this.storeList.page_size page_size: this.storeList.page_size,
store_ids:this.saleStore
}; };
if (this.latitude && this.longitude) { if (this.latitude && this.longitude) {
data.latitude = this.latitude; data.latitude = this.latitude;
@@ -161,6 +160,9 @@ export default {
if (this.storeList.page == 1) this.storeList.data == []; if (this.storeList.page == 1) this.storeList.data == [];
if (res.code >= 0 && res.data) { if (res.code >= 0 && res.data) {
this.storeList.data = this.storeList.data.concat(res.data.list); this.storeList.data = this.storeList.data.concat(res.data.list);
res.data.list.forEach(item=>{
if(item.store_id == this.globalStoreInfo.store_id) this.hasGlobalStore = true;
})
} else { } else {
this.$util.showToast({ this.$util.showToast({
title: res.message title: res.message
@@ -189,9 +191,6 @@ export default {
if (this.goodsEvaluate[index].images) this.goodsEvaluate[index].images = this.goodsEvaluate[index].images.split(","); if (this.goodsEvaluate[index].images) this.goodsEvaluate[index].images = this.goodsEvaluate[index].images.split(",");
if (this.goodsEvaluate[index].is_anonymous == 1) this.goodsEvaluate[index].member_name = this.goodsEvaluate[index].member_name.replace(this.goodsEvaluate[index].member_name.substring(1, this.goodsEvaluate[index].member_name.length - 1), '***') if (this.goodsEvaluate[index].is_anonymous == 1) this.goodsEvaluate[index].member_name = this.goodsEvaluate[index].member_name.replace(this.goodsEvaluate[index].member_name.substring(1, this.goodsEvaluate[index].member_name.length - 1), '***')
}) })
// if (this.goodsEvaluate.images) this.goodsEvaluate.images = this.goodsEvaluate.images.split(",");
// if (this.goodsEvaluate.is_anonymous == 1) this.goodsEvaluate.member_name = this.goodsEvaluate.member_name.replace(
// this.goodsEvaluate.member_name.substring(1, this.goodsEvaluate.member_name.length - 1), '***')
} }
}, },
// 预览评价图片 // 预览评价图片
@@ -263,6 +262,8 @@ export default {
copyUrl() { copyUrl() {
let text = this.$config.h5Domain + this.shareUrl; let text = this.$config.h5Domain + this.shareUrl;
if (this.memberInfo && this.memberInfo.member_id) text += '&source_member=' + this.memberInfo.member_id; if (this.memberInfo && this.memberInfo.member_id) text += '&source_member=' + this.memberInfo.member_id;
var store_info = this.$store.state.globalStoreInfo;
if (store_info) text += '&store_id=' + store_info.store_id;
this.$util.copy(text, () => { this.$util.copy(text, () => {
this.closeSharePopup(); this.closeSharePopup();
}); });
@@ -283,10 +284,11 @@ export default {
getGoodsPoster() { getGoodsPoster() {
uni.showLoading({ uni.showLoading({
'title': '海报生成中...' 'title': '海报生成中...'
}) });
//活动海报信息 //活动海报信息
if (this.memberInfo && this.memberInfo.member_id) this.posterParams.source_member = this.memberInfo.member_id; if (this.memberInfo && this.memberInfo.member_id) this.posterParams.source_member = this.memberInfo.member_id;
var store_info = this.$store.state.globalStoreInfo;
if (store_info) this.posterParams.store_id= store_info.store_id;
this.$api.sendRequest({ this.$api.sendRequest({
url: this.posterApi, url: this.posterApi,
data: { data: {

View File

@@ -39,37 +39,37 @@
<slot name="price"></slot> <slot name="price"></slot>
</view> </view>
<view class="newdetail margin-bottom" v-if="goodsSkuDetail.isinformation == 0"> <view class="newdetail margin-bottom">
<!-- 入口区域 --> <!-- 入口区域 -->
<slot name="entrance"></slot> <slot name="entrance"></slot>
<!-- 配送 --> <!-- 配送 -->
<!-- @click="$refs.deliveryType.open()" --> <view class="item delivery-type" v-if="goodsSkuDetail.is_virtual == 0" @click="$refs.deliveryType.open()">
<view class="item delivery-type" v-if="goodsSkuDetail.is_virtual == 0" > <view class="label">配送</view>
<view class="label">{{$lang('send')}}</view>
<block v-if="deliveryType"> <block v-if="deliveryType">
<view class="box"> <view class="box">
<block v-for="(item, index) in deliveryType" :key="index"> <block v-for="(item, index) in deliveryType" :key="index">
<text v-if="goodsSkuDetail.support_trade_type.indexOf(index) != -1">{{$lang('express')}}</text> <text v-if="goodsSkuDetail.support_trade_type.indexOf(index) != -1">{{ item.name }}</text>
<!-- {{ item.name }} -->
</block> </block>
</view> </view>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
</block> </block>
<block v-else> <block v-else>
<view class="box">未配置</view> <view class="box">商家未配置配送方式</view>
</block> </block>
</view> </view>
<!-- 门店 --> <!-- 门店 -->
<!-- <view class="item store-wrap" @click="openStoreListPopup()" v-if="addonIsExist.store && globalStoreInfo && isShowStore"> <view class="item store-wrap" @click="openStoreListPopup()" v-if="addonIsExist.store && globalStoreInfo && isShowStore">
<view class="label">门店</view> <view class="label">适用门店</view>
<view class="list-wrap"> <view class="list-wrap" v-if="hasGlobalStore">
<view class="name-wrap"> <view class="name-wrap">
<text class="icondiy icon-system-shop"></text> <text class="icondiy icon-system-shop"></text>
<text class="name">{{globalStoreInfo.store_name}}</text> <text class="name">{{ globalStoreInfo.store_name}}</text>
</view> </view>
<view class="close-desc" v-if="globalStoreInfo.status == 0 && globalStoreInfo.close_desc">
{{ globalStoreInfo.close_desc }}
</view>
<view class="other-wrap"> <view class="other-wrap">
<text class="distance" v-if="parseFloat(globalStoreInfo.distance)">距离{{ globalStoreInfo.distance > 1 ? globalStoreInfo.distance + 'km' : globalStoreInfo.distance * 1000 + 'm' }}</text> <text class="distance" v-if="parseFloat(globalStoreInfo.distance)">距离{{ globalStoreInfo.distance > 1 ? globalStoreInfo.distance + 'km' : globalStoreInfo.distance * 1000 + 'm' }}</text>
<text class="decorate" v-if="parseFloat(globalStoreInfo.distance)">.</text> <text class="decorate" v-if="parseFloat(globalStoreInfo.distance)">.</text>
@@ -77,8 +77,23 @@
</view> </view>
</view> </view>
</view> </view>
<view class="list-wrap" v-else-if="storeList && storeList.data.length">
<view class="name-wrap">
<text class="icondiy icon-system-shop"></text>
<text class="name">{{ storeList.data[0].store_name}}</text>
</view>
<view class="close-desc" v-if="storeList.data[0].status == 0 && storeList.data[0].close_desc">
{{ storeList.data[0].close_desc }}
</view>
<view class="other-wrap">
<text class="distance" v-if="parseFloat(storeList.data[0].distance)">距离{{ storeList.data[0].distance > 1 ? storeList.data[0].distance + 'km' : storeList.data[0].distance * 1000 + 'm' }}</text>
<text class="decorate" v-if="parseFloat(storeList.data[0].distance)">.</text>
<view class="address">{{ storeList.data[0].full_address + storeList.data[0].address }}
</view>
</view>
</view>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
</view> --> </view>
<view class="item service" @click="openMerchantsServicePopup()" v-if="goodsSkuDetail.goods_service.length"> <view class="item service" @click="openMerchantsServicePopup()" v-if="goodsSkuDetail.goods_service.length">
<view class="label">服务</view> <view class="label">服务</view>
@@ -96,34 +111,6 @@
</view> </view>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
</view> </view>
</view>
<!--多规格区域-->
<view class="newdetail margin-bottom" v-if="goodsSkuDetail.sku_spec_format">
<!-- 入口区域 -->
<slot name="skuspec"></slot>
</view>
<view class="newdetail margin-bottom" v-if="goodsSkuDetail.merch_id > 0">
<!-- 入口区域 -->
<slot name="entrance"></slot>
<!-- 商家 -->
<view class="item store-wrap" @click="$util.redirectTo('/pages_promotion/merch/detail', { merch_id: goodsSkuDetail.merch_id })">
<view class="list-wrap" style="display: flex;">
<view class="name-wrap">
<image :src="$util.img(goodsSkuDetail.merchinfo.merch_image)" mode="widthFix" style="width: 100rpx;height: 100rpx;border-radius: 50rpx;"></image>
</view>
<view class="other-wrap">
<view class="address" style="margin-left: 30rpx;">
<view>{{goodsSkuDetail.merchinfo.merch_name}}</view>
<view style="font-size: 24rpx;color: #888;">官方认证商家值得信赖</view>
</view>
</view>
</view>
<text class="iconfont icon-right"></text>
</view>
</view> </view>
<!-- 配送方式 --> <!-- 配送方式 -->
@@ -182,7 +169,7 @@
<uni-popup ref="storeListPopup" type="bottom"> <uni-popup ref="storeListPopup" type="bottom">
<view class="goods-merchants-service-popup-layer popup-layer store-list-wrap"> <view class="goods-merchants-service-popup-layer popup-layer store-list-wrap">
<view class="head-wrap" @click="closeStoreListPopup()"> <view class="head-wrap" @click="closeStoreListPopup()">
<text>门店列表</text> <text>适用门店</text>
<text class="iconfont icon-close"></text> <text class="iconfont icon-close"></text>
</view> </view>
<scroll-view scroll-y> <scroll-view scroll-y>
@@ -200,6 +187,8 @@
距离{{ item.distance > 1 ? item.distance + 'km' : item.distance * 1000 + 'm' }} 距离{{ item.distance > 1 ? item.distance + 'km' : item.distance * 1000 + 'm' }}
</text> </text>
</view> </view>
<view class="item-close-desc" v-if="item.status == 0 && item.close_desc">{{ item.close_desc }}
</view>
<view class="item-time" v-if="item.open_date">营业时间{{ item.open_date }} <view class="item-time" v-if="item.open_date">营业时间{{ item.open_date }}
</view> </view>
<view class="item-address">{{ item.full_address + item.address }}</view> <view class="item-address">{{ item.full_address + item.address }}</view>
@@ -228,7 +217,7 @@
</view> </view>
<!-- 促销 --> <!-- 促销 -->
<!-- <view class="community-model" @touchmove.prevent.stop @click.stop="onCloseCommunity()" v-show="isCommunity"> <view class="community-model" @touchmove.prevent.stop @click.stop="onCloseCommunity()" v-show="isCommunity">
<view class="community-model-content" @click.stop> <view class="community-model-content" @click.stop>
<view class="community-model-content-radius"> <view class="community-model-content-radius">
<view>添加社群</view> <view>添加社群</view>
@@ -241,13 +230,13 @@
<view class="community-model-close" @click.stop="onCloseCommunity()"> <view class="community-model-close" @click.stop="onCloseCommunity()">
<text class="iconfont icon-close"></text> <text class="iconfont icon-close"></text>
</view> </view>
</view> --> </view>
<!-- 参与流程 --> <!-- 参与流程 -->
<slot name="articipation"></slot> <slot name="articipation"></slot>
<!-- 商品评价 --> <!-- 商品评价 -->
<view class="group-wrap" v-if="evaluateConfig.evaluate_show == 1 && goodsSkuDetail.isinformation == 0" style="display: none;"> <view class="group-wrap" v-if="evaluateConfig.evaluate_show == 1">
<view class="goods-evaluate" @click="toEvaluateDetail(goodsSkuDetail.goods_id)"> <view class="goods-evaluate" @click="toEvaluateDetail(goodsSkuDetail.goods_id)">
<view class="tit"> <view class="tit">
<!-- <view class="tit" :class="{ active: goodsEvaluate.content }"> --> <!-- <view class="tit" :class="{ active: goodsEvaluate.content }"> -->
@@ -263,8 +252,7 @@
</view> </view>
</view> </view>
</view> </view>
<view class="evaluate-item" v-for="(item, index) in goodsEvaluate" :key="index" <view class="evaluate-item" v-for="(item, index) in goodsEvaluate" :key="index" v-if="item.content">
v-if="item.content">
<view class="evaluator"> <view class="evaluator">
<view class="evaluator-info"> <view class="evaluator-info">
<view class="evaluator-face"> <view class="evaluator-face">
@@ -294,7 +282,7 @@
</view> </view>
</view> </view>
</view> </view>
<view class="goods-attr" v-if="goodsSkuDetail.goods_attr_format && goodsSkuDetail.goods_attr_format.length > 0"> <view class="goods-attr" v-if="goodsSkuDetail.goods_attr_format && goodsSkuDetail.goods_attr_format.length > 0">
<view class="title">规格属性</view> <view class="title">规格属性</view>
<view class="attr-wrap"> <view class="attr-wrap">
@@ -315,24 +303,19 @@
</view> </view>
</view> </view>
<!-- 详情 --> <!-- 详情 -->
<view class="goods-detail-tab"> <view class="goods-detail-tab">
<view class="detail-tab"> <view class="detail-tab">
<view class="tab-item">{{$lang('details')}}</view> <view class="tab-item">商品详情</view>
</view> </view>
<view class="detail-content active"> <view class="detail-content active">
<view class="detail-content-item"> <view class="detail-content-item">
<view class="goods-details" v-if="goodsSkuDetail.goods_content"> <view class="goods-details" v-if="goodsSkuDetail.goods_content">
<!-- <rich-text :nodes="goodsSkuDetail.goods_content" @click="showImg($event)" :data-nodes="goodsSkuDetail.goods_content"></rich-text> --> <ns-mp-html :content="goodsSkuDetail.goods_content"></ns-mp-html>
<!-- {{goodsSkuDetail.goods_content}} -->
<mp-html :content="goodsSkuDetail.goods_content" />
<!-- :loading="loading" @preview="preview" @navigate="navigate" -->
</view> </view>
<view class="goods-details active" v-else></view> <view class="goods-details active" v-else>该商家暂无上传相关详情哦</view>
<view class="goods-details" v-if="service && service.is_display == 1 && service.content"> <view class="goods-details" v-if="service && service.is_display == 1 && service.content">
<rich-text :nodes="service.content" @click="showImg($event)" :data-nodes="service.content"></rich-text> <ns-mp-html :content="service.content"></ns-mp-html>
</view> </view>
</view> </view>
</view> </view>

View File

@@ -144,7 +144,7 @@ export default {
data: { t: new Date().getTime() }, data: { t: new Date().getTime() },
success: (res) => { success: (res) => {
const config = res.code === 0 ? res.data : this.$store.state.servicerConfig || {}; const config = res.code === 0 ? res.data : this.$store.state.servicerConfig || {};
this.$store.commit('UPDATE_SERVICER_CONFIG', config); this.$store.commit('setServicerConfig', config);
resolve(config); resolve(config);
}, },
fail: () => resolve(this.$store.state.servicerConfig || {}) fail: () => resolve(this.$store.state.servicerConfig || {})

View File

@@ -10,9 +10,9 @@
</view> </view>
<view class="birthday-title-desc" v-else>感谢您一直以来的支持在您生日到来之际特为您送上最真诚的祝福</view> <view class="birthday-title-desc" v-else>感谢您一直以来的支持在您生日到来之际特为您送上最真诚的祝福</view>
<view class="birthday-title-hint"> <view class="birthday-title-hint">
<image :src="$util.img('public/uniapp/birthday_gift/birthday_gift_left.png')" mode="" class="birthday-img-all"/> <image :src="$util.img('public/uniapp/birthday_gift/birthday_gift_left.png')" mode="" class="birthday-img-all" />
<view class="font-size-toolbar">生日贺礼</view> <view class="font-size-toolbar">生日贺礼</view>
<image :src="$util.img('public/uniapp/birthday_gift/birthday_gift_right.png')" mode="" class="birthday-img-all"/> <image :src="$util.img('public/uniapp/birthday_gift/birthday_gift_right.png')" mode="" class="birthday-img-all" />
</view> </view>
<scroll-view scroll-y="true" class="register-box"> <scroll-view scroll-y="true" class="register-box">
<view class="reward-content"> <view class="reward-content">
@@ -51,18 +51,14 @@
<block v-for="(item, index) in birthday.coupon_list" :key="index"> <block v-for="(item, index) in birthday.coupon_list" :key="index">
<view class="content"> <view class="content">
<view class="info"> <view class="info">
<block v-if="item.type == 'reward'"> <text class="num" v-if="item.type == 'reward'">
<text class="num"> {{ parseFloat(item.money) }}
{{ parseFloat(item.money) }} <text class="type">元优惠劵</text>
<text class="type">元优惠劵</text> </text>
</text> <text class="num" v-else-if="item.type == 'discount'">
</block> {{ item.discount }}
<block v-else-if="item.type == 'discount'"> <text class="type"></text>
<text class="num"> </text>
{{ item.discount }}
<text class="type"></text>
</text>
</block>
<view class="desc">用于下单时抵现或兑换商品等</view> <view class="desc">用于下单时抵现或兑换商品等</view>
</view> </view>
<view class="tip" @click="closeRewardPopup('3')">立即查看</view> <view class="tip" @click="closeRewardPopup('3')">立即查看</view>
@@ -93,7 +89,8 @@
birthday: { birthday: {
flag: false, flag: false,
coupon_list: {} coupon_list: {}
} },
callback: null
}; };
}, },
computed: { computed: {
@@ -117,7 +114,8 @@
this.init(); this.init();
}, },
methods: { methods: {
init() { init(callback = null) {
if (callback) this.callback = callback;
this.getBirthdayGift(); this.getBirthdayGift();
}, },
cancel() { cancel() {
@@ -148,7 +146,9 @@
data: { data: {
id: this.birthday.id id: this.birthday.id
}, },
success: res => {} success: res => {
if (this.callback) this.callback();
}
}); });
} }
}, },
@@ -170,7 +170,7 @@
} }
.register-box { .register-box {
max-height: 300rpx; max-height: 320rpx;
overflow-y: scroll; overflow-y: scroll;
/* margin-top:350rpx; */ /* margin-top:350rpx; */
} }
@@ -187,12 +187,12 @@
<style lang="scss"> <style lang="scss">
.reward-wrap { .reward-wrap {
width: 85vw; width: 600rpx;
height: auto; height: auto;
.wrap { .wrap {
width: 100%; width: 600rpx;
height: auto; height: 932rpx;
background-size: 100%; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
padding-bottom: 40rpx; padding-bottom: 40rpx;
@@ -266,7 +266,8 @@
background: #fff; background: #fff;
border-radius: 10rpx; border-radius: 10rpx;
margin-bottom: 20rpx; margin-bottom: 20rpx;
box-sizing: border-box;
height: 136rpx;
.info { .info {
flex: 1; flex: 1;
} }
@@ -323,13 +324,6 @@
height: 40rpx; height: 40rpx;
margin: 0 auto; margin: 0 auto;
line-height: 40rpx; line-height: 40rpx;
/* margin: 20rpx 140rpx;
border: none;
background: linear-gradient(90deg, #FF6A00, #FF3C00);
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center; */
} }
} }
} }

View File

@@ -1,95 +1,92 @@
<template> <template>
<view class="empty" :class="{ fixed: fixed }"> <view class="empty" :class="{ fixed: fixed }">
<view class="empty_img"><image :src="$util.img('public/uniapp/common/common-empty.png')" mode="aspectFit"></image></view> <view class="empty_img"><image :src="$util.img('public/uniapp/common/common-empty.png')" mode="aspectFit"></image></view>
<view class="color-tip margin-top title" :style="{ color: textColor + ' !important' }">{{ text }}</view> <view class="color-tip margin-top title" :style="{ color: textColor + ' !important' }">{{ text }}</view>
<view class="color-tip margin-bottom font-size-sub">{{ subText }}</view> <view class="color-tip margin-bottom font-size-sub">{{ subText }}</view>
<button type="primary" size="mini" class="button mini" @click="goIndex()" v-if="isIndex">{{ emptyBtn.text }}</button> <button type="primary" size="mini" class="button mini" @click="goIndex()" v-if="isIndex">{{ emptyBtn.text }}</button>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return {}; return {};
}, },
props: { props: {
text: { text: {
type: String, type: String,
default: '暂无相关数据' default: '暂无相关数据'
}, },
subText: { subText: {
type: String, type: String,
default: '' default: ''
}, },
isIndex: { isIndex: {
type: Boolean, type: Boolean,
default: true default: true
}, },
emptyBtn: { emptyBtn: {
type: Object, type: Object,
default: () => { default: () => {
return { text: '去逛逛' }; return { text: '去逛逛' };
} }
}, },
fixed: { fixed: {
type: Boolean, type: Boolean,
default: false default: false
}, },
textColor: { textColor: {
type: String, type: String,
default: '' default: ''
} }
}, },
methods: { methods: {
goIndex() { goIndex() {
if (this.emptyBtn.url) { if (this.emptyBtn.url) {
this.$util.redirectTo(this.emptyBtn.url, {}, 'redirectTo'); this.$util.redirectTo(this.emptyBtn.url, {}, 'redirectTo');
} else { } else {
this.$util.redirectTo('/pages/index/index'); this.$util.redirectTo('/pages/index/index');
} }
}, }
re(text) { }
this.text = text; };
} </script>
}
}; <style lang="scss">
</script> .empty {
width: 100%;
<style lang="scss"> display: flex;
.empty { flex-direction: column;
width: 100%; align-items: center;
display: flex; padding: $padding;
flex-direction: column; box-sizing: border-box;
align-items: center; justify-content: center;
padding: $padding; .title {
box-sizing: border-box; font-size: 30rpx;
justify-content: center; }
.title { .empty_img {
font-size: 30rpx; width: 50%;
} height: 450rpx;
.empty_img {
width: 50%; image {
height: 450rpx; width: 100%;
height: 100%;
image { padding-bottom: $padding;
width: 100%; }
height: 100%; }
padding-bottom: $padding; button {
} min-width: 300rpx;
} margin-top: 100rpx;
button { height: 70rpx;
min-width: 300rpx; line-height: 70rpx !important;
margin-top: 100rpx; font-size: $font-size-base;
height: 70rpx; font-weight: bold;
line-height: 70rpx !important; border-radius: 100rpx;
font-size: $font-size-base; }
font-weight: bold; }
border-radius: 100rpx; .fixed {
} position: fixed;
} left: 0;
.fixed { top: 20vh;
position: fixed; }
left: 0; </style>
top: 20vh;
}
</style>

View File

@@ -220,7 +220,7 @@
}, },
data() { data() {
return { return {
formData: this.data formData:[]
}; };
}, },
created() { created() {
@@ -229,23 +229,26 @@
watch: { watch: {
data: function() { data: function() {
this.setFormData(); this.setFormData();
} },
formData: {
handler(newVal, oldVal) {
this.$emit('changeFormVal',newVal)
},
deep: true
}
}, },
methods: { methods: {
setFormData() { setFormData() {
this.formData = this.data; let formData = JSON.parse(JSON.stringify(this.data));
formData.forEach(item => {
this.formData.forEach(item => {
if (!item.val) item.val = item.value.default ? item.value.default : ''; if (!item.val) item.val = item.value.default ? item.value.default : '';
if (item.value.options) { if (item.value.options) {
item.option_lists = []; item.option_lists = [];
item.value.options.forEach((v, k) => { item.value.options.forEach((v, k) => {
var obj = {}; var obj = {};
obj.value = v; obj.value = v;
obj.checked = false; obj.checked = false;
if (item.controller == 'Radio' && ((!item.val && k == 0) || (item.val && if (item.controller == 'Radio' && ((!item.val && k == 0) || (item.val && item.val == v))) {
item.val == v))) {
obj.checked = true; obj.checked = true;
item.val = v; item.val = v;
} }
@@ -359,6 +362,7 @@
else item.default_regions = []; else item.default_regions = [];
} }
}); });
this.formData = JSON.parse(JSON.stringify(formData))
}, },
verify() { verify() {
let verify = true; let verify = true;
@@ -392,6 +396,7 @@
} }
// 验证手机号 // 验证手机号
if (item.name == 'MOBILE' && this.$util.verifyMobile(item.val) === false) { if (item.name == 'MOBILE' && this.$util.verifyMobile(item.val) === false) {
verify = !item.value.required; verify = !item.value.required;
if (verify == false) { if (verify == false) {
@@ -515,7 +520,7 @@
} }
} }
} }
console.log(verify)
if (verify) { if (verify) {
return this.formData; return this.formData;
} else return verify; } else return verify;
@@ -678,7 +683,7 @@
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
border-bottom: solid 1px #eee; border-bottom: 0;
} }
&.align-top { &.align-top {
@@ -836,6 +841,9 @@
checkbox { checkbox {
display: none; display: none;
} }
label {
padding:10rpx 0;
}
.checkbox { .checkbox {
display: flex; display: flex;

View File

@@ -1,146 +1,146 @@
<template> <template>
<view> <view>
<block v-if="text == '客服'"> <block v-if="text == '客服' || text == 'Contact'">
<!-- <ns-contact :niushop="chatParam" :send-message-title="sendData.title" :send-message-path="sendData.path" :send-message-img="sendData.img"> --> <!-- <ns-contact :niushop="chatParam" :send-message-title="sendData.title" :send-message-path="sendData.path" :send-message-img="sendData.img"> -->
<button hoverClass="none" openType="contact" sessionFrom="weapp" showMessageCard="true" class="action-icon-wrap" style="background: transparent;padding: 0;margin: 0;"> <button hoverClass="none" openType="contact" sessionFrom="weapp" showMessageCard="true" class="action-icon-wrap" style="background: transparent;padding: 0;margin: 0;">
<view class="iconfont color-title" :class="icon"></view> <view class="iconfont color-title" :class="icon"></view>
<text>{{ text }}</text> <text>{{ text }}</text>
<view class="corner-mark color-base-bg" v-if="cornerMark.length" :style="{ background: cornerMarkBg+'!important', color: cornerMarkColor }">{{ cornerMark }}</view> <view class="corner-mark color-base-bg" v-if="cornerMark.length" :style="{ background: cornerMarkBg+'!important', color: cornerMarkColor }">{{ cornerMark }}</view>
</button> </button>
<!-- </ns-contact> --> <!-- </ns-contact> -->
</block> </block>
<block v-else> <block v-else>
<view class="action-icon-wrap" @click="clickEvent"> <view class="action-icon-wrap" @click="clickEvent">
<view class="iconfont " :class="icon"></view> <view class="iconfont color-title" :class="icon"></view>
<text>{{ text }}</text> <text>{{ text }}</text>
<view class="corner-mark color-base-bg" :class="{'max' : parseInt(cornerMark)>99}" v-if="cornerMark.length" :style="{ background: cornerMarkBg+'!important', color: cornerMarkColor }">{{ cornerMark > 99 ? '99+' : cornerMark }}</view> <view class="corner-mark color-base-bg" :class="{'max' : parseInt(cornerMark)>99}" v-if="cornerMark.length" :style="{ background: cornerMarkBg+'!important', color: cornerMarkColor }">{{ cornerMark > 99 ? '99+' : cornerMark }}</view>
</view> </view>
</block> </block>
</view> </view>
</template> </template>
<script> <script>
import nsContact from '@/components/ns-contact/ns-contact.vue'; import nsContact from '@/components/ns-contact/ns-contact.vue';
export default { export default {
name: 'ns-goods-action-icon', name: 'ns-goods-action-icon',
props: { props: {
// 商品底部icon导航icon图标 // 商品底部icon导航icon图标
icon: { icon: {
type: String, type: String,
default: '' default: ''
}, },
// 商品底部icon导航文字 // 商品底部icon导航文字
text: { text: {
type: String, type: String,
default: '' default: ''
}, },
// 角标文字 // 角标文字
cornerMark: { cornerMark: {
type: String, type: String,
default: '' default: ''
}, },
// 角标背景色 // 角标背景色
cornerMarkBg: { cornerMarkBg: {
type: String, type: String,
default: '' default: ''
}, },
// 角标文字颜色 // 角标文字颜色
cornerMarkColor: { cornerMarkColor: {
type: String, type: String,
default: '#fff' default: '#fff'
}, },
// 开放能力 // 开放能力
openType: { openType: {
type: String, type: String,
default: '' default: ''
}, },
// 发送内容 openType="contact"时有效 // 发送内容 openType="contact"时有效
sendData: { sendData: {
type: Object, type: Object,
default: function() { default: function() {
return { return {
title: '', title: '',
path: '', path: '',
img: '' img: ''
}; };
} }
}, },
chatParam: { chatParam: {
type: Object, type: Object,
default: function(){ default: function(){
return {} return {}
} }
} }
}, },
components:{ components:{
nsContact nsContact
}, },
methods: { methods: {
clickEvent() { clickEvent() {
this.$emit('click'); this.$emit('click');
} }
} }
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
.action-icon-wrap { .action-icon-wrap {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
height: 100rpx; height: 100rpx;
min-width: 90rpx; min-width: 90rpx;
text-align: center; text-align: center;
position: relative; position: relative;
margin-right: 6rpx; margin-right: 6rpx;
} }
.action-icon-wrap button { .action-icon-wrap button {
width: 100%; width: 100%;
height: 100%; height: 100%;
position: absolute; position: absolute;
border: none; border: none;
z-index: 1; z-index: 1;
padding: 0; padding: 0;
margin: 0; margin: 0;
background: none; background: none;
top: 0; top: 0;
left: 0; left: 0;
opacity: 0; opacity: 0;
} }
.action-icon-wrap button::after { .action-icon-wrap button::after {
border: none !important; border: none !important;
} }
.action-icon-wrap .iconfont { .action-icon-wrap .iconfont {
margin: 0 auto 10rpx; margin: 0 auto 10rpx;
line-height: 1; line-height: 1;
font-size: 40rpx; font-size: 40rpx;
} }
.action-icon-wrap .corner-mark { .action-icon-wrap .corner-mark {
position: absolute; position: absolute;
z-index: 99; z-index: 99;
font-size: $font-size-activity-tag; font-size: $font-size-activity-tag;
top: 4rpx; top: 4rpx;
right: 12rpx; right: 12rpx;
color: #fff; color: #fff;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 24rpx; width: 24rpx;
height: 24rpx; height: 24rpx;
padding: 6rpx; padding: 6rpx;
border-radius: 50%; border-radius: 50%;
&.max{ &.max{
right:-4rpx; right:-4rpx;
width: 40rpx; width: 40rpx;
border-radius: 24rpx; border-radius: 24rpx;
} }
} }
.action-icon-wrap text { .action-icon-wrap text {
font-size: $font-size-tag; font-size: $font-size-tag;
line-height: 1; line-height: 1;
} }
</style> </style>

View File

@@ -79,8 +79,6 @@ export default {
<style lang="scss"> <style lang="scss">
.ns-goods-promotion { .ns-goods-promotion {
background-color: #fff; background-color: #fff;
& > view {
}
.item { .item {
display: flex; display: flex;
font-size: $font-size-base; font-size: $font-size-base;

View File

@@ -1,5 +1,93 @@
<template> <template>
<view></view> <view class="goods-recommend" v-if="list.length">
<view class="goods-recommend-title">
<text class="title">{{ config.title }}</text>
</view>
<view class="goods-list double-column">
<view class="goods-item margin-bottom" v-for="(item, index) in list" :key="index" @click="toDetail(item)">
<view class="goods-img">
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)" :lazy-load="true" />
<view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }}</view>
<view class="sell-out" v-if="item.goods_stock <= 0">
<text class="iconfont icon-shuqing"></text>
</view>
</view>
<view class="info-wrap">
<view class="goods-name" :class="[{ 'using-hidden': config.nameLineMode == 'single' }, { 'multi-hidden': config.nameLineMode == 'multiple' }]">
{{ item.goods_name }}
</view>
<view class="lineheight-clear">
<view class="discount-price">
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
<text class="price price-style large">{{ parseFloat(showPrice(item)).toFixed(2).split('.')[0] }}</text>
<text class="unit price-style small">.{{ parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
</view>
<view class="member-price-tag" v-if="item.member_price && item.member_price == showPrice(item)">
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix"/>
</view>
<view class="member-price-tag" v-else-if="item.promotion_type == 1">
<image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix"/>
</view>
<view class="delete-price font-size-activity-tag color-tip price-font" v-if="showMarketPrice(item)">
<text class="unit">{{ $lang('common.currencySymbol') }}</text>
<text>{{ showMarketPrice(item) }}</text>
</view>
</view>
<view class="pro-info">
<view class="block-wrap">
<view class="sale font-size-activity-tag color-tip" v-if="item.sale_show">已售{{ item.sale_num }}{{ item.unit ? item.unit : '' }}</view>
</view>
<view class="cart-action-wrap" v-if="config.control && item.is_virtual == 0">
<!-- 购物车图标 -->
<view v-if="config.style == 'icon-cart'" :style="{
color: config.theme == 'diy' ? config.textColor : '',
borderColor: config.theme == 'diy' ? config.textColor : ''
}" class="cart shopping-cart-btn iconfont icon-gouwuche click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view>
</view>
<!--加号图标 -->
<view v-else-if="config.style == 'icon-add'" :style="{
color: config.theme == 'diy' ? config.textColor : '',
borderColor: config.theme == 'diy' ? config.textColor : ''
}" class="cart plus-sign-btn iconfont icon-add1 click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view>
</view>
<!-- 按钮 -->
<view v-else-if="config.style == 'button'" :style="{
backgroundColor: config.theme == 'diy' ? config.bgColor : '',
color: config.theme == 'diy' ? config.textColor : '',
fontWeight: config.theme == 'diy' ? (config.fontWeight ? 'bold' : 'normal') : '',
padding: config.theme == 'diy' ? '12rpx ' + config.padding * 2 + 'rpx' : ''
}" class="cart buy-btn click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
{{ config.text }}
<view class="click-event"></view>
</view>
<!--自定义图标 -->
<view v-else-if="config.style == 'icon-diy'" :style="{
color: config.theme == 'diy' ? config.textColor : ''
}" class="icon-diy click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view>
<diy-icon :icon="config.iconDiy.icon" :value="config.iconDiy.style ? config.iconDiy.style : null"></diy-icon>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="circle-box" v-if="showLoading && load"><ns-loading></ns-loading></view>
<ns-goods-sku-index ref="goodsSkuIndex" @cartListChange="cartListChange" @addCart="addCart"></ns-goods-sku-index>
</view>
</template> </template>
<script> <script>
@@ -256,6 +344,22 @@
right: 0; right: 0;
// transform: translateY(-50%); // transform: translateY(-50%);
} }
.sell-out{
position: absolute;
z-index: 1;
width: 100%;
height: 100%;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.5);
text{
color: #fff;
font-size: 220rpx;
}
}
} }
.goods-tag { .goods-tag {

View File

@@ -31,9 +31,11 @@
@click="change(item_value.sku_id, item_value.spec_id)"> @click="change(item_value.sku_id, item_value.spec_id)">
<image v-if="item_value.image" :src="$util.img(item_value.image, { size: 'small' })" @error="valueImageError(index, index_value)" /> <image v-if="item_value.image" :src="$util.img(item_value.image, { size: 'small' })" @error="valueImageError(index, index_value)" />
<text>{{ item_value.spec_value_name }}</text> <text>{{ item_value.spec_value_name }}</text>
<view class="empty-stock" v-if="item_value.stock == 0">缺货</view>
</view> </view>
</view> </view>
</view> </view>
<ns-form :data="goodsForm" v-if="goodsForm" ref="form"></ns-form>
</scroll-view> </scroll-view>
</view> </view>
<view class="footer"> <view class="footer">
@@ -50,12 +52,12 @@
</view> </view>
</view> </view>
<view class="footer-right"> <view class="footer-right">
<view class="change_num" v-if="number > 0"> <view class="change_num" v-if="cartInputLock">
<view class="num-action" @click="changeNum('-')"> <view class="num-action" @click="changeNum('-')">
<text class="desc iconfont icon-jianshao color-base-text"></text> <text class="desc iconfont icon-jianshao color-base-text"></text>
<view class="click-event"></view> <view class="click-event"></view>
</view> </view>
<input type="number" class="uni-input" @blur="blur" v-model="number" placeholder="0" @input="keyInput(false)" /> <input type="number" class="uni-input" @blur="blur" v-model.lazy="number" placeholder="0" @input="keyInput(false,null,true)" />
<view class="num-action" :id="'select-sku-num-' + goodsDetail.goods_id" @click="changeNum('+', $event)"> <view class="num-action" :id="'select-sku-num-' + goodsDetail.goods_id" @click="changeNum('+', $event)">
<text class="add iconfont icon-add-fill color-base-text change_hover"></text> <text class="add iconfont icon-add-fill color-base-text change_hover"></text>
<view class="click-event"></view> <view class="click-event"></view>
@@ -115,7 +117,9 @@
maxBuy: 0, maxBuy: 0,
minBuy: 0, minBuy: 0,
isLoad: false, isLoad: false,
timeout: null timeout: null,
goodsForm: null,
skuList: []
}; };
}, },
created() { created() {
@@ -124,21 +128,44 @@
watch: { watch: {
pointLimit(newNum, oldNum) { pointLimit(newNum, oldNum) {
this.limitNumber = Number(newNum); this.limitNumber = Number(newNum);
}, }
minBuy(newData, oldData) { },
if (this.minBuy > 1) { computed:{
this.number = Number(this.minBuy); cartInputLock:function() {
if(!this.isLoad){
return true
}else if(this.number>0){
return true
}else{
return false
} }
} }
}, },
methods: { methods: {
calcSkuStock() {
if(this.goodsDetail.goods_spec_format && this.goodsDetail.goods_spec_format.length){
this.goodsDetail.goods_spec_format.forEach(spec => {
spec.value.forEach(val => {
this.skuList.forEach(sku => {
if (val.sku_id == sku.sku_id) {
this.$set(val,'stock',sku.stock);
}
})
})
})
}
},
show(data) { show(data) {
this.number = 0 ; // 每次打开要初始化
this.isLoad = true; this.isLoad = true;
this.goodsDetail = data; this.goodsDetail = data;
this.goodsId = this.goodsDetail.goods_id; this.goodsId = this.goodsDetail.goods_id;
this.skuId = this.goodsDetail.sku_id; this.skuId = this.goodsDetail.sku_id;
this.maxBuy = this.goodsDetail.max_buy; this.maxBuy = this.goodsDetail.max_buy;
this.minBuy = this.goodsDetail.min_buy; this.minBuy = this.goodsDetail.min_buy;
this.goodsForm = null
this.getGoodsForm()
this.getGoodsSkuList(this.goodsId); this.getGoodsSkuList(this.goodsId);
this.keyInput(false); this.keyInput(false);
if (this.getCurrentCart()) { if (this.getCurrentCart()) {
@@ -146,6 +173,19 @@
} }
this.$refs.skuPopup.open(); this.$refs.skuPopup.open();
}, },
getGoodsForm(){
this.$api.sendRequest({
url: "/form/api/form/goodsform",
data: {
goods_id: this.goodsDetail.goods_id
},
success: res => {
if (res.code == 0 && res.data) {
this.goodsForm = res.data
}
}
});
},
hide() { hide() {
if(this.$refs.skuPopup) this.$refs.skuPopup.close(); if(this.$refs.skuPopup) this.$refs.skuPopup.close();
}, },
@@ -175,6 +215,7 @@
} else { } else {
this.number = 0; this.number = 0;
} }
this.calcSkuStock()
}, },
//查看规格图片 //查看规格图片
previewMedia() { previewMedia() {
@@ -200,7 +241,7 @@
if (res.code >= 0) { if (res.code >= 0) {
let data = res.data, let data = res.data,
obj = {}; obj = {};
res.data.forEach((item, index) => { res.data.forEach((item, index) => {
// 当前商品SKU规格 // 当前商品SKU规格
if (item.sku_spec_format) item.sku_spec_format = JSON.parse(item.sku_spec_format); if (item.sku_spec_format) item.sku_spec_format = JSON.parse(item.sku_spec_format);
@@ -228,6 +269,8 @@
obj['sku_' + item.sku_id] = item; obj['sku_' + item.sku_id] = item;
}); });
this.goodsSkuList = obj; this.goodsSkuList = obj;
this.skuList = res.data;
this.calcSkuStock();
} }
} }
}); });
@@ -281,12 +324,11 @@
} }
const query = uni.createSelectorQuery().in(this); const query = uni.createSelectorQuery().in(this);
query.select('#' + event.currentTarget.id + ' .click-event') query.select('#' + event.currentTarget.id + ' .click-event').boundingClientRect(data => {
.boundingClientRect(data => { if (data) {
if (data) { this.$emit('addCart', data.left, data.top);
this.$emit('addCart', data.left, data.top); }
} }).exec();
}).exec();
} else if (tag == '-') { } else if (tag == '-') {
// 减 // 减
if (this.number > min) { if (this.number > min) {
@@ -325,14 +367,16 @@
let newNumber = parseInt(this.number); let newNumber = parseInt(this.number);
this.isLoad = false; this.isLoad = true;
setTimeout(() => { setTimeout(() => {
this.number = newNumber; this.number = newNumber;
this.cartNumChange(this.number); this.cartNumChange(this.number);
}, 0); }, 0);
}, },
//输入数量 //输入数量
keyInput(flag, callback) { keyInput(flag, callback,isInput) {
if(isInput) this.isLoad = false
setTimeout(() => { setTimeout(() => {
var stock = this.goodsDetail.stock; var stock = this.goodsDetail.stock;
@@ -352,7 +396,7 @@
this.number = stock; this.number = stock;
} }
// 商品起售数 // 商品起售数
if (this.minBuy > 1 && this.number < this.minBuy) { if (flag && this.minBuy > 1 && this.number < this.minBuy) {
this.number = this.minBuy; this.number = this.minBuy;
} }
@@ -374,7 +418,13 @@
}); });
return; return;
} }
if (this.$refs.form) {
if (!this.$refs.form.verify()) return;
uni.setStorageSync('goodFormData', {
goods_id: this.goodsDetail.goods_id,
form_data: this.$refs.form.formData
});
}
this.number = 1; this.number = 1;
//纠正数量 //纠正数量
this.keyInput(true, () => { this.keyInput(true, () => {
@@ -676,7 +726,20 @@
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
} }
.body-item .sku-list-wrap .empty-stock{
font-size: 18rpx;
line-height: 22rpx;
position: absolute;
right: 0;
top: 0;
border-radius: 4rpx;
transform: translateY(-50%);
padding: 0 2rpx;
color: #989898;
background-color: #f0f1f2;
}
.sku-layer .body-item .sku-list-wrap .items { .sku-layer .body-item .sku-list-wrap .items {
text-align: center; text-align: center;
position: relative; position: relative;

View File

@@ -51,12 +51,7 @@
* @param {Object} data 商品项 * @param {Object} data 商品项
*/ */
singleSpecificationGoods(data, event) { singleSpecificationGoods(data, event) {
let cart = let cart = this.cartList['goods_' + data.goods_id] && this.cartList['goods_' + data.goods_id]['sku_' + data.sku_id] ? this.cartList['goods_' + data.goods_id]['sku_' + data.sku_id] : null;
this.cartList['goods_' + data.goods_id] && this.cartList['goods_' + data.goods_id]['sku_' + data
.sku_id
] ?
this.cartList['goods_' + data.goods_id]['sku_' + data.sku_id] :
null;
let cartNum = cart ? cart.num : 0; let cartNum = cart ? cart.num : 0;
let api = cart && cart.cart_id ? '/api/cart/edit' : '/api/cart/add'; let api = cart && cart.cart_id ? '/api/cart/edit' : '/api/cart/add';
@@ -66,6 +61,7 @@
if(cart && cart.cart_id){ if(cart && cart.cart_id){
_num = _num + (data.min_buy > 0 ? data.min_buy : 1) _num = _num + (data.min_buy > 0 ? data.min_buy : 1)
} }
let cart_id = cart ? cart.cart_id : 0; let cart_id = cart ? cart.cart_id : 0;
if (_num > parseInt(data.stock)) { if (_num > parseInt(data.stock)) {
this.$util.showToast({ this.$util.showToast({
@@ -119,8 +115,7 @@
this.isRepeat = false; this.isRepeat = false;
if (res.code == 0) { if (res.code == 0) {
if (cart_id == 0) { if (cart_id == 0) {
this.cartList['goods_' + data.goods_id]['sku_' + data.sku_id].cart_id = this.cartList['goods_' + data.goods_id]['sku_' + data.sku_id].cart_id = res.data;
res.data;
} }
this.$util.showToast({ this.$util.showToast({
title: "商品添加购物车成功" title: "商品添加购物车成功"

View File

@@ -153,6 +153,7 @@
}" class="items" @click="change(item_value.sku_id, item_value.spec_id)"> }" class="items" @click="change(item_value.sku_id, item_value.spec_id)">
<image v-if="item_value.image" :src="$util.img(item_value.image, { size: 'small' })" @error="valueImageError(index, index_value)" /> <image v-if="item_value.image" :src="$util.img(item_value.image, { size: 'small' })" @error="valueImageError(index, index_value)" />
<text>{{ item_value.spec_value_name }}</text> <text>{{ item_value.spec_value_name }}</text>
<view class="empty-stock" v-if="item_value.stock == 0">缺货</view>
</view> </view>
</view> </view>
@@ -173,8 +174,8 @@
</view> </view>
</view> </view>
</view> </view>
<ns-form :data="goodsForm" v-if="goodsForm" ref="form"></ns-form> <ns-form :data="goodsForm" v-if="goodsForm" ref="form" @changeFormVal="changeFormVal"></ns-form>
</scroll-view> </scroll-view>
</view> </view>
<view class="footer" @click="confirm()"> <view class="footer" @click="confirm()">
@@ -182,7 +183,8 @@
<block v-if="type == 'point'"> <block v-if="type == 'point'">
<block v-if="goodsDetail.type == 1"> <block v-if="goodsDetail.type == 1">
<!-- 兑换商品 --> <!-- 兑换商品 -->
<button v-if="goodsDetail.stock && goodsDetail.stock != 0" type="primary">兑换</button> <button v-if="goodsDetail.point * number > memberPoint" disabled="true" type="primary">积分不足</button>
<button v-else-if="goodsDetail.stock && goodsDetail.stock != 0" type="primary">兑换</button>
<button type="primary" v-else disabled="true">库存不足</button> <button type="primary" v-else disabled="true">库存不足</button>
</block> </block>
<block v-else-if="goodsDetail.type == 2 || goodsDetail.type == 3"> <block v-else-if="goodsDetail.type == 2 || goodsDetail.type == 3">
@@ -195,7 +197,8 @@
<button type="primary" v-else-if="goodsDetail.stock && goodsDetail.stock != 0 && type == 'buy_now'">立即购买</button> <button type="primary" v-else-if="goodsDetail.stock && goodsDetail.stock != 0 && type == 'buy_now'">立即购买</button>
<button type="primary" v-else-if="goodsDetail.stock && goodsDetail.stock != 0 && type == 'confirm'">确认</button> <button type="primary" v-else-if="goodsDetail.stock && goodsDetail.stock != 0 && type == 'confirm'">确认</button>
<template v-else-if="goodsDetail.stock && goodsDetail.stock != 0"> <template v-else-if="goodsDetail.stock && goodsDetail.stock != 0">
<template v-if="goodsDetail.buy_num"> <!-- 拼团和拼返的buy_num代表最大购买数量不是最小购买数量 -->
<template v-if="type != 'pintuan' && type != 'pinfan' && goodsDetail.buy_num">
<button type="primary" v-if="goodsDetail.buy_num <= goodsDetail.stock">立即抢购</button> <button type="primary" v-if="goodsDetail.buy_num <= goodsDetail.stock">立即抢购</button>
<button type="primary" v-else disabled="true">库存不足</button> <button type="primary" v-else disabled="true">库存不足</button>
</template> </template>
@@ -226,6 +229,10 @@
type: [Number, String], type: [Number, String],
default: 0 default: 0
}, },
memberPoint: {
type: [Number, String],
default: 0
},
goodsDetail: { goodsDetail: {
type: Object, type: Object,
default: null default: null
@@ -244,6 +251,12 @@
minBuy: { minBuy: {
type: Number, type: Number,
default: 0 default: 0
},
goodsFormVal: {
type: Array,
default () {
return [];
}
} }
}, },
data() { data() {
@@ -265,7 +278,8 @@
pintuan_num_field: 'pintuan_num', pintuan_num_field: 'pintuan_num',
goodsSkuInfo: null, //所有的商品规格信息 goodsSkuInfo: null, //所有的商品规格信息
goodsForm: null, goodsForm: null,
isLoad: false // 是否首次加载 isLoad: false ,// 是否首次加载
skuList: [],//所有规格数据
}; };
}, },
created() { created() {
@@ -310,8 +324,8 @@
this.pintuan_num_field = newData.pintuan_num_field; this.pintuan_num_field = newData.pintuan_num_field;
} }
if (this.goodsDetail.goods_form && !this.goodsForm) this.goodsForm = this.goodsDetail.goods_form; if (this.goodsDetail.goods_form && !this.goodsForm) this.goodsForm = this.goodsDetail.goods_form;
// 切换商品,重新赋值 // 切换商品,重新赋值
this.calcSkuStock()
if (newData.goods_id != oldData.goods_id) { if (newData.goods_id != oldData.goods_id) {
if (this.goodsDetail.pintuan_id) { if (this.goodsDetail.pintuan_id) {
this.getPintuanGoodsSkuList(); this.getPintuanGoodsSkuList();
@@ -378,6 +392,34 @@
} }
}, },
methods: { methods: {
calcSkuStock() {
if(this.goodsDetail.goods_spec_format && this.goodsDetail.goods_spec_format.length){
this.goodsDetail.goods_spec_format.forEach(spec => {
spec.value.forEach(val => {
this.skuList.forEach(sku => {
if (val.sku_id == sku.sku_id) {
this.$set(val,'stock',sku.stock);
}
})
})
})
}
},
changeFormVal(e) {
this.$emit('detailChangeVal',e)
},
getGoodsForm(){
this.$api.sendRequest({
url: "/form/api/form/goodsform",
data: {
goods_id: this.goodsDetail.goods_id
},
success: res => {
if (res.code == 0 && res.data) this.$set(this.goodsDetail, 'goods_form', res.data);
if(this.goodsFormVal.length) Object.assign(this.goodsDetail.goods_form,this.goodsFormVal)
}
});
},
//【普通商品】获取所有规格信息 //【普通商品】获取所有规格信息
getGeneralGoodsSkuList(callback) { getGeneralGoodsSkuList(callback) {
this.$api.sendRequest({ this.$api.sendRequest({
@@ -387,9 +429,7 @@
}, },
success: res => { success: res => {
if (res.code >= 0) { if (res.code >= 0) {
let data = res.data, let obj = {};
obj = {};
res.data.forEach((item, index) => { res.data.forEach((item, index) => {
item = this.handleData(item); item = this.handleData(item);
@@ -415,6 +455,8 @@
if (this.skuId == 0) this.skuId = res.data[0].sku_id; if (this.skuId == 0) this.skuId = res.data[0].sku_id;
this.goodsSkuInfo = obj; this.goodsSkuInfo = obj;
this.isLoad = false; this.isLoad = false;
this.skuList = res.data;
this.calcSkuStock();
if (callback) callback(); if (callback) callback();
} else { } else {
this.$util.redirectTo('/pages/index/index'); this.$util.redirectTo('/pages/index/index');
@@ -493,7 +535,7 @@
item = this.handleData(item); item = this.handleData(item);
item.show_price = this.goodsDetail.groupbuy_price; item.show_price = this.goodsDetail.groupbuy_price;
item.save_price = item.price - item.show_price > 0 ? (item.price - item.show_price).toFixed(2) : 0; item.save_price = item.price - item.show_price > 0 ? (item.price - item.show_price).toFixed(2) : 0;
//团购buy_num指最少购买数量
if (data.stock > data.buy_num) { if (data.stock > data.buy_num) {
this.number = this.goodsDetail.buy_num; this.number = this.goodsDetail.buy_num;
this.minNumber = this.goodsDetail.buy_num; this.minNumber = this.goodsDetail.buy_num;
@@ -730,6 +772,9 @@
popclose() { popclose() {
if (this.$refs.skuPopup.showPopup) { if (this.$refs.skuPopup.showPopup) {
this.$emit('hideSkuPop'); this.$emit('hideSkuPop');
}else{
this.goodsForm = null
this.getGoodsForm()
} }
}, },
//查看规格图片 //查看规格图片
@@ -766,7 +811,6 @@
} }
} }
} }
this.goodsSkuDetail = this.goodsSkuInfo['sku_' + this.skuId]; this.goodsSkuDetail = this.goodsSkuInfo['sku_' + this.skuId];
this.$emit('refresh', this.goodsSkuDetail); this.$emit('refresh', this.goodsSkuDetail);
this.$emit('getSkuId', this.skuId); this.$emit('getSkuId', this.skuId);
@@ -781,6 +825,7 @@
this.confirmDisabled = false; this.confirmDisabled = false;
} }
} }
this.keyInput(true); this.keyInput(true);
}, },
showPrice(price) { showPrice(price) {
@@ -1013,7 +1058,7 @@
return; return;
} }
if (this.goodsDetail.buy_num > this.goodsDetail.stock) { if (this.type != 'pintuan' && this.type != 'pinfan' && this.goodsDetail.buy_num > this.goodsDetail.stock) {
this.$util.showToast({ this.$util.showToast({
title: '库存小于最低购买数量' title: '库存小于最低购买数量'
}); });
@@ -1077,7 +1122,7 @@
title: '加入购物车成功' title: '加入购物车成功'
}); });
this.cartNum += this.number; this.cartNum += this.number;
this.$store.dispatch('getCartNumber');
let discount_price = this.goodsDetail.discount_price; let discount_price = this.goodsDetail.discount_price;
if (this.goodsDetail.member_price > 0 && Number(this.goodsDetail.member_price) <= Number(this.goodsDetail.discount_price)) { if (this.goodsDetail.member_price > 0 && Number(this.goodsDetail.member_price) <= Number(this.goodsDetail.discount_price)) {
discount_price = this.goodsDetail.member_price; discount_price = this.goodsDetail.member_price;
@@ -1213,28 +1258,29 @@
}); });
} else if (this.type == 'bargain') { } else if (this.type == 'bargain') {
// 砍价 // 砍价
this.$api.sendRequest({ if (this.callback) {
url: '/bargain/api/bargain/launch', this.callback();
data: { }else {
id: this.goodsDetail.id this.$api.sendRequest({
}, url: '/bargain/api/bargain/launch',
success: res => { data: {
this.btnSwitch = false; id: this.goodsDetail.id
if (res.code == 0) { },
this.$util.redirectTo( success: res => {
'/pages_promotion/bargain/detail', { this.btnSwitch = false;
if (res.code == 0) {
this.$util.redirectTo('/pages_promotion/bargain/detail', {
b_id: this.goodsDetail.bargain_id, b_id: this.goodsDetail.bargain_id,
l_id: res.data l_id: res.data
}, }, 'redirectTo');
'redirectTo' } else {
); this.$util.showToast({
} else { title: res.message
this.$util.showToast({ });
title: res.message }
});
} }
} });
}); }
} else if (this.type == 'point') { } else if (this.type == 'point') {
// 积分兑换 // 积分兑换
var data = { var data = {
@@ -1399,13 +1445,27 @@
.body-item .sku-list-wrap { .body-item .sku-list-wrap {
padding-bottom: 0rpx; padding-bottom: 0rpx;
position: relative;
} }
.body-item .sku-list-wrap .title { .body-item .sku-list-wrap .title {
padding: 20rpx 0; padding: 20rpx 0;
display: block; display: block;
} }
.body-item .sku-list-wrap .empty-stock{
font-size: 18rpx;
line-height: 22rpx;
position: absolute;
right: 0;
top: 0;
border-radius: 4rpx;
transform: translateY(-50%);
padding: 0 2rpx;
color: #989898;
background-color: #f0f1f2;
}
.body-item .sku-list-wrap .items { .body-item .sku-list-wrap .items {
position: relative; position: relative;
display: inline-block; display: inline-block;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
<template>
<view class="mp-html">
<mp-html :content="content"></mp-html>
</view>
</template>
<script>
export default {
props: {
content: {
type: String,
default: '',
}
},
}
</script>
<style lang="scss">
.mp-html{
/deep/ img{
width:100% !important;
display:block;
}
}
</style>

View File

@@ -1,404 +1,400 @@
<template> <template>
<!-- <view class="ns-navbar-wrap" :class="'style-' + data.navStyle"> <view class="ns-navbar-wrap" :class="'style-' + data.navStyle">
<!-- #ifndef MP-ALIPAY -->
<view class="u-navbar" :style="{ backgroundColor: bgColor, paddingTop: navbarHeight + 'px' }"> <view class="u-navbar" :style="{ backgroundColor: bgColor, paddingTop: navbarHeight + 'px' }">
<view class="navbar-inner" :style="navbarInnerStyle"> <view class="navbar-inner" :style="navbarInnerStyle">
<view class="back-wrap" v-if="isBack && isBackShow" @tap="goBack"> <view class="back-wrap" v-if="isBack && isBackShow" @tap="goBack">
<text class="iconfont icon-back_light" :style="{ color: titleColor }"></text> <text class="iconfont icon-back_light" :style="{ color: titleColor }"></text>
</view> </view>
<view v-if="data.navStyle == 1" class="content-wrap" :class="[data.textImgPosLink, isBack && isBackShow ? 'have-back' : '']" @click="toLink(data.moreLink.wap_url)"> <view v-if="data.navStyle == 1" class="content-wrap" :class="[data.textImgPosLink, isBack && isBackShow ? 'have-back' : '']" @click="toLink(data.moreLink.wap_url)">
<view class="title-wrap" :style="{ fontSize: '14px', color: data.textNavColor, textAlign: data.textImgPosLink }"> <view class="title-wrap" :style="{ fontSize: '16px', color: data.textNavColor, textAlign: data.textImgPosLink }">
{{ data.title }} {{ data.title }}
</view> </view>
</view> </view>
<view v-if="data.navStyle == 2" class="content-wrap" @click="toLink(data.moreLink.wap_url)"> <view v-if="data.navStyle == 2" class="content-wrap" @click="toLink(data.moreLink.wap_url)">
<view class="title-wrap" :style="{ color: data.textNavColor }"> <view class="title-wrap" :style="{ color: data.textNavColor }">
<view> <view>
<image :src="$util.img(data.topNavImg)" mode="heightFix"></image> <image :src="$util.img(data.topNavImg)" mode="heightFix"></image>
</view> </view>
<view :style="{ color: data.textNavColor }">{{ data.title }}</view> <view :style="{ color: data.textNavColor }">{{ data.title }}</view>
</view> </view>
</view> </view>
<view v-if="data.navStyle == 3" class="content-wrap"> <view v-if="data.navStyle == 3" class="content-wrap">
<view class="title-wrap" @click="toLink(data.moreLink.wap_url)"> <view class="title-wrap" @click="toLink(data.moreLink.wap_url)">
<image :src="$util.img(data.topNavImg)" mode="aspectFit"></image> <image :src="$util.img(data.topNavImg)" mode="aspectFit"></image>
</view> </view>
<view class="search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="{ height: menuButtonInfo.height - 2 + 'px', lineHeight: menuButtonInfo.height - 2 + 'px' }"> <view class="search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="{ height: menuButtonInfo.height - 2 + 'px', lineHeight: menuButtonInfo.height - 2 + 'px' }">
<text class="iconfont icon-sousuo3"></text> <text class="iconfont icon-sousuo3"></text>
<text>请输入商品名称</text> <text>请输入商品名称</text>
</view> </view>
<view :style="{ 'width': capsuleWidth }"></view> <view :style="{ 'width': capsuleWidth }"></view>
</view> </view>
<view v-if="data.navStyle == 4" class="content-wrap" :class="{ 'have-back': isBack && isBackShow }" @click="chooseOtherStore()"> <view v-if="data.navStyle == 4" class="content-wrap" :class="{ 'have-back': isBack && isBackShow }" @click="chooseOtherStore()">
<text class="iconfont icon-dizhi" :style="{ color: data.textNavColor }"></text> <text class="iconfont icon-dizhi" :style="{ color: data.textNavColor }"></text>
<view v-if="globalStoreInfo && globalStoreInfo.store_id" class="title-wrap" :style="{ color: data.textNavColor }">{{ globalStoreInfo.store_name }}</view> <view v-if="globalStoreInfo && globalStoreInfo.store_id" class="title-wrap" :style="{ color: data.textNavColor }">{{ globalStoreInfo.store_name }}</view>
<view v-else class="title-wrap" :style="{ color: data.textNavColor }">定位中...</view> <view v-else class="title-wrap" :style="{ color: data.textNavColor }">定位中...</view>
<text class="iconfont icon-right" :style="{ color: data.textNavColor }"></text> <text class="iconfont icon-right" :style="{ color: data.textNavColor }"></text>
<view class="nearby-store-name" :style="{ color: data.textNavColor }">附近门店</view> <view class="nearby-store-name" :style="{ color: data.textNavColor }">附近门店</view>
</view> </view>
</view> </view>
</view> </view>
<view class="u-navbar-placeholder" :style="{ width: '100%', paddingTop: placeholderHeight + 'px' }"></view> <!-- 解决fixed定位后导航栏塌陷的问题 -->
<view class="u-navbar-placeholder" :style="{ width: '100%', paddingTop: placeholderHeight + 'px' }"></view>
</view> --> <!-- #endif -->
</template> </view>
</template>
<script>
// 获取系统状态栏的高度 <script>
let systemInfo = uni.getSystemInfoSync(); // 获取系统状态栏的高度
let menuButtonInfo = {}; let systemInfo = uni.getSystemInfoSync();
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API尚未兼容) let menuButtonInfo = {};
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ // 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API尚未兼容)
menuButtonInfo = uni.getMenuButtonBoundingClientRect(); // #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
// #endif menuButtonInfo = uni.getMenuButtonBoundingClientRect();
// #endif
// 自定义导航栏
export default { // 自定义导航栏
name: 'ns-navbar', export default {
props: { name: 'ns-navbar',
data: { props: {
type: Object, data: {
default() { type: Object,
return {}; default() {
} return {};
}, }
// 标题的颜色 },
titleColor: { // 标题的颜色
type: String, titleColor: {
default: '#606266' type: String,
}, default: '#606266'
// 自定义返回逻辑 },
customBack: { // 自定义返回逻辑
type: Function, customBack: {
default: null type: Function,
}, default: null
scrollTop: { },
type: [String, Number], scrollTop: {
default: '0' type: [String, Number],
}, default: '0'
// 是否显示导航栏左边返回图标和辅助文字 },
isBack: { // 是否显示导航栏左边返回图标和辅助文字
type: Boolean, isBack: {
default: true type: Boolean,
} default: true
}, }
data() { },
return { data() {
menuButtonInfo: menuButtonInfo, return {
isBackShow: false, menuButtonInfo: menuButtonInfo,
placeholderHeight: 0 isBackShow: false,
}; placeholderHeight: 0
}, };
computed: { },
// 导航栏内部盒子的样式 computed: {
navbarInnerStyle() { // 导航栏内部盒子的样式
let style = ''; navbarInnerStyle() {
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离 let style = '';
style += 'height:' + menuButtonInfo.height * 2 + 'rpx;'; // 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
return style; style += 'height:' + menuButtonInfo.height * 2 + 'rpx;';
}, return style;
// 转换字符数值为真正的数值 },
navbarHeight() { // 转换字符数值为真正的数值
// #ifdef APP-PLUS || H5 navbarHeight() {
return 25; // #ifdef APP-PLUS || H5
// #endif return 25;
// #ifdef MP // #endif
// 小程序特别处理,让导航栏高度 = 胶囊高度 + 两倍胶囊顶部与状态栏底部的距离之差(相当于同时获得了导航栏底部与胶囊底部的距离) // #ifdef MP
let height = menuButtonInfo.top; // 小程序特别处理,让导航栏高度 = 胶囊高度 + 两倍胶囊顶部与状态栏底部的距离之差(相当于同时获得了导航栏底部与胶囊底部的距离)
return height; let height = menuButtonInfo.top;
// #endif return height;
}, // #endif
bgColor() { },
var color = ''; bgColor() {
if (this.data.topNavBg) { var color = '';
// 顶部透明 if (this.data.topNavBg) {
color = 'transparent'; // 顶部透明
let top = 0; color = 'transparent';
let top = 0;
if (this.data.navStyle == 4) {
// #ifdef H5 if (this.data.navStyle == 4) {
top = 15; // #ifdef H5
// #endif top = 15;
// #ifdef MP // #endif
top = this.navbarHeight - 25; // #ifdef MP
// #endif top = this.navbarHeight - 25;
} // #endif
}
if (this.scrollTop > top) {
color = this.data.topNavColor; if (this.scrollTop > top) {
} else { color = this.data.topNavColor;
color = 'transparent'; } else {
} color = 'transparent';
} else { }
color = this.data.topNavColor; } else {
} color = this.data.topNavColor;
return color; }
}, return color;
capsuleWidth() { },
let width = `calc(100vw - ${this.menuButtonInfo.right}px + ${this.menuButtonInfo.width}px + 10px)`; capsuleWidth() {
return width; let width = `calc(100vw - ${this.menuButtonInfo.right}px + ${this.menuButtonInfo.width}px + 10px)`;
} return width;
}, }
created(e) { },
// var pages = getCurrentPages(); created(e) {
// if (pages.length > 1) { var pages = getCurrentPages();
// this.isBackShow = true; if (pages.length > 1) {
// } this.isBackShow = true;
// this.navbarPlaceholderHeight(); }
}, this.navbarPlaceholderHeight();
mounted() { },
// this.setModuleLocatinoFn(); mounted() {
}, this.setModuleLocationFn();
methods: { },
toLink(val) { methods: {
if (val) this.$util.redirectTo(val); toLink(val) {
}, if (val) this.$util.redirectTo(val);
goBack() { },
// 如果自定义了点击返回按钮的函数,则执行,否则执行返回逻辑 goBack() {
if (typeof this.customBack === 'function') { // 如果自定义了点击返回按钮的函数,则执行,否则执行返回逻辑
this.customBack(); if (typeof this.customBack === 'function') {
} else { this.customBack();
uni.navigateBack(); } else {
} uni.navigateBack();
}, }
// 选择其他门店 },
chooseOtherStore() { // 选择其他门店
if (this.globalStoreConfig && this.globalStoreConfig.is_allow_change == 1) { chooseOtherStore() {
this.$util.redirectTo('/pages_tool/store/list'); if (this.globalStoreConfig && this.globalStoreConfig.is_allow_change == 1) {
} else if (this.globalStoreInfo) { this.$util.redirectTo('/pages_tool/store/list');
// 禁止切换门店,进入门店详情 } else if (this.globalStoreInfo) {
this.$util.redirectTo('/pages_tool/store/detail', { // 禁止切换门店,进入门店详情
store_id: this.globalStoreInfo.store_id this.$util.redirectTo('/pages_tool/store/detail', {
}); store_id: this.globalStoreInfo.store_id
} });
}, }
navbarPlaceholderHeight() { },
let height = 0; navbarPlaceholderHeight() {
setTimeout(() => { setTimeout(() => {
const query = uni.createSelectorQuery().in(this); const query = uni.createSelectorQuery().in(this);
query query.select('.ns-navbar-wrap .u-navbar').boundingClientRect(data => {
.select('.ns-navbar-wrap .u-navbar') // 获取公告自身高度
.boundingClientRect(data => { this.placeholderHeight = data.height;
// 获取公告自身高度 }).exec();
this.placeholderHeight = data.height; });
}) },
.exec(); // 向vuex中的diyIndexPositionObj增加公告导航组件定位位置
}); setModuleLocationFn() {
}, const query = uni.createSelectorQuery().in(this);
// 向vuex中的diyIndexPositionObj增加公告导航组件定位位置 query.select('.ns-navbar-wrap .u-navbar').boundingClientRect(data => {
setModuleLocatinoFn() { let diyIndexPage = {
const query = uni.createSelectorQuery().in(this); originalVal: data.height || 0, //自身高度 px
query.select('.ns-navbar-wrap .u-navbar') currVal: 0 //定位高度
.boundingClientRect(data => { };
let diyIndexPage = { this.$store.commit('setDiyGroupPositionObj', {
originalVal: data.height || 0, //自身高度 px 'nsNavbar': diyIndexPage
currVal: 0 //定位高度 });
}; }).exec();
this.$store.commit('setDiyGroupPositionObj', { }
'nsNavbar': diyIndexPage }
}); };
}).exec(); </script>
}
} <style scoped lang="scss">
}; /* #ifdef H5 */
</script> .style-1,
.style-2,
<style scoped lang="scss"> .style-3 {
/* #ifdef H5 */ display: none;
.style-1, }
.style-2,
.style-3 { /* #endif */
display: none;
} .u-navbar {
width: 100%;
/* #endif */ transition: background 0.3s;
position: fixed;
.u-navbar { left: 0;
width: 100%; right: 0;
transition: background 0.3s; top: 0;
position: fixed; z-index: 991;
left: 0; }
right: 0;
top: 0; .navbar-inner {
z-index: 991; display: flex;
} justify-content: space-between;
position: relative;
.navbar-inner { align-items: center;
display: flex; padding-bottom: 20rpx;
justify-content: space-between; /* #ifdef H5 */
position: relative; padding-bottom: 40rpx;
align-items: center; /* #endif */
padding-bottom: 20rpx; }
/* #ifdef H5 */
padding-bottom: 40rpx; .back-wrap {
/* #endif */ padding: 0 14rpx 0 24rpx;
}
.iconfont {
.back-wrap { font-size: 44rpx;
padding: 0 14rpx 0 24rpx; }
}
.iconfont {
font-size: 44rpx; .content-wrap {
} display: flex;
} align-items: center;
justify-content: flex-start;
.content-wrap { flex: 1;
display: flex; position: absolute;
align-items: center; left: 0;
justify-content: flex-start; right: 0;
flex: 1; top: 0;
position: absolute; height: 60rpx;
left: 0; text-align: center;
right: 0; flex-shrink: 0;
top: 0; }
height: 60rpx;
text-align: center; .title-wrap {
flex-shrink: 0; line-height: 1;
} flex: 1;
overflow: hidden;
.title-wrap { text-overflow: ellipsis;
line-height: 1; white-space: nowrap;
flex: 1; font-size: 32rpx;
overflow: hidden; color: #000000;
text-overflow: ellipsis; }
white-space: nowrap;
font-size: 32rpx; .ns-navbar-wrap {
color: #000000;
} &.style-1 {
.content-wrap {
.ns-navbar-wrap { .title-wrap {
font-size: 27rpx;
&.style-1 { }
.content-wrap {
.title-wrap { &.left {
font-size: 27rpx; left: 30rpx;
} }
&.left { &.center {
left: 30rpx; left: 0;
} padding-right: 0;
}
&.center {
left: 0; &.have-back {
padding-right: 0; left: 90rpx;
} padding-right: 200rpx;
}
&.have-back { }
left: 90rpx; }
padding-right: 200rpx;
} &.style-2 {
} .content-wrap {
} .title-wrap {
display: flex;
&.style-2 { align-items: center;
.content-wrap { text-align: left;
.title-wrap {
display: flex; >view {
align-items: center; height: 56rpx;
text-align: left; line-height: 56rpx;
max-width: 300rpx;
>view { margin-left: 30rpx;
height: 56rpx; font-size: 27rpx;
line-height: 56rpx;
max-width: 300rpx; image {
margin-left: 30rpx; width: 100%;
font-size: 27rpx; height: 100%;
}
image {
width: 100%; &:last-child {
height: 100%; overflow: hidden; //超出的文本隐藏
} text-overflow: ellipsis; //用省略号显示
white-space: nowrap; //不换行
&:last-child { flex: 1;
overflow: hidden; //超出的文本隐藏 }
text-overflow: ellipsis; //用省略号显示 }
white-space: nowrap; //不换行 }
flex: 1; }
} }
}
} &.style-3 {
} .content-wrap {
} .title-wrap {
height: 60rpx;
&.style-3 { width: 170rpx;
.content-wrap { max-width: 170rpx;
.title-wrap { margin-left: 30rpx;
height: 60rpx; flex: initial;
width: 170rpx; text-align: center;
max-width: 170rpx; margin-right: 10rpx;
margin-left: 30rpx;
flex: initial; image {
text-align: center; height: 100%;
margin-right: 10rpx; width: 100%;
}
image { }
height: 100%;
width: 100%; .search {
} flex: 1;
} padding: 0 20rpx;
background-color: #fff;
.search { text-align: left;
flex: 1; border-radius: 60rpx;
padding: 0 20rpx; height: 60rpx;
background-color: #fff; line-height: 60rpx;
text-align: left; border: 1px solid #eeeeee;
border-radius: 60rpx; color: rgb(102, 102, 102);
height: 60rpx; display: flex;
line-height: 60rpx; align-items: center;
border: 1px solid #eeeeee; margin-right: 10rpx;
color: rgb(102, 102, 102);
display: flex; .iconfont {
align-items: center; color: #909399;
margin-right: 10rpx; font-size: 32rpx;
margin-right: 10rpx;
.iconfont { }
color: #909399; }
font-size: 32rpx; }
margin-right: 10rpx; }
}
} &.style-4 {
} .icon-dizhi{
} font-size: 28rpx;
}
&.style-4 { .content-wrap {
.icon-dizhi{ top: initial;
font-size: 28rpx; text-align: left;
} padding-left: 30rpx;
.content-wrap {
top: initial; &.have-back {
text-align: left; left: 60rpx;
padding-left: 30rpx; right: 190rpx;
}
&.have-back {
left: 60rpx; .title-wrap {
right: 190rpx; flex: none;
} margin: 0 10rpx;
max-width: 360rpx;
.title-wrap { font-size: 27rpx;
flex: none; }
margin: 0 10rpx;
max-width: 360rpx; .icon-right {
font-size: 27rpx; font-size: 24rpx;
} }
.icon-right { .nearby-store-name {
font-size: 24rpx; margin: 0 10rpx;
} background: rgba(0, 0, 0, .2);
font-size: 22rpx;
.nearby-store-name { border-radius: 40rpx;
margin: 0 10rpx; padding: 10rpx 20rpx;
background: rgba(0, 0, 0, .2); line-height: 1;
font-size: 22rpx; }
border-radius: 40rpx; }
padding: 10rpx 20rpx; }
line-height: 1; }
}
}
}
}
</style> </style>

View File

@@ -1,349 +1,349 @@
<template> <template>
<view> <view>
<view @touchmove.prevent.stop v-if="newgift" class="reward-popup"> <view @touchmove.prevent.stop v-if="newgift" class="reward-popup">
<uni-popup ref="nsNewGift" type="center" :maskClick="false"> <uni-popup ref="nsNewGift" type="center" :maskClick="false">
<view class="reward-wrap"> <view class="reward-wrap">
<view class="newgift-content" :style="{ backgroundImage: 'url(' + $util.img('public/uniapp/new_gift/holiday_polite-bg.png') + ')' }"> <view class="newgift-content" :style="{ backgroundImage: 'url(' + $util.img('public/uniapp/new_gift/holiday_polite-bg.png') + ')' }">
<view class="content-title-holiday"> <view class="content-title-holiday">
<image :src="$util.img('public/uniapp/new_gift/holiday_polite_left.png')" mode="" class="birthday-img-all"/> <image :src="$util.img('public/uniapp/new_gift/holiday_polite_left.png')" mode="" class="birthday-img-all" />
<view class="font-size-toolbar activity-name">{{ newgift.activity_name }}</view> <view class="font-size-toolbar activity-name">{{ newgift.activity_name }}</view>
<image :src="$util.img('public/uniapp/new_gift/holiday_polite_right.png')" mode="" class="birthday-img-all"/> <image :src="$util.img('public/uniapp/new_gift/holiday_polite_right.png')" mode="" class="birthday-img-all" />
</view> </view>
<view class="content-title-name" v-if="memberInfo">Dear {{ memberInfo.nickname }}</view> <view class="content-title-name" v-if="memberInfo">Dear {{ memberInfo.nickname }}</view>
<view class="content-title-hint" v-if="newgift.remark">{{ newgift.remark }}</view> <view class="content-title-hint" v-if="newgift.remark">{{ newgift.remark }}</view>
<view class="content-title-hint" v-else>感谢您一直以来的支持为回馈会员商城{{ newgift.activity_name ? newgift.activity_name : 'xx' }}节日为您提供以下福利</view> <view class="content-title-hint" v-else>感谢您一直以来的支持为回馈会员商城{{ newgift.activity_name ? newgift.activity_name : 'xx' }}节日为您提供以下福利</view>
<scroll-view scroll-y="true" class="register-box"> <scroll-view scroll-y="true" class="register-box">
<view :class="introduction > 38 ? 'reward-content' : 'reward-content-two'"> <view :class="introduction > 38 ? 'reward-content' : 'reward-content-two'">
<view class="content" v-if="newgift.award_list.point > 0"> <view class="content" v-if="newgift.award_list.point > 0">
<view class="info"> <view class="info">
<text class="num"> <text class="num">
{{ newgift.award_list.point }} {{ newgift.award_list.point }}
<text class="type">积分</text> <text class="type">积分</text>
</text> </text>
<view class="desc">用于参与活动购买商品时抵扣</view> <view class="desc">用于参与活动购买商品时抵扣</view>
</view> </view>
<view class="tip" @click="closeRewardPopup('1')">立即查看</view> <view class="tip" @click="closeRewardPopup('1')">立即查看</view>
</view> </view>
<view class="content" v-if="newgift.award_list.balance_type == 0 && newgift.award_list.balance > 0"> <view class="content" v-if="newgift.award_list.balance_type == 0 && newgift.award_list.balance > 0">
<view class="info"> <view class="info">
<text class="num"> <text class="num">
{{ newgift.award_list.balance | int }} {{ newgift.award_list.balance | int }}
<text class="type">元红包</text> <text class="type">元红包</text>
</text> </text>
<view class="desc">不可提现红包</view> <view class="desc">不可提现红包</view>
</view> </view>
<view class="tip" @click="closeRewardPopup('2')">立即查看</view> <view class="tip" @click="closeRewardPopup('2')">立即查看</view>
</view> </view>
<view class="content" v-if="newgift.award_list.balance_type == 1 && newgift.award_list.balance_money > 0"> <view class="content" v-if="newgift.award_list.balance_type == 1 && newgift.award_list.balance_money > 0">
<view class="info"> <view class="info">
<text class="num"> <text class="num">
{{ newgift.award_list.balance_money | int }} {{ newgift.award_list.balance_money | int }}
<text class="type">元红包</text> <text class="type">元红包</text>
</text> </text>
<view class="desc">可提现红包</view> <view class="desc">可提现红包</view>
</view> </view>
<view class="tip" @click="closeRewardPopup('2')">立即查看</view> <view class="tip" @click="closeRewardPopup('2')">立即查看</view>
</view> </view>
<block v-if="newgift.award_list.coupon_list.length > 0"> <block v-if="newgift.award_list.coupon_list.length > 0">
<block v-for="(item, index) in newgift.award_list.coupon_list" :key="index"> <block v-for="(item, index) in newgift.award_list.coupon_list" :key="index">
<view class="content"> <view class="content">
<view class="info"> <view class="info">
<text v-if="item.type == 'reward'" class="num"> <text v-if="item.type == 'reward'" class="num">
{{ parseFloat(item.money) }} {{ parseFloat(item.money) }}
<text class="type">元优惠劵</text> <text class="type">元优惠劵</text>
</text> </text>
<text v-else-if="item.type == 'discount'" class="num"> <text v-else-if="item.type == 'discount'" class="num">
{{ item.discount | int }} {{ item.discount | int }}
<text class="type"></text> <text class="type"></text>
</text> </text>
<view class="desc">用于下单时抵现或兑换商品等</view> <view class="desc">用于下单时抵现或兑换商品等</view>
</view> </view>
<view class="tip" @click="closeRewardPopup('3')">立即查看</view> <view class="tip" @click="closeRewardPopup('3')">立即查看</view>
</view> </view>
</block> </block>
</block> </block>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
<view class="close-btn" @click="cancel()"> <view class="close-btn" @click="cancel()">
<text class="iconfont icon-close btn"></text> <text class="iconfont icon-close btn"></text>
</view> </view>
</view> </view>
</uni-popup> </uni-popup>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import uniPopup from '../uni-popup/uni-popup.vue'; import uniPopup from '../uni-popup/uni-popup.vue';
export default { export default {
components: { components: {
uniPopup uniPopup
}, },
data() { data() {
return { return {
newgift: { newgift: {
flag: false, flag: false,
award_list: { award_list: {
point: 0, point: 0,
coupon_list: {} coupon_list: {}
}, },
remark: {} remark: {}
}, },
bgHight: '940rpx !important', bgHight: '940rpx !important',
bytesCount: null, bytesCount: null,
}; callback: null
}, };
filters: { },
int(val) { filters: {
var str = String(val); int(val) {
var arr = str.split('.'); var str = String(val);
if (parseInt(arr[1]) > 0) { var arr = str.split('.');
return str; if (parseInt(arr[1]) > 0) {
} else { return str;
return arr[0]; } else {
} return arr[0];
} }
}, }
computed: { },
introduction() { computed: {
let bytesCount = 0; introduction() {
for (let i = 0, n = this.newgift.remark.length; i < n; i++) { let bytesCount = 0;
let c = this.newgift.remark.charCodeAt(i); for (let i = 0, n = this.newgift.remark.length; i < n; i++) {
if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) { let c = this.newgift.remark.charCodeAt(i);
bytesCount += 1; if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
} else { bytesCount += 1;
bytesCount += 2; } else {
} bytesCount += 2;
} }
return bytesCount; }
} return bytesCount;
}, }
created() { },
if (!this.storeToken) return; created() {
this.init(); if (!this.storeToken) return;
}, this.init();
methods: { },
init() { methods: {
this.getHolidayGift(); init(callback = null) {
}, if (callback) this.callback = callback;
// 查询节日有礼设置 this.getHolidayGift();
getHolidayGift() { },
this.$api.sendRequest({ // 查询节日有礼设置
url: '/scenefestival/api/config/config', getHolidayGift() {
success: res => { this.$api.sendRequest({
if (res.data && res.data[0]) { url: '/scenefestival/api/config/config',
this.newgift = res.data[0]; success: res => {
if (this.newgift.award_list.award_type.length <= 1) { if (res.data && res.data[0]) {
this.bgHight = '800rpx !important'; this.newgift = res.data[0];
} if (this.newgift.award_list.award_type.length <= 1) {
this.getGift(); this.bgHight = '800rpx !important';
} }
} this.getGift();
}); }
}, }
cancel() { });
this.$refs.nsNewGift.close(); },
}, cancel() {
getGift() { this.$refs.nsNewGift.close();
if (this.newgift.flag == true) { },
this.$refs.nsNewGift.open(); getGift() {
this.$api.sendRequest({ if (this.newgift.flag == true) {
url: '/scenefestival/api/config/receive', this.$refs.nsNewGift.open();
data: { this.$api.sendRequest({
festival_id: this.newgift.festival_id url: '/scenefestival/api/config/receive',
}, data: {
success: res => {} festival_id: this.newgift.festival_id
}); },
} success: res => {
}, if (this.callback) this.callback();
closeRewardPopup(type) { }
if (type == 1) { });
this.$util.redirectTo('/pages_tool/member/point_detail', {}); }
} else if (type == 2) { },
this.$util.redirectTo('/pages_tool/member/balance_detail', {}); closeRewardPopup(type) {
} else if (type == 3) { if (type == 1) {
this.$util.redirectTo('/pages_tool/member/coupon', {}); this.$util.redirectTo('/pages_tool/member/point_detail', {});
} } else if (type == 2) {
} this.$util.redirectTo('/pages_tool/member/balance_detail', {});
} } else if (type == 3) {
}; this.$util.redirectTo('/pages_tool/member/coupon', {});
</script> }
}
<style scoped> }
/deep/ .newgift-content uni-image { };
width: 113rpx !important; </script>
height: 24rpx !important;
} <style scoped>
/deep/ .newgift-content uni-image {
/deep/ .reward-popup .uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box { width: 113rpx !important;
max-height: unset !important; height: 24rpx !important;
overflow-y: unset; }
}
/deep/ .reward-popup .uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
.register-box /deep/ .uni-scroll-view { max-height: unset !important;
background: unset !important; overflow-y: unset;
} }
.register-box { .register-box /deep/ .uni-scroll-view {
max-height: 300rpx; background: unset !important;
overflow-y: scroll; }
/* margin-top: 610rpx; */
} .register-box {
</style> max-height: 300rpx;
overflow-y: scroll;
<style lang="scss"> /* margin-top: 610rpx; */
.reward-wrap { }
width: 85vw; </style>
height: auto;
<style lang="scss">
.newgift-content { .reward-wrap {
width: 100%; width: 85vw;
height: auto; height: auto;
background-size: 100%;
background-repeat: no-repeat; .newgift-content {
padding-bottom: 40rpx; width: 100%;
} height: auto;
background-size: 100%;
.content-title-holiday { background-repeat: no-repeat;
font-size: $font-size-toolbar; padding-bottom: 40rpx;
font-weight: bold; }
font-family: BDZongYi-A001;
display: flex; .content-title-holiday {
align-items: center; font-size: $font-size-toolbar;
justify-content: center; font-weight: bold;
// margin-bottom: 20rpx; font-family: BDZongYi-A001;
padding-top: 320rpx; display: flex;
line-height: 1; align-items: center;
justify-content: center;
.birthday-img-all { // margin-bottom: 20rpx;
width: 100rpx; padding-top: 320rpx;
height: 20rpx; line-height: 1;
}
.birthday-img-all {
&>view { width: 100rpx;
margin: 0 20rpx; height: 20rpx;
color: #fff; }
font-weight: bold;
} &>view {
} margin: 0 20rpx;
color: #fff;
.content-title-name { font-weight: bold;
font-size: $font-size-toolbar; }
font-weight: bold; }
overflow: hidden;
text-overflow: ellipsis; .content-title-name {
display: -webkit-box; font-size: $font-size-toolbar;
-webkit-line-clamp: 2; font-weight: bold;
-webkit-box-orient: vertical; overflow: hidden;
text-align: center; text-overflow: ellipsis;
color: #fff; display: -webkit-box;
margin: 30rpx 0 40rpx; -webkit-line-clamp: 2;
line-height: 1; -webkit-box-orient: vertical;
} text-align: center;
color: #fff;
.content-title-hint { margin: 30rpx 0 40rpx;
margin: 0 70rpx 40rpx; line-height: 1;
overflow: hidden; }
text-overflow: ellipsis;
display: -webkit-box; .content-title-hint {
-webkit-line-clamp: 2; margin: 0 70rpx 40rpx;
-webkit-box-orient: vertical; overflow: hidden;
text-align: center; text-overflow: ellipsis;
color: #fff; display: -webkit-box;
} -webkit-line-clamp: 2;
-webkit-box-orient: vertical;
.reward-content { text-align: center;
max-height: 300rpx; color: #fff;
margin: 0 56rpx; }
}
.reward-content {
.reward-content-two { max-height: 300rpx;
max-height: 360rpx; margin: 0 56rpx;
margin: 0 56rpx; }
}
.reward-content-two {
.head { max-height: 360rpx;
color: #fff; margin: 0 56rpx;
text-align: center; }
line-height: 1;
margin: 20rpx 0; .head {
} color: #fff;
text-align: center;
& .content:last-child { line-height: 1;
margin-bottom: 0; margin: 20rpx 0;
} }
.content { & .content:last-child {
display: flex; margin-bottom: 0;
align-items: center; }
padding: 16rpx 26rpx;
background: #fff; .content {
border-radius: 10rpx; display: flex;
margin-bottom: 20rpx; align-items: center;
padding: 16rpx 26rpx;
.info { background: #fff;
flex: 1; border-radius: 10rpx;
} margin-bottom: 20rpx;
.tip { .info {
color: #fa5b14; flex: 1;
padding: 10rpx 0 10rpx 20rpx; }
width: 60rpx;
line-height: 1.5; .tip {
letter-spacing: 2rpx; color: #fa5b14;
border-left: 2rpx dashed #e5e5e5; padding: 10rpx 0 10rpx 20rpx;
} width: 60rpx;
line-height: 1.5;
.num { letter-spacing: 2rpx;
font-size: 48rpx; border-left: 2rpx dashed #e5e5e5;
color: #fa5b14; }
font-weight: bolder;
line-height: 1; .num {
overflow: hidden; font-size: 48rpx;
text-overflow: ellipsis; color: #fa5b14;
white-space: nowrap; font-weight: bolder;
max-width: 300rpx; line-height: 1;
} overflow: hidden;
text-overflow: ellipsis;
.type { white-space: nowrap;
font-size: $font-size-tag; max-width: 300rpx;
margin-left: 10rpx; }
line-height: 1;
font-weight: normal; .type {
color: #606266; font-size: $font-size-tag;
} margin-left: 10rpx;
line-height: 1;
.desc { font-weight: normal;
margin-top: 8rpx; color: #606266;
color: $color-tip; }
font-size: $font-size-tag;
line-height: 1; .desc {
} margin-top: 8rpx;
} color: $color-tip;
font-size: $font-size-tag;
.close-btn { line-height: 1;
text-align: center; }
margin-top: 20rpx; }
z-index: 500;
.close-btn {
.btn { text-align: center;
/* margin: 0 50rpx; margin-top: 20rpx;
background: linear-gradient(90deg,#ff4100,#ff6a00) ; z-index: 500;
border: none; */
color: #fff; .btn {
font-size: 40rpx; color: #fff;
// padding: 100px; font-size: 40rpx;
border: 4rpx solid #fff; border: 4rpx solid #fff;
border-radius: 50%; border-radius: 50%;
padding: 10rpx; padding: 10rpx;
font-weight: bold; font-weight: bold;
width: 40rpx; width: 40rpx;
height: 40rpx; height: 40rpx;
margin: 0 auto; margin: 0 auto;
line-height: 40rpx; line-height: 40rpx;
} }
} }
} }
</style> </style>

View File

@@ -0,0 +1,933 @@
<template>
<view class="form-wrap form-component">
<view v-for="(item, index) in formData" :key="index">
<!-- 文本输入框 -->
<view v-if="item.controller == 'Text'" class="order-wrap">
<view class="order-cell">
<view class="name">
<text class="tit">{{ item.value.title }}</text>
<text class="required">{{ item.value.required ? '*' : '' }}</text>
</view>
<view class="box">
<input
type="text"
:placeholder="item.value.placeholder"
placeholder-class="placeholder color-tip"
v-model="item.val"
/>
</view>
</view>
</view>
<!-- 多行文本输入框 -->
<view v-if="item.controller == 'Textarea'" class="order-wrap">
<view class="order-cell flex-box textarea">
<view class="name">
<text class="tit">{{ item.value.title }}</text>
<text class="required">{{ item.value.required ? '*' : '' }}</text>
</view>
<view class="box">
<textarea
:placeholder="item.value.placeholder"
placeholder-class="placeholder color-tip"
v-model="item.val"
></textarea>
</view>
</view>
</view>
<!-- 下拉选择器 -->
<view v-if="item.controller == 'Select'" class="order-wrap">
<picker
mode="selector"
:range="item.value.options"
@change="pickerChange($event, index)"
>
<view class="order-cell">
<view class="name">
<text class="tit">{{ item.value.title }}</text>
<text class="required">{{ item.value.required ? '*' : '' }}</text>
</view>
<view class="box">
<text v-if="item.val != ''">{{ item.val }}</text>
<text v-else class="color-tip">请选择</text>
</view>
<text class="iconfont icon-right"></text>
</view>
</picker>
</view>
<!-- 复选框 -->
<view v-if="item.controller == 'Checkbox'" class="order-wrap">
<view class="order-cell">
<view class="name">
<text class="tit">{{ item.value.title }}</text>
<text class="required">{{ item.value.required ? '*' : '' }}</text>
</view>
<view class="box check-group-box">
<checkbox-group @change="checkboxChange($event, index)">
<label v-for="(v, k) in item.option_lists" :key="k">
<checkbox :value="v.value" :checked="v.checked"></checkbox>
<view class="checkbox">
<text
:class="[
'iconfont',
!v.checked ? 'icon-fuxuankuang2' : '',
v.checked ? 'icon-fuxuankuang1 color-base-text' : ''
]"
></text>
{{ v.value }}
</view>
</label>
</checkbox-group>
</view>
</view>
</view>
<!-- 单选框 -->
<view v-if="item.controller == 'Radio'" class="order-wrap">
<view class="order-cell">
<view class="name">
<text class="tit">{{ item.value.title }}</text>
<text class="required">{{ item.value.required ? '*' : '' }}</text>
</view>
<view class="box radio-group-box">
<radio-group @change="radioChange($event, index)">
<label v-for="(v, k) in item.option_lists" :key="k">
<radio :value="v.value" :checked="item.val == v.value"></radio>
<view class="radio-box">
<text
:class="[
'iconfont',
item.val != v.value ? 'icon-yuan_checkbox' : '',
item.val == v.value ? 'icon-yuan_checked color-base-text' : ''
]"
></text>
{{ v.value }}
</view>
</label>
</radio-group>
</view>
</view>
</view>
<!-- 图片上传 -->
<view v-if="item.controller == 'Img'" class="order-wrap">
<view class="order-cell flex-box">
<view class="name">
<text class="tit">{{ item.value.title }}</text>
<text class="required">{{ item.value.required ? '*' : '' }}</text>
</view>
<view class="box img-boxs">
<view v-for="(v, k) in item.img_lists" :key="k" class="img-box" @tap="uploadImg(index)">
<image :src="$util.img(v)" mode="aspectFill"></image>
<text class="iconfont icon-guanbi" @tap.stop="delImg(k, index)"></text>
</view>
<view class="img-box" @tap="addImg(index)">
<text class="iconfont icon-add1"></text>
</view>
</view>
</view>
</view>
<!-- 日期选择器 -->
<view v-if="item.controller == 'Date'" class="order-wrap">
<view class="order-cell">
<view class="name">
<text class="tit">{{ item.value.title }}</text>
<text class="required">{{ item.value.required ? '*' : '' }}</text>
</view>
<view class="box box-flex">
<picker
mode="date"
:value="item.val"
@change="bindDateChange($event, index)"
>
<view :class="['uni-input', !item.val ? 'color-tip' : '']">
{{ item.val ? item.val : item.value.placeholder }}
</view>
</picker>
</view>
<text class="iconfont icon-right"></text>
</view>
</view>
<!-- 日期范围选择器 -->
<view v-if="item.controller == 'Datelimit'" class="order-wrap">
<view class="order-cell flex-box">
<view class="name">
<text class="tit">{{ item.value.title }}</text>
<text class="required">{{ item.value.required ? '*' : '' }}</text>
</view>
<view class="box date-boxs">
<view class="date-box">
<picker
mode="date"
:value="item.start_date"
@change="bindStartDateChange($event, index)"
>
<view class="picker-box">
<view :class="['uni-input', !item.start_date ? 'color-tip' : '']">
{{ item.start_date ? item.start_date : item.value.placeholder_start }}
</view>
</view>
</picker>
</view>
<view class="interval iconfont icon-jian"></view>
<view class="date-box">
<picker
mode="date"
:value="item.end_date"
@change="bindEndDateChange($event, index)"
>
<view class="picker-box">
<view :class="['uni-input', !item.end_date ? 'color-tip' : '']">
{{ item.end_date ? item.end_date : item.value.placeholder_end }}
</view>
</view>
</picker>
</view>
</view>
</view>
</view>
<!-- 时间选择器 -->
<view v-if="item.controller == 'Time'" class="order-wrap">
<view class="order-cell">
<view class="name">
<text class="tit">{{ item.value.title }}</text>
<text class="required">{{ item.value.required ? '*' : '' }}</text>
</view>
<view class="box box-flex">
<picker
mode="time"
:value="item.val"
@change="bindTimeChange($event, index)"
>
<view :class="['uni-input', !item.val ? 'color-tip' : '']">
{{ item.val ? item.val : item.value.placeholder }}
</view>
</picker>
</view>
<text class="iconfont icon-right"></text>
</view>
</view>
<!-- 时间范围选择器 -->
<view v-if="item.controller == 'Timelimit'" class="order-wrap">
<view class="order-cell flex-box">
<view class="name">
<text class="tit">{{ item.value.title }}</text>
<text class="required">{{ item.value.required ? '*' : '' }}</text>
</view>
<view class="box date-boxs">
<view class="date-box">
<picker
mode="time"
:value="item.start_time"
@change="bindStartTimeChange($event, index)"
>
<view class="picker-box">
<view :class="['uni-input', !item.start_time ? 'color-tip' : '']">
{{ item.start_time ? item.start_time : item.value.placeholder_start }}
</view>
</view>
</picker>
</view>
<view class="interval iconfont icon-jian"></view>
<view class="date-box">
<picker
mode="time"
:value="item.end_time"
@change="bindEndTimeChange($event, index)"
>
<view class="picker-box">
<view :class="['uni-input', !item.end_time ? 'color-tip' : '']">
{{ item.end_time ? item.end_time : item.value.placeholder_end }}
</view>
</view>
</picker>
</view>
</view>
</view>
</view>
<!-- 城市选择器 -->
<view v-if="item.controller == 'City'" class="order-wrap">
<view class="order-cell box-flex">
<view class="name">
<text class="tit">{{ item.value.title }}</text>
<text class="required">{{ item.value.required ? '*' : '' }}</text>
</view>
<view class="box">
<pick-regions
:defaultRegions="item.default_regions"
:selectArr="item.select_arr"
@getRegions="handleGetRegions($event, index)"
>
<view :class="['select-address', !item.val ? 'empty' : '', !item.val ? 'color-tip' : '']">
{{ item.val ? item.val : (item.select_arr == '2' ? '请选择省市' : '请选择省市区/县') }}
</view>
</pick-regions>
</view>
<text class="iconfont icon-right"></text>
</view>
</view>
</view>
</view>
</template>
<script>
import pickRegions from '@/components/pick-regions/pick-regions.vue'
export default {
name: 'ns-form',
components: {
pickRegions
},
props: {
data: {
type: Array,
default: () => ({})
},
customAttr: {
type: Object,
default: () => ({})
}
},
data() {
return {
formData: this.data
}
},
created() {
this.setFormData();
},
watch: {
data: {
handler() {
this.setFormData();
},
deep: true
}
},
methods: {
setFormData() {
this.formData = this.data;
this.formData.forEach((item) => {
// 初始化默认值
if (!item.val) {
item.val = item.value.default ? item.value.default : '';
}
// 处理选项列表
if (item.value.options) {
item.option_lists = [];
item.value.options.forEach((option, index) => {
let optionItem = {};
optionItem.value = option;
optionItem.checked = false;
if (item.controller == 'Radio') {
if ((!item.val && index == 0) || (item.val && item.val == option)) {
optionItem.checked = true;
item.val = option;
}
}
if (item.controller == 'Checkbox' && item.val) {
let valArray = item.val.split(',');
optionItem.checked = valArray.indexOf(option) != -1;
}
item.option_lists.push(optionItem);
});
}
// 处理图片列表
if (item.controller == 'Img') {
item.img_lists = item.val ? item.val.split(',') : [];
}
// 处理日期
if (item.controller == 'Date' && !item.val) {
if (item.value.is_show_default) {
if (item.value.is_current) {
item.val = this.getDate();
} else {
item.val = item.value.default;
}
} else {
item.val = '';
}
}
// 处理日期范围
if (item.controller == 'Datelimit') {
if (item.val) {
let dateArray = item.val.split(' - ');
item.start_date = dateArray[0];
item.end_date = dateArray[1];
} else {
item.val = '';
// 开始日期
if (item.value.is_show_default_start) {
if (item.value.is_current_start) {
item.start_date = this.getDate();
} else {
item.start_date = item.value.default_start;
}
} else {
item.start_date = '';
}
// 结束日期
if (item.value.is_show_default_end) {
if (item.value.is_current_end) {
item.end_date = this.getDate();
} else {
item.end_date = item.value.default_end;
}
} else {
item.end_date = '';
}
if (item.start_date && item.end_date) {
item.val = item.start_date + ' - ' + item.end_date;
}
}
}
// 处理时间
if (item.controller == 'Time' && !item.val) {
if (item.value.is_show_default) {
if (item.value.is_current) {
item.val = this.getTime();
} else {
item.val = item.value.default;
}
} else {
item.val = '';
}
}
// 处理时间范围
if (item.controller == 'Timelimit') {
if (item.val) {
let timeArray = item.val.split(' - ');
item.start_time = timeArray[0];
item.end_time = timeArray[1];
} else {
item.val = '';
// 开始时间
if (item.value.is_show_default_start) {
if (item.value.is_current_start) {
item.start_time = this.getTime();
} else {
item.start_time = item.value.default_start;
}
} else {
item.start_time = '';
}
// 结束时间
if (item.value.is_show_default_end) {
if (item.value.is_current_end) {
item.end_time = this.getTime();
} else {
item.end_time = item.value.default_end;
}
} else {
item.end_time = '';
}
if (item.start_time && item.end_time) {
item.val = item.start_time + ' - ' + item.end_time;
}
}
}
// 处理城市选择
if (item.controller == 'City') {
item.full_address = '';
item.select_arr = item.value.default_type == 1 ? '2' : '3';
if (item.val) {
item.default_regions = item.val.split('-');
} else {
item.default_regions = [];
}
}
});
},
// 表单验证
verify() {
for (let i = 0; i < this.formData.length; i++) {
let item = this.formData[i];
// 文本验证
if (item.controller == 'Text') {
if (item.value.required && !item.val) {
this.$util.showToast({ title: '请输入' + item.value.title });
return false;
}
if (item.name == 'ID_CARD' && !/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(item.val)) {
if (!item.value.required) {
this.$util.showToast({ title: '身份证输入不合法' });
return false;
}
if (item.val != '') {
this.$util.showToast({ title: '身份证输入不合法' });
return false;
}
}
if (item.name == 'MOBILE' && !this.$util.verifyMobile(item.val)) {
if (!item.value.required) {
this.$util.showToast({ title: '手机号输入不合法' });
return false;
}
if (item.val != '') {
this.$util.showToast({ title: '手机号输入不合法' });
return false;
}
}
}
// 多行文本验证
if (item.controller == 'Textarea' && item.value.required && !item.val) {
this.$util.showToast({ title: '请输入' + item.value.title });
return false;
}
// 下拉选择验证
if (item.controller == 'Select' && item.value.required && !item.val) {
this.$util.showToast({ title: '请选择' + item.value.title });
return false;
}
// 复选框验证
if (item.controller == 'Checkbox' && item.value.required && !item.val) {
this.$util.showToast({ title: '请至少选择一个' + item.value.title });
return false;
}
// 图片上传验证
if (item.controller == 'Img' && item.value.required && !item.val) {
this.$util.showToast({ title: '请至少上传一张' + item.value.title });
return false;
}
// 日期验证
if (item.controller == 'Date' && item.value.required && !item.val) {
this.$util.showToast({ title: '请选择' + item.value.title });
return false;
}
// 日期范围验证
if (item.controller == 'Datelimit') {
if (item.value.required && !item.val) {
this.$util.showToast({ title: '请选择' + item.value.title });
return false;
}
if (this.$util.timeTurnTimeStamp(item.start_date) > this.$util.timeTurnTimeStamp(item.end_date)) {
this.$util.showToast({ title: '结束日期不能小于开始日期' });
return false;
}
}
// 时间验证
if (item.controller == 'Time' && item.value.required && !item.val) {
this.$util.showToast({ title: '请选择' + item.value.title });
return false;
}
// 时间范围验证
if (item.controller == 'Timelimit') {
if (item.value.required && !item.val) {
this.$util.showToast({ title: '请选择' + item.value.title });
return false;
}
if (item.start_time >= item.end_time) {
this.$util.showToast({ title: '结束时间必须大于开始时间' });
return false;
}
}
// 城市选择验证
if (item.controller == 'City' && item.value.required && !item.val) {
this.$util.showToast({ title: '请选择' + item.value.title });
return false;
}
}
return this.formData;
},
// 下拉选择改变
pickerChange(event, index) {
this.formData[index].val = this.data[index].value.options[event.detail.value];
this.$forceUpdate();
},
// 复选框改变
checkboxChange(event, index) {
this.formData[index].val = event.detail.value.toString();
this.formData[index].option_lists.forEach((option) => {
option.checked = event.detail.value.indexOf(option.value) != -1;
});
this.$forceUpdate();
},
// 单选框改变
radioChange(event, index) {
this.formData[index].val = event.detail.value;
this.$forceUpdate();
},
// 上传图片
uploadImg(index) {
let self = this;
this.$util.upload(Number(this.formData[index].value.max_count), { path: 'evaluateimg' }, function(res) {
if (res.length > 0) {
res.forEach(function(img) {
if (self.formData[index].img_lists.length >= Number(self.formData[index].value.max_count)) {
self.$util.showToast({ title: '最多上传' + self.formData[index].value.max_count + '张图片' });
return false;
}
self.formData[index].img_lists.push(img);
});
self.formData[index].val = self.formData[index].img_lists.toString();
self.$forceUpdate();
}
});
},
// 添加图片
addImg(index) {
let self = this;
if (this.formData[index].img_lists.length >= Number(this.formData[index].value.max_count)) {
this.$util.showToast({ title: '最多上传' + this.formData[index].value.max_count + '张图片' });
return false;
}
this.$util.upload(Number(this.formData[index].value.max_count), { path: 'evaluateimg' }, function(res) {
if (res.length > 0) {
res.forEach(function(img) {
self.formData[index].img_lists.push(img);
});
self.formData[index].val = self.formData[index].img_lists.toString();
self.$forceUpdate();
}
});
},
// 删除图片
delImg(imgIndex, formIndex) {
this.formData[formIndex].img_lists.splice(imgIndex, 1);
this.formData[formIndex].val = this.formData[formIndex].img_lists.toString();
this.$forceUpdate();
},
// 获取当前日期
getDate() {
let date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
month = month > 9 ? month : '0' + month;
day = day > 9 ? day : '0' + day;
return `${year}-${month}-${day}`;
},
// 获取当前时间
getTime() {
let date = new Date();
let hours = date.getHours();
let minutes = date.getMinutes();
hours = hours > 9 ? hours : '0' + hours;
minutes = minutes > 9 ? minutes : '0' + minutes;
return `${hours}:${minutes}`;
},
// 日期改变
bindDateChange(event, index) {
this.formData[index].val = event.detail.value;
this.$forceUpdate();
},
// 开始日期改变
bindStartDateChange(event, index) {
this.$set(this.formData[index], 'start_date', event.detail.value);
this.$set(this.formData[index], 'val', this.formData[index].start_date + ' - ' + this.formData[index].end_date);
this.$forceUpdate();
},
// 结束日期改变
bindEndDateChange(event, index) {
this.$set(this.formData[index], 'end_date', event.detail.value);
this.$set(this.formData[index], 'val', this.formData[index].start_date + ' - ' + this.formData[index].end_date);
this.$forceUpdate();
},
// 时间改变
bindTimeChange(event, index) {
this.formData[index].val = event.detail.value;
this.$forceUpdate();
},
// 开始时间改变
bindStartTimeChange(event, index) {
this.formData[index].start_time = event.detail.value;
this.$forceUpdate();
},
// 结束时间改变
bindEndTimeChange(event, index) {
this.formData[index].end_time = event.detail.value;
this.formData[index].val = this.formData[index].start_time + ' - ' + this.formData[index].end_time;
this.$forceUpdate();
},
// 处理地区选择
handleGetRegions(regions, index) {
this.formData[index].val = '';
this.formData[index].val += regions[0] != undefined ? regions[0].label : '';
this.formData[index].val += regions[1] != undefined ? '-' + regions[1].label : '';
this.formData[index].val += regions[2] != undefined ? '-' + regions[2].label : '';
this.$forceUpdate();
}
}
}
</script>
<style lang="scss" scoped>
.order-wrap {
padding: 20rpx 0;
&:last-child {
margin-bottom: 0;
border-bottom: 0;
}
.order-cell {
align-items: center;
background: #fff;
position: relative;
&.textarea {
align-items: unset;
}
&.clear-flex {
display: block;
.box {
margin-top: 16rpx;
text-align: left;
}
}
&:last-child {
margin-bottom: 0;
border-bottom: solid 1px #eee;
}
&.align-top {
align-items: flex-start;
}
text {
font-size: 28rpx;
}
.name {
width: 160rpx;
margin-bottom: 10rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
.tit {
text-align: left;
font-size: 32rpx;
color: #888;
text {
font-size: 28rpx;
}
}
.required {
color: red;
font-size: 28rpx;
margin-left: 4rpx;
width: 14rpx;
text-align: left;
display: inline-block;
}
}
.box {
flex: 1;
padding: 0 0rpx;
line-height: inherit;
text-align: left;
input {
font-size: 28rpx;
text-align: left;
height: 70rpx;
border: solid 2rpx #eee;
line-height: 70rpx;
padding: 0 16rpx;
}
textarea {
font-size: 28rpx;
width: 100%;
height: 88rpx;
line-height: 44rpx;
text-align: left;
}
checkbox-group {
display: flex;
flex-wrap: wrap;
}
radio-group {
display: flex;
flex-wrap: wrap;
}
label {
display: flex;
align-items: center;
line-height: 1;
margin-right: 30rpx;
}
&.img-boxs {
display: flex;
align-items: center;
flex-wrap: wrap;
.img-box {
margin: 10rpx 20rpx 10rpx 0;
display: flex;
justify-content: center;
align-items: center;
width: 100rpx;
height: 100rpx;
border: 1rpx solid #eee;
border-radius: 4rpx;
position: relative;
.icon-guanbi {
position: absolute;
top: -14rpx;
right: -14rpx;
display: inline-block;
width: 28rpx;
height: 28rpx;
line-height: 28rpx;
color: #909399;
}
.icon-add1 {
font-size: 40rpx;
}
image {
width: 100%;
height: 100%;
}
}
}
&.box-flex {
display: flex;
align-items: center;
justify-content: space-between;
}
&.date-boxs {
padding: 0 10rpx;
display: flex;
align-items: center;
.interval {
margin: 0 12rpx;
color: #000;
font-weight: 700;
}
.date-box {
.picker-box {
display: flex;
align-items: center;
justify-content: flex-end;
}
}
}
}
.radio-group-box {
radio {
display: none;
}
.radio-box {
display: flex;
align-items: center;
line-height: 1;
.iconfont {
font-size: 32rpx;
margin-right: 10rpx;
}
}
}
.check-group-box {
checkbox {
display: none;
}
.checkbox {
display: flex;
align-items: center;
line-height: 1;
.iconfont {
font-size: 32rpx;
margin-right: 10rpx;
}
}
}
.iconfont {
color: #909399;
font-size: 28rpx;
}
.box-flex {
picker {
display: block;
width: 100%;
}
}
.icon-right {
line-height: 1;
position: unset;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,369 +1,386 @@
<template> <template>
<view class="ns-time"> <view class="ns-time">
<uni-popup type="bottom" ref="selectTime"> <uni-popup type="bottom" ref="selectTime">
<view class="box"> <view class="box">
<view class="title"> <view class="title">
<block v-if="obj.delivery && obj.delivery.delivery_type == 'local'">选择送达时间</block> <block v-if="obj.delivery && obj.delivery.delivery_type == 'local'">选择送达时间</block>
<block v-if="obj.delivery && obj.delivery.delivery_type == 'store'">选择自提时间</block> <block v-if="obj.delivery && obj.delivery.delivery_type == 'store'">选择自提时间</block>
<text class="iconfont icon-close" @click="close"></text> <text class="iconfont icon-close" @click="close"></text>
</view> </view>
<view class="body"> <view class="body">
<!-- 左侧日期选择 --> <!-- 左侧日期选择 -->
<scroll-view :scroll-y="true" class="left"> <scroll-view :scroll-y="true" class="left">
<view class="item" :class="index == keyJudge ? 'itemDay' : ''" v-for="(item, index) in dayData" :key="index" @click="selectTime('days', index, 'yes')"> <view class="item" :class="index == keyJudge ? 'itemDay' : ''" v-for="(item, index) in dayData" :key="index" @click="selectTime('days', index, 'yes')">
<block v-if="item.title">{{ item.title }}</block> <block v-if="item.title">{{ item.title }}</block>
<block v-else>{{ item.month }}</block> <block v-else>{{ item.month }}</block>
<text class="itemtext">{{ item.Day }}</text> <text class="itemtext">{{ item.Day }}</text>
</view> </view>
</scroll-view> </scroll-view>
<!-- 右侧时间选择 --> <!-- 右侧时间选择 -->
<scroll-view :scroll-y="true" class="right"> <scroll-view :scroll-y="true" class="right">
<view class="item" :class="key == keyJudge && index == keys ? 'itemTime' : ''" v-for="(item, index) in timeData" :key="index" @click="selectTime('time', index, 'yes')"> <view class="item" :class="key == keyJudge && index == keys ? 'itemTime' : ''" v-for="(item, index) in timeData" :key="index" @click="selectTime('time', index, 'yes')">
{{ item }} {{ item }}
<text v-if="key == keyJudge && index == keys" class="iconfont icon-yuan_checked color-base-text"></text> <text v-if="key == keyJudge && index == keys" class="iconfont icon-yuan_checked color-base-text"></text>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
</view> </view>
</uni-popup> </uni-popup>
</view> </view>
</template> </template>
<script> <script>
import uniPopup from '@/components/uni-popup/uni-popup.vue'; import uniPopup from '@/components/uni-popup/uni-popup.vue';
export default { export default {
name: "nsSelectTime", name: "nsSelectTime",
components: { components: {
uniPopup uniPopup
}, },
data() { data() {
return { return {
//选中日期的键值 //选中日期的键值
key: 0, key: 0,
//选中时间的键值 //选中时间的键值
keys: 0, keys: 0,
//渲染用数据 //渲染用数据
obj: {}, obj: {},
//左侧渲染时间 //左侧渲染时间
dayData: [], dayData: [],
// 右侧渲染数据 // 右侧渲染数据
timeData: [], timeData: [],
//判断弹窗打开 //判断弹窗打开
judge: false, judge: false,
//判断左侧列表是否为日期选中列表 //判断左侧列表是否为日期选中列表
keyJudge: 0, keyJudge: 0,
//当前时间时间戳 //当前时间时间戳
dayTime: 0 dayTime: 0
}; };
}, },
methods: { methods: {
refresh(){ refresh(){
this.key = 0; this.key = 0;
this.keys = 0; this.keys = 0;
this.keyJudge = 0; this.keyJudge = 0;
}, },
/** /**
* 弹窗打开 * 弹窗打开
*/ */
open(obj, type) { open(obj, type) {
this.dayData = []; this.dayData = [];
this.timeData = []; this.timeData = [];
this.obj = obj; this.obj = obj;
this.toDay(obj.dataTime.time_type, obj.dataTime.time_week); this.toDay(obj.dataTime.time_type, obj.dataTime.time_week);
if (this.judge) { if (this.judge) {
if (type == 'no') { if (type == 'no') {
this.selectTime('', '', type); this.selectTime('', '', type);
} else { } else {
this.$refs.selectTime.open(); this.$refs.selectTime.open();
} }
} }
}, },
/** /**
* 时间选择 * 时间选择
*/ */
selectTime(type, index, judge) { selectTime(type, index, judge) {
if (type == 'days') { if (type == 'days') {
this.keyJudge = index; this.keyJudge = index;
this.toTime(); this.toTime();
} else if (type == 'time') { } else if (type == 'time') {
this.keys = index; this.keys = index;
this.key = this.keyJudge; this.key = this.keyJudge;
let obj = this.dayData[this.key]; let obj = this.dayData[this.key];
obj.time = this.timeData[this.keys]; obj.time = this.timeData[this.keys];
let time = obj.time.replace('立即配送(','').replace('',''); let time = obj.time.replace('立即配送(','').replace('','');
let dateTime = new Date();
var dateTime = new Date();
var format = time.split('-'); let format = time.split('-');
var startHours = format[0].split(':'); let startHours = format[0].split(':');
var endHours = format[1].split(':'); let endHours = format[1].split(':');
let timeData = obj.month.split('月'); let timeData = obj.month.split('月');
let month = timeData[0]; let month = timeData[0];
let date = timeData[1].split('日')[0]; let date = timeData[1].split('日')[0];
// 开始时间戳 // 开始时间戳
dateTime.setHours(startHours[0],startHours[1],0,0); dateTime.setHours(startHours[0],startHours[1],0,0);
obj.start_time = dateTime.getTime()/1000; obj.start_time = dateTime.getTime()/1000;
obj.start_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[0]; obj.start_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[0];
// 结束时间戳 // 结束时间戳
dateTime.setHours(endHours[0],endHours[1],0,0); dateTime.setHours(endHours[0],endHours[1],0,0);
obj.end_time = dateTime.getTime()/1000; obj.end_time = dateTime.getTime()/1000;
obj.end_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[1]; obj.end_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[1];
this.$emit('selectTime', { data: obj, type: judge }); this.$emit('selectTime', { data: obj, type: judge });
this.$refs.selectTime.close(); this.$refs.selectTime.close();
} }
if (judge == 'no') { if (judge == 'no') {
this.toTime(judge); this.toTime(judge);
let obj = this.dayData[0]; let obj = this.dayData[0];
obj.time = this.timeData[0]; obj.time = this.timeData[0];
this.$emit('selectTime', { data: obj, type: judge }); let dateTime = new Date();
} let format = obj.time.replace('立即配送(','').replace('','').split('-');
this.$forceUpdate(); let startHours = format[0].split(':');
}, let endHours = format[1].split(':');
/**
* 弹窗关闭 let timeData = obj.month.split('月');
*/ let month = timeData[0];
close() { let date = timeData[1].split('日')[0];
this.$refs.selectTime.close();
}, // 开始时间戳
/** dateTime.setHours(startHours[0],startHours[1],0,0);
* 左侧数据处理 obj.start_time = dateTime.getTime()/1000;
*/ obj.start_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[0];
toDay(type, obj) { // 结束时间戳
let today = new Date(); dateTime.setHours(endHours[0],endHours[1],0,0);
if (this.obj.dataTime.advance_day) { obj.end_time = dateTime.getTime()/1000;
today = new Date(today.getTime() + (this.obj.dataTime.advance_day * 86400000)); obj.end_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[1];
} this.$emit('selectTime', { data: obj, type: judge });
let nowYear = today.getFullYear(); //当前年 }
let nowMonth = today.getMonth() + 1; //当前月 this.$forceUpdate();
let nowDate = today.getDate(); //当前日 },
let nowDay = today.getDay(); //当前星期几 /**
let endDay = new Date(nowYear, nowMonth, 0).getDate(); //当月多少天 * 弹窗关闭
let Hours = today.getHours(); */
let Minutes = today.getMinutes(); close() {
this.dayTime = this.obj.dataTime.advance_day ? 0 : Number(Hours) * 3600 + Number(Minutes) * 60; //获取到当前时分秒的时间戳 this.$refs.selectTime.close();
let judge = false; },
let num = 1; //记录循环执行过的次数 /**
let mostDay = this.obj.dataTime.most_day ? this.obj.dataTime.most_day + 1 : 1; // 最多可预约天数 * 左侧数据处理
let startTime = parseInt(today.getTime() / 1000); */
let week = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; toDay(type, obj) {
if (obj.time_week && obj.time_week.length == 7) { let today = new Date();
//判断是否七天全有 if (this.obj.dataTime.advance_day) {
judge = true; today = new Date(today.getTime() + (this.obj.dataTime.advance_day * 86400000));
} }
let nowYear = today.getFullYear(); //当前年
for (let i = 0; i < mostDay; i++) { let nowMonth = today.getMonth() + 1; //当前月
let objects = {}; let nowDate = today.getDate(); //当前日
let dayStr = week[ nowDay ]; let nowDay = today.getDay(); //当前星期几
// 判断最大可预约时间 let endDay = new Date(nowYear, nowMonth, 0).getDate(); //当月多少天
if (this.obj.dataTime.most_day > 0 && ((startTime + num * 86400) > (startTime + this.obj.dataTime.most_day * 86400) ) ) { let Hours = today.getHours();
this.judge = true; let Minutes = today.getMinutes();
break; this.dayTime = this.obj.dataTime.advance_day ? 0 : Number(Hours) * 3600 + Number(Minutes) * 60; //获取到当前时分秒的时间戳
} let judge = false;
//判断当天是否能够配送、自提 let num = 1; //记录循环执行过的次数
if (type == 0 || judge || obj.indexOf(nowDay.toString()) != -1) { let mostDay = this.obj.dataTime.most_day ? this.obj.dataTime.most_day + 1 : 1; // 最多可预约天数
let endTime = this.obj.dataTime.delivery_time[ (this.obj.dataTime.delivery_time.length - 1) ].end_time; let startTime = parseInt(today.getTime() / 1000);
endTime -= this.obj.dataTime.time_interval * 60; let week = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
switch (num) { if (obj.time_week && obj.time_week.length == 7) {
case 1: //判断是否七天全有
if (i == 0) { judge = true;
if (endTime < this.dayTime) { }
i = i - 1;
} else { for (let i = 0; i < mostDay; i++) {
objects = { let objects = {};
title: this.obj.dataTime.advance_day == 0 ? '今天' : '', let dayStr = week[ nowDay ];
type: 'special', // 判断最大可预约时间
month: nowMonth + '月' + nowDate + '日', if (this.obj.dataTime.most_day > 0 && ((startTime + num * 86400) > (startTime + this.obj.dataTime.most_day * 86400) ) ) {
Day: '(' + dayStr + ')' this.judge = true;
}; break;
this.dayData.push(objects); //左侧日期数据处理 }
} //判断当天是否能够配送、自提
} if (type == 0 || judge || obj.indexOf(nowDay.toString()) != -1) {
break;
case 2: let endTime = this.obj.dataTime.delivery_time[ (this.obj.dataTime.delivery_time.length - 1) ].end_time;
if (i == 0 || i == 1) { endTime -= this.obj.dataTime.time_interval * 60;
objects = { switch (num) {
title: this.obj.dataTime.advance_day == 0 ? '明天' : '', case 1:
month: nowMonth + '月' + nowDate + '日', if (i == 0) {
Day: '(' + dayStr + ')' if (endTime < this.dayTime) {
}; i = i - 1;
this.dayData.push(objects); //左侧日期数据处理 } else {
} objects = {
break; title: this.obj.dataTime.advance_day == 0 ? '今天' : '',
default: type: 'special',
objects = { month: nowMonth + '月' + nowDate + '日',
title: '', Day: '(' + dayStr + ')'
month: nowMonth + '月' + nowDate + '日', };
Day: '(' + dayStr + ')' this.dayData.push(objects); //左侧日期数据处理
}; }
this.dayData.push(objects); //左侧日期数据处理 }
} break;
} else { case 2:
i = i - 1; if (i == 0 || i == 1) {
} objects = {
title: this.obj.dataTime.advance_day == 0 ? '明天' : '',
if (nowDate != endDay) { month: nowMonth + '月' + nowDate + '日',
nowDate += 1; Day: '(' + dayStr + ')'
} else { };
if (nowMonth != 12) { this.dayData.push(objects); //左侧日期数据处理
nowMonth += 1; }
} else { break;
nowMonth = 1; default:
} objects = {
nowDate = 1; title: '',
} month: nowMonth + '月' + nowDate + '日',
Day: '(' + dayStr + ')'
if (nowDay != 6) { };
nowDay += 1; this.dayData.push(objects); //左侧日期数据处理
} else { }
nowDay = 0; } else {
} i = i - 1;
num += 1; }
if (this.obj.dataTime.most_day == 0 && i == 0) { if (nowDate != endDay) {
this.judge = true; nowDate += 1;
} } else {
} if (nowMonth != 12) {
nowMonth += 1;
this.toTime(); //处理右侧时间数据 } else {
}, nowMonth = 1;
/** }
* 处理右侧时间数据 nowDate = 1;
*/ }
toTime(judge) {
//并非打开弹窗进入时,所有数据置零 if (nowDay != 6) {
if (judge == 'no') { nowDay += 1;
this.key = 0; } else {
this.keys = 0; nowDay = 0;
this.keyJudge = 0; }
} num += 1;
let timeData = []; if (this.obj.dataTime.most_day == 0 && i == 0) {
this.judge = true;
if (!this.obj.dataTime.delivery_time) { }
this.obj.dataTime.delivery_time = [ {start_time: this.obj.dataTime.start_time, end_time: this.obj.dataTime.end_time} ] }
} this.toTime(); //处理右侧时间数据
},
//判断选中是否为当天 /**
let remainder = 0; * 处理右侧时间数据
//当天配送自提的话向后推迟30分钟 */
let newDayTime = JSON.parse(JSON.stringify(this.dayTime)); toTime(judge) {
// newDayTime = Math.ceil(this.dayTime / 600) * 600 + 1800; //并非打开弹窗进入时,所有数据置零
if (judge == 'no') {
//判断选中是否为当天 this.key = 0;
let timeJudage = false; this.keys = 0;
if (this.dayData[this.keyJudge] && this.dayData[this.keyJudge].type && newDayTime > this.obj.dataTime.start_time) timeJudage = true; this.keyJudge = 0;
}
let timeInterval = this.obj.dataTime.time_interval ? this.obj.dataTime.time_interval * 60 : 1200;
let timeData = [];
this.obj.dataTime.delivery_time.forEach(item => {
item.end_time = item.end_time ? item.end_time : 86400; if (!this.obj.dataTime.delivery_time) {
let num = parseInt((parseInt(item.end_time) - parseInt(item.start_time)) / timeInterval); this.obj.dataTime.delivery_time = [ {start_time: this.obj.dataTime.start_time, end_time: this.obj.dataTime.end_time} ]
let time = timeJudage ? parseInt(newDayTime) : parseInt(item.start_time); }
for (let i = 0; i < num; i++) {
if (parseInt(time) + parseInt(timeInterval) > item.end_time) break; //判断选中是否为当天
if (timeJudage) { let remainder = 0;
if (time >= newDayTime) { //当天配送自提的话向后推迟30分钟
if (this.obj.dataTime.time_interval) { let newDayTime = JSON.parse(JSON.stringify(this.dayTime));
if (time <= item.end_time) { // newDayTime = Math.ceil(this.dayTime / 600) * 600 + 1800;
let text = '';
if (this.obj.delivery.delivery_type == 'local' && i == 0) { //判断选中是否为当天
text = '立即配送('+ this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval) + ''; let timeJudage = false;
} else { if (this.dayData[this.keyJudge] && this.dayData[this.keyJudge].type && newDayTime > this.obj.dataTime.start_time) timeJudage = true;
text = this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval);
} let timeInterval = this.obj.dataTime.time_interval ? this.obj.dataTime.time_interval * 60 : 1200;
timeData.push(text);
} this.obj.dataTime.delivery_time.forEach(item => {
} else { item.end_time = item.end_time ? item.end_time : 86400;
timeData.push(this.$util.getTimeStr(time)); let num = parseInt((parseInt(item.end_time) - parseInt(item.start_time)) / timeInterval);
} let time = timeJudage ? parseInt(newDayTime) : parseInt(item.start_time);
} for (let i = 0; i < num; i++) {
} else { if (parseInt(time) + parseInt(timeInterval) > item.end_time) break;
if (this.obj.dataTime.time_interval) { if (timeJudage) {
if (time <= item.end_time) timeData.push(this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval)); if (time >= newDayTime) {
} else { if (this.obj.dataTime.time_interval) {
timeData.push(this.$util.getTimeStr(time)); if (time <= item.end_time) {
} let text = '';
} if (this.obj.delivery.delivery_type == 'local' && i == 0) {
time = parseInt(time) + timeInterval; text = '立即配送('+ this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval) + '';
} } else {
}) text = this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval);
this.timeData = timeData; }
this.$forceUpdate(); timeData.push(text);
} }
} } else {
}; timeData.push(this.$util.getTimeStr(time));
</script> }
}
<style lang="scss" scoped> } else {
.box { if (this.obj.dataTime.time_interval) {
height: 728rpx; if (time <= item.end_time) timeData.push(this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval));
.title { } else {
padding: 0 30rpx; timeData.push(this.$util.getTimeStr(time));
box-sizing: border-box; }
text-align: center; }
font-size: 28rpx; time = parseInt(time) + timeInterval;
font-weight: bold; }
position: relative; })
height: 90rpx; this.timeData = timeData;
line-height: 90rpx; this.$forceUpdate();
border-bottom: 1rpx solid #f7f4f4; }
.icon-close { }
font-size: 26rpx; };
color: #909399; </script>
position: absolute;
right: 30rpx; <style lang="scss" scoped>
top: 50%; .box {
transform: translateY(-50%); height: 728rpx;
} .title {
} padding: 0 30rpx;
.body { box-sizing: border-box;
width: 100%; text-align: center;
height: calc(100% - 90rpx); font-size: 28rpx;
display: flex; font-weight: bold;
align-items: center; position: relative;
.left { height: 90rpx;
width: 230rpx; line-height: 90rpx;
background: #f8f8f8; border-bottom: 1rpx solid #f7f4f4;
height: 100%; .icon-close {
.item { font-size: 26rpx;
width: 100%; color: #909399;
padding: 16rpx 30rpx; position: absolute;
box-sizing: border-box; right: 30rpx;
text-align: center; top: 50%;
font-size: 24rpx; transform: translateY(-50%);
display: flex; }
align-items: center; }
} .body {
.itemDay { width: 100%;
background: #ffffff; height: calc(100% - 90rpx);
} display: flex;
} align-items: center;
.right { .left {
width: calc(100% - 230rpx); width: 230rpx;
height: 100%; background: #f8f8f8;
padding: 0 30rpx; height: 100%;
box-sizing: border-box; .item {
.item { width: 100%;
width: 100%; padding: 16rpx 30rpx;
font-size: 24rpx; box-sizing: border-box;
border-bottom: 1rpx solid #eeeeee; text-align: center;
display: flex; font-size: 24rpx;
align-items: center; display: flex;
justify-content: space-between; align-items: center;
height: 72rpx; }
.icon-yuan_checked { .itemDay {
font-size: 38rpx; background: #ffffff;
margin-right: 30rpx; }
} }
} .right {
.itemTime { width: calc(100% - 230rpx);
color: var(--main-color); height: 100%;
} padding: 0 30rpx;
} box-sizing: border-box;
} .item {
} width: 100%;
</style> font-size: 24rpx;
border-bottom: 1rpx solid #eeeeee;
display: flex;
align-items: center;
justify-content: space-between;
height: 72rpx;
.icon-yuan_checked {
font-size: 38rpx;
margin-right: 30rpx;
}
}
.itemTime {
color: var(--main-color);
}
}
}
}
</style>

View File

@@ -15,18 +15,20 @@
<view class="payment-item" v-if="balanceDeduct > 0 && balanceUsable && balanceConfig == 1"> <view class="payment-item" v-if="balanceDeduct > 0 && balanceUsable && balanceConfig == 1">
<view class="iconfont icon-yue"></view> <view class="iconfont icon-yue"></view>
<view class="info-wrap"> <view class="info-wrap">
<text class="name">余额支付</text> <text class="name">余额抵扣</text>
<view class="money">可用¥{{ balanceDeduct|moneyFormat }}</view> <view class="money">可用¥{{ balanceDeduct|moneyFormat }}</view>
</view> </view>
<ns-switch class="balance-switch" @change="useBalance" :checked="isBalance == 1"></ns-switch> <ns-switch class="balance-switch" @change="useBalance" :checked="isBalance == 1"></ns-switch>
</view> </view>
<block v-if="payMoney > 0"> <block v-if="payMoney > 0">
<block v-if="payTypeList.length"> <block v-if="payTypeList.length">
<view class="payment-item" v-for="(item, index) in payTypeList" :key="index" @click="payIndex = index"> <block v-for="(item, index) in payTypeList">
<view class="iconfont" :class="item.icon"></view> <view v-if="offlineShow||item.type!='offlinepay'" class="payment-item" :key="index" @click="payIndex = index">
<text class="name">{{ item.name }}</text> <view class="iconfont" :class="item.icon"></view>
<text class="iconfont" :class="payIndex == index ? 'icon-yuan_checked color-base-text' : 'icon-checkboxblank'"></text> <text class="name">{{ item.name }}</text>
</view> <text class="iconfont" :class="payIndex == index ? 'icon-yuan_checked color-base-text' : 'icon-checkboxblank'"></text>
</view>
</block>
</block> </block>
<block v-else> <block v-else>
<view class="empty">平台尚未配置支付方式</view> <view class="empty">平台尚未配置支付方式</view>
@@ -63,47 +65,44 @@
balanceUsable: { balanceUsable: {
type: Boolean, type: Boolean,
default: true default: true
} },
}, },
data() { data() {
return { return {
payIndex: 0, payIndex: 0,
// #ifdef H5 payTypeList: [
payTypeList: [{ // #ifdef H5 || MP-ALIPAY
{
name: '支付宝支付', name: '支付宝支付',
icon: 'icon-zhifubaozhifu-', icon: 'icon-zhifubaozhifu-',
type: 'alipay' type: 'alipay'
}, },
// #endif
// #ifdef H5 || MP-WEIXIN
{ {
name: '微信支付', name: '微信支付',
icon: 'icon-weixin1', icon: 'icon-weixin1',
type: 'wechatpay' type: 'wechatpay'
} },
// #endif
{
name: '线下支付',
icon: 'icondiy icon-yuezhifu',
type: 'offlinepay'
},
], ],
// #ifdef H5
timer: null, timer: null,
// #endif // #endif
// #ifdef MP-WEIXIN
payTypeList: [{
name: '微信支付',
provider: 'wxpay',
icon: 'icon-weixin1',
type: 'wechatpay'
}],
// #endif
// #ifdef MP-ALIPAY
payTypeList: [{
name: '支付宝支付',
icon: 'icon-zhifubaozhifu-',
type: 'alipay',
provider: 'alipay'
}],
// #endif
payInfo: null, payInfo: null,
balanceConfig: 0, balanceConfig: 0,
// 预售页面判断 // 预售页面判断
sale: true, sale: true,
isBalance: 0, isBalance: 0,
balance: 0 balance: 0,
//重置是否已完成没有完成不能调用api/pay/pay
resetPayComplete:true,
repeatFlag:false,
}; };
}, },
created(e) { created(e) {
@@ -127,9 +126,32 @@
} }
} }
return money; return money;
} },
offlineShow(){
// 获取当前页面栈实例数组
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
// 获取页面路由路径
let routePath = currentPage.route;
return this.$store.state.offlineWhiteList.length?this.$store.state.offlineWhiteList.includes(routePath):false
}
}, },
methods: { methods: {
/**
* 父级页面onShow调用
*/
pageShow() {
if(this.payInfo){
let offlinepay = uni.getStorageSync('offlinepay');
if(offlinepay){
uni.removeStorageSync('offlinepay');
this.close()
}
}else{
uni.removeStorageSync('offlinepay');
}
},
close() { close() {
this.$emit('close'); this.$emit('close');
this.$refs.choosePaymentPopup.close(); this.$refs.choosePaymentPopup.close();
@@ -146,14 +168,22 @@
}); });
return; return;
} }
if(this.resetPayComplete == false){
this.$util.showToast({
title: '支付取消中,请稍后再试!'
});
return;
}
uni.showLoading({ uni.showLoading({
title: '支付中...', title: '支付中...',
mask: true mask: true
}); });
if(this.repeatFlag) return;
this.repeatFlag = true;
this.pay(); this.pay();
uni.setStorageSync('pay_flag', 1); uni.setStorageSync('pay_flag', 1);
}, },
getPayInfo(out_trade_no) { getPayInfo(out_trade_no, callback) {
this.$api.sendRequest({ this.$api.sendRequest({
url: '/api/pay/info', url: '/api/pay/info',
data: { data: {
@@ -165,6 +195,7 @@
if (this.balanceConfig && this.balanceUsable) this.getMemberBalance(); if (this.balanceConfig && this.balanceUsable) this.getMemberBalance();
setTimeout(() => { setTimeout(() => {
this.$refs.choosePaymentPopup.open(); this.$refs.choosePaymentPopup.open();
if(typeof callback == 'function') callback();
}) })
} else { } else {
this.$util.showToast({ this.$util.showToast({
@@ -178,7 +209,6 @@
* 获取余额配置 * 获取余额配置
*/ */
getBalanceConfig() { getBalanceConfig() {
this.$api.sendRequest({ this.$api.sendRequest({
url: '/api/pay/getBalanceConfig', url: '/api/pay/getBalanceConfig',
data: {}, data: {},
@@ -196,10 +226,6 @@
success: res => { success: res => {
if (res.code == 0 && res.data) { if (res.code == 0 && res.data) {
this.balance = parseFloat(res.data.usable_balance); this.balance = parseFloat(res.data.usable_balance);
//余额不足以抵扣整个订单时不显示
if(parseFloat(this.payMoney) > this.balance){
this.balanceConfig = 0
}
} }
} }
}) })
@@ -215,10 +241,8 @@
if (res.data.pay_type == '') { if (res.data.pay_type == '') {
this.payTypeList = []; this.payTypeList = [];
} else { } else {
this.payTypeList.forEach((val, key) => { this.payTypeList = this.payTypeList.filter((val, key) => {
if (res.data.pay_type.indexOf(val.type) == -1) { return res.data.pay_type.indexOf(val.type) != -1
this.payTypeList.splice(key, 1);
}
}); });
} }
} }
@@ -239,8 +263,7 @@
data: { data: {
out_trade_no: this.payInfo.out_trade_no, out_trade_no: this.payInfo.out_trade_no,
pay_type: payType ? payType.type : '', pay_type: payType ? payType.type : '',
return_url: encodeURIComponent(this.$config.h5Domain + return_url + this.payInfo return_url: encodeURIComponent(this.$config.h5Domain + return_url + this.payInfo.out_trade_no),
.out_trade_no),
is_balance: this.isBalance is_balance: this.isBalance
}, },
success: res => { success: res => {
@@ -258,7 +281,9 @@
wx_alipay: wx_alipay, wx_alipay: wx_alipay,
out_trade_no: this.payInfo.out_trade_no out_trade_no: this.payInfo.out_trade_no
}, '', 'redirectTo'); }, '', 'redirectTo');
this.repeatFlag = false;
} else { } else {
this.repeatFlag = false;
location.href = res.data.data; location.href = res.data.data;
this.checkPayStatus(); this.checkPayStatus();
} }
@@ -290,12 +315,14 @@
res => { res => {
if (res.errMsg == 'chooseWXPay:ok') { if (res.errMsg == 'chooseWXPay:ok') {
this.paySuccess(); this.paySuccess();
this.repeatFlag = false;
} else { } else {
this.$util.showToast({ this.$util.showToast({
title: res.errMsg title: res.errMsg
}); });
setTimeout(() => { setTimeout(() => {
this.close(); this.close();
this.repeatFlag = false;
}, 1500) }, 1500)
} }
}, },
@@ -304,20 +331,30 @@
title: '您已取消支付' title: '您已取消支付'
}); });
this.resetpay(); this.resetpay();
this.repeatFlag = false;
} }
); );
} }
}); });
} else { } else {
this.repeatFlag = false;
location.href = res.data.url; location.href = res.data.url;
this.checkPayStatus(); this.checkPayStatus();
} }
break; break;
case 'offlinepay':
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
outTradeNo: this.payInfo.out_trade_no
});
this.repeatFlag = false;
break;
} }
} else { } else {
this.$util.showToast({ this.$util.showToast({
title: res.message title: res.message
}); });
this.repeatFlag = false;
} }
}, },
fail: res => { fail: res => {
@@ -325,6 +362,7 @@
this.$util.showToast({ this.$util.showToast({
title: 'request:fail' title: 'request:fail'
}); });
this.repeatFlag = false;
} }
}); });
}, },
@@ -365,72 +403,87 @@
if (res.code >= 0) { if (res.code >= 0) {
if (res.data.pay_success) { if (res.data.pay_success) {
this.paySuccess(); this.paySuccess();
this.repeatFlag = false;
return; return;
} }
var payData = res.data.data; if (payType.type=='offlinepay') {
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
// #ifdef MP-WEIXIN outTradeNo: this.payInfo.out_trade_no
var scene = uni.getStorageSync('is_test') ? 1175 : wx.getLaunchOptionsSync().scene; });
if ([1175, 1176, 1177, 1191, 1195].indexOf(scene) != -1) { this.repeatFlag = false;
uni.requestOrderPayment({ }else{
timeStamp: payData.timeStamp, var payData = res.data.data;
nonceStr: payData.nonceStr,
package: payData.package, // #ifdef MP-WEIXIN
signType: payData.signType, var scene = uni.getStorageSync('is_test') ? 1175 : wx.getLaunchOptionsSync().scene;
paySign: payData.paySign, if ([1175, 1176, 1177, 1191, 1195].indexOf(scene) != -1) {
success: res => { uni.requestOrderPayment({
this.paySuccess(); timeStamp: payData.timeStamp,
}, nonceStr: payData.nonceStr,
fail: res => { package: payData.package,
this.flag = false; signType: payData.signType,
if (res.errMsg == 'requestOrderPayment:fail cancel') { paySign: payData.paySign,
this.$util.showToast({ success: res => {
title: '您已取消支付' this.paySuccess();
}); this.repeatFlag = false;
this.resetpay(); },
} else { fail: res => {
uni.showModal({ this.flag = false;
content: '支付失败,失败原因: ' + res.errMsg, if (res.errMsg == 'requestOrderPayment:fail cancel') {
showCancel: false this.$util.showToast({
}); title: '您已取消支付'
setTimeout(() => { });
this.close(); this.resetpay();
}, 1500) this.repeatFlag = false;
} } else {
} uni.showModal({
}); content: '支付失败,失败原因: ' + res.errMsg,
return showCancel: false
} });
// #endif setTimeout(() => {
this.close();
uni.requestPayment({ this.repeatFlag = false;
provider: payType.provider, }, 1500)
...payData, }
success: res => { }
this.paySuccess(); });
}, return
fail: res => { }
this.flag = false; // #endif
if (res.errMsg == 'requestPayment:fail cancel') {
this.$util.showToast({ uni.requestPayment({
title: '您已取消支付' provider: payType.provider,
}); ...payData,
this.resetpay(); success: res => {
} else { this.paySuccess();
uni.showModal({ this.repeatFlag = false;
content: '支付失败,失败原因: ' + res.errMsg, },
showCancel: false fail: res => {
}); this.flag = false;
setTimeout(() => { if (res.errMsg == 'requestPayment:fail cancel') {
this.close(); this.$util.showToast({
}, 1500) title: '您已取消支付'
} });
} this.resetpay();
}); this.repeatFlag = false;
} else { } else {
uni.showModal({
content: '支付失败,失败原因: ' + res.errMsg,
showCancel: false
});
setTimeout(() => {
this.close();
this.repeatFlag = false;
}, 1500)
}
}
});
}
} else {
this.$util.showToast({ this.$util.showToast({
title: res.message title: res.message
}); });
this.repeatFlag = false;
} }
}, },
fail: res => { fail: res => {
@@ -438,6 +491,7 @@
this.$util.showToast({ this.$util.showToast({
title: 'request:fail' title: 'request:fail'
}); });
this.repeatFlag = false;
} }
}); });
}, },
@@ -463,14 +517,24 @@
* 重置支付单据 * 重置支付单据
*/ */
resetpay() { resetpay() {
this.resetPayComplete = false;
this.$api.sendRequest({ this.$api.sendRequest({
url: '/api/pay/resetpay', url: '/api/pay/resetpay',
data: { data: {
out_trade_no: this.payInfo.out_trade_no, out_trade_no: this.payInfo.out_trade_no,
}, },
success: res => { success: res => {
if (res.code == 0) this.getPayInfo(res.data); if (res.code == 0) {
} this.getPayInfo(res.data, ()=>{
this.resetPayComplete = true;
});
}else{
this.resetPayComplete = true;
}
},
fail:res =>{
this.resetPayComplete = true;
}
}) })
} }
}, },
@@ -569,7 +633,9 @@
.icon-weixin1 { .icon-weixin1 {
color: #24af41; color: #24af41;
} }
.icon-yuezhifu{
color: #f9a647;
}
.icon-zhifubaozhifu- { .icon-zhifubaozhifu- {
color: #00a0e9; color: #00a0e9;
} }

View File

@@ -1,269 +1,259 @@
<template> <template>
<view v-if="isShow"> <view v-if="isShow">
<view ref="ani" :animation="animationData" class="message" :style="{ top: top + 'px', left: left + 'px' }" v-if="show"> <view ref="ani" :animation="animationData" class="message" :style="{ top: top + 'px', left: left + 'px' }" v-if="show">
<view class="round bg-gradual-orange flex justify-start shadow" style="padding: 3px;"> <view class="round bg-gradual-orange flex justify-start shadow" style="padding: 3px;">
<view class="cu-avatar cu-a-sm round" :style="{ backgroundImage: 'url(' + $util.img(penpaiData.img) + ')' }"> <view class="cu-avatar cu-a-sm round" :style="{ backgroundImage: 'url(' + $util.img(penpaiData.img) + ')' }">
<!-- #ifdef APP-NVUE --> <!-- #ifdef APP-NVUE -->
<!-- <image :src="penpaiData.img" class="avatarimg"></image> --> <!-- <image :src="penpaiData.img" class="avatarimg"></image> -->
<!-- #endif --> <!-- #endif -->
</view> </view>
<view class="padding-lr-sm flex align-center"> <view class="padding-lr-sm flex align-center">
<text class="text-sm">{{ penpaiData.title }}</text> <text class="text-sm">{{ penpaiData.title }}</text>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
// #ifdef APP-NVUE // #ifdef APP-NVUE
const animation = uni.requireNativePlugin('animation'); const animation = uni.requireNativePlugin('animation');
// #endif // #endif
export default { export default {
name: 'pengpai-fadein-out', name: 'pengpai-fadein-out',
props: { props: {
//持续时间 //持续时间
duration: { duration: {
type: Number, type: Number,
default: 3000 default: 3000
}, },
//停留时间 //停留时间
wait: { wait: {
type: Number, type: Number,
default: 3500 default: 3500
}, },
//顶部距离px //顶部距离px
top: { top: {
type: Number, type: Number,
default: 350 default: 350
}, },
//左边距离px //左边距离px
left: { left: {
type: Number, type: Number,
default: 10 default: 10
}, },
//动画半径 //动画半径
radius: { radius: {
type: Number, type: Number,
default: 30 default: 30
}, },
//数据 //数据
info: { info: {
type: [Array, Object], type: [Array, Object],
default: () => { default: () => {
return []; return [];
} }
} }
}, },
data() { data() {
return { return {
animationData: {}, animationData: {},
animationNumber: {}, animationNumber: {},
show: true, show: true,
index: 0, index: 0,
penpaiData: {}, penpaiData: {},
timeIndex: 0 timeIndex: 0
}; };
}, },
computed:{ computed:{
isShow(){ isShow(){
return this.penpaiData && Object.keys(this.penpaiData).length; return this.penpaiData && Object.keys(this.penpaiData).length;
} }
}, },
mounted() { mounted() {
this.initData(); this.initData();
}, },
methods: { methods: {
initData() { initData() {
// 初始化执行第一次 // 初始化执行第一次
this.penpaiData = this.info[this.index]; this.penpaiData = this.info[this.index];
this.donghua(); this.donghua();
// 开启时间函数,轮询推值 // 开启时间函数,轮询推值
clearInterval(this.timeIndex); clearInterval(this.timeIndex);
this.timeIndex = setInterval(() => { this.timeIndex = setInterval(() => {
if (this.index == this.info.length - 1) { if (this.index == this.info.length - 1) {
this.index = 0; this.index = 0;
} else { } else {
this.index++; this.index++;
} }
this.penpaiData = this.info[this.index]; this.penpaiData = this.info[this.index];
// 执行动画 // 执行动画
this.donghua(); this.donghua();
}, this.duration + this.wait); }, this.duration + this.wait);
}, },
donghua() { donghua() {
//进入 //进入
// #ifndef APP-NVUE // #ifndef APP-NVUE
this.animationData = uni this.animationData = uni
.createAnimation({ .createAnimation({
duration: this.duration / 2, duration: this.duration / 2,
timingFunction: 'ease' timingFunction: 'ease'
}) })
.top(this.top - this.radius) .top(this.top - this.radius)
.opacity(0.9) .opacity(0.9)
.step() .step()
.export(); .export();
// #endif // #endif
// #ifdef APP-NVUE // #ifdef APP-NVUE
if (!this.$refs['ani']) return; if (!this.$refs['ani']) return;
animation.transition(this.$refs['ani'].ref, { animation.transition(this.$refs['ani'].ref, {
styles: { styles: {
transform: `translateY(-${this.radius / 2}px)`, transform: `translateY(-${this.radius / 2}px)`,
opacity: 1 opacity: 1
}, },
duration: this.duration / 2, duration: this.duration / 2,
timingFunction: 'linear', timingFunction: 'linear',
needLayout: false, needLayout: false,
delay: 0 delay: 0
}); });
// #endif // #endif
//停留 //停留
setTimeout(() => { setTimeout(() => {
//消失 //消失
// #ifndef APP-NVUE // #ifndef APP-NVUE
this.animationData = uni this.animationData = uni.createAnimation({
.createAnimation({ duration: this.duration / 2,
duration: this.duration / 2, timingFunction: 'ease'
timingFunction: 'ease' }).top(this.top - this.radius * 2).opacity(0).step().export();
})
.top(this.top - this.radius * 2) // #endif
.opacity(0)
.step() // #ifdef APP-NVUE
.export(); if (!this.$refs['ani']) return;
animation.transition(this.$refs['ani'].ref, {
// #endif styles: {
transform: `translateY(-${this.radius}px)`,
// #ifdef APP-NVUE opacity: 0
if (!this.$refs['ani']) return; },
animation.transition(this.$refs['ani'].ref, { duration: this.duration / 2,
styles: { timingFunction: 'linear',
transform: `translateY(-${this.radius}px)`, needLayout: false,
opacity: 0 delay: 0
}, });
duration: this.duration / 2, // #endif
timingFunction: 'linear', }, this.wait);
needLayout: false,
delay: 0 // console.log('this.top', this.top);
}); // console.log('this.radius', this.radius);
// #endif
}, this.wait); setTimeout(() => {
this.animationData = uni.createAnimation({
// console.log('this.top', this.top); duration: this.duration / 2,
// console.log('this.radius', this.radius); timingFunction: 'ease'
}).top(this.top).opacity(0).step().export();
setTimeout(() => { }, 2800);
this.animationData = uni },
.createAnimation({ closeTimer() {
duration: this.duration / 2, clearInterval(this.timeIndex); //关闭弹幕定时器
timingFunction: 'ease' }
}) }
.top(this.top) };
.opacity(0) </script>
.step()
.export(); <style scoped lang="scss">
}, 2800); .message {
}, position: absolute;
closeTimer() { z-index: 8;
clearInterval(this.timeIndex); //关闭弹幕定时器 opacity: 0;
} }
}
}; .round {
</script> border-radius: 50px;
}
<style scoped lang="scss">
.message { .bg-gradual-orange {
position: absolute; background-color: rgba($color: #000, $alpha: 0.4);
z-index: 8; color: #fff;
opacity: 0; }
}
.shadow {
.round { box-shadow: 40rpx 40rpx 50rpx rgba(217, 109, 26, 0.2);
border-radius: 50px; }
}
.flex {
.bg-gradual-orange { /* #ifndef APP-NVUE */
background-color: rgba($color: #000, $alpha: 0.4); display: flex;
color: #fff; /* #endif */
} flex-direction: row;
}
.shadow {
box-shadow: 40rpx 40rpx 50rpx rgba(217, 109, 26, 0.2); .justify-start {
} justify-content: flex-start;
}
.flex {
/* #ifndef APP-NVUE */ .cu-avatar {
display: flex; /* #ifndef APP-NVUE */
/* #endif */ font-variant: small-caps;
flex-direction: row; display: inline-flex;
} white-space: nowrap;
background-size: cover;
.justify-start { background-position: center;
justify-content: flex-start; vertical-align: middle;
} /* #endif */
margin: 0;
.cu-avatar { padding: 0;
/* #ifndef APP-NVUE */ text-align: center;
font-variant: small-caps; justify-content: center;
display: inline-flex; align-items: center;
white-space: nowrap; background-color: #ccc;
background-size: cover; color: #ffffff;
background-position: center; position: relative;
vertical-align: middle; width: 300rpx;
/* #endif */ height: 300rpx;
margin: 0; font-size: 300rpx;
padding: 0; }
text-align: center;
justify-content: center; /* #ifdef APP-NVUE */
align-items: center; .avatarimg {
background-color: #ccc; width: 30rpx;
color: #ffffff; height: 30rpx;
position: relative; border-radius: 50rpx;
width: 300rpx; }
height: 300rpx;
font-size: 300rpx; /* #endif */
} .cu-a-sm {
width: 60rpx;
/* #ifdef APP-NVUE */ height: 60rpx;
.avatarimg { font-size: 20rpx;
width: 30rpx; }
height: 30rpx;
border-radius: 50rpx; .padding-lr-sm {
} padding-left: 20upx;
padding-right: 20upx;
/* #endif */ }
.cu-a-sm {
width: 60rpx; .align-center {
height: 60rpx; align-items: center;
font-size: 20rpx; }
}
.margin-left-xs {
.padding-lr-sm { margin-left: 10upx;
padding-left: 20upx; }
padding-right: 20upx;
} .text-bold {
font-weight: bold;
.align-center { }
align-items: center;
} .margin-lr-sm {
margin-left: 20upx;
.margin-left-xs { margin-right: 20upx;
margin-left: 10upx; }
}
.text-sm {
.text-bold { font-size: $font-size-tag;
font-weight: bold; color: #ffffff;
} }
</style>
.margin-lr-sm {
margin-left: 20upx;
margin-right: 20upx;
}
.text-sm {
font-size: $font-size-tag;
color: #ffffff;
}
</style>

View File

@@ -1,297 +1,329 @@
<template> <template>
<view> <view>
<view @touchmove.prevent.stop class="reward-popup" v-if="reward"> <view @touchmove.prevent.stop class="reward-popup" v-if="reward">
<uni-popup ref="registerReward" type="center" :maskClick="false"> <uni-popup ref="registerRewardpopup" type="center" :maskClick="false">
<view class="reward-wrap"> <view class="reward-wrap">
<image :src="$util.img('public/uniapp/register_reward/register_reward_img.png')" mode="widthFix" class="bg-img-head"/> <image :src="$util.img('public/uniapp/register_reward/register_reward_img.png')" mode="widthFix" class="bg-img-head"/>
<image :src="$util.img('public/uniapp/register_reward/register_reward_money.png')" mode="widthFix" class="bg-img-money"/> <image :src="$util.img('public/uniapp/register_reward/register_reward_money.png')" mode="widthFix" class="bg-img-money"/>
<image :src="$util.img('public/uniapp/register_reward/register_reward_head.png')" mode="widthFix" class="bg-img"/> <image :src="$util.img('public/uniapp/register_reward/register_reward_head.png')" mode="widthFix" class="bg-img"/>
<view class="wrap"> <view class="wrap">
<view> <view>
<scroll-view scroll-y="true" class="register-box"> <scroll-view scroll-y="true" class="register-box">
<view class="reward-content"> <view class="reward-content">
<view class="reward-item" v-if="reward.point > 0"> <view class="reward-item" v-if="reward.point > 0">
<view class="head">积分奖励</view> <view class="head">积分奖励</view>
<view class="content"> <view class="content">
<view class="info"> <view class="info">
<view> <view>
<text class="num">{{ reward.point }}</text> <text class="num">{{ reward.point }}</text>
<text class="type">积分</text> <text class="type">积分</text>
</view> </view>
<view class="desc">用于下单时抵现或兑换商品等</view> <view class="desc">用于下单时抵现或兑换商品等</view>
</view> </view>
<view class="tip" @click="closeRewardPopup('point')">立即查看</view> <view class="tip" @click="closeRewardPopup('point')">立即查看</view>
</view> </view>
</view> </view>
<view class="reward-item" v-if="reward.growth > 0"> <view class="reward-item" v-if="reward.growth > 0">
<view class="head">成长值</view> <view class="head">成长值</view>
<view class="content"> <view class="content">
<view class="info"> <view class="info">
<view> <view>
<text class="num">{{ reward.growth }}</text> <text class="num">{{ reward.growth }}</text>
<text class="type">成长值</text> <text class="type">成长值</text>
</view> </view>
<view class="desc">用于提升会员等级</view> <view class="desc">用于提升会员等级</view>
</view> </view>
<view class="tip" @click="closeRewardPopup('growth')">立即查看</view> <view class="tip" @click="closeRewardPopup('growth')">立即查看</view>
</view> </view>
</view> </view>
<view class="reward-item" v-if="reward.balance > 0"> <view class="reward-item" v-if="reward.balance > 0">
<view class="head">红包奖励</view> <view class="head">红包奖励</view>
<view class="content"> <view class="content">
<view class="info"> <view class="info">
<view> <view>
<text class="num">{{ reward.balance }}</text> <text class="num">{{ reward.balance }}</text>
<text class="type"></text> <text class="type"></text>
</view> </view>
<view class="desc">不可提现下单时可用</view> <view class="desc">不可提现下单时可用</view>
</view> </view>
<view class="tip" @click="closeRewardPopup('balance')">立即查看</view> <view class="tip" @click="closeRewardPopup('balance')">立即查看</view>
</view> </view>
</view> </view>
<view class="reward-item" v-if="reward.coupon_list.length > 0"> <view class="reward-item" v-if="reward.coupon_list.length > 0">
<view class="head">优惠券奖励</view> <view class="head">优惠券奖励</view>
<view class="content" v-for="(item, index) in reward.coupon_list" :key="index"> <view class="content" v-for="(item, index) in reward.coupon_list" :key="index">
<view class="info"> <view class="info">
<view> <view>
<text class="num coupon-name">{{ item.coupon_name }}</text> <text class="num coupon-name">{{ item.coupon_name }}</text>
</view> </view>
<view class="desc" v-if="item.at_least > 0"> <view class="desc" v-if="item.at_least > 0">
{{ item.at_least }}{{ item.type == 'discount' ? '' + item.discount + '' : '' + item.money }} {{ item.at_least }}{{ item.type == 'discount' ? '' + item.discount + '' : '' + item.money }}
</view> </view>
<view class="desc" v-else> <view class="desc" v-else>
无门槛{{ item.type == 'discount' ? '' + item.discount + '' : '' + item.money }} 无门槛{{ item.type == 'discount' ? '' + item.discount + '' : '' + item.money }}
</view> </view>
</view> </view>
<view class="tip" @click="closeRewardPopup('coupon')">立即查看</view> <view class="tip" @click="closeRewardPopup('coupon')">立即查看</view>
</view> </view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
</view> </view>
<view class="close-btn" @click="closeRewardPopup()"><text class="iconfont icon-close"></text></view> <view class="close-btn" @click="closeRewardPopup()"><text class="iconfont icon-close"></text></view>
</view> </view>
</uni-popup> </uni-popup>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import uniPopup from '@/components/uni-popup/uni-popup.vue'; import uniPopup from '@/components/uni-popup/uni-popup.vue';
// 注册奖励弹出层 // 注册奖励弹出层
export default { export default {
name: 'register-reward', name: 'register-reward',
components: { components: {
uniPopup uniPopup
}, },
data() { data() {
return { return {
reward: null, reward: null,
back: '' back: '',
}; path: '',
}, };
created() {}, },
methods: { created() {
open(back) { let pages = getCurrentPages();
if (back) this.back = back; let currentPage = pages[pages.length - 1].route;
if (this.addonIsExist.memberregister) { this.path = '/'+currentPage;
this.getRegisterReward();
} else { },
this.closeRewardPopup(); watch: {
} 'canReceiveRegistergift': {
}, handler(newValue, oldValue) {
cancel() { if (newValue.status && newValue.status != oldValue.status && newValue.path.split('?')[0] == this.path) {
this.$refs.registerReward.close(); this.$store.commit('setCanReceiveRegistergiftInfo',{status:false,path:''});
}, // this.$nextTick(()=>{
/** this.open()
* 获取新人礼配置 // })
*/ }
getRegisterReward() { },
this.$api.sendRequest({ deep: true
url: '/memberregister/api/Config/Config', }
success: res => { },
if (res.code >= 0) { computed: {
let data = res.data; canReceiveRegistergift() {
if (data.is_use == 1 && (data.value.point > 0 || data.value.balance > 0 || data return this.$store.state.canReceiveRegistergiftInfo;
.value.growth > 0 || data.value.coupon_list.length > 0)) { },
this.reward = data.value; },
this.$nextTick(() => { methods: {
if(this.$refs.registerReward) this.$refs.registerReward.open(); open(back) {
}); if (back) this.back = back;
} if (this.addonIsExist.memberregister) {
} this.getRegisterReward();
this.closeRewardPopup(); } else {
} this.closeRewardPopup();
}); }
}, },
closeRewardPopup(type) { cancel() {
if (this.$refs.registerReward) this.$refs.registerReward.close(); this.$refs.registerRewardpopup.close();
switch (type) { },
case 'point': /**
this.$util.redirectTo('/pages_tool/member/point_detail', {}); * 获取新人礼配置
break; */
case 'balance': getRegisterReward() {
this.$util.redirectTo('/pages_tool/member/balance_detail', {}); this.$api.sendRequest({
break; url: '/memberregister/api/Config/Config',
case 'growth': success: res => {
this.$util.redirectTo('/pages_tool/member/level', {}); if (res.code >= 0) {
break; let data = res.data;
case 'coupon': if (data.is_use == 1 && (data.value.point > 0 || data.value.balance > 0 || data.value.growth > 0 || data.value.coupon_list.length > 0)) {
this.$util.redirectTo('/pages_tool/member/coupon', {}); this.reward = data.value;
break; this.$forceUpdate()
default: this.$nextTick(()=>{
if (this.back) this.$util.redirectTo(decodeURIComponent(this.back), {}, 'redirectTo'); setTimeout(() => {
else this.$util.redirectTo('/pages/index/index'); this.$refs.registerRewardpopup.open();
break; });
} })
}
} } else {
}; this.closeRewardPopup();
</script> }
<style scoped> }else{
.register-box /deep/ .uni-scroll-view { this.closeRewardPopup();
background: unset !important; }
} }
});
.register-box { },
max-height: 630rpx; closeRewardPopup(type) {
overflow-y: scroll; if (this.$refs.registerRewardpopup) this.$refs.registerRewardpopup.close();
} if(!type) return;
switch (type) {
.register-box /deep/.uni-popup__wrapper-box { case 'point':
overflow: unset !important; this.$util.redirectTo('/pages_tool/member/point_detail', {});
} break;
case 'balance':
.reward-popup /deep/.uni-popup__wrapper { this.$util.redirectTo('/pages_tool/member/balance_detail', {});
background: none; break;
} case 'growth':
</style> this.$util.redirectTo('/pages_tool/member/level', {});
break;
<style lang="scss"> case 'coupon':
.uni-popup__wrapper-box { this.$util.redirectTo('/pages_tool/member/coupon', {});
overflow: unset !important; break;
} default:
this.$util.loginComplete('/pages/index/index','redirectTo');
.close-btn { // if (this.back) this.$util.redirectTo(decodeURIComponent(this.back), {}, 'redirectTo');
text-align: center; // else this.$util.redirectTo('/pages/index/index');
margin-top: 20rpx; break;
}
.iconfont { }
color: #fff; }
font-size: 40rpx; };
} </script>
} <style scoped>
.register-box /deep/ .uni-scroll-view {
.reward-wrap { background: unset !important;
width: 80vw; }
height: auto;
position: relative; .register-box {
// padding-top: 150rpx; max-height: 630rpx;
overflow-y: scroll;
&>uni-image, }
.bg-img {
width: 100%; .register-box /deep/.uni-popup__wrapper-box {
will-change: transform; overflow: unset !important;
} }
.bg-img-head { .reward-popup /deep/.uni-popup__wrapper {
position: absolute; background: none;
top: -150rpx; }
width: 100vw; </style>
left: -10vw;
} <style lang="scss">
.uni-popup__wrapper-box {
.bg-img-money { overflow: unset !important;
position: absolute; }
width: 93vw;
left: -48rpx; .close-btn {
top: 100rpx; text-align: center;
z-index: 10; margin-top: 20rpx;
}
.iconfont {
.wrap { color: #fff;
width: calc(100% - 2rpx); font-size: 40rpx;
height: 100%; }
background-color: #ef3030; }
margin-top: -80rpx;
padding-bottom: 30rpx; .reward-wrap {
border-bottom-left-radius: 10rpx; width: 80vw;
border-bottom-right-radius: 10rpx; height: auto;
position: relative;
&>view { // padding-top: 150rpx;
position: relative;
} &>uni-image,
} .bg-img {
width: 100%;
.reward-content { will-change: transform;
margin: 0 50rpx 0 50rpx; }
}
.bg-img-head {
.reward-item { position: absolute;
.head { top: -150rpx;
color: #fff; width: 100vw;
text-align: center; left: -10vw;
line-height: 1; }
margin: 20rpx 0;
} .bg-img-money {
position: absolute;
.content { width: 93vw;
display: flex; left: -48rpx;
padding: 16rpx 26rpx; top: 100rpx;
background: #fff; z-index: 10;
border-radius: 10rpx; }
margin-bottom: 10rpx;
.wrap {
.info { width: calc(100% - 2rpx);
flex: 1; height: 100%;
} background-color: #ef3030;
margin-top: -80rpx;
.tip { padding-bottom: 30rpx;
color: #ff222d; border-bottom-left-radius: 10rpx;
padding: 10rpx 0 10rpx 30rpx; border-bottom-right-radius: 10rpx;
width: 70rpx;
line-height: 1.5; &>view {
letter-spacing: 2rpx; position: relative;
border-left: 2rpx dashed #e5e5e5; }
} }
.num { .reward-content {
font-size: 52rpx; margin: 0 50rpx 0 50rpx;
color: #ff222d; }
font-weight: bolder;
line-height: 1; .reward-item {
} .head {
color: #fff;
.coupon-name { text-align: center;
font-size: 38rpx; line-height: 1;
} margin: 20rpx 0;
}
.type {
font-size: $font-size-base; .content {
margin-left: 10rpx; display: flex;
line-height: 1; padding: 16rpx 26rpx;
} background: #fff;
border-radius: 10rpx;
.desc { margin-bottom: 10rpx;
margin-top: 8rpx;
color: $color-tip; .info {
font-size: $font-size-tag; flex: 1;
line-height: 1; }
}
} .tip {
} color: #ff222d;
padding: 10rpx 0 10rpx 30rpx;
.btn { width: 70rpx;
position: absolute; line-height: 1.5;
width: calc(100% - 100rpx); letter-spacing: 2rpx;
bottom: 40rpx; border-left: 2rpx dashed #e5e5e5;
left: 50rpx; }
.btn-img { .num {
width: 100%; font-size: 52rpx;
} color: #ff222d;
} font-weight: bolder;
} line-height: 1;
}
.coupon-name {
font-size: 38rpx;
}
.type {
font-size: $font-size-base;
margin-left: 10rpx;
line-height: 1;
}
.desc {
margin-top: 8rpx;
color: $color-tip;
font-size: $font-size-tag;
line-height: 1;
}
}
}
.btn {
position: absolute;
width: calc(100% - 100rpx);
bottom: 40rpx;
left: 50rpx;
.btn-img {
width: 100%;
}
}
}
</style> </style>

View File

@@ -1,95 +1,91 @@
<template> <template>
<view> <view>
<view :id="elId" :class="{ border: showBorder }" :style="{ 'border-left': showBorder ? '1px ' + borderColor + ' solid' : 'none' }" class="uni-grid"> <view :id="elId" :class="{ border: showBorder }" :style="{ 'border-left': showBorder ? '1px ' + borderColor + ' solid' : 'none' }" class="uni-grid">
<slot /> <slot />
</view> </view>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
name: 'UniGrid', name: 'UniGrid',
props: { props: {
// 每列显示个数 // 每列显示个数
column: { column: {
type: Number, type: Number,
default: 3 default: 3
}, },
// 是否显示边框 // 是否显示边框
showBorder: { showBorder: {
type: Boolean, type: Boolean,
default: true default: true
}, },
// 是否显示边框 // 是否显示边框
borderColor: { borderColor: {
type: String, type: String,
default: '#e5e5e5' default: '#e5e5e5'
}, },
// 全局标记水平方向移动距离 ,起点为中心,负数为左移动,正数为右移动 // 全局标记水平方向移动距离 ,起点为中心,负数为左移动,正数为右移动
hor: { hor: {
type: Number, type: Number,
default: 0 default: 0
}, },
// 全局标记垂直方向移动距离 ,起点为中心,负数为上移动,正数为下移动 // 全局标记垂直方向移动距离 ,起点为中心,负数为上移动,正数为下移动
ver: { ver: {
type: Number, type: Number,
default: 0 default: 0
}, },
// 是否正方形显示,默认为 true // 是否正方形显示,默认为 true
square: { square: {
type: Boolean, type: Boolean,
default: true default: true
}, },
highlight: { highlight: {
type: Boolean, type: Boolean,
default: true default: true
} }
}, },
provide() { provide() {
return { return {
grid: this grid: this
}; };
}, },
data() { data() {
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`; const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`;
return { return {
index: 0, index: 0,
elId elId
}; };
}, },
created() { created() {
this.index = 0; this.index = 0;
this.childrens = []; this.childrens = [];
this.pIndex = this.pIndex ? this.pIndex++ : 0; this.pIndex = this.pIndex ? this.pIndex++ : 0;
}, },
methods: { methods: {
change(e) { change(e) {
this.$emit('change', e); this.$emit('change', e);
}, },
_getSize(fn) { _getSize(fn) {
uni.createSelectorQuery() uni.createSelectorQuery().in(this).select(`#${this.elId}`).boundingClientRect().exec(ret => {
.in(this) if (!ret[0]) {
.select(`#${this.elId}`) setTimeout(this._getSize(fn));
.boundingClientRect() return;
.exec(ret => { }
if (!ret[0]) { let width = (parseInt(ret[0].width / this.column) - 1) * 2 + 'rpx';
setTimeout(this._getSize(fn)); typeof fn === 'function' && fn(width);
return; });
} }
let width = (parseInt(ret[0].width / this.column) - 1) * 2 + 'rpx'; }
typeof fn === 'function' && fn(width); };
}); </script>
}
} <style>
};
</script> .uni-grid {
display: flex;
<style> flex-wrap: wrap;
box-sizing: border-box;
.uni-grid { border-left: 2rpx #e5e5e5 solid;
display: flex; }
flex-wrap: wrap; </style>
box-sizing: border-box;
border-left: 2rpx #e5e5e5 solid;
}
</style>

File diff suppressed because one or more lines are too long

View File

@@ -1,261 +1,263 @@
<template> <template>
<view class="uni-numbox" :class="{ small: size == 'small' }"> <view class="uni-numbox" :class="{ small: size == 'small' }">
<button type="default" class="decrease" :class="{ disabled: inputValue <= min || disabled, small: size == 'small' }" @click="_calcValue('minus')">-</button> <button type="default" class="decrease" :class="{ disabled: inputValue <= min || disabled, small: size == 'small' }" @click="_calcValue('minus')">-</button>
<!-- <view <!-- <view
class="uni-numbox__minus" class="uni-numbox__minus"
> --> > -->
<!-- :style="'background-image:url(' + $util.img('public/uniapp/jian.png') + ')'" --> <!-- :style="'background-image:url(' + $util.img('public/uniapp/jian.png') + ')'" -->
<!-- </view> --> <!-- </view> -->
<!-- <input :disabled="disabled || inputDisabled" class="uni-input uni-numbox__value" type="number" @input="_onInput" @blur="_onInput" :class="{ small: size == 'small' }" v-model="inputValue"/> --> <!-- <input :disabled="disabled || inputDisabled" class="uni-input uni-numbox__value" type="number" @input="_onInput" @blur="_onInput" :class="{ small: size == 'small' }" v-model="inputValue"/> -->
<input :disabled="disabled || inputDisabled" class="uni-input uni-numbox__value" type="number" @blur="_onInput" :class="{ small: size == 'small' }" v-model="inputValue" /> <input :disabled="disabled || inputDisabled" class="uni-input uni-numbox__value" type="number" @blur="_onInput" :class="{ small: size == 'small' }" v-model="inputValue" />
<button type="default" class="increase" :class="{ disabled: inputValue >= max || disabled, small: size == 'small' }" @click="_calcValue('plus')">+</button> <button type="default" class="increase" :class="{ disabled: inputValue >= max || disabled, small: size == 'small' }" @click="_calcValue('plus')">+</button>
<!-- <view <!-- <view
class="uni-numbox__plus" @click="_calcValue('plus')" class="uni-numbox__plus" @click="_calcValue('plus')"
:style="'background-image:url(' + $util.img('public/uniapp/jia.png') + ')'" :style="'background-image:url(' + $util.img('public/uniapp/jia.png') + ')'"
> >
</view> --> </view> -->
</view> </view>
</template> </template>
<script> <script>
export default { export default {
name: 'UniNumberBox', name: 'UniNumberBox',
props: { props: {
value: { value: {
type: [Number, String], type: [Number, String],
default: 1 default: 1
}, },
min: { min: {
type: Number, type: Number,
default: 0 default: 0
}, },
max: { max: {
type: Number, type: Number,
default: 100 default: 100
}, },
step: { step: {
type: Number, type: Number,
default: 1 default: 1
}, },
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false default: false
}, },
inputDisabled: { inputDisabled: {
type: Boolean, type: Boolean,
default: false default: false
}, },
size: { size: {
type: String, type: String,
default: 'default' default: 'default'
}, },
index: { index: {
type: [Number, String], type: [Number, String],
default: -1 default: -1
} }
}, },
data() { data() {
return { return {
inputValue: 0, inputValue: 0,
initialValue: 0, // 初始值,防止第一次触发变化 initialValue: 0, // 初始值,防止第一次触发变化
initialIndex: 0, // 初始索引,防止第一次触发变化 initialIndex: 0, // 初始索引,防止第一次触发变化
}; };
}, },
watch: { watch: {
value(val) { value(val) {
this.inputValue = +val; this.inputValue = +val;
}, },
inputValue(newVal, oldVal, params) { inputValue(newVal, oldVal, params) {
// 与初始值相同,不允许操作 // 与初始值相同,不允许操作
if (+newVal != 0 && +newVal == this.initialValue) return; if (+newVal != 0 && +newVal == this.initialValue) return;
// 索引不同,不允许操作 // 索引不同,不允许操作
if (this.initialIndex != this.index) return; if (this.initialIndex != this.index) return;
if (+newVal !== +oldVal) { if (+newVal !== +oldVal) {
this.$emit('change', newVal, params); this.$emit('change', newVal, params);
} }
} }
}, },
created() { created() {
this.initialValue = +this.value; this.initialValue = +this.value;
this.inputValue = +this.value; this.inputValue = +this.value;
this.initialIndex = this.index; this.initialIndex = this.index;
}, },
methods: { methods: {
_calcValue(type) { _calcValue(type) {
if (this.disabled) { if (this.disabled) {
return; return;
} }
const scale = this._getDecimalScale(); const scale = this._getDecimalScale();
let value = this.inputValue * scale; let value = this.inputValue * scale;
let step = this.step * scale; let step = this.step * scale;
if (type === 'minus') { if (type === 'minus') {
value -= step; value -= step;
} else if (type === 'plus') { } else if (type === 'plus') {
value += step; value += step;
} }
if (value < this.min && type === 'minus') { if (value < this.min && type === 'minus') {
this.$emit('limit', { this.$emit('limit', {
value: this.inputValue, value: this.inputValue,
type type
}, this.index); }, this.index);
return; return;
} }
if (value > this.max && type === 'plus') { if (value > this.max && type === 'plus') {
this.$emit('limit', { this.$emit('limit', {
value: this.inputValue, value: this.inputValue,
type type
}, this.index); }, this.index);
return; return;
} }
this.inputValue = value / scale; this.inputValue = value / scale;
}, this.$emit('change', this.inputValue);
_getDecimalScale() { },
let scale = 1; _getDecimalScale() {
// 浮点型 let scale = 1;
if (~~this.step !== this.step) { // 浮点型
scale = Math.pow(10, (this.step + '').split('.')[1].length); if (~~this.step !== this.step) {
} scale = Math.pow(10, (this.step + '').split('.')[1].length);
return scale; }
}, return scale;
_onInput(event) { },
setTimeout(() => { _onInput(event) {
let value = event.detail.value; setTimeout(() => {
// if (!/(^[1-9]\d*$)/.test(value)) value = this.min; let value = event.detail.value;
// if (!value) { // if (!/(^[1-9]\d*$)/.test(value)) value = this.min;
// this.inputValue = 0; // if (!value) {
// return; // this.inputValue = 0;
// } // return;
value = +value; // }
value = +value;
if (value > this.max) {
value = this.max; if (value > this.max) {
this.$util.showToast({ value = this.max;
title: '商品库存不足' this.$util.showToast({
}); title: '商品库存不足'
} else if (value < this.min) { });
this.$util.showToast({ } else if (value < this.min) {
title: '商品最少购买' + this.min + '件' this.$util.showToast({
}); title: '商品最少购买' + this.min + '件'
value = this.min; });
} value = this.min;
// 如果没有最小购买同时也删除了输入框的内容默认赋值为1 }
if (!value) value = 1; // 如果没有最小购买同时也删除了输入框的内容默认赋值为1
if (!value) value = 1;
this.inputValue = value;
this.$forceUpdate(); this.inputValue = value;
}, 0); this.$forceUpdate();
} this.$emit('change', value);
} }, 0);
}; }
</script> }
<style lang="scss"> };
.uni-numbox { </script>
display: inline-flex; <style lang="scss">
flex-direction: row; .uni-numbox {
justify-content: flex-start; display: inline-flex;
align-items: center; flex-direction: row;
height: 70rpx; justify-content: flex-start;
position: relative; align-items: center;
} height: 70rpx;
position: relative;
.uni-numbox.small { }
height: 44rpx;
} .uni-numbox.small {
height: 44rpx;
.uni-numbox:after { }
content: '';
position: absolute; .uni-numbox:after {
transform-origin: center; content: '';
box-sizing: border-box; position: absolute;
pointer-events: none; transform-origin: center;
top: -50%; box-sizing: border-box;
left: -50%; pointer-events: none;
right: -50%; top: -50%;
bottom: -50%; left: -50%;
border-radius: 12rpx; right: -50%;
transform: scale(0.5); bottom: -50%;
} border-radius: 12rpx;
transform: scale(0.5);
.uni-numbox__minus, }
.uni-numbox__plus {
width: 40rpx; .uni-numbox__minus,
height: 40rpx; .uni-numbox__plus {
border-radius: 50%; width: 40rpx;
background-size: 100% 100%; height: 40rpx;
background-position: center; border-radius: 50%;
} background-size: 100% 100%;
background-position: center;
.uni-numbox__value { }
position: relative;
background-color: $color-bg; .uni-numbox__value {
width: 80rpx; position: relative;
height: 40rpx; background-color: $color-bg;
text-align: center; width: 80rpx;
border: 1px solid $color-line; height: 40rpx;
display: inline-block; text-align: center;
line-height: 36rpx; border: 1px solid $color-line;
font-weight: bold; display: inline-block;
margin: 0; line-height: 36rpx;
padding: 0; font-weight: bold;
vertical-align: top; margin: 0;
min-height: initial; padding: 0;
border-left: none; vertical-align: top;
border-right: none; min-height: initial;
} border-left: none;
border-right: none;
.uni-numbox__value.small { }
width: 60rpx;
font-size: $font-size-tag; .uni-numbox__value.small {
} width: 60rpx;
font-size: $font-size-tag;
.uni-numbox__value:after { }
content: '';
position: absolute; .uni-numbox__value:after {
transform-origin: center; content: '';
box-sizing: border-box; position: absolute;
pointer-events: none; transform-origin: center;
top: -50%; box-sizing: border-box;
left: -50%; pointer-events: none;
right: -50%; top: -50%;
bottom: -50%; left: -50%;
border-top-width: 0; right: -50%;
border-bottom-width: 0; bottom: -50%;
transform: scale(0.5); border-top-width: 0;
} border-bottom-width: 0;
transform: scale(0.5);
.uni-numbox--disabled { }
color: silver;
} .uni-numbox--disabled {
color: silver;
.uni-numbox button { }
width: 40rpx;
height: 40rpx; .uni-numbox button {
display: inline-block; width: 40rpx;
box-sizing: content-box; height: 40rpx;
border: 1px solid $color-line; display: inline-block;
padding: 0; box-sizing: content-box;
margin: 0; border: 1px solid $color-line;
border-radius: 0; padding: 0;
background-color: #fff; margin: 0;
font-weight: bold; border-radius: 0;
background-color: #fff;
&.disabled { font-weight: bold;
color: $color-line;
background-color: #f8f8f8 !important; &.disabled {
} color: $color-line;
background-color: #f8f8f8 !important;
&.decrease { }
font-size: 44rpx;
line-height: 32rpx; &.decrease {
} font-size: 44rpx;
line-height: 32rpx;
&.increase { }
font-size: $font-size-toolbar;
line-height: 36rpx; &.increase {
} font-size: $font-size-toolbar;
} line-height: 36rpx;
}
}
</style> </style>

View File

@@ -1,244 +1,243 @@
<template> <template>
<view v-if="showPopup" class="uni-popup" :class="customClass" :style="{'top': top}"> <view v-if="showPopup" class="uni-popup" :class="customClass" :style="{'top': top}">
<view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" ></view> <view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" ></view>
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup safe-area" @click="close(true)" v-if="isIphoneX"> <view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup safe-area" @click="close(true)" v-if="isIphoneX">
<view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear"> <view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear">
<slot /> <slot />
</view> </view>
</view> </view>
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup" @click="close(true)" v-else> <view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup" @click="close(true)" v-else>
<view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear"> <view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear">
<slot /> <slot />
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
name: 'UniPopup', name: 'UniPopup',
props: { props: {
// 开启动画 // 开启动画
animation: { animation: {
type: Boolean, type: Boolean,
default: true default: true
}, },
// 弹出层类型可选值top: 顶部弹出层bottom底部弹出层center全屏弹出层 // 弹出层类型可选值top: 顶部弹出层bottom底部弹出层center全屏弹出层
type: { type: {
type: String, type: String,
default: 'center' default: 'center'
}, },
// 是否开启自定义 // 是否开启自定义
custom: { custom: {
type: Boolean, type: Boolean,
default: false default: false
}, },
// maskClick maskClick: {
maskClick: { type: Boolean,
type: Boolean, default: true
default: true },
}, show: {
show: { type: Boolean,
type: Boolean, default: true
default: true },
}, top: {
top: { type: String,
type: String, default: '0'
default: '0' },
}, customClass: {
customClass: { type: String,
type: String, default: ''
default: '' }
} },
}, data() {
data() { return {
return { ani: '',
ani: '', showPopup: false,
showPopup: false, callback: null,
callback: null, isIphoneX: false
isIphoneX: false };
}; },
}, watch: {
watch: { show(newValue) {
show(newValue) { if (newValue) {
if (newValue) { this.open();
this.open(); } else {
} else { this.close();
this.close(); }
} }
} },
}, created() {
created() { this.isIphoneX = this.$util.uniappIsIPhoneX();
this.isIphoneX = this.$util.uniappIsIPhoneX(); },
}, methods: {
methods: { clear() {},
clear() {}, open(callback) {
open(callback) { if (callback) this.callback = callback;
if (callback) this.callback = callback;
this.$emit('change', {
this.$emit('change', { show: true
show: true });
}); this.showPopup = true;
this.showPopup = true; this.$nextTick(() => {
this.$nextTick(() => { setTimeout(() => {
setTimeout(() => { this.ani = 'uni-' + this.type;
this.ani = 'uni-' + this.type; }, 30);
}, 30); });
}); },
}, close(type, callback) {
close(type, callback) { if (!this.maskClick && type) return;
if (!this.maskClick && type) return; this.$emit('change', {
this.$emit('change', { show: false
show: false });
}); this.ani = '';
this.ani = ''; this.$nextTick(() => {
this.$nextTick(() => { setTimeout(() => {
setTimeout(() => { this.showPopup = false;
this.showPopup = false; }, 300);
}, 300); });
});
if (callback) callback();
if (callback) callback();
if (this.callback) this.callback.call(this);
if (this.callback) this.callback.call(this); }
} }
} };
}; </script>
</script> <style>
<style> .uni-popup {
.uni-popup { position: fixed;
position: fixed; top: 0;
top: 0; bottom: 0;
bottom: 0; left: 0;
left: 0; right: 0;
right: 0; z-index: 999;
z-index: 999; overflow: hidden;
overflow: hidden; }
}
.uni-popup__mask {
.uni-popup__mask { position: absolute;
position: absolute; top: 0;
top: 0; bottom: 0;
bottom: 0; left: 0;
left: 0; right: 0;
right: 0; z-index: 998;
z-index: 998; background: rgba(0, 0, 0, 0.4);
background: rgba(0, 0, 0, 0.4); opacity: 0;
opacity: 0; }
}
.uni-popup__mask.ani {
.uni-popup__mask.ani { transition: all 0.3s;
transition: all 0.3s; }
}
.uni-popup__mask.uni-bottom,
.uni-popup__mask.uni-bottom, .uni-popup__mask.uni-center,
.uni-popup__mask.uni-center, .uni-popup__mask.uni-right,
.uni-popup__mask.uni-right, .uni-popup__mask.uni-left,
.uni-popup__mask.uni-left, .uni-popup__mask.uni-top {
.uni-popup__mask.uni-top { opacity: 1;
opacity: 1; }
}
.uni-popup__wrapper {
.uni-popup__wrapper { position: absolute;
position: absolute; z-index: 999;
z-index: 999; box-sizing: border-box;
box-sizing: border-box; //background: #ffffff;
//background: #ffffff; }
}
.uni-popup__wrapper.ani {
.uni-popup__wrapper.ani { transition: all 0.3s;
transition: all 0.3s; }
}
.uni-popup__wrapper.top {
.uni-popup__wrapper.top { top: 0;
top: 0; left: 0;
left: 0; width: 100%;
width: 100%; transform: translateY(-100%);
transform: translateY(-100%); }
}
.uni-popup__wrapper.bottom {
.uni-popup__wrapper.bottom { bottom: 0;
bottom: 0; left: 0;
left: 0; width: 100%;
width: 100%; transform: translateY(100%);
transform: translateY(100%); background: #ffffff;
background: #ffffff; }
}
.uni-popup__wrapper.right {
.uni-popup__wrapper.right { bottom: 0;
bottom: 0; left: 0;
left: 0; width: 100%;
width: 100%; transform: translateX(100%);
transform: translateX(100%); }
}
.uni-popup__wrapper.left {
.uni-popup__wrapper.left { bottom: 0;
bottom: 0; left: 0;
left: 0; width: 100%;
width: 100%; transform: translateX(-100%);
transform: translateX(-100%); }
}
.uni-popup__wrapper.center {
.uni-popup__wrapper.center { width: 100%;
width: 100%; height: 100%;
height: 100%; display: flex;
display: flex; justify-content: center;
justify-content: center; align-items: center;
align-items: center; transform: scale(1.2);
transform: scale(1.2); opacity: 0;
opacity: 0; }
}
.uni-popup__wrapper-box {
.uni-popup__wrapper-box { position: relative;
position: relative; box-sizing: border-box;
box-sizing: border-box; border-radius: 10rpx;
border-radius: 10rpx; }
}
.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { background: #fff;
background: #fff; }
}
.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box { position: relative;
position: relative; max-width: 80%;
max-width: 80%; max-height: 80%;
max-height: 80%; overflow-y: scroll;
overflow-y: scroll; }
}
.uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box,
.uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box, .uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box {
.uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box { width: 100%;
width: 100%; max-height: 500px;
max-height: 500px; overflow-y: scroll;
overflow-y: scroll; }
}
.uni-popup__wrapper.uni-bottom,
.uni-popup__wrapper.uni-bottom, .uni-popup__wrapper.uni-top {
.uni-popup__wrapper.uni-top { transform: translateY(0);
transform: translateY(0); }
}
.uni-popup__wrapper.uni-left,
.uni-popup__wrapper.uni-left, .uni-popup__wrapper.uni-right {
.uni-popup__wrapper.uni-right { transform: translateX(0);
transform: translateX(0); }
}
.uni-popup__wrapper.uni-center {
.uni-popup__wrapper.uni-center { transform: scale(1);
transform: scale(1); opacity: 1;
opacity: 1; }
}
/* isIphoneX系列手机底部安全距离 */
/* isIphoneX系列手机底部安全距离 */ .bottom.safe-area {
.bottom.safe-area { padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom); }
}
.left.safe-area {
.left.safe-area { padding-bottom: 68rpx;
padding-bottom: 68rpx; }
}
.right.safe-area {
.right.safe-area { padding-bottom: 68rpx;
padding-bottom: 68rpx; }
}
</style> </style>

View File

@@ -1,158 +1,158 @@
<template> <template>
<view <view
v-if="text" v-if="text"
:class="[ :class="[
disabled === true || disabled === 'true' ? 'uni-tag--disabled' : '', disabled === true || disabled === 'true' ? 'uni-tag--disabled' : '',
inverted === true || inverted === 'true' ? 'uni-tag--inverted' : '', inverted === true || inverted === 'true' ? 'uni-tag--inverted' : '',
circle === true || circle === 'true' ? 'uni-tag--circle' : '', circle === true || circle === 'true' ? 'uni-tag--circle' : '',
mark === true || mark === 'true' ? 'uni-tag--mark' : '', mark === true || mark === 'true' ? 'uni-tag--mark' : '',
'uni-tag--' + size, 'uni-tag--' + size,
'uni-tag--' + type 'uni-tag--' + type
]" ]"
class="uni-tag" class="uni-tag"
@click="onClick()" @click="onClick()"
> >
{{ text }} {{ text }}
</view> </view>
</template> </template>
<script> <script>
export default { export default {
name: 'UniTag', name: 'UniTag',
props: { props: {
type: { type: {
// 标签类型default、primary、success、warning、danger、royal // 标签类型default、primary、success、warning、danger、royal
type: String, type: String,
default: 'default' default: 'default'
}, },
size: { size: {
// 标签大小 normal, small // 标签大小 normal, small
type: String, type: String,
default: 'normal' default: 'normal'
}, },
// 标签内容 // 标签内容
text: { text: {
type: String, type: String,
default: '' default: ''
}, },
disabled: { disabled: {
// 是否为禁用状态 // 是否为禁用状态
type: [String, Boolean], type: [String, Boolean],
defalut: false default: false
}, },
inverted: { inverted: {
// 是否为空心 // 是否为空心
type: [String, Boolean], type: [String, Boolean],
defalut: false default: false
}, },
circle: { circle: {
// 是否为圆角样式 // 是否为圆角样式
type: [String, Boolean], type: [String, Boolean],
defalut: false default: false
}, },
mark: { mark: {
// 是否为标记样式 // 是否为标记样式
type: [String, Boolean], type: [String, Boolean],
defalut: false default: false
} }
}, },
methods: { methods: {
onClick() { onClick() {
if (this.disabled === true || this.disabled === 'true') { if (this.disabled === true || this.disabled === 'true') {
return; return;
} }
this.$emit('click'); this.$emit('click');
} }
} }
}; };
</script> </script>
<style> <style>
.uni-tag { .uni-tag {
box-sizing: border-box; box-sizing: border-box;
padding: 0 32rpx; padding: 0 32rpx;
height: 60rpx; height: 60rpx;
line-height: calc(60rpx - 2px); line-height: calc(60rpx - 2px);
font-size: 28rpx; font-size: 28rpx;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
color: #333; color: #333;
border-radius: 6rpx; border-radius: 6rpx;
background-color: #f8f8f8; background-color: #f8f8f8;
border: 1px solid #f8f8f8; border: 1px solid #f8f8f8;
} }
.uni-tag--circle { .uni-tag--circle {
border-radius: 30rpx; border-radius: 30rpx;
} }
.uni-tag--mark { .uni-tag--mark {
border-radius: 0 30rpx 30rpx 0; border-radius: 0 30rpx 30rpx 0;
} }
.uni-tag--disabled { .uni-tag--disabled {
opacity: 0.5; opacity: 0.5;
} }
.uni-tag--small { .uni-tag--small {
height: 40rpx; height: 40rpx;
padding: 0 16rpx; padding: 0 16rpx;
line-height: calc(40rpx - 2px); line-height: calc(40rpx - 2px);
font-size: 24rpx; font-size: 24rpx;
} }
.uni-tag--primary { .uni-tag--primary {
color: #fff; color: #fff;
background-color: #007aff; background-color: #007aff;
border: 1px solid #007aff; border: 1px solid #007aff;
} }
.uni-tag--primary.uni-tag--inverted { .uni-tag--primary.uni-tag--inverted {
color: #007aff; color: #007aff;
background-color: #fff; background-color: #fff;
border: 1px solid #007aff; border: 1px solid #007aff;
} }
.uni-tag--success { .uni-tag--success {
color: #fff; color: #fff;
background-color: #4cd964; background-color: #4cd964;
border: 1px solid #4cd964; border: 1px solid #4cd964;
} }
.uni-tag--success.uni-tag--inverted { .uni-tag--success.uni-tag--inverted {
color: #4cd964; color: #4cd964;
background-color: #fff; background-color: #fff;
border: 1px solid #4cd964; border: 1px solid #4cd964;
} }
.uni-tag--warning { .uni-tag--warning {
color: #fff; color: #fff;
background-color: #f0ad4e; background-color: #f0ad4e;
border: 1px solid #f0ad4e; border: 1px solid #f0ad4e;
} }
.uni-tag--warning.uni-tag--inverted { .uni-tag--warning.uni-tag--inverted {
color: #f0ad4e; color: #f0ad4e;
background-color: #fff; background-color: #fff;
border: 1px solid #f0ad4e; border: 1px solid #f0ad4e;
} }
.uni-tag--error { .uni-tag--error {
color: #fff; color: #fff;
background-color: #dd524d; background-color: #dd524d;
border: 1px solid #dd524d; border: 1px solid #dd524d;
} }
.uni-tag--error.uni-tag--inverted { .uni-tag--error.uni-tag--inverted {
color: #dd524d; color: #dd524d;
background-color: #fff; background-color: #fff;
border: 1px solid #dd524d; border: 1px solid #dd524d;
} }
.uni-tag--inverted { .uni-tag--inverted {
color: #333; color: #333;
background-color: #fff; background-color: #fff;
border: 1px solid #f8f8f8; border: 1px solid #f8f8f8;
} }
</style> </style>

View File

@@ -0,0 +1,218 @@
<template>
<text
class="uv-count-num"
:style="textStyle"
>
{{ displayValue }}
</text>
</template>
<script>
export default {
name: 'uv-count-to',
props: {
startVal: {
type: [String, Number],
default: 0
},
endVal: {
type: [String, Number],
default: 0
},
duration: {
type: [String, Number],
default: 2000
},
autoplay: {
type: Boolean,
default: true
},
decimals: {
type: [String, Number],
default: 0
},
useEasing: {
type: Boolean,
default: true
},
decimal: {
type: [String, Number],
default: '.'
},
color: {
type: String,
default: '#606266'
},
fontSize: {
type: [String, Number],
default: 22
},
bold: {
type: Boolean,
default: false
},
separator: {
type: String,
default: ''
}
},
data() {
return {
localStartVal: this.startVal,
displayValue: this.formatNumber(this.startVal),
printVal: null,
paused: false,
localDuration: Number(this.duration),
startTime: null,
timestamp: null,
remaining: null,
rAF: null,
lastTime: 0
}
},
computed: {
countDown() {
return this.startVal > this.endVal
},
textStyle() {
return {
fontSize: this.fontSize + 'px',
fontWeight: this.bold ? 'bold' : 'normal',
color: this.color
}
}
},
watch: {
startVal() {
if (this.autoplay) {
this.start()
}
},
endVal() {
console.log(123)
if (this.autoplay) {
this.start()
}
}
},
mounted() {
if (this.autoplay) {
this.start()
}
},
methods: {
easingFn(t, b, c, d) {
return c * (1 - Math.pow(2, -10 * t / d)) * 1024 / 1023 + b
},
requestAnimationFrame(callback) {
const currTime = new Date().getTime()
const timeToCall = Math.max(0, 16 - (currTime - this.lastTime))
const id = setTimeout(() => {
callback(currTime + timeToCall)
}, timeToCall)
this.lastTime = currTime + timeToCall
return id
},
cancelAnimationFrame(id) {
clearTimeout(id)
},
start() {
this.localStartVal = this.startVal
this.startTime = null
this.localDuration = this.duration
this.paused = false
this.rAF = this.requestAnimationFrame(this.count)
},
restart() {
if (this.paused) {
this.resume()
this.paused = false
} else {
this.stop()
this.paused = true
}
},
stop() {
this.cancelAnimationFrame(this.rAF)
this.paused = true
},
resume() {
if (this.remaining) {
this.startTime = 0
this.localDuration = this.remaining
this.localStartVal = this.printVal
this.requestAnimationFrame(this.count)
}
},
reset() {
this.startTime = null
this.cancelAnimationFrame(this.rAF)
this.displayValue = this.formatNumber(this.startVal)
},
count(timestamp) {
if (!this.startTime) this.startTime = timestamp
this.timestamp = timestamp
const progress = timestamp - this.startTime
this.remaining = this.localDuration - progress
if (this.useEasing) {
if (this.countDown) {
this.printVal = this.localStartVal - this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration)
} else {
this.printVal = this.easingFn(progress, this.localStartVal, this.endVal - this.localStartVal, this.localDuration)
}
} else {
if (this.countDown) {
this.printVal = this.localStartVal - (this.localStartVal - this.endVal) * (progress / this.localDuration)
} else {
this.printVal = this.localStartVal + (this.endVal - this.localStartVal) * (progress / this.localDuration)
}
}
if (this.countDown) {
this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal
} else {
this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal
}
this.displayValue = this.formatNumber(this.printVal) || 0
if (progress < this.localDuration) {
this.rAF = this.requestAnimationFrame(this.count)
} else {
this.$emit('end')
}
},
isNumber(val) {
return !isNaN(parseFloat(val))
},
formatNumber(num) {
num = Number(num)
num = num.toFixed(Number(this.decimals))
num += ''
const x = num.split('.')
let x1 = x[0]
const x2 = x.length > 1 ? this.decimal + x[1] : ''
const rgx = /(\d+)(\d{3})/
if (this.separator && !this.isNumber(this.separator)) {
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + this.separator + '$2')
}
}
return x1 + x2
}
},
destroyed() {
this.cancelAnimationFrame(this.rAF)
}
}
</script>
<style scoped>
.uv-count-num {
display: inline-flex;
text-align: center;
}
</style>

View File

@@ -1,14 +1,16 @@
export const lang = { export const lang = {
//title为每个页面的标题 //title为每个页面的标题
title: '编辑收货地址', title: '编辑收货地址',
consignee: '姓名', consignee: '姓名',
consigneePlaceholder: '收货人姓名', consigneePlaceholder: '收货人姓名',
mobile: '手机', mobile: '手机',
mobilePlaceholder: '收货人手机号', mobilePlaceholder: '收货人手机号',
telephone: '电话', telephone: '电话',
telephonePlaceholder: '收货人固定电话(选填)', telephonePlaceholder: '收货人固定电话(选填)',
receivingCity: '地区', receivingCity: '地区',
address: '详细地址', address: '详细地址',
addressPlaceholder: '小区、街道、写字楼', house:'门牌号',
save: '保存' housePlaceholder:'请输入楼层门牌号',
} addressPlaceholder: '小区、街道、写字楼',
save: '保存'
}

View File

@@ -1,51 +1,51 @@
export const lang = { export const lang = {
//title为每个页面的标题 //title为每个页面的标题
title: '会员中心', title: '会员中心',
login: '登录/注册', login: '立即登录',
loginTpis: '点击登录 享受更多精彩信息', loginTpis: '点击登录 享受更多精彩信息',
memberLevel: '会员等级', memberLevel: '会员等级',
moreAuthority: '更多权限', moreAuthority: '更多权限',
allOrders: '全部订单', allOrders: '全部订单',
seeAllOrders: '查看全部订单', seeAllOrders: '查看全部订单',
waitPay: '待付款', waitPay: '待付款',
readyDelivery: '待发货', readyDelivery: '待发货',
waitDelivery: '待收货', waitDelivery: '待收货',
refunding: '退款', refunding: '退款',
// 会员中心入口 // 会员中心入口
sign: '签到', sign: '签到',
personInfo: '个人资料', personInfo: '个人资料',
receivingAddress: '收货地址', receivingAddress: '收货地址',
accountList: '账户列表', accountList: '账户列表',
couponList: '优惠券', couponList: '优惠券',
mySpellList: '我的拼单', mySpellList: '我的拼单',
myBargain: '我的砍价', myBargain: '我的砍价',
virtualCode: '虚拟码', virtualCode: '虚拟码',
winningRecord: '我的礼品', winningRecord: '我的礼品',
myCollection: '我的关注', myCollection: '我的关注',
myTracks: '我的足迹', myTracks: '我的足迹',
pintuanOrder: '拼团订单', pintuanOrder: '拼团订单',
yushouOrder: '预售订单', yushouOrder: '预售订单',
verification: '核销台', verification: '核销台',
message: '我的消息', message: '我的消息',
exchangeOrder: '积分兑换', exchangeOrder: '积分兑换',
waitpay:'待付款', waitpay:'待付款',
waitsend:'待发货', waitsend:'待发货',
waitconfirm:'待收货', waitconfirm:'待收货',
activist:'售后', activist:'售后',
completed:'已完成', completed:'已完成',
// 推广中心 // 推广中心
balance: '余额', balance: '余额',
point: '积分', point: '积分',
coupon: '优惠券', coupon: '优惠券',
memberRecommend: '邀请有礼', memberRecommend: '邀请有礼',
myPresale: '我的预售', myPresale: '我的预售',
myGiftcard: '我的礼品卡', myGiftcard: '我的礼品卡',
myDivideticket: '我的瓜分券', myDivideticket: '我的瓜分券',
myRebate:'拼团返利', myRebate:'拼团返利',
myHongbao:'我的红包列表', myHongbao:'我的红包列表',
myBlindBox:'我的盲盒', myBlindBox:'我的盲盒',
} }

View File

@@ -1,13 +1,14 @@
export const lang = { export const lang = {
//title为每个页面的标题 //title为每个页面的标题
title: '订单列表', title: '订单列表',
emptyTips: '暂无相关订单', emptyTips: '暂无相关订单',
all: '全部', all: '全部',
waitPay: '待付款', waitPay: '待付款',
readyDelivery: '待发货', readyDelivery: '待发货',
waitDelivery: '待收货', waitDelivery: '待收货',
waitEvaluate: '待评价', waitEvaluate: '待评价',
waitUse: '待使用', waitUse: '待使用',
update: "释放刷新", update: "释放刷新",
updateIng: "加载中..." updateIng: "加载中...",
} toLogin: "去登录"
}

View File

@@ -38,12 +38,15 @@ Vue.mixin(globalConfig);
App.mpType = 'app'; App.mpType = 'app';
// 重写存储,增加前缀 // 重写存储,增加前缀
uniStorage(); Util.rewriteUniStorageMethod();
//常用组件 //常用组件
import loadingCover from '@/components/loading-cover/loading-cover.vue'; import loadingCover from '@/components/loading-cover/loading-cover.vue';
Vue.component('loading-cover', loadingCover); Vue.component('loading-cover', loadingCover);
import nsMpHtml from '@/components/ns-mp-html/ns-mp-html.vue';
Vue.component('ns-mp-html', nsMpHtml);
import nsEmpty from '@/components/ns-empty/ns-empty.vue'; import nsEmpty from '@/components/ns-empty/ns-empty.vue';
Vue.component('ns-empty', nsEmpty); Vue.component('ns-empty', nsEmpty);

View File

@@ -58,12 +58,14 @@
"quickapp" : {}, "quickapp" : {},
/* */ /* */
"mp-weixin" : { "mp-weixin" : {
"appid" : "wxa8f94045d9c2fc10", "appid" : "wx29215aa1bd97bbd6",
"setting" : { "setting" : {
"urlCheck" : false, "urlCheck" : false,
"postcss" : false, "postcss" : false,
"es6" : true, "es6" : true,
"minified" : true "minified" : true,
"codeSigning" : true,
"uglifyFileName" : true
}, },
"usingComponents" : true, "usingComponents" : true,
"permission" : { "permission" : {
@@ -108,7 +110,7 @@
}, },
"optimization" : { "optimization" : {
"treeShaking" : { "treeShaking" : {
"enable" : false "enable" : true
} }
}, },
"domain" : " ", "domain" : " ",

View File

@@ -3,7 +3,7 @@
{ {
"path": "pages/index/index", "path": "pages/index/index",
"style": { "style": {
// "navigationStyle": "custom", "navigationStyle": "custom",
"enablePullDownRefresh": true "enablePullDownRefresh": true
} }
}, },
@@ -28,15 +28,17 @@
"path": "pages/goods/category", "path": "pages/goods/category",
"style": { "style": {
"disableScroll": true, "disableScroll": true,
"navigationStyle": "custom",
"navigationBarTitleText": "商品分类", "navigationBarTitleText": "商品分类",
"enablePullDownRefresh": true "enablePullDownRefresh": true
} }
}, },
// 商品详情 // 商品详情、限时折扣、预售
{ {
"path": "pages/goods/detail", "path": "pages/goods/detail",
"style": { "style": {
"navigationStyle": "custom",
"navigationBarTitleText": "商品详情" "navigationBarTitleText": "商品详情"
} }
}, },
@@ -54,6 +56,7 @@
{ {
"path": "pages/member/index", "path": "pages/member/index",
"style": { "style": {
"navigationStyle": "custom",
"enablePullDownRefresh": true "enablePullDownRefresh": true
} }
}, },
@@ -112,6 +115,55 @@
//******************营销活动模块26****************** //******************营销活动模块26******************
"root": "pages_promotion", "root": "pages_promotion",
"pages": [ "pages": [
//----------组合套餐模块2----------
{
"path": "bundling/detail",
"style": {
// #ifdef H5
"navigationStyle": "custom"
// #endif
}
},
{
"path": "bundling/payment",
"style": {
// #ifdef H5
"navigationStyle": "custom"
// #endif
}
},
//----------砍价模块5----------
{
"path": "bargain/list",
"style": {
// #ifdef H5
"navigationStyle": "custom"
// #endif
}
},
{
"path": "bargain/detail",
"style": {
// #ifdef H5
"navigationStyle": "custom"
// #endif
}
},
{
"path": "bargain/my_bargain",
"style": {
// #ifdef H5
"navigationStyle": "custom"
// #endif
}
},
{
"path": "bargain/payment",
"style": {
"navigationStyle": "custom"
}
},
//----------积分模块2---------- //----------积分模块2----------
{ {
@@ -710,11 +762,21 @@
// #endif // #endif
} }
}, },
//******************聊天4******************
{
"path": "chat/room",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"softinputMode": "adjustResize"
}
},
//******************支付模块2****************** //******************支付模块2******************
{ {
"path": "pay/index", "path": "pay/index",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -722,7 +784,7 @@
{ {
"path": "pay/wx_pay", "path": "pay/wx_pay",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -730,7 +792,7 @@
{ {
"path": "pay/result", "path": "pay/result",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -738,7 +800,15 @@
{ {
"path": "pay/cashier", "path": "pay/cashier",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom"
// #endif
}
},
{
"path": "pay/offlinepay",
"style": {
// #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -746,7 +816,7 @@
{ {
"path": "storeclose/storeclose", "path": "storeclose/storeclose",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -755,7 +825,7 @@
{ {
"path": "order/logistics", "path": "order/logistics",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -763,7 +833,7 @@
{ {
"path": "order/evaluate", "path": "order/evaluate",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -771,7 +841,7 @@
{ {
"path": "order/refund", "path": "order/refund",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -779,7 +849,7 @@
{ {
"path": "order/refund_goods_select", "path": "order/refund_goods_select",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -787,7 +857,7 @@
{ {
"path": "order/refund_type_select", "path": "order/refund_type_select",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -795,7 +865,7 @@
{ {
"path": "order/refund_batch", "path": "order/refund_batch",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -803,7 +873,7 @@
{ {
"path": "order/refund_detail", "path": "order/refund_detail",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
@@ -811,38 +881,130 @@
{ {
"path": "order/activist", "path": "order/activist",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom", "navigationStyle": "custom",
// #endif // #endif
"navigationBarTitleText": "退款" "navigationBarTitleText": "退款"
} }
}, },
{
"path": "order/detail_virtual",
"style": {
// #ifdef APP-PLUS
"navigationStyle": "custom"
// #endif
}
},
//******************登录模块3****************** //******************登录模块3******************
{ {
"path": "login/login", "path": "login/index",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom", "navigationStyle": "custom",
// #endif // #endif
"navigationBarTitleText": "登录" "navigationBarTitleText": "登录"
} }
}, },
{
"path": "login/aggrement",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "协议"
}
},
{
"path": "login/login",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "登录"
}
},
{
"path": "login/register",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "注册"
}
},
{ {
"path": "form/form", "path": "form/form",
"style": { "style": {
// #ifdef APP-PLUS // #ifdef H5
"navigationStyle": "custom" "navigationStyle": "custom"
// #endif // #endif
} }
}, },
{
"path": "store/list",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "门店列表"
}
},
{
"path": "store/detail",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "门店详情"
}
},
{
"path": "store/store_payment",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "门店付款"
}
},
{
"path": "store/payment_qrcode",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "付款码"
}
},
//******************核销模块4******************
{
"path": "verification/index",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "核销台"
}
},
{
"path": "verification/list",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "核销列表"
}
},
{
"path": "verification/detail",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "核销详情"
}
},
{
"path": "weapp/order_shipping",
"style": {
// #ifdef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "小程序发货"
}
},
//******************AI客服****************** //******************AI客服******************
{ {
"path": "ai-chat/index", "path": "ai-chat/index",
@@ -879,7 +1041,7 @@
"text": "" "text": ""
}, },
{ {
"pagePath": "pages/contact/contact", "pagePath": "pages/goods/cart",
"text": "" "text": ""
}, },
{ {

View File

@@ -14,13 +14,13 @@
<view class="dite-button" @click="officialAccountsOpen">关注公众号</view> <view class="dite-button" @click="officialAccountsOpen">关注公众号</view>
</view> </view>
<!-- <view class="page-header" v-if="diyData.global && diyData.global.navBarSwitch" :style="{ backgroundImage: bgImg }"> <view class="page-header" v-if="diyData.global && diyData.global.navBarSwitch" :style="{ backgroundImage: bgImg }">
<ns-navbar :title-color="textNavColor" :data="diyData.global" :scrollTop="scrollTop" :isBack="false"/> <ns-navbar :title-color="textNavColor" :data="diyData.global" :scrollTop="scrollTop" :isBack="false"/>
</view> --> </view>
<diy-index-page v-if="topIndexValue" ref="indexPage" :value="topIndexValue" :bgUrl="bgUrl" :scrollTop="scrollTop" :diyGlobal="diyData.global" class="diy-index-page"> <diy-index-page v-if="topIndexValue" ref="indexPage" :value="topIndexValue" :bgUrl="bgUrl" :scrollTop="scrollTop" :diyGlobal="diyData.global" class="diy-index-page">
<template v-slot:components> <template v-slot:components>
<diy-group ref="diyGroup" v-if="diyData.value" :diyData="diyData" :scrollTop="scrollTop" :haveTopCategory="true" :followOfficialAccount="followOfficialAccount"/> <diy-group ref="diyGroup" v-if="diyData.value" :refresh="refresh" :diyData="diyData" :scrollTop="scrollTop" :haveTopCategory="true" :followOfficialAccount="followOfficialAccount"/>
</template> </template>
<template v-slot:default> <template v-slot:default>
<ns-copyright v-show="isShowCopyRight"/> <ns-copyright v-show="isShowCopyRight"/>
@@ -94,26 +94,27 @@
<!-- 选择门店弹出框定位当前位置展示最近的一个门店 --> <!-- 选择门店弹出框定位当前位置展示最近的一个门店 -->
<view @touchmove.prevent.stop class="choose-store"> <view @touchmove.prevent.stop class="choose-store">
<uni-popup ref="chooseStorePopup" type="center" :maskClick="false" class="choose-store"> <uni-popup ref="chooseStorePopup" type="center" :maskClick="false" class="choose-store">
<view class="choose-store-popup"> <view class="choose-store-popup" v-if="currentStore">
<view class="head-wrap" @click="closeChooseStorePopup">请确认门店</view> <view class="head-wrap">请确认门店</view>
<view class="position-wrap"> <view class="position-wrap">
<text class="iconfont icon-dizhi"></text> <text class="iconfont icon-dizhi"></text>
<text class="address">{{ currentPosition }}</text> <text class="address">{{ currentPosition || currentStore.show_address }}</text>
<view class="reposition" @click="reposition" v-if="globalStoreConfig && globalStoreConfig.is_allow_change == 1"> <view class="reposition" @click="reGetLocation" v-if="globalStoreConfig && globalStoreConfig.is_allow_change == 1">
<text class="iconfont icon-dingwei"></text> <text class="iconfont icon-dingwei"></text>
<text>重新定位</text> <text>重新定位</text>
</view> </view>
</view> </view>
<view class="store-wrap" v-if="nearestStore"> <view class="store-wrap" v-if="currentStore">
<text class="tag">当前门店</text> <text class="tag">当前门店</text>
<view class="store-name">{{ nearestStore.store_name }}</view> <view class="store-name">{{ currentStore.store_name }}</view>
<view class="address">{{ nearestStore.show_address }}</view> <view class="store-close-desc" v-if="currentStore.status == 0 && currentStore.close_desc">{{ currentStore.close_desc }}</view>
<view class="distance" v-if="nearestStore.distance"> <view class="address">{{ currentStore.show_address }}</view>
<view class="distance" v-if="currentStore.distance">
<text class="iconfont icon-dizhi"></text> <text class="iconfont icon-dizhi"></text>
<text>{{ nearestStore.distance > 1 ? nearestStore.distance + 'km' : nearestStore.distance * 1000 + 'm' }}</text> <text>{{ currentStore.distance > 1 ? currentStore.distance + 'km' : currentStore.distance * 1000 + 'm' }}</text>
</view> </view>
</view> </view>
<button type="primary" @click="enterStore">确认进入</button> <button type="primary" @click="closeChooseStorePopup">确认进入</button>
<view class="other-store" @click="chooseOtherStore" v-if="globalStoreConfig && globalStoreConfig.is_allow_change == 1"> <view class="other-store" @click="chooseOtherStore" v-if="globalStoreConfig && globalStoreConfig.is_allow_change == 1">
<text>选择其他门店</text> <text>选择其他门店</text>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
@@ -121,12 +122,34 @@
</view> </view>
</uni-popup> </uni-popup>
</view> </view>
<hover-nav></hover-nav> <!-- 连锁门店未开启定位或定位失败弹框 -->
<view @touchmove.prevent.stop class="chain-stores">
<uni-popup ref="getLocationFailRef" type="bottom" :maskClick="false" class="choose-store">
<view class="chain-store-popup">
<view class="title">获取位置失败</view>
<view class="body">
<view class="center">
<view class="image">
<image width="341rpx" :src="$util.img('public/uniapp/index/no_location_tips.png')" mode="aspectFit"/>
</view>
<view class="text-top">系统暂时定位不到您的位置</view>
<view class="text-bottom" v-if="mapConfig.wap_is_open == 1">请确认定位服务已经打开或者您可手动选择附近的门店以便我们提供更精确的服务</view>
<view class="text-bottom" v-else>请手动选择附近的门店以便我们提供更精确的服务</view>
<view class="footer">
<button :type="mapConfig.wap_is_open == 1?'default':'primary'" @click="chooseStore">选择门店</button>
<button v-if="mapConfig.wap_is_open == 1" type="primary" class="btn-right" @click="openSetting">开启定位</button>
</view>
</view>
</view>
</view>
</uni-popup>
</view>
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 --> <!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup> <privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif --> <!-- #endif -->
<to-top v-if="showTop" @toTop="scrollToTopNative()"></to-top> <to-top v-if="showTop" @toTop="scrollToTopNative()"></to-top>
<ns-login ref="login"></ns-login> <ns-login ref="login"></ns-login>
</view> </view>
</template> </template>
@@ -136,8 +159,8 @@
import nsNavbar from '@/components/ns-navbar/ns-navbar.vue'; import nsNavbar from '@/components/ns-navbar/ns-navbar.vue';
import diyJs from '@/common/js/diy.js'; import diyJs from '@/common/js/diy.js';
import indexJs from './public/js/index.js'; import indexJs from './public/js/index.js';
import toTop from '@/components/toTop/toTop.vue'; import toTop from '@/components/toTop/toTop.vue';
import scroll from '@/common/js/scroll-view.js'; import scroll from '@/common/js/scroll-view.js';
export default { export default {
@@ -250,6 +273,14 @@
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important; max-height: unset !important;
} }
/deep/ .chain-stores .uni-popup__mask{
backdrop-filter: blur(10rpx);
}
/deep/ .chain-stores .uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box, .uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box{
max-height: 100vh !important;
}
/deep/ .mescroll-totop { /deep/ .mescroll-totop {
right: 24rpx!important; right: 24rpx!important;

View File

@@ -3,7 +3,8 @@ export default {
return { return {
minScrollTop: 100, // 设置回到顶端按钮显示要求,最小页面滚动距离 minScrollTop: 100, // 设置回到顶端按钮显示要求,最小页面滚动距离
wechatQrcode: '', // 公众号二维码 wechatQrcode: '', // 公众号二维码
diyRoute: '/pages/index/index' diyRoute: '/pages/index/index',
refresh:false,
}; };
}, },
onLoad(option) { onLoad(option) {
@@ -41,6 +42,9 @@ export default {
if (this.unsubscribe) this.unsubscribe(); if (this.unsubscribe) this.unsubscribe();
}, },
methods: { methods: {
changeCategoryNav(e){
if(e == 0) this.refresh = !this.refresh;
},
// 关注公众号 // 关注公众号
getFollowQrcode() { getFollowQrcode() {
if (!this.$util.isWeiXin()) return; if (!this.$util.isWeiXin()) return;

View File

@@ -1,127 +1,127 @@
<template> <template>
<page-meta :page-style="themeColor"></page-meta> <page-meta :page-style="themeColor"></page-meta>
<view :style="{ backgroundColor: bgColor, minHeight: openBottomNav ? 'calc(100vh - 55px)' : '' }" class="page-img"> <view :style="{ backgroundColor: bgColor, minHeight: openBottomNav ? 'calc(100vh - 55px)' : '' }" class="page-img">
<view class="page-header" v-if="diyData.global && diyData.global.navBarSwitch" :style="{ backgroundImage: bgImg }"> <view class="page-header" v-if="diyData.global && diyData.global.navBarSwitch" :style="{ backgroundImage: bgImg }">
<ns-navbar :title-color="textNavColor" :data="diyData.global" :scrollTop="scrollTop" :isBack="true"/> <ns-navbar :title-color="textNavColor" :data="diyData.global" :scrollTop="scrollTop" :isBack="false"/>
</view> </view>
<diy-index-page v-if="topIndexValue" ref="indexPage" :value="topIndexValue" :bgUrl="bgUrl" :scrollTop="scrollTop" :diyGlobal="diyData.global" class="diy-index-page"> <diy-index-page v-if="topIndexValue" ref="indexPage" :value="topIndexValue" :bgUrl="bgUrl" :scrollTop="scrollTop" :diyGlobal="diyData.global" class="diy-index-page">
<diy-group ref="diyGroup" v-if="diyData.value" :diyData="diyData" :scrollTop="scrollTop" :haveTopCategory="true"/> <diy-group ref="diyGroup" v-if="diyData.value" :diyData="diyData" :scrollTop="scrollTop" :haveTopCategory="true"/>
<ns-copyright v-show="isShowCopyRight"/> <ns-copyright v-show="isShowCopyRight"/>
</diy-index-page> </diy-index-page>
<view v-else class="bg-index" :style="{ backgroundImage: backgroundUrl, paddingTop: paddingTop, marginTop: marginTop }"> <view v-else class="bg-index" :style="{ backgroundImage: backgroundUrl, paddingTop: paddingTop, marginTop: marginTop }">
<diy-group ref="diyGroup" v-if="diyData.value" :diyData="diyData" :scrollTop="scrollTop"/> <diy-group ref="diyGroup" v-if="diyData.value" :diyData="diyData" :scrollTop="scrollTop"/>
<ns-copyright v-show="isShowCopyRight"/> <ns-copyright v-show="isShowCopyRight"/>
<view class="foot"> <view class="foot">
<view class="item" @click="tourl('/pages_tool/agreement/contenr?type=0')">隐私协议</view> <view class="item" @click="tourl('/pages_tool/agreement/contenr?type=0')">隐私协议</view>
<view class="item" @click="tourl('/pages_tool/agreement/contenr?type=1')">注册协议</view> <view class="item" @click="tourl('/pages_tool/agreement/contenr?type=1')">注册协议</view>
</view> </view>
</view> </view>
<template v-if="diyData.global && diyData.global.popWindow && diyData.global.popWindow.count != -1 && diyData.global.popWindow.imageUrl"> <template v-if="diyData.global && diyData.global.popWindow && diyData.global.popWindow.count != -1 && diyData.global.popWindow.imageUrl">
<view @touchmove.prevent.stop> <view @touchmove.prevent.stop>
<uni-popup ref="uniPopupWindow" type="center" class="wap-floating" :maskClick="false"> <uni-popup ref="uniPopupWindow" type="center" class="wap-floating" :maskClick="false">
<view class="image-wrap"> <view class="image-wrap">
<image :src="$util.img(diyData.global.popWindow.imageUrl)" :style="popWindowStyle" @click="uniPopupWindowFn()" mode="aspectFit"/> <image :src="$util.img(diyData.global.popWindow.imageUrl)" :style="popWindowStyle" @click="uniPopupWindowFn()" mode="aspectFit"/>
</view> </view>
<text class="iconfont icon-round-close" @click="closePopupWindow"></text> <text class="iconfont icon-round-close" @click="closePopupWindow"></text>
</uni-popup> </uni-popup>
</view> </view>
</template> </template>
<!-- 底部tabBar --> <!-- 底部tabBar -->
<view id="tab-bar" :class="{ hide: bottomNavHidden }" v-if="openBottomNav"> <view id="tab-bar" :class="{ hide: bottomNavHidden }" v-if="openBottomNav">
<diy-bottom-nav @callback="callback"/> <diy-bottom-nav @callback="callback"/>
</view> </view>
<!-- 收藏 --> <!-- 收藏 -->
<uni-popup ref="collectPopupWindow" type="top" class="wap-floating wap-floating-collect"> <uni-popup ref="collectPopupWindow" type="top" class="wap-floating wap-floating-collect">
<view v-if="showTip" class="collectPopupWindow" :style="{ marginTop: (collectTop + statusBarHeight) * 2 + 'rpx' }"> <view v-if="showTip" class="collectPopupWindow" :style="{ marginTop: (collectTop + statusBarHeight) * 2 + 'rpx' }">
<image :src="$util.img('public/uniapp/index/collect2.png')" mode="aspectFit"/> <image :src="$util.img('public/uniapp/index/collect2.png')" mode="aspectFit"/>
<text @click="closeCollectPopupWindow">我知道了</text> <text @click="closeCollectPopupWindow">我知道了</text>
</view> </view>
</uni-popup> </uni-popup>
<ns-birthday-gift ref="birthdayGift"></ns-birthday-gift> <ns-birthday-gift ref="birthdayGift"></ns-birthday-gift>
<ns-new-gift ref="nsNewGift"></ns-new-gift> <ns-new-gift ref="nsNewGift"></ns-new-gift>
<hover-nav></hover-nav> <hover-nav></hover-nav>
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 --> <!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup> <privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif --> <!-- #endif -->
</view> </view>
</template> </template>
<script> <script>
import uniPopup from '@/components/uni-popup/uni-popup.vue'; import uniPopup from '@/components/uni-popup/uni-popup.vue';
import nsNavbar from '@/components/ns-navbar/ns-navbar.vue'; import nsNavbar from '@/components/ns-navbar/ns-navbar.vue';
import diyJs from '@/common/js/diy.js'; import diyJs from '@/common/js/diy.js';
import indexJs from './public/js/index.js'; import indexJs from './public/js/index.js';
export default { export default {
components: { components: {
uniPopup, uniPopup,
nsNavbar nsNavbar
}, },
mixins: [diyJs, indexJs], mixins: [diyJs, indexJs],
methods:{ methods:{
tourl(url){ tourl(url){
this.$util.redirectTo(url); this.$util.redirectTo(url);
} }
} }
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import '@/common/css/diy.scss'; @import '@/common/css/diy.scss';
.foot{ .foot{
display: flex; display: flex;
// position: absolute; // position: absolute;
width: 100%; width: 100%;
margin-bottom: 40rpx; margin-bottom: 40rpx;
.item{ .item{
width: 50%; width: 50%;
text-align: center; text-align: center;
color:#F4391c color:#F4391c
} }
} }
</style> </style>
<style scoped> <style scoped>
.wap-floating>>>.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { .wap-floating>>>.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: none !important; background: none !important;
} }
/deep/.diy-index-page .uni-popup .uni-popup__wrapper-box { /deep/.diy-index-page .uni-popup .uni-popup__wrapper-box {
border-radius: 0; border-radius: 0;
} }
.choose-store>>>.goodslist-uni-popup-box { .choose-store>>>.goodslist-uni-popup-box {
width: 80%; width: 80%;
} }
/deep/ .placeholder { /deep/ .placeholder {
height: 0; height: 0;
} }
/deep/::-webkit-scrollbar { /deep/::-webkit-scrollbar {
width: 0; width: 0;
height: 0; height: 0;
background-color: transparent; background-color: transparent;
display: none; display: none;
} }
.hide { .hide {
display: none; display: none;
} }
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important; max-height: unset !important;
} }
</style> </style>

View File

@@ -1,95 +1,97 @@
export default { export default {
data() { data() {
return { return {
diyRoute: '/pages/member/index' diyRoute: '/pages/member/index'
}; };
}, },
computed: {}, computed: {},
watch: { watch: {
storeToken: function(nVal, oVal) { storeToken: function(nVal, oVal) {
if (nVal) { if (nVal) {
this.initData(); this.initData();
if (uni.getStorageSync('source_member')) this.$util.onSourceMember(uni.getStorageSync( if (uni.getStorageSync('source_member')) this.$util.onSourceMember(uni.getStorageSync('source_member'));
'source_member')); }
} }
} },
}, onLoad(data) {
onLoad(data) { uni.hideTabBar();
//刷新多语言 this.name = 'DIY_VIEW_MEMBER_INDEX';
this.$langConfig.refresh(); if (data.code) {
this.$api.sendRequest({
uni.hideTabBar(); url: '/wechat/api/wechat/authcodetoopenid',
this.name = 'DIY_VIEW_MEMBER_INDEX'; data: {
if (data.code) { code: data.code
this.$api.sendRequest({ },
url: '/wechat/api/wechat/authcodetoopenid', success: res => {
data: { if (res.code >= 0) {
code: data.code if (res.data.userinfo.nickName) this.modifyNickname(res.data.userinfo.nickName);
}, if (res.data.userinfo.avatarUrl) this.modifyHeadimg(res.data.userinfo.avatarUrl);
success: res => { }
if (res.code >= 0) { }
if (res.data.userinfo.nickName) this.modifyNickname(res.data.userinfo.nickName); });
if (res.data.userinfo.avatarUrl) this.modifyHeadimg(res.data.userinfo }
.avatarUrl); },
} onShow() {
} // 刷新会员数据
}); if (this.$refs.diyGroup) {
} if (this.$refs.diyGroup.$refs.diyMemberIndex) this.$refs.diyGroup.$refs.diyMemberIndex[0].init();
}, if (this.$refs.diyGroup.$refs.diyMemberMyOrder) this.$refs.diyGroup.$refs.diyMemberMyOrder[0].getOrderNum();
onShow() { }
},
// 刷新会员数据 methods: {
if (this.$refs.diyGroup) { /**
if (this.$refs.diyGroup.$refs.diyMemberIndex) this.$refs.diyGroup.$refs.diyMemberIndex[0].init(); * 查询会员信息
if (this.$refs.diyGroup.$refs.diyMemberMyOrder) this.$refs.diyGroup.$refs.diyMemberMyOrder[0].getOrderNum(); */
} initData() {
}, if (this.storeToken) {
methods: { this.$nextTick(() => {
/** let callback = () => {
* 查询会员信息 // 刷新会员数据
*/ if (this.$refs.diyGroup) {
initData() { if (this.$refs.diyGroup.$refs.diyMemberIndex) {
if (this.storeToken) { this.$refs.diyGroup.$refs.diyMemberIndex[0].init();
this.$nextTick(() => { }
this.$refs.nsNewGift.init(); }
this.$refs.birthdayGift.init(); }
}); this.$refs.nsNewGift.init(callback);
} this.$refs.birthdayGift.init(callback);
}, });
/** }
* 修改昵称 },
* @param {Object} nickName /**
*/ * 修改昵称
modifyNickname(nickName) { * @param {Object} nickName
this.$api.sendRequest({ */
url: '/api/member/modifynickname', modifyNickname(nickName) {
data: { this.$api.sendRequest({
nickname: nickName url: '/api/member/modifynickname',
}, data: {
success: res => { nickname: nickName
if (res.code == 0) { },
this.memberInfo.nickname = nickName; success: res => {
this.$store.commit('setMemberInfo', this.memberInfo); if (res.code == 0) {
} this.memberInfo.nickname = nickName;
} this.$store.commit('setMemberInfo', this.memberInfo);
}); }
}, }
/** });
* 修改头像 },
*/ /**
modifyHeadimg(headimg) { * 修改头像
this.$api.sendRequest({ */
url: '/api/member/modifyheadimg', modifyHeadimg(headimg) {
data: { this.$api.sendRequest({
headimg: headimg url: '/api/member/modifyheadimg',
}, data: {
success: res => { headimg: headimg
if (res.code == 0) { },
this.memberInfo.headimg = headimg; success: res => {
this.$store.commit('setMemberInfo', this.memberInfo); if (res.code == 0) {
} this.memberInfo.headimg = headimg;
} this.$store.commit('setMemberInfo', this.memberInfo);
}); }
}, }
}, });
},
},
}; };

View File

@@ -11,12 +11,12 @@
<text v-if="orderData.promotion_status_name">{{ orderData.promotion_status_name }}</text> <text v-if="orderData.promotion_status_name">{{ orderData.promotion_status_name }}</text>
</view> </view>
<view class="desc" v-if="orderData.promotion_type == 'presale' && orderData.order_status == 1"> <view class="desc" v-if="orderData.promotion_type == 'presale' && orderData.order_status == 1">
预计{{ $util.timeStampTurnTime(orderData.predict_delivery_time, true) }}日后发货 预计{{ $util.timeStampTurnTime(orderData.predict_delivery_time, 'Y-m-d') }}发货
</view> </view>
<view class="desc" v-if="orderData.close_cause">订单关闭原因{{ orderData.close_cause }}</view> <view class="desc" v-if="orderData.close_cause">订单关闭原因{{ orderData.close_cause }}</view>
</view> </view>
</view> </view>
<view class="order-time" v-if="orderData.order_status == 0" id="action-date"> <view class="order-time" v-if="orderData.order_status == 0 && orderData.pay_type != 'offlinepay'" id="action-date">
剩余时间 剩余时间
<uni-count-down :day="orderData.closeTimeMachine.d" :hour="orderData.closeTimeMachine.h" <uni-count-down :day="orderData.closeTimeMachine.d" :hour="orderData.closeTimeMachine.h"
:minute="orderData.closeTimeMachine.i" :second="orderData.closeTimeMachine.s" color="#fff" :minute="orderData.closeTimeMachine.i" :second="orderData.closeTimeMachine.s" color="#fff"
@@ -42,7 +42,7 @@
<view class="font-size-base">送达时间</view> <view class="font-size-base">送达时间</view>
<view class="last-child">{{ orderData.buyer_ask_delivery_time }}</view> <view class="last-child">{{ orderData.buyer_ask_delivery_time }}</view>
</view> </view>
<block v-if="orderData.package_list"> <block v-if="orderData.package_list.deliverer">
<view class="pick-block"> <view class="pick-block">
<view>配送员</view> <view>配送员</view>
<view class="last-child">{{ orderData.package_list.deliverer }}</view> <view class="last-child">{{ orderData.package_list.deliverer }}</view>
@@ -133,6 +133,10 @@
{{ i < goodsItem.sku_spec_format.length - 1 ? '; ' : '' }} {{ i < goodsItem.sku_spec_format.length - 1 ? '; ' : '' }}
</block> </block>
</view> </view>
<view class="goods-num">
<text class="iconfont icon-close"></text>
<text>{{ goodsItem.num }}</text>
</view>
</view> </view>
<view class="goods-sub-section"> <view class="goods-sub-section">
<view> <view>
@@ -142,11 +146,9 @@
<text class="unit price-style small">.{{ parseFloat(goodsItem.price).toFixed(2).split('.')[1] }}</text> <text class="unit price-style small">.{{ parseFloat(goodsItem.price).toFixed(2).split('.')[1] }}</text>
</text> </text>
</view> </view>
<view> <view v-if="orderData.order_type == 1 && orderData.order_status == 1 && goodsItem.delivery_status == 1"
<text class="font-size-base"> class="delivery-status color-base-text">
<text class="iconfont icon-close"></text> {{goodsItem.delivery_status_name}}
{{ goodsItem.num }}
</text>
</view> </view>
</view> </view>
<view v-if="goodsItem.card_item_id" class="goods-card"> <view v-if="goodsItem.card_item_id" class="goods-card">
@@ -176,15 +178,11 @@
</view> </view>
<view class="goods-action"> <view class="goods-action">
<block v-if="orderData.is_enable_refund"> <view class="order-box-btn" @click="goRefund(goodsItem.order_goods_id)" v-if="orderData.is_enable_refund && orderData.order_scene == 'online' && goodsItem.refund_status == 0 && orderData.promotion_type != 'blindbox'">
<view @click="goRefund(goodsItem.order_goods_id)" v-if="orderData.order_scene == 'online' && (goodsItem.refund_status == 0 || goodsItem.refund_status == -1)"> {{ orderData.order_status == 10 ? '申请售后' : '申请退款' }}
<view class="order-box-btn" v-if="orderData.promotion_type != 'blindbox'"> </view>
{{ orderData.order_status == 10 ? '申请售后' : '申请退款' }} <view class="order-box-btn" @click="goRefundDetail(goodsItem.order_goods_id)" v-if="goodsItem.refund_status != 0">
</view> {{ goodsItem.refund_status_name }}
</view>
</block>
<view @click="goRefundDetail(goodsItem.order_goods_id)" v-if="goodsItem.refund_status != 0 && goodsItem.refund_status != -1">
<view class="order-box-btn">{{ orderData.order_status == 10 ? '查看售后' : '查看退款' }}</view>
</view> </view>
</view> </view>
</view> </view>
@@ -319,15 +317,36 @@
<view class="box"><text class="color-base-text" @click="$util.redirectTo('/pages_promotion/cardservice/card/my_card')">查看</text></view> <view class="box"><text class="color-base-text" @click="$util.redirectTo('/pages_promotion/cardservice/card/my_card')">查看</text></view>
</view> </view>
</block> </block>
<block v-if="orderData.pay_type=='offlinepay' && orderData.offline_pay_info">
<view class="hr"></view>
<view class="order-cell">
<text class="tit">支付方式</text>
<view class="box">
<text class="color-title">线下支付</text>
</view>
</view>
<view class="order-cell">
<text class="tit">支付状态</text>
<view class="box">
<text class="color-title">{{orderData.offline_pay_info.status_info.name}}</text>
</view>
</view>
<view class="order-cell remark" v-if="orderData.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
<text class="tit">审核备注</text>
<view class="box">
<text class="color-title">{{orderData.offline_pay_info.audit_remark}}</text>
</view>
</view>
</block>
<!-- 联系客服 --> <!-- 联系客服 -->
<!-- <ns-contact :niushop="{ order_id: orderData.order_id }"> <ns-contact :niushop="{ order_id: orderData.order_id }">
<view class="kefu"> <view class="kefu">
<view> <view>
<text class="iconfont icon-ziyuan"></text> <text class="iconfont icon-ziyuan"></text>
<text>联系客服</text> <text>联系客服</text>
</view> </view>
</view> </view>
</ns-contact> --> </ns-contact>
</view> </view>
<block v-if="orderData.virtual_goods && orderData.goods_class == 2 && orderData.virtual_goods.is_veirfy == 0"> <block v-if="orderData.virtual_goods && orderData.goods_class == 2 && orderData.virtual_goods.is_veirfy == 0">
@@ -362,7 +381,7 @@
</view> </view>
</view> </view>
</view> </view>
<view class="verify-info-wrap"> <view class="verify-info-wrap">
<view class="head">核销记录</view> <view class="head">核销记录</view>
<view v-if="orderData.virtual_goods.verify_record.length"> <view v-if="orderData.virtual_goods.verify_record.length">
@@ -598,8 +617,7 @@
</view> </view>
<!-- 订单 --> <!-- 订单 -->
<view class="fixed-bottom-box bottom-safe-area" v-if="orderData.action.length > 0 || (orderData.is_evaluate == 1 && evaluateConfig.evaluate_status == 1)"> <view class="fixed-bottom-box bottom-safe-area" v-if="orderData.action.length > 0 || (orderData.is_evaluate == 1 && evaluateConfig.evaluate_status == 1)"></view>
</view>
<ns-goods-recommend ref="goodrecommend" route="order_detail"></ns-goods-recommend> <ns-goods-recommend ref="goodrecommend" route="order_detail"></ns-goods-recommend>
<!-- 选择支付方式弹窗 --> <!-- 选择支付方式弹窗 -->
@@ -646,6 +664,12 @@
if (option.order_id) this.orderId = option.order_id; if (option.order_id) this.orderId = option.order_id;
if (option.merchant_trade_no) this.merchantTradeNo = option.merchant_trade_no; if (option.merchant_trade_no) this.merchantTradeNo = option.merchant_trade_no;
}, },
onPullDownRefresh() {
this.getOrderData();
setTimeout(function () {
uni.stopPullDownRefresh();
}, 50);
},
onShow() { onShow() {
this.isIphoneX = this.$util.uniappIsIPhoneX(); this.isIphoneX = this.$util.uniappIsIPhoneX();
@@ -657,6 +681,7 @@
back: '/pages/order/detail?order_id=' + this.orderId + '&merchant_trade_no=' + this.merchantTradeNo back: '/pages/order/detail?order_id=' + this.orderId + '&merchant_trade_no=' + this.merchantTradeNo
}); });
} }
if(this.$refs.choosePaymentPopup) this.$refs.choosePaymentPopup.pageShow()
}, },
methods: { methods: {
goDetail(e) { goDetail(e) {
@@ -733,11 +758,20 @@
/** /**
* 下拉刷新 * 下拉刷新
*/ */
onPullDownRefresh() {
this.getOrderData();
},
operation(action) { operation(action) {
switch (action) { switch (action) {
case 'orderDelete':
this.orderDelete(this.orderData.order_id, () => {
setTimeout(()=>{
if (getCurrentPages().length == 1) {
this.$util.redirectTo('/pages/member/index')
} else {
uni.navigateBack();
}
},500)
});
break;
case 'orderPay': // 支付 case 'orderPay': // 支付
this.orderPay(this.orderData); this.orderPay(this.orderData);
break; break;
@@ -772,6 +806,11 @@
this.getOrderData(); this.getOrderData();
}); });
break; break;
case 'orderOfflinePay':
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
outTradeNo: this.orderData.out_trade_no
});
break;
} }
}, },
imageError(index) { imageError(index) {

View File

@@ -80,14 +80,14 @@
</view> </view>
</view> </view>
<!-- 联系客服 --> <!-- 联系客服 -->
<!-- <ns-contact :niushop="{ order_id: orderData.order_id }"> <ns-contact :niushop="{ order_id: orderData.order_id }">
<view class="kefu"> <view class="kefu">
<view> <view>
<text class="iconfont icon-ziyuan"></text> <text class="iconfont icon-ziyuan"></text>
<text>联系客服</text> <text>联系客服</text>
</view> </view>
</view> </view>
</ns-contact> --> </ns-contact>
</view> </view>
<!-- 订单金额 --> <!-- 订单金额 -->
@@ -127,8 +127,7 @@
<ns-goods-recommend ref="goodrecommend" route="order_detail"></ns-goods-recommend> <ns-goods-recommend ref="goodrecommend" route="order_detail"></ns-goods-recommend>
<!-- 选择支付方式弹窗 --> <!-- 选择支付方式弹窗 -->
<ns-payment ref="choosePaymentPopup" :payMoney="orderData.order_money" <ns-payment ref="choosePaymentPopup" :payMoney="orderData.order_money" @confirm="orderPay(orderData)"></ns-payment>
@confirm="orderPay(orderData)"></ns-payment>
<loading-cover ref="loadingCover"></loading-cover> <loading-cover ref="loadingCover"></loading-cover>
</view> </view>
</template> </template>

View File

@@ -1,7 +1,7 @@
<template> <template>
<page-meta :page-style="themeColor"></page-meta> <page-meta :page-style="themeColor"></page-meta>
<view class="order-container"> <view class="order-container">
<view class="cate-search"> <view class="cate-search" v-if="storeToken">
<view class="search-box"> <view class="search-box">
<input class="uni-input" maxlength="50" v-model="searchText" confirm-type="search" placeholder="请输入商品名称/订单编号" @confirm="search()" /> <input class="uni-input" maxlength="50" v-model="searchText" confirm-type="search" placeholder="请输入商品名称/订单编号" @confirm="search()" />
<text class="iconfont icon-sousuo3" @click="search()"></text> <text class="iconfont icon-sousuo3" @click="search()"></text>
@@ -18,137 +18,138 @@
<!-- #ifdef MP --> <!-- #ifdef MP -->
<mescroll-uni ref="mescroll" @getData="getListData" top="176rpx" v-if="storeToken"> <mescroll-uni ref="mescroll" @getData="getListData" top="176rpx" v-if="storeToken">
<!-- #endif --> <!-- #endif -->
<!-- #ifndef MP --> <!-- #ifndef MP -->
<mescroll-uni ref="mescroll" @getData="getListData" top="196rpx" v-if="storeToken"> <mescroll-uni ref="mescroll" @getData="getListData" top="196rpx" v-if="storeToken">
<!-- #endif --> <!-- #endif -->
<block slot="list"> <block slot="list">
<view class="order-list" v-if="orderList.length > 0"> <view class="order-list" v-if="orderList.length > 0">
<view class="order-item" v-for="(orderItem, orderIndex) in orderList" :key="orderIndex"> <view class="order-item" v-for="(orderItem, orderIndex) in orderList" :key="orderIndex">
<view class="order-header" :class="{ waitpay: orderStatus == 'waitpay' && orderItem.order_status == 0 }"> <view class="order-header" :class="{ waitpay: orderStatus == 'waitpay' && orderItem.order_status == 0 }">
<!-- <view class="iconfont" <!-- <view class="iconfont"
:class="$util.inArray(orderItem.order_id, mergePayOrder) == -1 ? 'icon-yuan_checkbox' : 'icon-yuan_checked color-base-text'" :class="$util.inArray(orderItem.order_id, mergePayOrder) == -1 ? 'icon-yuan_checkbox' : 'icon-yuan_checked color-base-text'"
@click="selectOrder(orderItem.order_id, orderItem.pay_money)" @click="selectOrder(orderItem.order_id, orderItem.pay_money)"
v-if="orderStatus == 'waitpay' && orderItem.order_status == 0"></view> --> v-if="orderStatus == 'waitpay' && orderItem.order_status == 0"></view> -->
<text class="order-no">订单号{{ orderItem.order_no }}</text> <text class="order-no">订单号{{ orderItem.order_no }}</text>
<text class="order-type-name">{{ orderItem.order_type_name }}</text> <text class="order-type-name">{{ orderItem.order_type_name }}</text>
<text class="status-name">{{ orderItem.order_status_name }}</text> <text class="status-name">{{ orderItem.order_status_name }}</text>
</view> </view>
<view class="order-body" @click="orderDetail(orderItem)"> <view class="order-body" @click="orderDetail(orderItem)">
<block v-if="orderItem.order_goods.length == 1"> <block v-if="orderItem.order_goods.length == 1">
<view class="goods-wrap" v-for="(goodsItem, goodsIndex) in orderItem.order_goods" :key="goodsIndex"> <view class="goods-wrap" v-for="(goodsItem, goodsIndex) in orderItem.order_goods" :key="goodsIndex">
<view class="goods-img"> <view class="goods-img">
<image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(orderIndex, goodsIndex)" mode="aspectFill" :lazy-load="true"/> <image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(orderIndex, goodsIndex)" mode="aspectFill" :lazy-load="true"/>
</view> </view>
<view class="goods-info"> <view class="goods-info">
<view class="pro-info"> <view class="pro-info">
<view class="goods-name" v-if="goodsItem.goods_class == 2">{{ goodsItem.goods_name }}</view> <view class="goods-name" v-if="goodsItem.goods_class == 2">{{ goodsItem.goods_name }}</view>
<view class="goods-name" v-else>{{ goodsItem.sku_name }}</view> <view class="goods-name" v-else>{{ goodsItem.sku_name }}</view>
<view class="sku" v-if="goodsItem.sku_spec_format"> <view class="sku" v-if="goodsItem.sku_spec_format">
<view class="goods-spec"> <view class="goods-spec">
<block v-for="(x, i) in goodsItem.sku_spec_format" :key="i"> <block v-for="(x, i) in goodsItem.sku_spec_format" :key="i">
{{ x.spec_value_name }} {{ x.spec_value_name }}
{{ i < goodsItem.sku_spec_format.length - 1 ? '; ' : '' }} {{ i < goodsItem.sku_spec_format.length - 1 ? '; ' : '' }}
</block> </block>
</view>
</view> </view>
</view> </view>
<!-- <view class="goods-sub-section">
<text class="goods-price">
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
<text class="price-style large">{{ parseFloat(goodsItem.price).toFixed(2).split(".")[0] }}</text>
<text class="unit price-style small">.{{ parseFloat(goodsItem.price).toFixed(2).split(".")[1] }}</text>
</text>
<text class="goods-num">
<text class="iconfont icon-close"></text>
{{ goodsItem.num }}
</text>
</view> -->
<view class="goods-action"><!-- <view class="action-btn">加购物车</view> -->
</view>
</view> </view>
</view> <!-- <view class="goods-sub-section">
</block> <text class="goods-price">
<block v-else> <text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
<view class="multi-order-goods"> <text class="price-style large">{{ parseFloat(goodsItem.price).toFixed(2).split(".")[0] }}</text>
<scroll-view scroll-x="true" class="scroll-view"> <text class="unit price-style small">.{{ parseFloat(goodsItem.price).toFixed(2).split(".")[1] }}</text>
<view class="goods-wrap">
<view class="goods-img" v-for="(goodsItem, goodsIndex) in orderItem.order_goods" :key="goodsIndex">
<image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(orderIndex, goodsIndex)" mode="aspectFill" :lazy-load="true"/>
</view>
</view>
</scroll-view>
<view class="shade">
<image :src="$util.img('public/uniapp/order/order-shade.png')"></image>
</view>
</view>
</block>
</view>
<view class="order-footer">
<view class="order-base-info">
<view class="total">
<text class="font-size-sub">{{ orderItem.goods_num }}件商品</text>
<text class="align-right font-size-base">
实付款
<text class="font-size-base price-font">{{ $lang('common.currencySymbol') }}{{ orderItem.order_money }}</text>
</text> </text>
<text class="goods-num">
<text class="iconfont icon-close"></text>
{{ goodsItem.num }}
</text>
</view> -->
<view class="goods-action"><!-- <view class="action-btn">加购物车</view> -->
</view>
</view> </view>
</view> </view>
<view class="order-action" v-if="orderItem.action.length > 0"> </block>
<view class="order-time" v-if="orderItem.order_status == 0" id="action-date"> <block v-else>
<image :src="$util.img('public/uniapp/order/time.png')"></image> <view class="multi-order-goods">
剩余时间 <scroll-view scroll-x="true" class="scroll-view">
<uni-count-down :day="orderItem.discountTimeMachine.d" <view class="goods-wrap">
:hour="orderItem.discountTimeMachine.h" <view class="goods-img" v-for="(goodsItem, goodsIndex) in orderItem.order_goods" :key="goodsIndex">
:minute="orderItem.discountTimeMachine.i" <image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(orderIndex, goodsIndex)" mode="aspectFill" :lazy-load="true"/>
:second="orderItem.discountTimeMachine.s" color="#FF4644" </view>
splitorColor="#FF4644" /> </view>
</view> </scroll-view>
<view class="order-box-btn" <view class="shade">
v-if="evaluateConfig.evaluate_status == 1 && orderItem.is_evaluate == 1" <image :src="$util.img('public/uniapp/order/order-shade.png')"></image>
@click="operation('memberOrderEvaluation', orderItem)">
<text v-if="orderItem.evaluate_status == 0">评价</text>
<text v-else-if="orderItem.evaluate_status == 1">追评</text>
</view>
<view class="order-box-btn"
:class="{ 'color-base-border color-base-bg': operationItem.action == 'orderPay' }"
v-for="(operationItem, operationIndex) in orderItem.action"
:key="operationIndex" @click="operation(operationItem.action, orderItem)">
{{ operationItem.title }}
</view> </view>
</view> </view>
<view class="order-action" v-else-if="orderItem.action.length == 0 && orderItem.is_evaluate == 1 && evaluateConfig.evaluate_status == 1"> </block>
<view class="order-box-btn" v-if="orderItem.is_evaluate == 1" @click="operation('memberOrderEvaluation', orderItem)"> </view>
<text v-if="orderItem.evaluate_status == 0">评价</text> <view class="order-footer">
<text v-else-if="orderItem.evaluate_status == 1">追评</text> <view class="order-base-info">
</view> <view class="total">
<text class="font-size-sub">{{ orderItem.goods_num }}件商品</text>
<text class="align-right font-size-base">
实付款
<text class="font-size-base price-font">{{ $lang('common.currencySymbol') }}{{ orderItem.order_money }}</text>
</text>
</view> </view>
<view class="order-action" v-else> </view>
<view class="order-box-btn" @click="orderDetail(orderItem)">查看详情</view> <view class="order-action" v-if="orderItem.action.length > 0">
<view class="order-time" v-if="orderItem.order_status == 0 && orderItem.pay_type !== 'offlinepay'" id="action-date">
<image :src="$util.img('public/uniapp/order/time.png')"></image>
剩余时间
<uni-count-down :day="orderItem.discountTimeMachine.d"
:hour="orderItem.discountTimeMachine.h"
:minute="orderItem.discountTimeMachine.i"
:second="orderItem.discountTimeMachine.s" color="#FF4644"
splitorColor="#FF4644" />
</view> </view>
<view class="order-box-btn"
v-if="evaluateConfig.evaluate_status == 1 && orderItem.is_evaluate == 1"
@click="operation('memberOrderEvaluation', orderItem)">
<text v-if="orderItem.evaluate_status == 0">评价</text>
<text v-else-if="orderItem.evaluate_status == 1">追评</text>
</view>
<view class="order-box-btn"
:class="{ 'color-base-border color-base-bg': operationItem.action == 'orderPay' }"
v-for="(operationItem, operationIndex) in orderItem.action"
:key="operationIndex" @click="operation(operationItem.action, orderItem)">
{{ operationItem.title }}
</view>
</view>
<view class="order-action" v-else-if="orderItem.action.length == 0 && orderItem.is_evaluate == 1 && evaluateConfig.evaluate_status == 1">
<view class="order-box-btn" v-if="orderItem.is_evaluate == 1" @click="operation('memberOrderEvaluation', orderItem)">
<text v-if="orderItem.evaluate_status == 0">评价</text>
<text v-else-if="orderItem.evaluate_status == 1">追评</text>
</view>
</view>
<view class="order-action" v-else>
<view class="order-box-btn" @click="orderDetail(orderItem)">查看详情</view>
</view> </view>
</view> </view>
</view> </view>
<view v-else><ns-empty :isIndex="false" :text="$lang('emptyTips')"></ns-empty></view> </view>
</block> <view v-else><ns-empty :isIndex="false" :text="$lang('emptyTips')"></ns-empty></view>
</mescroll-uni> </block>
</mescroll-uni>
<view v-if="!storeToken" class="no-login">
<view><ns-empty :isIndex="false" :text="$lang('emptyTips')"></ns-empty></view>
<button type="primary" size="mini" class="button mini" @click="toLogin">去登录</button>
</view>
<!-- <view class="order-batch-action" :class="{ 'bottom-safe-area': isIphoneX }" v-if="mergePayOrder.length"> <!-- 选择支付方式弹窗 -->
<view class="action-btn color-base-text color-base-border" @click="mergePay()">合并付款</view> <payment ref="choosePaymentPopup"></payment>
</view> -->
<!-- 选择支付方式弹窗 --> <ns-login ref="login"></ns-login>
<ns-payment ref="choosePaymentPopup"></ns-payment> <loading-cover ref="loadingCover"></loading-cover>
<ns-payment ref="choosePaymentMergePopup"></ns-payment>
<ns-login ref="login"></ns-login>
<loading-cover ref="loadingCover"></loading-cover>
</view> </view>
</template> </template>
<script> <script>
import orderMethod from './public/js/orderMethod.js'; import orderMethod from './public/js/orderMethod.js';
import nsPayment from '@/components/payment/payment.vue'; import payment from '@/components/payment/payment.vue';
export default { export default {
data() { data() {
@@ -176,7 +177,7 @@
}; };
}, },
components: { components: {
nsPayment payment
}, },
mixins: [orderMethod], mixins: [orderMethod],
onLoad(option) { onLoad(option) {
@@ -192,14 +193,19 @@
if (this.$refs.mescroll) this.$refs.mescroll.refresh(); if (this.$refs.mescroll) this.$refs.mescroll.refresh();
} else { } else {
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.login.open('/pages/order/list?status=' + this.orderStatus); if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
// this.$refs.login.open('/pages/order/list?status=' + this.orderStatus);
}) })
} }
if(this.$refs.choosePaymentPopup) this.$refs.choosePaymentPopup.pageShow()
}, },
onUnload() { onUnload() {
if (!this.storeToken && this.$refs.login) this.$refs.login.cancelCompleteInfo(); if (!this.storeToken && this.$refs.login) this.$refs.login.cancelCompleteInfo();
}, },
methods: { methods: {
toLogin() {
this.$refs.login.open();
},
ontabtap(e) { ontabtap(e) {
let index = e.target.dataset.current || e.currentTarget.dataset.current; let index = e.target.dataset.current || e.currentTarget.dataset.current;
this.orderStatus = this.statusList[index].status; this.orderStatus = this.statusList[index].status;
@@ -208,7 +214,7 @@
this.$refs.mescroll.refresh(); this.$refs.mescroll.refresh();
}, },
getListData(mescroll) { getListData(mescroll) {
this.$api.sendRequest({ this.$api.sendRequest({
url: '/api/order/lists', url: '/api/order/lists',
data: { data: {
@@ -268,39 +274,39 @@
getOrderStatus() { getOrderStatus() {
this.statusList = [{ this.statusList = [{
status: 'all', status: 'all',
name:'全部', name: this.$lang('all'),
id: 'status_0' id: 'status_0'
}, },
{ {
status: 'waitpay', status: 'waitpay',
name: '待付款', name: this.$lang('waitPay'),
id: 'status_1' id: 'status_1'
}, },
{ {
status: 'waitsend', status: 'waitsend',
name: '待发货', name: this.$lang('readyDelivery'),
id: 'status_2' id: 'status_2'
}, },
{ {
status: 'waitconfirm', status: 'waitconfirm',
name: '待收货', name: this.$lang('waitDelivery'),
id: 'status_3' id: 'status_3'
}, },
{ {
status: 'waitrate',
name: '已完成',
id: 'status_4'
},
/*{
status: 'wait_use', status: 'wait_use',
name: '待使用', name: this.$lang('waitUse'),
id: 'status_4' id: 'status_4'
}*/ }
]; ];
}, },
operation(action, orderData) { operation(action, orderData) {
let index = this.status; let index = this.status;
switch (action) { switch (action) {
case 'orderDelete':
this.orderDelete(orderData.order_id, () => {
this.$refs.mescroll.refresh();
});
break;
case 'orderPay': // 支付 case 'orderPay': // 支付
this.orderData = orderData; this.orderData = orderData;
this.payMoney = parseFloat(orderData.pay_money); this.payMoney = parseFloat(orderData.pay_money);
@@ -339,34 +345,18 @@
this.$refs.mescroll.refresh(); this.$refs.mescroll.refresh();
}); });
break; break;
case 'orderOfflinePay':
this.orderData = orderData;
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
outTradeNo: this.orderData.out_trade_no
});
break;
} }
}, },
orderDetail(data) { orderDetail(data) {
switch (parseInt(data.order_type)) { this.$util.redirectTo('/pages/order/detail', {
case 2: order_id: data.order_id
// 自提订单 });
this.$util.redirectTo('/pages/order/detail_pickup', {
order_id: data.order_id
});
break;
case 3:
// 本地配送订单
this.$util.redirectTo('/pages/order/detail_local_delivery', {
order_id: data.order_id
});
break;
case 4:
// 虚拟订单
this.$util.redirectTo('/pages_tool/order/detail_virtual', {
order_id: data.order_id
});
break;
default:
this.$util.redirectTo('/pages/order/detail', {
order_id: data.order_id
});
break;
}
}, },
/** /**
* 选择订单 * 选择订单
@@ -381,28 +371,6 @@
this.mergePayOrder.push(orderId); this.mergePayOrder.push(orderId);
} }
}, },
/**
* 合并支付
*/
mergePay() {
if (this.mergePayOrder.length) {
this.$api.sendRequest({
url: '/api/order/pay',
data: {
order_ids: this.mergePayOrder.toString()
},
success: res => {
if (res.code >= 0) {
this.$refs.choosePaymentMergePopup.getPayInfo(res.data);
} else {
this.$util.showToast({
title: res.message
});
}
}
});
}
},
imageError(orderIndex, goodsIndex) { imageError(orderIndex, goodsIndex) {
this.orderList[orderIndex].order_goods[goodsIndex].sku_image = this.$util.getDefaultImage().goods; this.orderList[orderIndex].order_goods[goodsIndex].sku_image = this.$util.getDefaultImage().goods;
this.$forceUpdate(); this.$forceUpdate();
@@ -450,4 +418,18 @@
/deep/ .mescroll-upwarp { /deep/ .mescroll-upwarp {
padding-bottom: 100rpx; padding-bottom: 100rpx;
} }
.no-login{
display: flex;
flex-direction: column;
align-items: center;
}
.no-login .button{
width: 300rpx;
margin-top: 100rpx;
height: 70rpx;
line-height: 70rpx !important;
font-size: 28rpx;
border-radius: 50rpx;
}
</style> </style>

View File

@@ -435,7 +435,7 @@ view {
line-height: 1.3; line-height: 1.3;
display: flex; display: flex;
margin-top: 20rpx; margin-top: 20rpx;
align-items: center;
.goods-price { .goods-price {
font-weight: 700; font-weight: 700;
font-size: $font-size-activity-tag; font-size: $font-size-activity-tag;
@@ -525,7 +525,9 @@ view {
align-items: center; align-items: center;
background: #fff; background: #fff;
line-height: 40rpx; line-height: 40rpx;
&.remark{
align-items: flex-start !important;
}
.tit { .tit {
text-align: left; text-align: left;
} }
@@ -847,7 +849,13 @@ view {
white-space: nowrap; white-space: nowrap;
flex: 1; flex: 1;
} }
.goods-num{
font-size: 22rpx;
margin-left: 20rpx;
}
.delivery-status{
line-height: 1.3;
}
.fixed-bottom { .fixed-bottom {
width: 100%; width: 100%;
position: fixed; position: fixed;

View File

@@ -1,5 +1,36 @@
export default { export default {
methods: { methods: {
/**
* 删除订单
* @param {Object} orderData
*/
orderDelete(order_id, callback) {
uni.showModal({
title: '提示',
content: '您确定要删除该订单吗?',
success: res => {
if (res.confirm) {
this.$api.sendRequest({
url: '/api/order/delete',
data: {
order_id
},
success: res => {
if (res.code >= 0) {
this.$util.showToast({title:'删除订单成功'})
typeof callback == 'function' && callback();
} else {
this.$util.showToast({
title: '删除订单失败,' + res.message,
duration: 2000
})
}
}
})
}
}
})
},
/** /**
* 订单支付 * 订单支付
* @param {Object} orderData * @param {Object} orderData
@@ -57,8 +88,7 @@ export default {
typeof callback == 'function' && callback(); typeof callback == 'function' && callback();
} else { } else {
this.$util.showToast({ this.$util.showToast({
title: '当前订单可能存在拼团,维权等操作' + res.message + title: '关闭失败' + res.message,
'不可以关闭哦!',
duration: 2000 duration: 2000
}) })
} }

View File

@@ -0,0 +1,471 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="bargain">
<view class="bargain_top" :style="{ backgroundImage: 'url(' + $util.img('public/uniapp/bargain/bargain_background.png') + ')' }">
<view>{{ goodsDetail ? goodsDetail.browse_num : 0 }}人查看</view>
<view>|</view>
<view>{{ goodsDetail ? goodsDetail.share_num : 0 }}人分享</view>
<view>|</view>
<view>{{ goodsDetail ? goodsDetail.join_num : 0 }}人参与</view>
</view>
<view class="rule-mark-enter" @click="openRulePopup">活动规则</view>
<view class="bargin_content">
<view class="uer_info_base" v-if="launchInfo">
<view class="user_info_img">
<image :src="launchInfo.headimg == '' ? $util.img($util.getDefaultImage().head) : $util.img(launchInfo.headimg)" mode="widthFix"></image>
</view>
<text class="user_info_name">{{ launchInfo.nickname }}</text>
</view>
<!-- 宣传语 -->
<view class="bargin_propaganda" v-if="launchInfo">
<text class="marks"></text>
<text>我发现一件好物快来帮我砍一刀</text>
<text class="marks"></text>
</view>
<!-- 商品 -->
<view class="goods" v-if="goodsDetail">
<view class="goods_img"><image :src="$util.img(goodsDetail.sku_image, { size: 'mid' })" mode="aspectFit"></image></view>
<view class="goods_content" v-if="launchInfo">
<view class="goods_title">{{ goodsDetail.sku_name }}</view>
<view class="goods_price">
<view>
原价
<text class="original_price">{{ $lang('common.currencySymbol') }}{{ launchInfo.price }}</text>
</view>
<view>
最低可砍至
<text class="bottom_price">{{ $lang('common.currencySymbol') }}{{ launchInfo.floor_price }}</text>
</view>
</view>
<view class="partake_num" v-if="launchInfo">
已有
<text class="ident">{{ launchInfo.curr_num }}</text>
人帮砍
<text class="residue-num">
剩余库存
<text class="ident">{{ goodsDetail.bargain_stock }}{{ goodsDetail.unit }}</text>
</text>
</view>
<view v-if="launchInfo && timeMachine && goodsDetail.bargain_status == 1" class="count-down">
<uni-count-down
:day="timeMachine.d"
:hour="timeMachine.h"
:minute="timeMachine.i"
:second="timeMachine.s"
color="#fff"
splitorColor="#333 !important"
backgroundColor="#000"
border-color="transparent"
@timeup="timeUp()"
></uni-count-down>
<text>后结束</text>
</view>
</view>
<view class="goods_content launch" v-else>
<view class="goods_title">{{ goodsDetail.sku_name }}</view>
<view class="goods_price">
<view>
原价
<text class="original_price price-font">
<text class="price-style small">{{ $lang('common.currencySymbol') }}</text>
<text class="price price-style small">{{ parseFloat(goodsDetail.price).toFixed(2).split('.')[0] }}</text>
<text class="price-symbol price-style small">.{{ parseFloat(goodsDetail.price).toFixed(2).split('.')[1] }}</text>
</text>
</view>
<view>
最低可砍至
<text class="bottom_price price-style small">{{ $lang('common.currencySymbol') }}{{ goodsDetail.floor_price }}</text>
</view>
</view>
</view>
</view>
<!-- 进度 -->
<view class="progress">
<view class="progress_item" :style="{ width: (progress > 2 ? progress : 2) + '%' }"><text class="icon-futou iconfont"></text></view>
<view class="progress-point"></view>
</view>
<view class="info-bottom" v-if="goodsDetail">
<view class="price-box" v-if="launchInfo">
<view class="discount-price">
已砍
<text class="price price-font">
{{ $lang('common.currencySymbol') }}{{ parseFloat(parseFloat(launchInfo.price) - parseFloat(launchInfo.curr_price)).toFixed(2) }}
</text>
</view>
<view class="delete-price ">
还剩
<text class="price price-font">
{{ $lang('common.currencySymbol')
}}{{
parseFloat(
parseFloat(launchInfo.price) - parseFloat(launchInfo.floor_price) - (parseFloat(launchInfo.price) - parseFloat(launchInfo.curr_price))
).toFixed(2)
}}
</text>
</view>
</view>
<view class="price-box" v-else>
<view class="discount-price">
已砍
<text class="price price-font">{{ $lang('common.currencySymbol') }}0</text>
</view>
<view class="delete-price ">
还剩
<text class="price price-font">
{{ $lang('common.currencySymbol') }} {{ parseFloat(parseFloat(goodsDetail.price) - parseFloat(goodsDetail.floor_price)).toFixed(2) }}
</text>
</view>
</view>
<view class="pro-info" v-if="!parseFloat(goodsDetail.floor_price)"><view class="button-border">免费拿</view></view>
</view>
<!-- 邀请新用户 -->
<view class="invitation_peo" v-if="launchInfo">
<!-- <view class="tip">邀请新用户砍掉金额更多哦~</view> -->
<block v-if="launchInfo.self">
<view class="bargain-success" v-if="launchInfo.status == 1">
<text class="iconfont icon-kanjiachenggong"></text>
<text>恭喜您砍价成功快去支付吧</text>
</view>
<view class="bargain-success" v-if="launchInfo.status == 2">
<text class="iconfont icon-biaoqing_nanguo"></text>
<text v-if="launchInfo.buy_type == 0 && launchInfo.order_id == 0">很遗憾未能砍至最低价可立即支付带走您心仪的宝贝</text>
<text v-else-if="launchInfo.buy_type == 0 && launchInfo.order_id > 0">很遗憾未能砍至最低价</text>
<text v-else>很遗憾砍价未成单</text>
</view>
<view class="launch-success" v-if="launchInfo.status == 2 && launchInfo.buy_type == 0 && launchInfo.order_id > 0">恭喜您通过立即支付带走您心仪的宝贝</view>
</block>
<block v-if="goodsDetail.bargain_status == 1">
<view v-if="launchInfo.self" class="flex-box" :class="{ success: launchInfo.status == 1 }">
<block v-if="launchInfo.status != 1 && (goodsDetail.bargain_status != 1 || goodsDetail.bargain_stock == 0)">
<block v-if="goodsDetail.bargain_status != 1">
<button class="btn-vice disabled">活动已结束</button>
<button class="btn" @click="$util.redirectTo('/pages_promotion/bargain/list')">更多砍价商品</button>
</block>
<block v-else-if="goodsDetail.bargain_stock == 0">
<button class="btn-vice disabled">已售罄</button>
<button class="btn" @click="$util.redirectTo('/pages_promotion/bargain/list')">更多砍价商品</button>
</block>
</block>
<block v-else>
<block v-if="launchInfo.status == 0">
<button class="btn-vice" v-if="launchInfo.buy_type == 0" @click="buyNow">不砍了直接买</button>
<button class="btn" @click="openSharePopup">喊好友砍一刀</button>
</block>
<block v-if="launchInfo.status == 1">
<button class="btn" @click="buyNow" v-if="launchInfo.order_id == 0">立即支付</button>
<button class="btn" v-if="launchInfo.order_id > 0" @click="$util.redirectTo('/pages/order/detail', { order_id: launchInfo.order_id })">
查看订单
</button>
<button class="btn-vice" @click="$util.redirectTo('/pages/index/index')">低价拿更多商品</button>
</block>
<block v-if="launchInfo.status == 2">
<button class="btn" v-if="launchInfo.order_id > 0" @click="$util.redirectTo('/pages/order/detail', { order_id: launchInfo.order_id })">
查看订单
</button>
<button class="btn" @click="$util.redirectTo('/pages/index/index')">低价拿更多商品</button>
</block>
</block>
</view>
<view v-else class="flex-box">
<block v-if="launchInfo.status == 0">
<button class="btn" @click="bargain" v-if="!launchInfo.cut">帮好友砍一刀</button>
<button class="btn-vice" @click="$util.redirectTo('/pages_promotion/bargain/list')" v-else>我也要低价拿</button>
</block>
<button v-else class="btn" @click="$util.redirectTo('/pages_promotion/bargain/list')">我也要低价拿</button>
</view>
</block>
<block v-else>
<view class="flex-box success">
<button class="btn" v-if="launchInfo.self && launchInfo.order_id > 0" @click="$util.redirectTo('/pages/order/detail', { order_id: launchInfo.order_id })">
查看订单
</button>
<button class="btn-vice disabled">活动已结束</button>
</view>
</block>
</view>
<view class="invitation_peo" v-else>
<view class="flex-box">
<button class="btn" v-if="goodsDetail && goodsDetail.bargain_status == 1" @click="createBargain()">立即参与砍价</button>
<button class="btn-vice disabled" v-else>活动已结束</button>
</view>
</view>
</view>
<view class="bargin_introduction" v-if="launchInfo">
<view class="bargin_introduction_title">帮砍记录</view>
<view class="bargin_introduction_content">
<view class="bargin_invitation" v-if="bargainRecord.length">
<view class="item" v-for="(item, index) in bargainRecord" :key="index">
<view class="item_left">
<image :src="item.headimg == '' ? $util.img($util.getDefaultImage().head) : $util.img(item.headimg)"></image>
<view class="bargin_info">
<view>{{ item.nickname[0] }}*{{ item.nickname[item.nickname.length - 1] }}</view>
<view>{{ $util.timeStampTurnTime(item.bargain_time) }}</view>
</view>
</view>
<view class="item_right">
<image :src="$util.img('public/uniapp/bargain/bargain-icon.png')" class="bargain-icon"></image>
帮砍
<text>{{ item.money }}</text>
</view>
</view>
<view class="item_more" v-if="showMore" @click="scrolltolower()">加载更多</view>
</view>
<view v-else class="record-empty">现在还没有砍价记录</view>
</view>
</view>
<view class="bargin_introduction">
<view class="bargin_introduction_title">砍价流程</view>
<view class="bargin_introduction_content">
<view class="flow">
<view class="flow_item">
<image :src="$util.img('public/uniapp/bargain/bargain_kanjia.png')"></image>
<view>发起商品砍价</view>
</view>
<view class="flow_item">
<image :src="$util.img('public/uniapp/bargain/bargain_friend.png')"></image>
<view>邀请好友砍价达要求</view>
</view>
<view class="flow_item">
<image :src="$util.img('public/uniapp/bargain/bargain_good.png')"></image>
<view>领取商品带回家</view>
</view>
</view>
</view>
</view>
<view class="bargin_introduction" v-if="launchList && launchList.length > 0">
<view class="bargin_introduction_title">砍成晒单</view>
<view class="bargin_introduction_content">
<view class="bargain-list">
<swiper vertical="true" autoplay="true" interval="3000" :display-multiple-items="showNum" :circular="true" :class="'swiper-' + launchList.length">
<swiper-item v-for="(item, index) in launchList" :key="index">
<view class="bargain-item">
<view>
<view class="bargain-head"><image :src="item.headimg == '' ? $util.img($util.getDefaultImage().head) : $util.img(item.headimg)"></image></view>
<view class="bargain-info">
<view class="bargain-title">{{ item.nickname[0] }}*{{ item.nickname[item.nickname.length - 1] }}</view>
<view class="bargain-desc">{{ $util.timeStampTurnTime(item.end_time) }}</view>
</view>
</view>
<view class="bargain-price">
成功砍至
<text>{{ parseFloat(item.curr_price).toFixed(2) }}</text>
</view>
</view>
</swiper-item>
</swiper>
</view>
</view>
</view>
<view class="bargin_introduction">
<view class="bargin_introduction_title">商品详情</view>
<view class="bargin_introduction_content">
<view class="detail-content">
<view class="goods-details" v-if="goodsDetail && goodsDetail.goods_content">
<ns-mp-html :content="goodsDetail.goods_content"></ns-mp-html>
</view>
<view class="goods-details active" v-else>该商家暂无上传相关详情哦</view>
</view>
</view>
</view>
<ns-goods-sku
ref="goodsSku"
v-if="goodsDetail"
@refresh="refreshGoodsSkuDetail"
:goods-id="goodsDetail.goods_id"
:goods-detail="goodsDetail"
:maxBuy="maxBuy"
></ns-goods-sku>
<!-- 帮砍弹出 -->
<uni-popup ref="uniHelpPopup" type="center" :maskClick="false">
<view class="bargain-popup self help">
<image :src="$util.img('public/uniapp/bargain/bargain-pop-1.png')" mode="widthFix" class="head"></image>
<view class="bargain-content">
<view class="uer_info_base" v-if="launchInfo">
<view class="user_info_img">
<image :src="launchInfo.headimg == '' ? $util.img($util.getDefaultImage().head) : $util.img(launchInfo.headimg)" mode="widthFix"></image>
</view>
<text class="user_info_name">{{ launchInfo.nickname }}</text>
</view>
<view v-if="goodsDetail && launchInfo && timeMachine && goodsDetail.bargain_status == 1" class="count-down">
<text>还剩</text>
<uni-count-down
:day="timeMachine.d"
:hour="timeMachine.h"
:minute="timeMachine.i"
:second="timeMachine.s"
color="#fff"
splitorColor="#333 !important"
backgroundColor="#000"
border-color="transparent"
@timeup="timeUp()"
></uni-count-down>
<text>结束</text>
</view>
</view>
<button class="bargain-btn" type="primary" @click="bargain()">帮他砍价</button>
</view>
<text class="iconfont icon-round-close" @click="$refs.uniHelpPopup.close()"></text>
</uni-popup>
<!-- 帮砍成功 -->
<uni-popup ref="uniPopup" type="center" :maskClick="false">
<view class="bargain-popup self">
<image :src="$util.img('public/uniapp/bargain/bargain-pop-2.png')" mode="widthFix" class="head"></image>
<view class="bargain-content">
<text>您已帮砍</text>
<text class="money color-base-text">{{ bargainMoney }}</text>
<text>您也可以参与砍价快去挑选心仪的宝贝吧~~~</text>
</view>
<button class="bargain-btn" type="primary" @click="$util.redirectTo('/pages_promotion/bargain/list')">我也要参与</button>
</view>
<text class="iconfont icon-round-close" @click="closePopup"></text>
</uni-popup>
<!-- 自砍一刀展示 -->
<uni-popup ref="uniSelfBargainPopup" type="center" :maskClick="false">
<view class="bargain-popup self">
<image :src="$util.img('public/uniapp/bargain/bargain-pop-2.png')" mode="widthFix" class="head"></image>
<view class="bargain-content">
<text>您已砍掉</text>
<text class="money color-base-text">{{ my_bargain_money }}</text>
<text>听说分享次数越多砍价成功的机会越大哦</text>
</view>
<button class="bargain-btn" type="primary" @click="openSharePopup">邀请好友帮砍价</button>
</view>
<text class="iconfont icon-round-close" @click="closeSelfPop"></text>
</uni-popup>
<!-- 分享弹窗 -->
<view @touchmove.prevent.stop>
<uni-popup ref="sharePopup" type="bottom" class="share-popup">
<view>
<view class="share-title">分享</view>
<view class="share-content">
<!-- #ifdef MP -->
<view class="share-box">
<button class="share-btn" :plain="true" open-type="share">
<view class="iconfont icon-share-friend"></view>
<text>分享给好友</text>
</button>
</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="share-box" @click="copyUrl">
<button class="share-btn" :plain="true">
<view class="iconfont icon-fuzhilianjie"></view>
<text>复制链接</text>
</button>
</view>
<!-- #endif -->
<view class="share-box" @click="openPosterPopup">
<button class="share-btn" :plain="true">
<view class="iconfont icon-pengyouquan"></view>
<text>生成分享海报</text>
</button>
</view>
</view>
<view class="share-footer" @click="closeSharePopup"><text>取消分享</text></view>
</view>
</uni-popup>
</view>
<!-- 海报 -->
<view @touchmove.prevent.stop class="poster-layer">
<uni-popup ref="posterPopup" type="center">
<template v-if="poster != '-1'">
<view class="poster-wrap">
<view class="image-wrap">
<image :src="$util.img(poster)" :show-menu-by-longpress="true" mode="widthFix" />
<view class="close iconfont icon-close" @click="closePosterPopup()"></view>
</view>
<!-- #ifdef MP || APP-PLUS -->
<view class="save-btn" @click="saveGoodsPoster()">保存图片</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="save-btn">长按图片进行保存</view>
<!-- #endif -->
</view>
</template>
</uni-popup>
</view>
<!-- 悬浮按钮 -->
<hover-nav :need="true"></hover-nav>
<!-- 活动规则 -->
<uni-popup ref="rulePopup" type="center" :maskClick="false">
<view class="rule-wrap">
<view class="content-wrap">
<image :src="$util.img('public/uniapp/common/promotion_rule_head.png')" mode="widthFix" class="rule-head"></image>
<scroll-view scroll-y="true" class="rule">
<view class="text" v-if="goodsDetail && goodsDetail.remark != ''">{{ goodsDetail.remark }}</view>
</scroll-view>
<text class="iconfont icon-round-close" @click="closeRulePopup"></text>
</view>
</view>
</uni-popup>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
import LTime from '@/pages_promotion/components/l-time/l-time.vue';
import uniPopup from '@/components/uni-popup/uni-popup.vue';
import goodsSku from '@/components/ns-goods-sku/ns-goods-sku.vue';
import detail from './public/js/detail.js';
export default {
components: {
LTime,
goodsSku,
uniPopup
},
mixins: [detail]
};
</script>
<style lang="scss">
@import './public/css/detail.scss';
</style>
<style scoped>
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important;
}
/deep/.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
overflow-y: unset;
background: none !important;
}
.detail-content >>> img {
max-width: 100% !important;
}
.detail-content >>> image {
max-width: 100% !important;
}
/deep/.uni-countdown__number {
padding: 0 4rpx;
line-height: 36rpx;
height: 36rpx;
}
/deep/ .uni-countdown__splitor.day {
line-height: 36rpx;
}
</style>

View File

@@ -0,0 +1,357 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="page" :style="{ background: bgColor }">
<mescroll-uni @getData="getData" ref="mescroll" :size="10" v-if="addonIsExist.bargain">
<block slot="list">
<ns-adv keyword="NS_BARGAIN" class-name="adv-wrap"></ns-adv>
<block v-if="dataList.length > 0 || dataListing.length > 0">
<view class="goods-list single-column" v-if="dataListing.length">
<view class="goods-item margin-bottom" v-for="(item, index) in dataListing" :key="index">
<view class="goods-item-content">
<view class="goods-img" @click="toDetailP(item)">
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"/>
<view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }}</view>
</view>
<view class="info-wrap">
<view class="name-wrap">
<view class="goods-name" @click="toDetailP(item)">{{ item.goods_name }}</view>
<text class="info-sub-title">已有{{ item.join_num }}人参与</text>
<view class="progress-wrap">
<progress percent="20" :show-info="false" stroke-width="8"
backgroundColor="#FFF4F4" :activeColor="themeStyle.main_color"
border-radius="6" :percent="progressP(item)" />
<view class="progress-point"></view>
<view class="progress-select icon"
:style="{ left: 'calc(' + progressP(item) + '% - 16rpx)' }">
<text class="iconfont icon-futou"></text>
</view>
</view>
</view>
<view class="info-bottom">
<view class="price-box">
<view class="discount-price">已砍<text class="price price-font">{{ (item.price - item.curr_price).toFixed(2) }}</text></view>
<view class="delete-price ">还剩<text class="price price-font">{{ $lang('common.currencySymbol') }}{{ (item.curr_price - item.floor_price).toFixed(2) }}</text></view>
</view>
<view class="pro-info">
<view class="button-border">免费拿</view>
</view>
</view>
</view>
</view>
<view class="goods-item-bottom">
<view class="item-bottom-left">
<uni-count-down :day="item.time.d" :hour="item.time.h" :minute="item.time.i" :second="item.time.s" color="#fff" borderColor="none" splitorColor="#303133" backgroundColor="#303133" />
<view class="color-sub txt">后结束</view>
</view>
<view class="item-bottom-right">
<button type="primary" @click="toDetailP(item)" size="mini" class="mini">继续砍价</button>
</view>
</view>
</view>
</view>
<view class="goods-list single-column" v-if="dataList.length">
<view class="goods-item margin-bottom" v-for="(item, index) in dataList" :key="index">
<view class="goods-item-content">
<view class="goods-img" @click="toDetail(item)">
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"/>
<view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }}</view>
</view>
<view class="info-wrap">
<view class="name-wrap">
<view class="goods-name" @click="toDetail(item)">{{ item.sku_name }}</view>
<text class="info-sub-title">已有{{ item.join_num }}人参与</text>
<view class="progress-wrap"><progress percent="20" :show-info="false" stroke-width="8" backgroundColor="#FFF4F4" :activeColor="themeStyle.main_color" border-radius="6" :percent="progress(item)" />
<view class="progress-point"></view>
<view class="progress-select icon" :style="{ left: 'calc(' + progress(item) + '% - 8rpx)' }">
<text class="iconfont icon-futou"></text>
</view>
</view>
</view>
<view class="info-bottom">
<view class="sale-box price-font">已砍{{ item.sale_num }}</view>
<view class="pro-info">
<view class="button-border">免费拿</view>
</view>
</view>
</view>
</view>
<view class="goods-item-bottom">
<view class="item-bottom-left">
<view class="txt">底价</view>
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
<text class="price price-style large">{{ parseFloat(item.floor_price).toFixed(2).split('.')[0] }}</text>
<text class="unit price-style large">.{{ parseFloat(item.floor_price).toFixed(2).split('.')[1] }}</text>
<view class="delete-pirce">{{ $lang('common.currencySymbol') }}{{ item.price }}</view>
</view>
<view class="item-bottom-right">
<button type="primary" @click="toDetail(item)" size="mini" class="mini">去砍价</button>
</view>
</view>
</view>
</view>
</block>
<ns-empty v-else-if="isLoad && isLoading" textColor="#fff" :isIndex="false" text="暂无砍价商品"></ns-empty>
</block>
</mescroll-uni>
<!-- 悬浮按钮 -->
<hover-nav></hover-nav>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
import uniCountDown from '@/components/uni-count-down/uni-count-down.vue';
export default {
components: {
uniCountDown
},
data() {
return {
dataList: [],
dataListing: [],
isLoading: false,
isLoad: false,
skuId: 0,
mpShareData: null, //小程序分享数据
progressBorder: '10',
bgColor: ''
};
},
onLoad(option) {
//小程序分享接收source_member
if (option.source_member) {
uni.setStorageSync('source_member', option.source_member);
}
// 小程序扫码进入接收source_member
if (option.scene) {
var sceneParams = decodeURIComponent(option.scene);
sceneParams = sceneParams.split('&');
if (sceneParams.length) {
sceneParams.forEach(item => {
if (item.indexOf('sku_id') != -1) this.skuId = item.split('-')[1];
if (item.indexOf('m') != -1) uni.setStorageSync('source_member', item.split('-')[1]);
if (item.indexOf('is_test') != -1) uni.setStorageSync('is_test', 1);
});
}
}
},
async onShow() {
setTimeout( () => {
if (!this.addonIsExist.bargain) {
this.$util.showToast({
title: '商家未开启砍价',
mask: true,
duration: 2000
});
setTimeout(() => {
this.$util.redirectTo('/pages/index/index');
}, 2000);
}
},1000);
//记录分享关系
if (this.storeToken && uni.getStorageSync('source_member')) {
this.$util.onSourceMember(uni.getStorageSync('source_member'));
}
//小程序分享
// #ifdef MP-WEIXIN
this.$util.getMpShare().then(res => {
this.mpShareData = res;
});
// #endif
await this.getZoneConfig();
if (this.$refs.mescroll) this.$refs.mescroll.refresh();
this.getDataing();
},
//分享给好友
onShareAppMessage() {
return this.mpShareData.appMessage;
},
//分享到朋友圈
onShareTimeline() {
return this.mpShareData.timeLine;
},
methods: {
// 活动页面配置
async getZoneConfig() {
let res = await this.$api.sendRequest({
url: '/api/config/promotionZoneConfig',
data: {
name: 'bargain'
},
async: false
});
let data = res.data;
if (data) {
this.bgColor = data.bg_color;
}
},
getData(mescroll) {
this.$api.sendRequest({
url: '/bargain/api/goods/page',
data: {
page_size: mescroll.size,
page: mescroll.num,
is_exclude_bargaining: 1
},
success: res => {
let newArr = [];
let msg = res.message;
if (res.code == 0 && res.data) {
newArr = res.data.list;
} else {
this.$util.showToast({
title: msg
});
}
if (mescroll.endSuccess) mescroll.endSuccess(newArr.length);
//设置列表数据
if (mescroll.num == 1) this.dataList = []; //如果是第一页需手动制空列表
this.dataList = this.dataList.concat(newArr); //追加新数据
this.isLoad = true;
this.$forceUpdate();
setTimeout(() => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}, 300);
},
fail() {
//联网失败的回调
if (mescroll.endErr) mescroll.endErr();
setTimeout(() => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}, 300);
}
});
},
getDataing() {
this.$api.sendRequest({
url: '/bargain/api/goods/bargainingList',
data: {},
success: res => {
this.dataListing = res.data;
for (var index in res.data) {
this.dataListing[index].time = this.$util.countDown(res.data[index].end_time - res.timestamp);
}
this.isLoading = true;
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail() {
//联网失败的回调
mescroll.endErr();
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
toDetail(e) {
this.$util.redirectTo('/pages_promotion/bargain/detail', {
b_id: e.bargain_id
});
},
toDetailP(e) {
this.$util.redirectTo('/pages_promotion/bargain/detail', {
b_id: e.bargain_id,
l_id: e.launch_id
});
},
imgError(index) {
this.dataList[index].goods_image = this.$util.getDefaultImage().goods;
this.$forceUpdate();
},
goodsImg(imgStr) {
let imgs = imgStr.split(',');
return imgs[0] ? this.$util.img(imgs[0], {
size: 'mid'
}) : this.$util.getDefaultImage().goods;
},
progress(data) {
let progress = ((parseInt(data.sale_num) / (parseInt(data.bargain_stock) + parseInt(data.sale_num))) * 100).toFixed();
if (progress == 'NaN') {
progress = 0;
}
return progress;
},
progressP(data) {
let progress = (((parseFloat(data.price) - parseFloat(data.curr_price)) / parseFloat(data.price)) * 100).toFixed();
if (progress == 'NaN') {
progress = 0;
}
return progress;
},
goodsTag(data) {
return data.label_name || '';
}
},
onHide() {
if (this.$refs.loadingCover) this.$refs.loadingCover.show();
}
};
</script>
<style lang="scss">
@import './public/css/list.scss';
</style>
<style lang="scss" scoped>
/deep/ .fixed {
position: relative;
top: 0;
}
/deep/ .empty {
margin-top: 0 !important;
}
.clockrun {
.delete-price {
max-width: 60%;
}
}
/deep/ .uni-countdown__number {
min-width: 32rpx;
height: 32rpx;
text-align: center;
line-height: 32rpx;
border-radius: 4px;
display: inline-block;
padding: 4rpx;
margin: 0;
border: none !important;
}
/deep/ .uni-countdown__splitor {
width: 10rpx;
height: 32rpx;
line-height: 36rpx;
text-align: center;
display: inline-block;
}
/deep/ .uni-countdown__splitor.day {
width: initial;
}
</style>
<style>
.progress-wrap>>>.uni-progress .uni-progress-bar {
border-radius: 16rpx;
overflow: hidden;
}
.progress-wrap>>>.uni-progress-bar .uni-progress-inner-bar {
background: linear-gradient(to left, var(--bargain-promotion-color), var(--bargain-promotion-aux-color)) !important;
}
</style>

View File

@@ -0,0 +1,432 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view>
<view class="my_spell_category" v-if="storeToken">
<view class="category-item" v-for="(item, index) in statusList" :key="index" @click="categoryChange(item.id)">
<view class="item-con" :class="item.id == status ? 'active color-base-text color-base-bg-before' : ''">{{ item.name }}</view>
</view>
</view>
<mescroll-uni @getData="getData" top="90" ref="mescroll" :size="10" v-if="storeToken">
<block slot="list">
<view class="goods-list" v-for="(item, index) in dataList" :key="index">
<view class="goods-item-content" @click="goBargainDetail(item)">
<view class="goods-item-state">
<text class="state-time">发起砍价 {{ $util.timeStampTurnTime(item.start_time) }}</text>
<text class="state-sign" :style="{ color: bargainState[item.status].color }">{{ bargainState[item.status].text }}</text>
</view>
<view class="goods-item-wrap">
<view class="image-wrap">
<image :src="$util.img(item.sku_image,{'size':'mid'})" mode="aspectFit" @error="imageError(index)"></image>
</view>
<view class="content">
<view class="title">{{ item.sku_name }}</view>
<text class="residue-price color-base-text">已砍至{{ item.curr_price }}</text>
<view class="price-box">
<text class="original-price" v-if="item.status">{{ $lang('common.currencySymbol') }}{{ item.price }}</text>
<view class="time" v-if="item.timeMachine && item.status == 0">
<uni-count-down :day="item.timeMachine.d" :hour="item.timeMachine.h"
:minute="item.timeMachine.i" :second="item.timeMachine.s" color="#fff"
splitorColor="#000 !important" backgroundColorClass="color-base-bg"
border-color="transparent" />
<text class="end-txt">后结束</text>
</view>
</view>
</view>
</view>
</view>
<view class="goods-item-action">
<view class="invitation-bargain">
<image :src="recordItem.headimg == '' ? $util.img($util.getDefaultImage().head) : $util.img(recordItem.headimg)" v-for="(recordItem, recordIndex) in item.bargain_record" :key="recordIndex" @error="memberImageError(index, recordIndex)"/>
<text class="invitation-bargain-end color-base-text color-base-border" v-if="item.status == 0">+</text>
<text class="invitation-bargain-end color-base-text color-base-border " v-else>
<text class="icon-ellipsis iconfont"></text>
</text>
</view>
<button class="btn" type="default" v-if="item.status == 0 && item.bargain_status == 1" @click="goBargainDetail(item)">继续砍价</button>
<block v-if="item.status == 1 && item.bargain_status == 1">
<button class="btn" type="default" v-if="item.order_id == 0" @click="goBargainDetail(item)">购买商品</button>
<button class="btn" type="default" v-else @click="goBargainDetail(item)">查看详情</button>
</block>
<button class="btn" type="default" v-if="item.status == 2 && item.bargain_status == 1" @click="$util.redirectTo('/pages_promotion/bargain/list')">重新砍价</button>
</view>
</view>
<ns-empty v-if="dataList.length == 0" :isIndex="true" :emptyBtn="{url: '/pages_promotion/bargain/list',text: '去逛逛'}" text="暂无砍价订单"></ns-empty>
</block>
</mescroll-uni>
<ns-login ref="login"></ns-login>
<loading-cover ref="loadingCover"></loading-cover>
</view>
</template>
<script>
import uniCountDown from '@/components/uni-count-down/uni-count-down.vue';
export default {
components: {
uniCountDown
},
data() {
return {
mescroll: null,
dataList: [],
statusList: [{
id: 'all',
name: '全部'
},
{
id: 0,
name: '正在砍价'
},
{
id: 1,
name: '砍价成功'
},
{
id: 2,
name: '砍价失败'
}
],
status: 'all',
bargainState: [{
color: '#FFA044',
text: '正在砍价'
},
{
color: '#11BD64',
text: '砍价成功'
},
{
color: '#FF4544',
text: '砍价失败'
}
],
};
},
onShow() {
setTimeout( () => {
if (!this.addonIsExist.bargain) {
this.$util.showToast({
title: '商家未开启砍价',
mask: true,
duration: 2000
});
setTimeout(() => {
this.$util.redirectTo('/pages/index/index');
}, 2000);
}
},1000);
if (!this.storeToken) {
this.$nextTick(() => {
this.$refs.login.open('/pages_promotion/bargain/my_bargain');
});
}
},
methods: {
//请求列表数据
getData(mescroll) {
this.mescroll = mescroll;
this.$api.sendRequest({
url: '/bargain/api/bargain/launchPage',
data: {
page_size: mescroll.size,
page: mescroll.num,
status: this.status
},
success: res => {
let newArr = [];
let msg = res.message;
if (res.code == 0 && res.data) {
newArr = res.data.list;
} else {
this.$util.showToast({
title: msg
});
}
mescroll.endSuccess(newArr.length);
//设置列表数据
if (mescroll.num == 1) this.dataList = []; //如果是第一页需手动制空列表
newArr.forEach(v => {
if (v.end_time > res.timestamp) {
v.timeMachine = this.$util.countDown(v.end_time - res.timestamp);
} else {
v.timeMachine = null;
}
});
this.dataList = this.dataList.concat(newArr); //追加新数据
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail() {
//联网失败的回调
mescroll.endErr();
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
//砍价详情
goBargainDetail(data) {
this.$util.redirectTo('/pages_promotion/bargain/detail', {
l_id: data.launch_id,
b_id: data.bargain_id
});
},
//切换分类
categoryChange(e) {
this.status = e;
this.mescroll.resetUpScroll();
},
imageError(index) {
this.dataList[index].sku_image = this.$util.getDefaultImage().goods;
this.$forceUpdate();
},
memberImageError(index, j) {
this.dataList[index].bargain_record[j].headimg = this.$util.getDefaultImage().head;
this.$forceUpdate();
}
},
onBackPress(options) {
if (options.from === 'navigateBack') {
return false;
}
this.$util.redirectTo('/pages/member/index');
return true;
},
watch: {
storeToken: function(nVal, oVal) {
if (nVal) {
this.$refs.mescroll.refresh();
}
}
}
};
</script>
<style lang="scss">
.my_spell_category {
width: 100%;
height: 88rpx;
display: flex;
justify-content: space-around;
background: #fff;
position: fixed;
top: 0;
z-index: 999;
box-sizing: border-box;
.category-item {
width: 130rpx;
text-align: center;
.item-con {
display: inline-block;
height: 88rpx;
font-size: 30rpx;
position: relative;
line-height: 88rpx;
}
.item-con.active:after {
content: '';
display: block;
width: 100%;
height: 4rpx;
border-radius: 6rpx;
position: absolute;
left: 0;
bottom: 0;
}
&:last-of-type {
margin-right: 0;
}
}
}
.goods-list {
margin: 20rpx 30rpx 20rpx;
background-color: #fff;
border-radius: 10rpx;
height: 358rpx;
padding: 30rpx;
}
.goods-list .goods-item-content {
background-color: #fff;
border-radius: 10rpx;
box-sizing: border-box;
.goods-item-state {
display: flex;
align-items: center;
justify-content: space-between;
.state-time {
font-size: $font-size-base;
color: $color-title;
}
.state-sign {
font-size: $font-size-tag;
}
}
.goods-item-wrap {
display: flex;
margin-top: 42rpx;
}
.image-wrap {
display: flex;
align-items: center;
justify-content: center;
width: 170rpx;
height: 170rpx;
margin-right: 18rpx;
border-radius: 10rpx;
overflow: hidden;
image {
width: 170rpx;
height: 170rpx;
}
}
.content {
flex: 1;
position: relative;
line-height: 1;
width: calc(100% - 220rpx);
.title {
margin-top: -8rpx;
height: 84rpx;
font-size: $font-size-base;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 42rpx;
color: $color-title;
}
.residue-price {
display: inline-block;
margin-top: 16rpx;
font-size: $font-size-sub;
padding: 2rpx 4rpx;
}
.price-box {
position: absolute;
bottom: 0;
line-height: 1.6;
font-size: $font-size-tag;
width: 100%;
.original-price {
color: $color-tip;
font-size: $font-size-tag;
text-decoration: line-through;
}
.time {
display: flex;
align-items: center;
margin-bottom: -12rpx;
font-size: $font-size-goods-tag;
.uni-countdown {
display: flex;
align-items: center;
}
.end-txt {
font-size: $font-size-base;
margin-left: 10rpx;
}
}
}
}
}
.goods-list .goods-item-action {
display: flex;
align-items: center;
justify-content: space-between;
height: 120rpx;
box-sizing: border-box;
.invitation-bargain {
display: flex;
flex-flow: wrap;
width: 510rpx;
image {
border: 2rpx solid #fff;
}
image,
.invitation-bargain-end {
margin-right: -24rpx;
width: 50rpx;
height: 50rpx;
border-radius: 50%;
border: 2rpx solid #fff;
}
.invitation-bargain-end {
display: flex;
align-items: center;
justify-content: center;
border: 2rpx dashed;
font-size: 24rpx;
background-color: #fff;
z-index: 999;
}
}
.btn {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
padding: 0;
width: 130rpx;
height: 60rpx;
line-height: 1;
font-size: $font-size-tag;
border-radius: 60rpx;
border-color: #999999;
&.fail {
background-color: #aaa;
}
}
}
</style>
<style scoped>
>>>.uni-countdown__number,
>>>.uni-countdown__splitor {
margin: 0;
padding: 0;
}
.time>>>.uni-countdown__number {
min-width: 28rpx;
height: 28rpx;
text-align: center;
line-height: 28rpx;
background: #000;
border-radius: 4px;
display: inline-block;
padding: 4rpx;
margin: 0;
border: none;
}
.time>>>.uni-countdown__splitor {
margin: 0 4rpx;
}
</style>

View File

@@ -0,0 +1,52 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view>
<common-payment :api="api" create-data-key="bargainOrderCreateData" ref="payment"></common-payment>
</view>
</template>
<script>
export default {
data() {
return {
api: {
payment: '/bargain/api/ordercreate/payment',
calculate: '/bargain/api/ordercreate/calculate',
create: '/bargain/api/ordercreate/create'
}
}
},
provide() {
return {
promotion: this.promotion.bind(this)
}
},
onShow() {
if (this.$refs.payment) this.$refs.payment.pageShow();
},
methods:{
/**
* 处理活动信息 如不需要则留空
*/
promotion(data){
if(data.bargain_info){
return {title: '砍价活动', content: '该商品参与砍价活动'}
}
}
}
};
</script>
<style scoped lang="scss">
/deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: none;
max-height: unset !important;
overflow-y: hidden !important;
}
/deep/ .uni-popup__wrapper {
border-radius: 20rpx 20rpx 0 0;
}
/deep/ .uni-popup {
z-index: 8;
}
</style>

View File

@@ -0,0 +1,989 @@
.bargain {
background-size: cover;
background-repeat: repeat-y;
padding-bottom: 100rpx;
background: var(--bargain-promotion-color);
.bargain_top {
height: 360rpx;
background-size: 100% auto;
background-repeat: no-repeat;
display: flex;
color: #fff;
justify-content: center;
position: relative;
line-height: 1;
view {
color: #fff;
line-height: 50rpx;
height: 50rpx;
display: flex;
align-items: center;
font-size: 24rpx;
margin: 26rpx 2rpx;
}
}
.bargin_content {
background-color: #fff;
border-radius: 20rpx;
margin: 24rpx;
padding-bottom: 60rpx;
padding-top: 30rpx;
margin-top: 0;
.uer_info_base {
display: flex;
position: relative;
padding: 0 0;
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
.user_info_img {
background-color: #fff;
width: 120rpx;
height: 120rpx;
margin-top: -80rpx;
margin-left: 0;
border-radius: 50%;
border: 2px solid #fff;
overflow: hidden;
image {
width: 100%;
height: 100%;
}
}
.user_info_name {
margin-left: 0;
color: $color-tip;
align-self: center;
}
.rule_detail {
position: absolute;
height: 34rpx;
line-height: 34rpx;
padding: 0 12rpx;
font-size: 18rpx;
border: 1px solid;
right: 24rpx;
top: 30rpx;
border-radius: 34rpx;
}
}
.bargin_propaganda {
display: flex;
justify-content: space-between;
margin: 0 27rpx 30rpx;
font-size: 34rpx;
color: #333333;
font-weight: bold;
.marks {
font-size: 60rpx;
line-height: 1;
color: #b0b0b0;
}
}
.goods {
display: flex;
margin-top: 0;
margin-left: 24rpx;
margin-right: 24rpx;
padding: 24rpx;
background-color: #fafafa;
border-radius: 10rpx;
overflow: hidden;
.goods_img {
min-width: 180rpx;
width: 230rpx;
height: 230rpx;
margin-right: 20rpx;
border-radius: 10rpx;
image {
width: 100%;
height: 100%;
}
}
.goods_content {
flex: 1;
overflow: hidden;
.goods_title {
line-height: 1.3;
font-size: 30rpx;
margin-bottom: 10rpx;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -moz-box;
-moz-line-clamp: 2;
-moz-box-orient: vertical;
word-wrap: break-word;
word-break: break-all;
white-space: normal;
height: 78rpx;
}
.goods_price {
display: flex;
> view {
color: #666666;
font-size: 22rpx;
.original_price {
margin-left: 3rpx;
}
.bottom_price {
color: var(--price-color);
margin-left: 3rpx;
}
&:first-child {
margin-right: 10rpx;
}
}
}
.partake_num {
font-size: 22rpx;
color: #666666;
margin-top: 4rpx;
.residue-num {
margin-left: 10rpx;
}
.ident {
color: #fe0b42;
margin: 0 4rpx;
}
}
.count-down {
color: #666666;
margin-top: 6rpx;
text {
margin-left: 16rpx;
}
}
&.launch {
.goods_price {
flex-direction: column;
.original_price {
text-decoration: unset;
color: var(--price-color);
}
}
}
}
}
.progress_info {
display: flex;
justify-content: space-between;
margin: 40rpx 24rpx 0;
> view {
font-size: $font-size-tag;
color: #666666;
text {
color: var(--price-color);
}
}
}
.progress {
position: relative;
margin: 40rpx 35rpx 0;
height: 20rpx;
background-color: #fff4f4;
border-radius: 30rpx;
.progress_item {
width: 5%;
position: absolute;
left: 0;
border-radius: 30rpx;
height: 20rpx;
background: linear-gradient(to left, var(--bargain-promotion-color), var(--bargain-promotion-aux-color));
animation: all 1s forwards;
.iconfont {
position: absolute;
right: -20rpx;
top: -10rpx;
height: 40rpx;
width: 40rpx;
color: #fff;
background-color: var(--bargain-promotion-color);
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
border-radius: 50%;
font-size: 24rpx;
z-index: 1;
}
}
.progress-point {
position: absolute;
background-color: var(--bargain-promotion-color);
height: 26rpx;
width: 26rpx;
border-radius: 50%;
right: -13rpx;
top: -4rpx;
}
}
.info-bottom {
display: flex;
justify-content: space-between;
margin: 10px 12px 0;
align-items: center;
.sale-box {
color: var(--bargain-promotion-color);
}
.price-box {
display: flex;
line-height: 1;
.discount-price {
display: flex;
font-size: 26rpx;
line-height: 1;
margin-top: 4rpx;
.price {
}
}
.delete-price {
display: flex;
font-size: 26rpx;
line-height: 1;
margin-top: 4rpx;
}
.price {
line-height: 1.2;
color: var(--bargain-promotion-color);
}
}
.pro-info {
line-height: 1;
display: flex;
align-items: center;
.button-border {
border: 2rpx solid var(--bargain-promotion-color);
color: var(--bargain-promotion-color);
font-size: 24rpx;
padding: 4rpx 6rpx;
line-height: 1;
border-radius: 4rpx;
background-color: #fff4f4;
position: relative;
border-top-right-radius: 0;
}
.button-border::before {
content: '';
display: block;
position: absolute;
top: -10rpx;
right: -2rpx;
border-left: 10rpx solid transparent;
border-right: 0 solid transparent;
border-bottom: 10rpx solid var(--bargain-promotion-color);
}
.button-border::after {
content: '';
display: block;
position: absolute;
top: -6rpx;
right: 0rpx;
border-left: 10rpx solid transparent;
border-right: 0 solid transparent;
border-bottom: 10rpx solid #fff4f4;
}
}
}
.bragain_recode {
display: flex;
align-items: center;
justify-content: space-between;
margin: 58rpx 24rpx 20rpx;
.bragain_recode_list {
display: flex;
margin: 0 26rpx;
.bragain_recode_add {
margin-left: 44rpx;
}
image {
width: 84rpx;
height: 84rpx;
border: 4rpx solid #fe0b42;
border-radius: 50%;
margin-left: -22rpx;
&:first-child {
margin-left: 0;
}
}
}
.bragain_recode_more {
width: 84rpx;
height: 84rpx;
line-height: 84rpx;
text-align: center;
font-size: 12rpx;
color: #999999;
}
.bragain_recode_add {
width: 84rpx;
height: 84rpx;
line-height: 76rpx;
text-align: center;
border-radius: 50%;
border: 1px dashed #e6e6e6;
font-size: 60rpx;
color: #e6e6e6;
}
}
.bragain_recode_detail {
font-size: 24rpx;
color: #000;
margin: 0 34rpx 0;
.iconfont {
font-size: 24rpx;
color: #333333;
}
}
.invitation_peo {
margin: 28rpx 30rpx 0;
.bargain-success {
display: flex;
align-items: center;
justify-content: center;
font-size: $font-size-tag;
margin: 40rpx 0 0;
.iconfont {
margin-right: 8rpx;
color: rgb(250, 26, 26);
}
> view {
text-align: center;
}
}
.launch-success {
text-align: center;
font-size: $font-size-tag;
}
.tip {
text-align: center;
color: #fe0b42;
font-size: $font-size-goods-tag;
}
.flex-box {
display: flex;
margin-top: 20rpx;
button {
flex: 1;
&:nth-child(2) {
margin-left: 20rpx;
}
}
&.success {
flex-direction: column;
.btn {
margin: 0 !important;
}
.btn-vice {
background-color: #fff;
border: 2rpx solid var(--bargain-promotion-color);
color: var(--bargain-promotion-color);
margin: 0 !important;
margin-top: 20rpx !important;
}
}
}
.btn {
height: 80rpx;
line-height: 80rpx;
background: var(--bargain-promotion-color);
border-radius: $border-radius;
text-align: center;
font-size: 30rpx;
color: #fff;
font-weight: bold;
margin: 20rpx 0;
}
.btn-vice {
height: 80rpx;
line-height: 80rpx;
background: var(--bargain-promotion-aux-color);
border-radius: $border-radius;
text-align: center;
font-size: 30rpx;
color: #fff;
font-weight: bold;
margin: 20rpx 0;
}
}
}
.bargin_introduction {
margin: 24rpx;
background-color: #fff;
border-radius: 20rpx;
.record-empty {
text-align: center;
font-size: $font-size-tag;
color: #999;
padding: 100rpx 0;
background-color: #fff;
border-radius: 20rpx;
}
.bargin_introduction_title {
display: flex;
align-items: center;
justify-content: center;
font-size: 34rpx;
color: #222222;
padding: 36rpx 0 0;
font-weight: bold;
&::before {
content: '';
background-color: #222222;
width: 20rpx;
height: 5rpx;
display: block;
margin-right: 10rpx;
}
&::after {
content: '';
background-color: #222222;
width: 20rpx;
height: 5rpx;
display: block;
margin-left: 10rpx;
}
}
.detail-content {
padding: 20rpx;
overflow: hidden;
* {
max-width: 100%;
}
img {
width: 100%;
}
}
.flow {
display: flex;
background-color: #fff;
border-radius: 20rpx;
padding: 40rpx 0;
.flow_item {
position: relative;
flex: 1;
text-align: center;
image {
width: 88rpx;
height: 88rpx;
margin-bottom: 20rpx;
}
> view {
color: #333333;
font-size: 24rpx;
}
&::after {
position: absolute;
content: '';
height: 2rpx;
width: 100rpx;
background-color: #fd0742;
top: 44rpx;
right: -22%;
}
&:last-child::after {
width: 0;
}
}
}
.bargin_invitation {
background-color: #fff;
border-radius: 20rpx;
padding: 27rpx;
.item {
display: flex;
align-items: center;
padding: 20rpx 0;
border-bottom: 2rpx solid rgba(237, 237, 237, 0.5);
&:last-child {
border-bottom: 0;
}
.item_left {
flex: 1;
display: flex;
overflow: hidden;
align-items: center;
image {
height: 70rpx;
width: 70rpx;
border: 2rpx solid #979797;
border-radius: 50%;
margin-right: 20rpx;
}
> view {
overflow: hidden;
align-items: center;
display: flex;
color: #6d7278;
white-space: nowrap;
/* 不换行 */
text-overflow: ellipsis;
.tip {
font-size: 20rpx;
color: #666666;
}
}
.bargin_info {
display: flex;
flex-direction: column;
justify-content: left;
align-items: flex-start;
> view:last-child {
color: #999999;
font-size: $font-size-tag;
}
}
}
.item_right {
min-width: 100rpx;
color: var(--bargain-promotion-color);
font-size: $font-size-base;
font-weight: bold;
display: flex;
align-items: center;
text {
font-size: $font-size-base;
color: var(--bargain-promotion-color);
font-weight: bold;
}
.bargain-icon {
width: 44rpx;
height: 44rpx;
margin-right: 14rpx;
}
}
}
.item_more {
margin-top: 20rpx;
text-align: center;
font-size: $font-size-tag;
color: #999999;
}
}
.bargain-list {
padding: 40rpx 0;
margin: 0 24rpx;
swiper {
height: 360rpx;
&.swiper-1 {
height: 120rpx;
}
&.swiper-2 {
height: 240rpx;
}
}
.bargain-item {
background-color: #f2f2f2;
display: flex;
align-items: center;
justify-content: space-between;
padding: 16rpx 24rpx;
> view:first-child {
display: flex;
align-items: center;
}
.bargain-head {
width: 60rpx;
height: 60rpx;
margin-right: 20rpx;
border: 2rpx solid #979797;
border-radius: 50%;
overflow: hidden;
image {
width: 100%;
height: 100%;
}
}
.bargain-info {
.bargain-title {
font-size: 24rpx;
color: #333333;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 260rpx;
}
.bargain-desc {
font-size: 22rpx;
color: #6d7278;
}
}
.bargain-price {
text {
color: var(--bargain-promotion-color);
margin-left: 4rpx;
}
}
}
}
}
}
.bargain-popup {
width: 70vw;
background-color: #fff;
position: relative;
box-sizing: border-box;
border-radius: 20rpx;
height: 650rpx;
.head {
width: 55%;
position: absolute;
left: 50%;
top: 0;
transform: translate(-50%, -70%);
}
.title {
text-align: center;
font-size: 38rpx;
margin-top: 40rpx;
}
.money {
text-align: center;
.num {
font-size: 36rpx;
font-weight: 600;
}
.unit {
font-size: 24rpx;
margin-left: 8rpx;
}
}
&.self {
.head {
position: unset;
transform: unset;
top: 0;
left: 0;
width: 100%;
max-height: 350rpx;
}
.bargain-content {
text-align: center;
padding: 60rpx 40rpx;
.money {
font-weight: bold;
}
}
.bargain-btn {
width: max-content;
margin: 0 auto;
font-weight: bold;
padding: 0 60rpx;
background-color: var(--bargain-promotion-color);
color: #ffffff;
}
}
&.help {
.bargain-content {
.uer_info_base {
display: flex;
position: relative;
padding: 0 0;
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
.user_info_img {
background-color: #fff;
width: 120rpx;
height: 120rpx;
margin-top: -240rpx;
margin-left: 0;
border-radius: 50%;
border: 2px solid var(--bargain-promotion-color);
overflow: hidden;
image {
width: 100%;
height: 100%;
}
}
.user_info_name {
margin-left: 0;
align-self: center;
font-size: 30rpx;
font-weight: bold;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 100%;
}
}
.count-down {
> text {
color: #666;
margin: 0 6rpx;
}
}
}
}
}
.icon-round-close {
display: block;
font-size: 60rpx;
color: #ffffff;
text-align: center;
}
.share-popup,
.uni-popup__wrapper-box {
.share-title {
line-height: 60rpx;
font-size: $font-size-toolbar;
padding: 15rpx 0;
text-align: center;
}
.share-content {
display: flex;
display: -webkit-flex;
-webkit-flex-wrap: wrap;
-moz-flex-wrap: wrap;
-ms-flex-wrap: wrap;
-o-flex-wrap: wrap;
flex-wrap: wrap;
padding: 15rpx;
.share-box {
flex: 1;
text-align: center;
.share-btn {
margin: 0;
padding: 0;
border: none;
line-height: 1;
height: auto;
background-color: unset;
text {
margin-top: 20rpx;
font-size: $font-size-tag;
display: block;
color: $color-title;
}
}
.iconfont {
font-size: 80rpx;
line-height: initial;
}
.icon-fuzhilianjie,
.icon-pengyouquan,
.icon-haowuquan,
.icon-share-friend {
color: #07c160;
}
}
}
.share-footer {
height: 90rpx;
line-height: 90rpx;
border-top: 2rpx #f5f5f5 solid;
text-align: center;
color: #666;
}
}
.poster-layer {
/deep/ .uni-popup__wrapper.center {
width: 100vw!important;
height: 100vh!important;
background: none!important;
}
/deep/ .uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
max-width: 100vw!important;
max-height: 100vh!important;
background: none!important;
width: 100vw;
height: 100vh;
}
.poster-wrap {
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
flex-direction: column;
}
.generate-poster {
padding: 40rpx 0;
.iconfont {
font-size: 80rpx;
color: #07c160;
line-height: initial;
}
> view {
text-align: center;
&:last-child {
margin-top: 20rpx;
}
}
}
.image-wrap {
width: 80%;
position: relative;
image {
width: 100%;
line-height: 1;
border-radius: 10rpx;
overflow: hidden;
}
}
.msg {
padding: 40rpx;
}
.save-btn {
text-align: center;
height: 80rpx;
line-height: 80rpx;
background-color: $base-color;
border-radius: 10rpx;
width: 80%;
color: #fff;
margin-top: 30rpx;
}
.save-text {
color: #fff;
margin-top: 10rpx;
}
.close {
position: absolute;
top: 0;
right: 20rpx;
width: 40rpx;
height: 80rpx;
font-size: 50rpx;
color: #999;
}
}
.goods-details img {
max-width: 100%;
}
.rule-mark-enter {
position: absolute;
top: 120rpx;
right: 0;
width: 20rpx;
height: 100rpx;
line-height: 1;
background: #fff4f4;
padding: 10rpx 20rpx 10rpx 20rpx;
border-radius: 20rpx 0 0 20rpx;
color: var(--bargain-promotion-color);
font-size: $font-size-tag;
z-index: 100;
}
.rule-wrap {
border-radius: 10rpx;
background-color: #fff;
width: 80vw;
padding: 12rpx;
box-sizing: border-box;
.content-wrap {
width: 100%;
border-radius: 8rpx;
position: relative;
.rule-head {
width: 100%;
position: absolute;
transform: translateY(-50%);
left: 0;
top: 0;
}
.rule {
max-height: 880rpx;
overflow: hidden;
padding: 80rpx 30rpx 0 30rpx;
box-sizing: border-box;
.text {
font-size: $font-size-sub;
}
}
.icon-round-close {
color: #fff;
text-align: center;
position: absolute;
bottom: -150rpx;
left: 50%;
transform: translateX(-50%);
font-size: 70rpx;
}
}
}

View File

@@ -0,0 +1,243 @@
.page {
width: 100%;
min-height: 100vh;
background: var(--bargain-promotion-color);
}
.adv-wrap {
margin: $margin-updown $margin-both;
width: auto;
}
.lineheight-clear {
line-height: 1 !important;
}
// 商品列表单列样式
.goods-list.single-column {
.goods-item {
padding: 26rpx 26rpx 20rpx;
background: #fff;
margin: $margin-updown $margin-both;
border-radius: 24rpx;
display: flex;
position: relative;
flex-direction: column;
.goods-item-content {
display: flex;
}
.goods-item-bottom {
display: flex;
justify-content: space-between;
margin-top: 10rpx;
line-height: 1;
.item-bottom-left {
display: flex;
align-items: baseline;
margin-top: 10rpx;
.delete-pirce {
text-decoration: line-through;
color: $color-sub;
margin-left: 20rpx;
}
.txt {
margin-left: 10rpx;
font-weight: 26rpx;
}
.unit,
.price {
color: var(--bargain-promotion-color) !important;
}
}
.item-bottom-right {
display: flex;
align-items: center;
font-weight: bold;
button {
color: #fff;
background-color: var(--bargain-promotion-color);
}
}
}
.goods-img {
width: 200rpx;
height: 200rpx;
overflow: hidden;
border-radius: $border-radius;
margin-right: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.goods-tag {
color: #fff;
line-height: 1;
padding: 8rpx 12rpx;
position: absolute;
border-top-left-radius: $border-radius;
border-bottom-right-radius: $border-radius;
top: 26rpx;
left: 26rpx;
font-size: $font-size-goods-tag;
}
.info-wrap {
flex: 1;
display: flex;
flex-direction: column;
width: calc(100% - 220rpx);
.info-sub-title {
color: $color-tip;
font-size: $font-size-tag;
margin-top: 6rpx;
}
}
.info-bottom {
display: flex;
justify-content: space-between;
margin-top: 10rpx;
align-items: center;
.sale-box {
color: var(--bargain-promotion-color);
}
.price-box {
display: flex;
line-height: 1;
.discount-price {
display: flex;
font-size: 26rpx;
line-height: 1;
margin-top: 4rpx;
}
.delete-price {
display: flex;
font-size: 26rpx;
line-height: 1;
margin-top: 4rpx;
}
.price {
line-height: 1.2;
color: var(--bargain-promotion-color);
}
}
.pro-info {
line-height: 1;
display: flex;
align-items: center;
.button-border {
border: 2rpx solid var(--bargain-promotion-color);
color: var(--bargain-promotion-color);
font-size: 24rpx;
padding: 4rpx 6rpx;
line-height: 1;
border-radius: 4rpx;
background-color: var(--bargain-promotion-color-shallow);
position: relative;
border-top-right-radius: 0;
}
.button-border::before {
content: '';
display: block;
position: absolute;
top: -10rpx;
right: -2rpx;
border-left: 10rpx solid transparent;
border-right: 0 solid transparent;
border-bottom: 10rpx solid var(--bargain-promotion-color);
}
.button-border::after {
content: '';
display: block;
position: absolute;
top: -6rpx;
right: 0rpx;
border-left: 10rpx solid transparent;
border-right: 0 solid transparent;
border-bottom: 10rpx solid var(--bargain-promotion-color-shallow);
}
}
}
.name-wrap {
flex: 1;
}
.goods-name {
font-size: $font-size-base;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
font-weight: bold;
word-wrap: break-word;
height: 80rpx;
}
.progress-wrap {
display: flex;
position: relative;
width: calc(100% - 32rpx);
margin: 10rpx auto;
progress {
flex: 1;
}
.progress-point {
background: var(--bargain-promotion-color);
width: 24rpx;
height: 24rpx;
border-radius: 50%;
position: absolute;
right: -12rpx;
top: -4rpx;
z-index: 1;
}
.progress-select {
background-color: var(--bargain-promotion-color);
color: var(--bargain-promotion-aux-color);
width: 24rpx;
height: 24rpx;
border-radius: 50%;
position: absolute;
left: 0;
top: -4rpx;
font-size: 24rpx;
z-index: 11;
&.icon {
width: 34rpx;
height: 34rpx;
display: flex;
align-items: center;
justify-content: center;
top: -10rpx;
}
.iconfont {
background-color: unset;
color: #fff;
font-size: 20rpx;
}
}
.txt {
margin: 0 100rpx 0 20rpx;
}
}
.member-price-tag {
display: inline-block;
width: 60rpx;
line-height: 1;
margin-left: 6rpx;
image {
width: 100%;
}
}
}
}

View File

@@ -0,0 +1,537 @@
import htmlParser from '@/common/js/html-parser';
export default {
data() {
return {
windowHeight: 0,
launch_id: 0,
bargain_id: 0,
info: {
headimg: ''
},
bargainRecord: [],
page: 1,
totalPage: 1,
load: false,
timeMachine: null,
bargainMoney: '0.00',
poster: '-1', //海报
posterMsg: '', //海报错误信息
posterHeight: 0,
goodsDetail: null,
launchInfo: null,
maxBuy: 1,
launchList: null,
showMore: false,
isOwn: 0, //是否自己砍了一刀
my_bargain_money: 0,
shareImg: ''
};
},
onLoad(data) {
setTimeout(() => {
if (!this.addonIsExist.bargain) {
this.$util.showToast({
title: '商家未开启砍价',
mask: true,
duration: 2000
});
setTimeout(() => {
this.$util.redirectTo('/pages/index/index');
}, 2000);
}
}, 1000);
// #ifdef MP-ALIPAY
let options = my.getLaunchOptionsSync();
options.query && Object.assign(data, options.query);
// #endif
this.getHeight();
if (data.l_id) this.launch_id = data.l_id;
if (data.b_id) this.bargain_id = data.b_id;
if (data.is_own) this.isOwn = data.is_own;
if (data.scene) {
var sceneParams = decodeURIComponent(data.scene);
sceneParams = sceneParams.split('&');
if (sceneParams.length) {
sceneParams.forEach(item => {
if (item.indexOf('m') != -1) uni.setStorageSync('source_member', item.split('-')[1]);
if (item.indexOf('l_id') != -1) this.id = item.split('-')[1];
if (item.indexOf('b_id') != -1) this.bargain_id = item.split('-')[1];
if (item.indexOf('is_own') != -1) this.isOwn = item.split('-')[1];
});
}
}
// #ifdef MP-WEIXIN
this.getShareImg();
// #endif
},
onShow() {
this.getBargainInfo();
},
computed: {
progress() {
if (this.launchInfo && this.goodsDetail) {
let total = this.goodsDetail.price - this.launchInfo.floor_price,
progress = parseInt(((this.goodsDetail.price - this.launchInfo.curr_price) / total) * 100);
return isNaN(progress) ? 0 : progress;
} else {
return 0;
}
},
showNum() {
if (this.launchList && this.launchList.length < 3) {
return this.launchList.length;
} else {
return 3;
}
}
},
methods: {
timeUp() {
this.getBargainInfo();
},
getHeight() {
var self = this;
uni.getSystemInfo({
success: function (res) {
self.windowHeight = res.windowHeight - 44;
if (self.iphoneX) {
self.windowHeight = self.windowHeight - 33;
}
}
});
},
getBargainInfo() {
if (this.load) return;
this.load = true;
this.$api.sendRequest({
url: '/bargain/api/bargain/detail',
data: {
launch_id: this.launch_id,
bargain_id: this.bargain_id
},
success: res => {
if (res.code == 0) {
this.goodsDetail = res.data.goods_sku_detail;
if (this.goodsDetail.sku_spec_format) this.goodsDetail.sku_spec_format = JSON.parse(this.goodsDetail.sku_spec_format);
this.$langConfig.title(this.goodsDetail.sku_name);
this.goodsDetail.unit = this.goodsDetail.unit || "件";
// 商品SKU格式
if (this.goodsDetail.goods_spec_format) this.goodsDetail.goods_spec_format = JSON.parse(this.goodsDetail.goods_spec_format);
// if (this.goodsDetail.goods_content) this.goodsDetail.goods_content = htmlParser(this.goodsDetail.goods_content);
if (this.addonIsExist.form) {
this.getGoodsForm();
}
if (res.data.launch_info && Object.keys(res.data.launch_info).length > 0) {
this.launchInfo = res.data.launch_info;
if (this.launchInfo.status == 0) {
this.timeMachine = this.$util.countDown(this.launchInfo.end_time - res.timestamp);
}
this.launch_id = this.launchInfo.launch_id;
}
if (res.data.launch_list && Object.keys(res.data.launch_list).length > 0) {
this.launchList = res.data.launch_list;
}
//发起砍价后自砍一刀展示
if (this.isOwn && this.goodsDetail.is_own > 0 && this.launchInfo && this.launchInfo.self && this.launchInfo.my_bargain_money) {
this.my_bargain_money = this.launchInfo.my_bargain_money;
this.$refs.uniSelfBargainPopup.open();
}
//好友进来后帮砍弹出
if (this.launchInfo && !this.launchInfo.self && !this.launchInfo.cut && this.goodsDetail.bargain_status == 1) this.$refs.uniHelpPopup.open();
this.load = false;
this.getBargainRecord(1);
this.setPublicShare();
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
} else {
this.load = false;
this.$util.redirectTo('/pages_promotion/bargain/my_bargain');
}
},
fail: res => {
this.load = false;
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
getBargainRecord(page) {
if (this.load) return;
if (!this.launchInfo) return;
this.load = true;
this.$api.sendRequest({
url: '/bargain/api/bargain/record',
data: {
page: page,
id: this.launchInfo.launch_id
},
success: res => {
this.load = false;
this.totalPage = res.data.page_count;
this.page = page;
if (res.code == 0 && res.data.list.length) {
if (page == 1) {
this.bargainRecord = res.data.list;
} else {
this.bargainRecord = this.bargainRecord.concat(res.data.list);
}
}
this.showMore = false;
if (page < this.totalPage) {
this.showMore = true;
}
}
});
},
scrolltolower() {
let next = this.page + 1;
if (!this.load && next <= this.totalPage) {
this.getBargainRecord(next);
}
},
browse() {
this.$api.sendRequest({
url: '/bargain/api/bargain/browse',
data: {
bargain_id: this.goodsDetail.bargain_id
},
success: res => {
}
});
},
share() {
this.$api.sendRequest({
url: '/bargain/api/bargain/share',
data: {
bargain_id: this.goodsDetail.bargain_id
},
success: res => {
}
});
},
/**
* 刷新商品详情数据
* @param {Object} goodsSkuDetail
*/
refreshGoodsSkuDetail(goodsSkuDetail) {
Object.assign(this.goodsDetail, goodsSkuDetail);
},
// 发起砍价
createBargain() {
if (!this.storeToken) {
this.$refs.login.open('/pages_promotion/bargain/detail?l_id=' + this.launch_id + '&b_id=' + this.bargain_id);
return;
}
// #ifdef MP
this.$util.subscribeMessage('BARGAIN_COMPLETE');
// #endif
if (this.goodsDetail.sku_spec_format || this.goodsDetail.goods_form) {
this.$refs.goodsSku.show('bargain');
} else {
this.$api.sendRequest({
url: '/bargain/api/bargain/launch',
data: {
id: this.goodsDetail.id
},
success: res => {
if (res.code == 0) {
let params = {
l_id: res.data,
b_id: this.bargain_id
};
if (this.goodsDetail.is_own) params.is_own = 1;
this.$util.redirectTo('/pages_promotion/bargain/detail', params, 'redirectTo');
} else {
this.$util.showToast({
title: res.message
});
}
}
});
}
},
/**
* 立即购买,不砍了,直接买
*/
buyNow() {
let goodsFormData = uni.getStorageSync('goodFormData');
let fn = ()=>{
uni.setStorage({
key: 'bargainOrderCreateData',
data: {
launch_id: this.launchInfo.launch_id
},
success: () => {
this.$util.redirectTo('/pages_promotion/bargain/payment');
}
});
};
if(!goodsFormData && this.goodsDetail.goods_form){
this.$refs.goodsSku.show('bargain',()=>{
fn();
});
}else{
fn();
}
},
/**
* 帮好友砍价
*/
bargain() {
if (this.storeToken) {
this.$api.sendRequest({
url: '/bargain/api/bargain/bargain',
data: {
id: this.launchInfo.launch_id
},
success: res => {
if (res.code == 0) {
this.bargainMoney = parseFloat(res.data.bargain_money).toFixed(2);
this.$refs.uniHelpPopup.close();
this.$refs.uniPopup.open();
this.getBargainInfo();
} else {
this.$util.showToast({
title: res.message
});
}
}
});
} else {
this.$refs.login.open('/pages_promotion/bargain/detail?l_id=' + this.launch_id + '&b_id=' + this.bargain_id);
}
},
closePopup() {
this.$refs.uniPopup.close();
},
closeSelfPop() {
this.$refs.uniSelfBargainPopup.close();
},
// 打开分享弹出层
openSharePopup() {
this.$refs.uniSelfBargainPopup.close();
this.$refs.sharePopup.open();
this.share();
},
// 关闭分享弹出层
closeSharePopup() {
this.$refs.sharePopup.close();
},
copyUrl() {
let text = '嘿!朋友就差你这一刀了,帮一下忙呗~' + this.$config.h5Domain + '/pages_promotion/bargain/detail?l_id=' + this.launch_id + '&b_id=' + this.bargain_id;
if (this.memberInfo && this.memberInfo.member_id) text += '&source_member=' + this.memberInfo.member_id;
this.$util.copy(text, () => {
this.closeSharePopup();
});
},
toBargainRecode() {
let view = uni.createSelectorQuery().select('.bargin_introduction');
view.boundingClientRect(data => {
uni.pageScrollTo({
duration: 100,
scrollTop: data.top + 100
});
}).exec();
},
/**
* 设置公众号分享
*/
setPublicShare() {
let shareUrl = this.$config.h5Domain + '/pages_promotion/bargain/detail?l_id=' + this.launch_id + '&b_id=' + this.bargain_id;
if (this.memberInfo && this.memberInfo.member_id) shareUrl += '&source_member=' + this.memberInfo.member_id;
this.$util.setPublicShare({
title: this.goodsDetail.sku_name,
desc: '嘿!朋友就差你这一刀了,帮一下忙呗~',
link: shareUrl,
imgUrl: this.goodsDetail.sku_image
},
res => {
// console.log('公众号分享成功');
// this.share();
}
);
},
//-------------------------------------海报-------------------------------------
// 打开海报弹出层
openPosterPopup() {
this.getGoodsPoster();
this.$refs.sharePopup.close();
},
// 关闭海报弹出层
closePosterPopup() {
this.$refs.posterPopup.close();
},
/**
* 获取海报
*/
getGoodsPoster() {
uni.showLoading({
title: '海报生成中...'
});
//活动海报信息
let posterParams = {
l_id: this.launch_id,
b_id: this.bargain_id,
bargain_id: this.goodsDetail.bargain_id
};
if (this.memberInfo && this.memberInfo.member_id) posterParams.source_member = this.memberInfo.member_id;
this.$api.sendRequest({
url: '/bargain/api/goods/poster',
data: {
page: '/pages_promotion/bargain/detail',
qrcode_param: JSON.stringify(posterParams)
},
success: res => {
if (res.code == 0) {
this.poster = res.data.path + '?time=' + new Date().getTime();
this.$refs.posterPopup.open();
} else {
this.posterMsg = res.message;
this.$util.showToast({
title: this.posterMsg
})
}
uni.hideLoading();
},
fail: err => {
uni.hideLoading();
}
});
},
getNewArray(array, subGroupLength) {
if (array) {
let index = 0;
let newArray = [];
while (index < array.length) {
newArray.push(array.slice(index, (index += subGroupLength)));
}
return newArray;
}
},
toDetail(goods_id) {
this.$util.redirectTo('/pages/goods/detail', {
goods_id: goods_id
});
},
/**
* 获取分享图
*/
getShareImg() {
let posterParams = {
l_id: this.launch_id,
b_id: this.bargain_id,
bargain_id: this.bargain_id
};
this.$api.sendRequest({
url: '/bargain/api/goods/shareimg',
data: {
page: '/pages_promotion/bargain/launch',
qrcode_param: JSON.stringify(posterParams)
},
success: res => {
if (res.code == 0) this.shareImg = res.data.path;
}
});
},
openRulePopup() {
this.$refs.rulePopup.open();
},
closeRulePopup() {
this.$refs.rulePopup.close();
},
/**
* 获取商品表单
*/
getGoodsForm() {
this.$api.sendRequest({
url: "/form/api/form/goodsform",
data: {
goods_id: this.goodsDetail.goods_id
},
success: res => {
if (res.code == 0 && res.data) {
this.$set(this.goodsDetail, 'goods_form', res.data);
let goodsFormData = uni.getStorageSync('goodFormData');
// 检测是否填写过自定义表单,已经发起砍价后,禁止切换规格
if (!goodsFormData && this.launchInfo && this.goodsDetail.goods_spec_format) {
this.goodsDetail.goods_spec_format.forEach(item => {
item.value.forEach(specItem => {
for (var i = 0; i < this.goodsDetail.sku_spec_format.length; i++) {
let skuItem = this.goodsDetail.sku_spec_format[i];
if (skuItem.spec_id == specItem.spec_id && skuItem.spec_value_id != specItem.spec_value_id) {
specItem.disabled = true;
break;
}
}
});
});
}
}
}
});
}
},
filters: {
/**
* 字符掩饰输出
* @param {Object} str
*/
cover(str) {
if (typeof str == 'string' && str.length > 0) {
return str.substr(0, 1) + '******' + str.substr(-1);
} else {
return '';
}
}
},
/**
* 自定义分享内容
*/
onShareAppMessage() {
var path = '/pages_promotion/bargain/detail?l_id=' + this.launch_id + '&b_id=' + this.bargain_id;
if (this.memberInfo && this.memberInfo.member_id) path += '&source_member=' + this.memberInfo.member_id;
this.share();
return {
title: '嘿!朋友就差你这一刀了,帮一下忙呗~',
imageUrl: this.shareImg ? this.$util.img(this.shareImg) : this.$util.img(this.goodsDetail.sku_image, {
size: 'big'
}),
path: path,
success: res => {
},
fail: res => {
},
complete: res => {
}
};
}
}

View File

@@ -0,0 +1,340 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view>
<view class="combo-package" :class="isIphoneX ? 'combo-iphonex' : ''">
<view class="combo-package-content">
<view class="combo-package-name color-title">{{ combo.bl_name }}</view>
<view v-for="(item, index) in combo.bundling_goods" :key="index" class="goods-info" @click="toGoodsDetail(item)">
<view class="goods-img">
<view class="img-wrap"><image :src="$util.img(item.sku_image, { size: 'mid' })" @error="imageError(index)" mode="aspectFit" /></view>
</view>
<view class="data-info">
<view class="goods-name">{{ item.sku_name }}</view>
<view class="price-wrap">
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
<text class="price price-style large">{{ parseFloat(item.price).toFixed(2).split(".")[0] }}</text>
<text class="unit price-style small">.{{ parseFloat(item.price).toFixed(2).split(".")[1] }}</text>
<text class="num">x1</text>
</view>
<view class="stock-tips color-base-text" v-if="item.stock < num">
库存不足剩余{{ item.stock }}
<block v-if="item.unit">{{ item.unit }}</block>
<block v-else></block>
</view>
</view>
</view>
</view>
<view class="footer" :class="isIphoneX ? 'padding-bottom' : ''">
<view class="price-wrap">
<text class="label">套餐价</text>
<text class="unit price-color">{{ $lang('common.currencySymbol') }}</text>
<text class="price price-color">{{ parseFloat(packagePrice).toFixed(2).split(".")[0] }}</text>
<text class="unit price-color">.{{ parseFloat(packagePrice).toFixed(2).split(".")[1] }}</text>
<!-- <text class="info-num">为您节省{{ $lang('common.currencySymbol') }} {{ saveThePrice }}</text> -->
</view>
<button class="footer-btn mini" v-if="isDisabled" type="primary" @click="comboBuy()" size="mini">立即购买</button>
<button class="footer-btn mini" v-else disabled>立即购买</button>
</view>
</view>
<!-- 悬浮按钮 -->
<hover-nav></hover-nav>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
export default {
data() {
return {
num: 1, //购买数量
blId: 0, //商品id
combo: [],
packagePrice: [], //套餐价
saveThePrice: 0, //节省价格
isDisabled: false, //按钮失效
isIphoneX: false //判断是否是iphoneX以上的设备
};
},
onLoad(e) {
this.blId = e.bl_id || 0;
this.isIphoneX = this.$util.uniappIsIPhoneX();
},
onShow() {
setTimeout( () => {
if (!this.addonIsExist.bundling) {
this.$util.showToast({
title: '商家未开启组合套餐',
mask: true,
duration: 2000
});
setTimeout(() => {
this.$util.redirectTo('/pages/index/index');
}, 2000);
}
},1000);
this.getDetail();
},
onHide() {
this.btnSwitch = true;
},
methods: {
// 获取套餐详情
getDetail() {
this.$api.sendRequest({
url: '/bundling/api/bundling/detail',
data: {
bl_id: this.blId
},
success: res => {
if (res.data) {
this.combo = res.data;
this.numberChange();
} else {
this.$util.showToast({
title: res.message
});
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
toGoodsDetail(e) {
this.$util.redirectTo('/pages/goods/detail', { goods_id: e.goods_id });
},
numberChange(flag, callback) {
setTimeout(() => {
var disabledCount = 0;
// 防止空
if (flag && this.num.length == 0) {
this.num = 1;
disabledCount++;
}
// 防止输入0和负数、非法输入
if (flag && (this.num <= 0 || isNaN(this.num))) {
this.number = 1;
disabledCount++;
}
if (flag) this.num = parseInt(this.num);
var price = 0;
for (var i = 0; i < this.combo.bundling_goods.length; i++) {
price += parseFloat(this.combo.bundling_goods[i].price);
//检测库存
if (this.combo.bundling_goods[i].stock < this.num) disabledCount++;
}
this.isDisabled = !(disabledCount > 0);
this.saveThePrice = ((price - this.combo.bl_price) * this.num).toFixed(2);
this.packagePrice = (this.combo.bl_price * this.num).toFixed(2);
if (callback) callback();
}, 0);
},
// 套餐立即购买点击
async comboBuy() {
if (!this.isDisabled) return;
//纠正数量
this.numberChange(true, () => {
if (!this.storeToken) {
this.$refs.login.open('/pages_promotion/bundling/detail?bl_id=' + this.blId);
return;
}
if (this.btnSwitch == false) return;
this.btnSwitch = false;
var data = {
bl_id: this.blId,
num: this.num
};
uni.setStorage({
key: 'comboOrderCreateData',
data: data,
success: () => {
this.$util.redirectTo('/pages_promotion/bundling/payment');
this.btnSwitch = true;
}
});
});
},
imageError(index) {
this.combo.bundling_goods[index].sku_image = this.$util.getDefaultImage().goods;
this.$forceUpdate();
}
},
onShareAppMessage(res) {
var title = '购买套餐,优惠多多哦';
var path = '/pages_promotion/combo/detail?bl_id=' + this.blId;
return {
title: title,
path: path,
success: res => {},
fail: res => {}
};
}
};
</script>
<style lang="scss">
.combo-package {
border-radius: $border-radius;
margin: 20rpx 30rpx;
margin-bottom: 160rpx;
background: #ffffff;
&.combo-iphonex {
margin-bottom: 230rpx;
}
.combo-package-content {
// padding-bottom: 40rpx;
.combo-package-name {
padding: 20rpx 30rpx;
}
.goods-info {
overflow: hidden;
padding: $padding 30rpx;
border-radius: $border-radius;
.goods-img {
display: inline-block;
width: 30%;
text-align: center;
line-height: 100%;
float: left;
.img-wrap {
display: inline-block;
width: 180rpx;
height: 180rpx;
text-align: center;
border-radius: $border-radius;
image {
height: 100%;
width: 100%;
vertical-align: middle;
}
}
}
.data-info {
display: inline-block;
width: 66%;
float: left;
position: relative;
margin-left: 20rpx;
height: 180rpx;
.goods-name {
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
line-height: 150%;
// margin-bottom: 20rpx;
}
.stock-tips {
position: absolute;
width: 100%;
bottom: 50rpx;
height: 40rpx;
line-height: 40rpx;
font-size: $font-size-tag;
}
.price-wrap {
height: 50rpx;
line-height: 50rpx;
position: absolute;
width: 100%;
bottom: 0;
.unit {
font-weight: bold;
font-size: $font-size-tag;
margin-right: 4rpx;
}
.price {
font-weight: bold;
font-size: $font-size-toolbar;
}
.num {
float: right;
}
}
}
}
}
.footer {
width: 100%;
background: #fff;
display: flex;
justify-content: space-between;
padding: 20rpx 24rpx;
box-sizing: border-box;
position: fixed;
bottom: 0;
left: 0;
.price-wrap {
flex: 1;
text-align: right;
vertical-align: middle;
line-height: 70rpx;
margin-right: 30rpx;
.label {
font-size: $font-size-base;
}
.unit {
font-weight: bold;
font-size: $font-size-tag;
margin-right: 4rpx;
}
.price {
font-weight: bold;
font-size: $font-size-toolbar;
}
.info-num {
font-size: $font-size-activity-tag;
color: $color-tip;
line-height: 1;
margin-top: 12rpx;
}
}
.footer-btn {
display: flex;
align-items: center;
justify-content: center;
height: 70rpx;
line-height: 70rpx;
}
}
.padding-bottom {
padding-bottom: 80rpx;
}
}
</style>

View File

@@ -0,0 +1,49 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view>
<common-payment :api="api" create-data-key="comboOrderCreateData" ref="payment"></common-payment>
</view>
</template>
<script>
export default {
data() {
return {
api: {
payment: '/bundling/api/ordercreate/payment',
calculate: '/bundling/api/ordercreate/calculate',
create: '/bundling/api/ordercreate/create'
}
}
},
provide() {
return {
promotion: this.promotion.bind(this)
}
},
onShow() {
if (this.$refs.payment) this.$refs.payment.pageShow();
},
methods: {
promotion(data){
if (data.bunding_info) {
return {title: '组合套餐', content: data.bunding_info.bl_name}
}
}
}
};
</script>
<style scoped lang="scss">
/deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: none;
max-height: unset !important;
overflow-y: hidden !important;
}
/deep/ .uni-popup__wrapper {
border-radius: 20rpx 20rpx 0 0;
}
/deep/ .uni-popup {
z-index: 8;
}
</style>

View File

@@ -1,161 +1,159 @@
Function.prototype.asyAfter = function(afterfn) { Function.prototype.asyAfter = function(afterfn) {
var _self = this; var _self = this;
return function() { return function() {
var ret = _self.apply(this, arguments); var ret = _self.apply(this, arguments);
if (ret === 'next') { if (ret === 'next') {
return afterfn.apply(this, arguments); return afterfn.apply(this, arguments);
} }
return ret; return ret;
} }
} }
Date.prototype.pattern = function(fmt) { Date.prototype.pattern = function(fmt) {
var o = { var o = {
"M+": this.getMonth() + 1, //月份 "M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日 "d+": this.getDate(), //日
"h+": this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时 "h+": this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时
"H+": this.getHours(), //小时 "H+": this.getHours(), //小时
"m+": this.getMinutes(), //分 "m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒 "s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度 "q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒 "S": this.getMilliseconds() //毫秒
}; };
var week = { var week = {
"0": "\u65e5", "0": "\u65e5",
"1": "\u4e00", "1": "\u4e00",
"2": "\u4e8c", "2": "\u4e8c",
"3": "\u4e09", "3": "\u4e09",
"4": "\u56db", "4": "\u56db",
"5": "\u4e94", "5": "\u4e94",
"6": "\u516d" "6": "\u516d"
}; };
if (/(y+)/.test(fmt)) { if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
} }
if (/(E+)/.test(fmt)) { if (/(E+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "\u661f\u671f" : "\u5468") : fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "\u661f\u671f" : "\u5468") : "") + week[this.getDay() + ""]);
"") + }
week[this.getDay() + ""]); for (var k in o) {
} if (new RegExp("(" + k + ")").test(fmt)) {
for (var k in o) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
if (new RegExp("(" + k + ")").test(fmt)) { }
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]) }
.length))); return fmt;
} }
}
return fmt; const isType = type => (/^\[object\s(.*)\]$/.exec(Object.prototype.toString.call(type)))[1];
} let Time = function() {};
let timeProto = Time.prototype;
const isType = type => (/^\[object\s(.*)\]$/.exec(Object.prototype.toString.call(type)))[1];
let Time = function() {}; //获取当前时间戳
let timeProto = Time.prototype; timeProto.getUnix = function() {
return new Date().getTime();
//获取当前时间戳 }
timeProto.getUnix = function() {
return new Date().getTime(); //获取当天0点0分0秒时间戳
} timeProto.getTodayUnix = function() {
let date = new Date();
//获取当天0点0分0秒时间戳 let myDate = `${date.getFullYear()}/${(date.getMonth() + 1)}/${date.getDate()} 00:00:00`;
timeProto.getTodayUnix = function() { return new Date(myDate).getTime();
let date = new Date(); }
let myDate = `${date.getFullYear()}/${(date.getMonth() + 1)}/${date.getDate()} 00:00:00`;
return new Date(myDate).getTime(); //获取今年1月1日0点0分0秒时间戳
} timeProto.getYearUnix = function() {
let date = new Date();
//获取今年1月1日0点0分0秒时间戳 date.setMonth(0);
timeProto.getYearUnix = function() { date.setDate(1);
let date = new Date(); date.setHours(0);
date.setMonth(0); date.setMinutes(0);
date.setDate(1); date.setSeconds(0);
date.setHours(0); date.setMilliseconds(0);
date.setMinutes(0); return date.getTime();
date.setSeconds(0); }
date.setMilliseconds(0);
return date.getTime(); //获取当前时间标准年月日
} timeProto.getLastDate = function(constTime) {
if (!constTime) {
//获取当前时间标准年月日 return;
timeProto.getLastDate = function(constTime) { }
if (!constTime) { let date = new Date(constTime);
return; if (date.pattern) {
} return date.pattern("yyyy-MM-dd");
let date = new Date(constTime); }
if (date.pattern) {
return date.pattern("yyyy-MM-dd"); let month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
} let day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
return date.getFullYear() + '-' + month + '-' + day;
let month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1; }
let day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
return date.getFullYear() + '-' + month + '-' + day; const resDateStr = function(timer, constTime) {
} let _just = function(timer) {
const resDateStr = function(timer, constTime) { if (timer <= 0 || Math.floor(timer / 60) <= 0) {
let _just = function(timer) { return "刚刚"
} else return 'next';
if (timer <= 0 || Math.floor(timer / 60) <= 0) { }
return "刚刚"
} else return 'next'; let _mm = function(timer) {
} if (timer < 3600) {
return Math.floor(timer / 60) + "分钟前"
let _mm = function(timer) { } else return 'next';
if (timer < 3600) { }
return Math.floor(timer / 60) + "分钟前" let _hh = function(timer, constTime) {
} else return 'next'; let today = _time_.getTodayUnix();
} if (timer >= 3600 && (constTime - today >= 0)) {
let _hh = function(timer, constTime) { //可切换显示模式
let today = _time_.getTodayUnix(); // return "今天 " + new Date(constTime).pattern("HH:mm");
if (timer >= 3600 && (constTime - today >= 0)) { return Math.floor(timer / 60 / 60) + "小时前";
//可切换显示模式 } else {
// return "今天 " + new Date(constTime).pattern("HH:mm"); return 'next'
return Math.floor(timer / 60 / 60) + "小时前"; }
} else { }
return 'next' let _dd = function(timer, constTime) {
}; let today = _time_.getTodayUnix();
} timer = (today - constTime) / 1000;
let _dd = function(timer, constTime) { if (timer / 86400 <= 31) {
let today = _time_.getTodayUnix(); return Math.ceil(timer / 86400) + "天前"
timer = (today - constTime) / 1000; } else return 'next';
if (timer / 86400 <= 31) { }
return Math.ceil(timer / 86400) + "天前" let _dlast = function(timer, constTime) {
} else return 'next'; return _time_.getLastDate(constTime);
} }
let _dlast = function(timer, constTime) {
return _time_.getLastDate(constTime); let dateFilter = _just.asyAfter(_mm).asyAfter(_hh).asyAfter(_dd).asyAfter(_dlast);
} return dateFilter(timer, constTime);
}
let dateFilter = _just.asyAfter(_mm).asyAfter(_hh).asyAfter(_dd).asyAfter(_dlast);
return dateFilter(timer, constTime);
} //转换时间
const reg = new RegExp("-", "g");
timeProto.getFormatTime = function(constTime, max) {
//转换时间 if (!constTime) {
const reg = new RegExp("-", "g"); return "";
timeProto.getFormatTime = function(constTime, max) { }
if (!constTime) {
return ""; switch (isType(constTime)) {
} case 'Date':
constTime = constTime.getTime();
switch (isType(constTime)) { break;
case 'Date': case 'String':
constTime = constTime.getTime(); constTime = constTime.replace(reg, "/");
break; break;
case 'String': default:
constTime = constTime.replace(reg, "/"); constTime = new Date(constTime).getTime();
default: break;
constTime = new Date(constTime).getTime(); }
break;
} let now = this.getUnix();
let year = this.getYearUnix();
let now = this.getUnix(); let timer = (now - constTime) / 1000;
let year = this.getYearUnix(); if (constTime > now && max) {
let timer = (now - constTime) / 1000; return this.getLastDate(constTime);
if (constTime > now && max) { }
return this.getLastDate(constTime);
} let _t = this;
return resDateStr(timer, constTime);
let _t = this; }
return resDateStr(timer, constTime);
} const _time_ = new Time();
export default _time_;
const _time_ = new Time();
export default _time_;

View File

@@ -1,98 +1,97 @@
//字符串拼接 //字符串拼接
export function strFormat(str) { export function strFormat(str) {
return str < 10 ? `0${str}` : str return str < 10 ? `0${str}` : str
} }
// 获取当前时间 // 获取当前时间
export function currentTime() { export function currentTime() {
const myDate = new Date(); const myDate = new Date();
const year = myDate.getFullYear() const year = myDate.getFullYear()
const m = myDate.getMonth() + 1; const m = myDate.getMonth() + 1;
const d = myDate.getDate(); const d = myDate.getDate();
// const date = year + '-' + strFormat(m) + '-' + strFormat(d); // 隐藏年 // const date = year + '-' + strFormat(m) + '-' + strFormat(d); // 隐藏年
const date = strFormat(m) + '-' + strFormat(d); const date = strFormat(m) + '-' + strFormat(d);
const hour = myDate.getHours() const hour = myDate.getHours()
const min = myDate.getMinutes() const min = myDate.getMinutes()
const secon = myDate.getSeconds() const secon = myDate.getSeconds()
const time = strFormat(hour) + ':' + strFormat(min) + ':' + strFormat(secon); const time = strFormat(hour) + ':' + strFormat(min) + ':' + strFormat(secon);
return { return {
year, year,
date, date,
time time
} }
} }
//时间戳转日期 //时间戳转日期
export function timeStamp(time) { export function timeStamp(time) {
const dates = new Date(time) const dates = new Date(time)
const year = dates.getFullYear() const year = dates.getFullYear()
const month = dates.getMonth() + 1 const month = dates.getMonth() + 1
const date = dates.getDate() const date = dates.getDate()
const day = dates.getDay() const day = dates.getDay()
const hour = dates.getHours() const hour = dates.getHours()
const min = dates.getMinutes() const min = dates.getMinutes()
const days = ['日', '一', '二', '三', '四', '五', '六'] const days = ['日', '一', '二', '三', '四', '五', '六']
return { return {
allDate: `${year}/${strFormat(month)}/${strFormat(date)}`, allDate: `${year}/${strFormat(month)}/${strFormat(date)}`,
date: `${strFormat(month)}-${strFormat(date)}`, //返回的日期 07-01${strFormat(year)}-${strFormat(month)}-${strFormat(date)} date: `${strFormat(month)}-${strFormat(date)}`, //返回的日期 07-01${strFormat(year)}-${strFormat(month)}-${strFormat(date)}
day: `${days[day]}`, //返回的礼拜天数 星期一 day: `${days[day]}`, //返回的礼拜天数 星期一
hour: strFormat(hour) + ':' + strFormat(min) // + ':00' //返回的时钟 08:00 hour: strFormat(hour) + ':' + strFormat(min) // + ':00' //返回的时钟 08:00
} }
} }
//获取最近7天的日期和礼拜天数 //获取最近7天的日期和礼拜天数
export function initData(appointedDay = '') { export function initData(appointedDay = '') {
const time = [] const time = []
const date = appointedDay ? new Date(appointedDay) : new Date() const date = appointedDay ? new Date(appointedDay) : new Date()
const now = date.getTime() //获取当前日期的时间戳 const now = date.getTime() //获取当前日期的时间戳
let timeStr = 3600 * 24 * 1000 //一天的时间戳 let timeStr = 3600 * 24 * 1000 //一天的时间戳
let obj = { let obj = {
0: "今天", 0: "今天",
1: "明天", 1: "明天",
2: "后天" 2: "后天"
} }
for (let i = 0; i < 7; i++) { for (let i = 0; i < 7; i++) {
const timeObj = {} const timeObj = {}
timeObj.date = timeStamp(now + timeStr * i).date //保存日期 timeObj.date = timeStamp(now + timeStr * i).date //保存日期
timeObj.timeStamp = now + timeStr * i //保存时间戳 timeObj.timeStamp = now + timeStr * i //保存时间戳
timeObj.week = appointedDay == '' ? (obj[i] ?? timeStamp(now + timeStr * i).day) : timeStamp(now + timeStr * i) timeObj.week = appointedDay == '' ? (obj[i] ?? timeStamp(now + timeStr * i).day) : timeStamp(now + timeStr * i).day
.day time.push(timeObj)
time.push(timeObj) }
} return time
return time }
}
//时间数组
//时间数组 export function initTime(startTime = '09:00', endTime = '18:30', timeInterval = 1) {
export function initTime(startTime = '09:00', endTime = '18:30', timeInterval = 1) { const time = []
const time = [] const date = timeStamp(Date.now()).allDate
const date = timeStamp(Date.now()).allDate const startDate = `${date} ${startTime}`
const startDate = `${date} ${startTime}` const endDate = `${date} ${endTime}`
const endDate = `${date} ${endTime}` const startTimeStamp = new Date(startDate).getTime()
const startTimeStamp = new Date(startDate).getTime() const endTimeStamp = new Date(endDate).getTime()
const endTimeStamp = new Date(endDate).getTime() const timeStr = 3600 * 1000 * timeInterval
const timeStr = 3600 * 1000 * timeInterval for (let i = startTimeStamp; i <= endTimeStamp; i = i + timeStr) {
for (let i = startTimeStamp; i <= endTimeStamp; i = i + timeStr) { const timeObj = {}
const timeObj = {} timeObj.time = timeStamp(i).hour
timeObj.time = timeStamp(i).hour timeObj.disable = false
timeObj.disable = false time.push(timeObj)
time.push(timeObj) }
} return time
return time }
}
export function weekDate(){
export function weekDate(){ var now = new Date(); //当前日期
var now = new Date(); //当前日期 var nowDayOfWeek = now.getDay(); //今天本周的第几天
var nowDayOfWeek = now.getDay(); //今天本周的第几天 var nowDay = now.getDate(); //当前日
var nowDay = now.getDate(); //当前 var nowMonth = now.getMonth(); //当前
var nowMonth = now.getMonth(); //当前 var nowYear = now.getYear(); //当前
var nowYear = now.getYear(); //当前年
var weekStartDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek + 1);
var weekStartDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek + 1); var weekEndDate = new Date(nowYear, nowMonth, nowDay + (7 - nowDayOfWeek));
var weekEndDate = new Date(nowYear, nowMonth, nowDay + (7 - nowDayOfWeek));
var arr = [];
var arr = []; arr[0] = strFormat(weekStartDate.getMonth()+1) + '-' + strFormat(weekStartDate.getDate());
arr[0] = strFormat(weekStartDate.getMonth()+1) + '-' + strFormat(weekStartDate.getDate()); arr[1] = strFormat(weekEndDate.getMonth()+1) + '-' + strFormat(weekEndDate.getDate());
arr[1] = strFormat(weekEndDate.getMonth()+1) + '-' + strFormat(weekEndDate.getDate()); return arr;
return arr; }
}

View File

@@ -1,413 +1,414 @@
<template> <template>
<page-meta :page-style="themeColor"></page-meta> <page-meta :page-style="themeColor"></page-meta>
<view class="content"> <view class="content">
<mescroll-uni ref="mescroll" @getData="getGoodsList"> <mescroll-uni ref="mescroll" @getData="getGoodsList">
<block slot="list"> <block slot="list">
<view class="goods-list" :style="{ backgroundImage: 'url(' + $util.img('public/uniapp/fenxiao/promote/promote_bg.png') + ')' }"> <view class="goods-list" :style="{ backgroundImage: 'url(' + $util.img('public/uniapp/fenxiao/promote/promote_bg.png') + ')' }">
<scroll-view class="quick-nav" scroll-x="true"> <scroll-view class="quick-nav" scroll-x="true">
<!-- #ifdef MP --> <!-- #ifdef MP -->
<view class="uni-scroll-view-content"> <view class="uni-scroll-view-content">
<!-- #endif --> <!-- #endif -->
<view class="quick-nav-item" :class="{ selected: categoryId == 0 }" @click="changeCategory(0)">全部</view> <view class="quick-nav-item" :class="{ selected: categoryId == 0 }" @click="changeCategory(0)">全部</view>
<view <view
class="quick-nav-item" class="quick-nav-item"
v-for="item in categoryList" v-for="item in categoryList"
:class="{ selected: categoryId == item.category_id }" :key="item.category_id"
@click="changeCategory(item.category_id)" :class="{ selected: categoryId == item.category_id }"
> @click="changeCategory(item.category_id)"
{{ item.category_name }} >
</view> {{ item.category_name }}
<!-- #ifdef MP --> </view>
</view> <!-- #ifdef MP -->
<!-- #endif --> </view>
</scroll-view> <!-- #endif -->
<view v-for="(item, index) in goodsList" :key="index" class="goods-item" @click="navToDetailPage(item)"> </scroll-view>
<view class="image-wrap"> <view v-for="(item, index) in goodsList" :key="index" class="goods-item" @click="navToDetailPage(item)">
<image :src="$util.img(item.sku_image, { size: 'mid' })" @error="imageError(index)" mode="aspectFill" /> <view class="image-wrap">
</view> <image :src="$util.img(item.sku_image, { size: 'mid' })" @error="imageError(index)" mode="aspectFill" />
<view class="goods-content"> </view>
<view class="goods-name"> <view class="goods-content">
<text class="name">{{ item.sku_name }}</text> <view class="goods-name">
<view class="label-list" v-if="item.label_name"> <text class="name">{{ item.sku_name }}</text>
<text class="label-item">{{ item.label_name }}</text> <view class="label-list" v-if="item.label_name">
</view> <text class="label-item">{{ item.label_name }}</text>
</view> </view>
<view class="goods-bottom"> </view>
<view class="goods-price color-base-text"> <view class="goods-bottom">
<text class="font-size-tag"></text> <view class="goods-price color-base-text">
{{ item.discount_price }} <text class="font-size-tag"></text>
</view> {{ item.discount_price }}
<view class="goods-share" @click.stop="shareFn('goods', index)"> </view>
<text class="icondiy icon-system-share"></text> <view class="goods-share" @click.stop="shareFn('goods', index)">
<text class="txt" v-if="!is_fenxiao">分享</text> <text class="icondiy icon-system-share"></text>
<text class="txt" v-else>{{ item.commission_money }}</text> <text class="txt" v-if="!is_fenxiao">分享</text>
</view> <text class="txt" v-else>{{ item.commission_money }}</text>
</view> </view>
</view> </view>
</view> </view>
<view class="empty" v-if="goodsList.length == 0"> </view>
<ns-empty :isIndex="false" text="暂无分销商品" textColor="#fff"></ns-empty> <view class="empty" v-if="goodsList.length == 0">
</view> <ns-empty :isIndex="false" text="暂无分销商品" textColor="#fff"></ns-empty>
</view> </view>
</block> </view>
</mescroll-uni> </block>
<view class="active-btn" v-if="goodsList.length"> </mescroll-uni>
<!-- #ifdef MP --> <view class="active-btn" v-if="goodsList.length">
<button class="share-btn" :plain="true" open-type="share">分享好友</button> <!-- #ifdef MP -->
<text class="tag">|</text> <button class="share-btn" :plain="true" open-type="share">分享好友</button>
<!-- #endif --> <text class="tag">|</text>
<text class="btn" @click="shareFn('fenxiao')">生成海报</text> <!-- #endif -->
</view> <text class="btn" @click="shareFn('fenxiao')">生成海报</text>
<loading-cover ref="loadingCover"></loading-cover> </view>
<loading-cover ref="loadingCover"></loading-cover>
<!-- 分享弹窗 -->
<view @touchmove.prevent.stop> <!-- 分享弹窗 -->
<uni-popup ref="sharePopup" type="bottom" class="share-popup"> <view @touchmove.prevent.stop>
<view> <uni-popup ref="sharePopup" type="bottom" class="share-popup">
<view class="share-title">分享</view> <view>
<view class="share-content"> <view class="share-title">分享</view>
<!-- #ifdef MP --> <view class="share-content">
<view class="share-box"> <!-- #ifdef MP -->
<button class="share-btn" :plain="true" open-type="share"> <view class="share-box">
<view class="iconfont icon-share-friend"></view> <button class="share-btn" :plain="true" open-type="share">
<text>分享给好友</text> <view class="iconfont icon-share-friend"></view>
</button> <text>分享给好友</text>
</view> </button>
<!-- #endif --> </view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="share-box" v-if="goodsCircle"> <!-- #ifdef MP-WEIXIN -->
<button class="share-btn" :plain="true" @click="openBusinessView"> <view class="share-box" v-if="goodsCircle">
<view class="iconfont icon-haowuquan"></view> <button class="share-btn" :plain="true" @click="openBusinessView">
<text>分享到好物圈</text> <view class="iconfont icon-haowuquan"></view>
</button> <text>分享到好物圈</text>
</view> </button>
<!-- #endif --> </view>
<!-- #endif -->
<view class="share-box" @click="openPosterPopup">
<button class="share-btn" :plain="true"> <view class="share-box" @click="openPosterPopup">
<view class="iconfont icon-pengyouquan"></view> <button class="share-btn" :plain="true">
<text>生成分享海报</text> <view class="iconfont icon-pengyouquan"></view>
</button> <text>生成分享海报</text>
</view> </button>
<!-- #ifdef H5 --> </view>
<view class="share-box" @click="copyUrl"> <!-- #ifdef H5 -->
<button class="share-btn" :plain="true"> <view class="share-box" @click="copyUrl">
<view class="iconfont icon-fuzhilianjie"></view> <button class="share-btn" :plain="true">
<text>复制链接</text> <view class="iconfont icon-fuzhilianjie"></view>
</button> <text>复制链接</text>
</view> </button>
<!-- #endif --> </view>
</view> <!-- #endif -->
<view class="share-footer" @click="closeSharePopup"><text>取消分享</text></view> </view>
</view> <view class="share-footer" @click="closeSharePopup"><text>取消分享</text></view>
</uni-popup> </view>
</view> </uni-popup>
<!-- 海报 --> </view>
<view @touchmove.prevent.stop> <!-- 海报 -->
<uni-popup ref="posterPopup" type="bottom" class="poster-layer"> <view @touchmove.prevent.stop>
<template v-if="poster != '-1'"> <uni-popup ref="posterPopup" type="bottom" class="poster-layer">
<view> <template v-if="poster != '-1'">
<view class="image-wrap"> <view>
<image :src="$util.img(poster)" :show-menu-by-longpress="true" /> <view class="image-wrap">
</view> <image :src="$util.img(poster)" :show-menu-by-longpress="true" />
<!-- #ifdef MP || APP-PLUS --> </view>
<view class="save" @click="saveGoodsPoster()">保存图片</view> <!-- #ifdef MP || APP-PLUS -->
<!-- #endif --> <view class="save" @click="saveGoodsPoster()">保存图片</view>
<!-- #ifdef H5 --> <!-- #endif -->
<view class="save">长按保存图片</view> <!-- #ifdef H5 -->
<!-- #endif --> <view class="save">长按保存图片</view>
</view> <!-- #endif -->
<view class="close iconfont icon-close" @click="closePosterPopup()"></view> </view>
</template> <view class="close iconfont icon-close" @click="closePosterPopup()"></view>
<view v-else class="msg">{{ posterMsg }}</view> </template>
</uni-popup> <view v-else class="msg">{{ posterMsg }}</view>
</view> </uni-popup>
</view>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 --> <!-- #ifdef MP-WEIXIN -->
<privacy-popup ref="privacyPopup"></privacy-popup> <!-- 小程序隐私协议 -->
<!-- #endif --> <privacy-popup ref="privacyPopup"></privacy-popup>
</view> <!-- #endif -->
</template> </view>
</template>
<script>
import list from './public/js/goods_list.js'; <script>
import fenxiaoWords from 'common/js/fenxiao-words.js'; import list from './public/js/goods_list.js';
import fenxiaoWords from 'common/js/fenxiao-words.js';
export default {
mixins: [list, fenxiaoWords] export default {
}; mixins: [list, fenxiaoWords]
</script> };
</script>
<style>
.quick-nav >>> .uni-scroll-view-content { <style>
display: flex; .quick-nav >>> .uni-scroll-view-content {
} display: flex;
</style> }
<style lang="scss"> </style>
/deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { <style lang="scss">
max-height: unset !important; /deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
} max-height: unset !important;
.quick-nav { }
margin-bottom: 20rpx; .quick-nav {
.quick-nav-item { margin-bottom: 20rpx;
display: flex; .quick-nav-item {
align-items: center; display: flex;
padding: 0 18rpx; align-items: center;
box-sizing: border-box; padding: 0 18rpx;
flex-shrink: 0; box-sizing: border-box;
border-radius: 40rpx; flex-shrink: 0;
margin-right: 20rpx; border-radius: 40rpx;
height: 48rpx; margin-right: 20rpx;
font-size: 24rpx; height: 48rpx;
background: #fff; font-size: 24rpx;
color: $base-color; background: #fff;
color: $base-color;
&.selected {
background: $base-color; &.selected {
color: #fff; background: $base-color;
} color: #fff;
}
&:last-child {
margin-right: 0; &:last-child {
} margin-right: 0;
} }
} }
.content { }
overflow: hidden; .content {
padding: 0 30rpx 160rpx; overflow: hidden;
min-height: 100vh; padding: 0 30rpx 160rpx;
background-color: #ff2d46; min-height: 100vh;
background-color: #ff2d46;
.goods-list {
min-height: 100vh; .goods-list {
padding: 420rpx 30rpx 0; min-height: 100vh;
background-size: 100%; padding: 420rpx 30rpx 0;
background-repeat: no-repeat; background-size: 100%;
box-sizing: border-box; background-repeat: no-repeat;
.goods-item { box-sizing: border-box;
margin-bottom: 20rpx; .goods-item {
background: #ffffff; margin-bottom: 20rpx;
padding: $padding; background: #ffffff;
display: flex; padding: $padding;
border-radius: 10rpx; display: flex;
&:last-child { border-radius: 10rpx;
margin-bottom: 0; &:last-child {
} margin-bottom: 0;
} }
}
.image-wrap {
display: inline-block; .image-wrap {
width: 200rpx; display: inline-block;
height: 200rpx; width: 200rpx;
line-height: 200rpx; height: 200rpx;
border-radius: 10rpx; line-height: 200rpx;
overflow: hidden; border-radius: 10rpx;
flex-shrink: 0; overflow: hidden;
image { flex-shrink: 0;
width: 100%; image {
height: 100%; width: 100%;
opacity: 1; height: 100%;
border-radius: 20rpx; opacity: 1;
} border-radius: 20rpx;
} }
}
.goods-content {
width: calc(100% - 200rpx); .goods-content {
min-height: 160rpx; width: calc(100% - 200rpx);
padding-left: $padding; min-height: 160rpx;
box-sizing: border-box; padding-left: $padding;
display: flex; box-sizing: border-box;
flex-direction: column; display: flex;
justify-content: space-between; flex-direction: column;
justify-content: space-between;
.goods-name {
width: 100%; .goods-name {
line-height: 1.3; width: 100%;
.name { line-height: 1.3;
line-height: 1.3; .name {
word-break: break-all; line-height: 1.3;
text-overflow: ellipsis; word-break: break-all;
overflow: hidden; text-overflow: ellipsis;
display: -webkit-box; overflow: hidden;
-webkit-line-clamp: 2; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-line-clamp: 2;
} -webkit-box-orient: vertical;
.label-list { }
display: flex; .label-list {
align-items: center; display: flex;
margin-top: 6rpx; align-items: center;
.label-item { margin-top: 6rpx;
padding: 4rpx 10rpx; .label-item {
font-size: $font-size-tag; padding: 4rpx 10rpx;
color: $base-color; font-size: $font-size-tag;
border: 2rpx solid $base-color; color: $base-color;
border-radius: 6rpx; border: 2rpx solid $base-color;
line-height: 1; border-radius: 6rpx;
} line-height: 1;
} }
} }
}
.goods-bottom {
width: 100%; .goods-bottom {
display: flex; width: 100%;
justify-content: space-between; display: flex;
align-items: center; justify-content: space-between;
align-items: center;
.goods-price {
line-height: 1.3; .goods-price {
font-size: $font-size-base; line-height: 1.3;
font-weight: bold; font-size: $font-size-base;
} font-weight: bold;
}
.goods-share {
height: 50rpx; .goods-share {
display: flex; height: 50rpx;
justify-content: center; display: flex;
align-items: center; justify-content: center;
padding: 0 $padding; align-items: center;
border-radius: 50rpx; padding: 0 $padding;
border: 2rpx solid $base-color; border-radius: 50rpx;
text { border: 2rpx solid $base-color;
color: $base-color; text {
border-radius: 40rpx; color: $base-color;
font-size: $font-size-tag; border-radius: 40rpx;
} font-size: $font-size-tag;
}
.icondiy {
margin-right: 4rpx; .icondiy {
font-size: $font-size-base; margin-right: 4rpx;
} font-size: $font-size-base;
} }
} }
} }
} }
.active-btn { }
position: fixed; .active-btn {
bottom: 40rpx; position: fixed;
left: 80rpx; bottom: 40rpx;
right: 80rpx; left: 80rpx;
height: 80rpx; right: 80rpx;
display: flex; height: 80rpx;
justify-content: center; display: flex;
align-items: center; justify-content: center;
z-index: 2; align-items: center;
border-radius: 50rpx; z-index: 2;
background-color: $base-color; border-radius: 50rpx;
color: #fff; background-color: $base-color;
.btn { color: #fff;
flex: 1; .btn {
text-align: center; flex: 1;
} text-align: center;
.share-btn { }
margin: 0; .share-btn {
padding: 0; margin: 0;
flex: 1; padding: 0;
text-align: center; flex: 1;
border: 0; text-align: center;
color: #fff; border: 0;
} color: #fff;
} }
}
.share-popup,
.uni-popup__wrapper-box { .share-popup,
.share-title { .uni-popup__wrapper-box {
line-height: 60rpx; .share-title {
font-size: $font-size-toolbar; line-height: 60rpx;
padding: 15rpx 0; font-size: $font-size-toolbar;
text-align: center; padding: 15rpx 0;
} text-align: center;
}
.share-content {
display: flex; .share-content {
display: -webkit-flex; display: flex;
-webkit-flex-wrap: wrap; display: -webkit-flex;
-moz-flex-wrap: wrap; -webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap; -moz-flex-wrap: wrap;
-o-flex-wrap: wrap; -ms-flex-wrap: wrap;
flex-wrap: wrap; -o-flex-wrap: wrap;
padding: 80rpx 15rpx; flex-wrap: wrap;
padding: 80rpx 15rpx;
.share-box {
flex: 1; .share-box {
text-align: center; flex: 1;
text-align: center;
.share-btn {
margin: 0; .share-btn {
padding: 0; margin: 0;
border: none; padding: 0;
line-height: 1; border: none;
height: auto; line-height: 1;
text { height: auto;
margin-top: 20rpx; text {
font-size: $font-size-tag; margin-top: 20rpx;
display: block; font-size: $font-size-tag;
color: $color-title; display: block;
} color: $color-title;
} }
}
.iconfont {
font-size: 80rpx; .iconfont {
line-height: initial; font-size: 80rpx;
} line-height: initial;
.icon-fuzhilianjie, }
.icon-pengyouquan, .icon-fuzhilianjie,
.icon-haowuquan, .icon-pengyouquan,
.icon-share-friend { .icon-haowuquan,
color: #07c160; .icon-share-friend {
} color: #07c160;
} }
} }
}
.share-footer {
height: 90rpx; .share-footer {
line-height: 90rpx; height: 90rpx;
border-top: 2rpx solid $color-line; line-height: 90rpx;
text-align: center; border-top: 2rpx solid $color-line;
} text-align: center;
} }
.poster-layer { }
.generate-poster { .poster-layer {
padding: 40rpx 0; .generate-poster {
.iconfont { padding: 40rpx 0;
font-size: 80rpx; .iconfont {
color: #07c160; font-size: 80rpx;
line-height: initial; color: #07c160;
} line-height: initial;
> view { }
text-align: center; > view {
&:last-child { text-align: center;
margin-top: 20rpx; &:last-child {
} margin-top: 20rpx;
} }
} }
.image-wrap { }
width: 64%; .image-wrap {
height: 854rpx; width: 64%;
margin: 60rpx auto 40rpx auto; height: 854rpx;
box-shadow: 0 0 32rpx rgba(100, 100, 100, 0.3); margin: 60rpx auto 40rpx auto;
image { box-shadow: 0 0 32rpx rgba(100, 100, 100, 0.3);
width: 480rpx; image {
height: 854rpx; width: 480rpx;
} height: 854rpx;
} }
.msg { }
padding: 40rpx; .msg {
} padding: 40rpx;
.save { }
text-align: center; .save {
height: 80rpx; text-align: center;
line-height: 80rpx; height: 80rpx;
} line-height: 80rpx;
.close { }
position: absolute; .close {
top: 0; position: absolute;
right: 20rpx; top: 0;
width: 40rpx; right: 20rpx;
height: 80rpx; width: 40rpx;
font-size: 50rpx; height: 80rpx;
} font-size: 50rpx;
} }
} }
</style> }
</style>

View File

@@ -1,58 +1,58 @@
<template> <template>
<page-meta :page-style="themeColor"></page-meta> <page-meta :page-style="themeColor"></page-meta>
<view> <view>
<view class="category-page-wrap category-template-1" style="height: calc(-56px + 100vh);"> <view class="category-page-wrap category-template-1" style="height: calc(-56px + 100vh);">
<!-- <view class="search-box" @click="$util.redirectTo('/pages_tool/goods/search')"> <!-- <view class="search-box" @click="$util.redirectTo('/pages_tool/goods/search')">
<view class="search-content"> <view class="search-content">
<input type="text" class="uni-input" maxlength="50" placeholder="商品搜索" confirm-type="search" disabled="true" /> <input type="text" class="uni-input" maxlength="50" placeholder="商品搜索" confirm-type="search" disabled="true" />
<text class="iconfont icon-sousuo3"></text> <text class="iconfont icon-sousuo3"></text>
</view> </view>
</view> --> </view> -->
<view class="content-box" v-if="categoryTree"> <view class="content-box" v-if="categoryTree">
<block v-if="categoryTree.length"> <block v-if="categoryTree.length">
<scroll-view scroll-y="true" class="tree-wrap"> <scroll-view scroll-y="true" class="tree-wrap">
<view class="category-item-wrap"> <view class="category-item-wrap">
<view class="category-item" v-for="(item, index) in categoryTree" :key="index" :class="[ <view class="category-item" v-for="(item, index) in categoryTree" :key="index" :class="[
{ select: select == index }, { select: select == index },
]" @click="switchOneCategory(index)"> ]" @click="switchOneCategory(index)">
<view class="">{{ item.category_name }}</view> <view class="">{{ item.category_name }}</view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
<view class="right-flex-wrap"> <view class="right-flex-wrap">
<scroll-view scroll-y="true" class="content-wrap" ref="contentWrap" :scroll-into-view="categoryId" :scroll-with-animation="true" <scroll-view scroll-y="true" class="content-wrap" ref="contentWrap" :scroll-into-view="categoryId" :scroll-with-animation="true"
@scroll="listenScroll" @touchstart="touchStart" :refresher-enabled="true" @scroll="listenScroll" @touchstart="touchStart" :refresher-enabled="true"
refresher-default-style="none" :refresher-triggered="triggered" @refresherrefresh="onRefresh" refresher-default-style="none" :refresher-triggered="triggered" @refresherrefresh="onRefresh"
@refresherrestore="onRestore"> @refresherrestore="onRestore">
<view class="child-category" v-for="(item, index) in categoryTree" :id="'category-' + index" v-if="item.child_list.length > 0"> <view class="child-category" v-for="(item, index) in categoryTree" :id="'category-' + index" v-if="item.child_list.length > 0" :key="item.category_id || index">
<!----> <!---->
<view class="item-wrap category"> <view class="item-wrap category">
<view class="category-title">{{ item.category_name }}</view> <view class="category-title">{{ item.category_name }}</view>
<view class="category-list"> <view class="category-list">
<view class="category-item" v-for="(one, oneIndex) in item.child_list" :key="oneIndex" @click="$util.redirectTo('/pages_promotion/merch/detail', { merch_id: one.merch_id })"> <view class="category-item" v-for="(one, oneIndex) in item.child_list" :key="oneIndex" @click="$util.redirectTo('/pages_promotion/merch/detail', { merch_id: one.merch_id })">
<view class="img-box"> <view class="img-box">
<image :src="$util.img(one.merch_image)" mode="widthFix"/> <image :src="$util.img(one.merch_image)" mode="widthFix"/>
</view> </view>
<view class="name">{{ one.merch_name }}</view> <view class="name">{{ one.merch_name }}</view>
</view> </view>
</view> </view>
</view> </view>
<!-- <view class="category-empty" v-else> <!-- <view class="category-empty" v-else>
<image src="/static/common-empty.png" mode="widthFix"/> <image src="/static/common-empty.png" mode="widthFix"/>
</view> --> </view> -->
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
</block> </block>
<!-- <view class="category-empty"> <!-- <view class="category-empty">
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix"></image> <image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix"></image>
<view class="tips">暂时没有分类哦</view> <view class="tips">暂时没有分类哦</view>
</view> --> </view> -->
</view> </view>
</view> </view>
<ns-login ref="login"></ns-login> <ns-login ref="login"></ns-login>
<!-- <loading-cover ref="loadingCover"></loading-cover> --> <!-- <loading-cover ref="loadingCover"></loading-cover> -->
@@ -64,34 +64,34 @@
export default { export default {
components: {}, components: {},
data() { data() {
return { return {
scrollTop: 0, scrollTop: 0,
select: 0, select: 0,
categoryId: 'category-0', categoryId: 'category-0',
scrollLock: false, scrollLock: false,
triggered: true, triggered: true,
heightArea: [], heightArea: [],
loadType: '', loadType: '',
categoryTree:[ categoryTree:[
/*{ /*{
category_id:6277, category_id:6277,
category_name:"物业", category_name:"物业",
child_list:[ child_list:[
{ {
category_id:6572, category_id:6572,
category_name:"鞋里革", category_name:"鞋里革",
image:"attachment\/images\/979\/2024\/04\/y46Gg41i552o9iq9249295oz991444.jpg", image:"attachment\/images\/979\/2024\/04\/y46Gg41i552o9iq9249295oz991444.jpg",
} }
] ]
},*/ },*/
], ],
user_type:uni.getStorageSync('user_type') user_type:uni.getStorageSync('user_type')
}; };
}, },
onLoad() { onLoad() {
uni.hideTabBar() uni.hideTabBar()
this.getCategory() this.getCategory()
// this.getgoodslist() // this.getgoodslist()
}, },
@@ -101,118 +101,118 @@
onUnload() { onUnload() {
if (!this.storeToken && this.$refs.login) this.$refs.login.cancelCompleteInfo(); if (!this.storeToken && this.$refs.login) this.$refs.login.cancelCompleteInfo();
}, },
methods: { methods: {
switchOnetype(e){ switchOnetype(e){
this.goods_type = e this.goods_type = e
this.select = -1; this.select = -1;
this.categoryId = '' this.categoryId = ''
this.getgoodslist() this.getgoodslist()
},
/**
* 切换一级分类
* @param {Object} index
*/
switchOneCategory(index) {
if (index >= this.categoryTree.length) return;
this.select = index;
this.categoryId = 'category-' + index;
// 阻止切换分类之后滚动事件也立即执行
this.scrollLock = true;
console.log(index)
// this.goodsList = []
// this.getgoodslist()
},
touchStart() {
this.scrollLock = false;
},
/**
* 监听滚动
* @param {Object} event
*/
listenScroll(event) {
if (this.scrollLock) return;
let scrollTop = event.detail.scrollTop;
if (this.heightArea.length) {
for (let i = 0; i < this.heightArea.length; i++) {
if (scrollTop >= this.heightArea[i][0] && scrollTop <= this.heightArea[i][1]) {
this.select = i;
break;
}
}
if (this.value.template != 1 && this.value.loadType == 'all' && this.heightArea[this.select][1] -
scrollTop - contentWrapHeight < 300) {
this.$refs.categoryItem[this.select].getGoodsList();
}
}
},
sethead(item,type){
var is_select = item.is_select
this.$api.sendRequest({
url: 'app.ajax_batchheads',
data: {
goods_id:item.actId,
is_select:is_select
},
success: res => {
this.$util.showToast({
title: res.result.message
});
this.getgoodslist()
},
fail: () => {
this.$util.showToast({
title: 'request:fail'
});
}
});
},
//获取分类列表
getCategory(){
this.$api.sendRequest({
url: '/merch/api/merch/getcategory',
data: {
is_type_show:1,
},
success: res => {
console.log( res.data)
this.categoryTree = res.data
},
fail: () => {
this.$util.showToast({
title: 'request:fail'
});
}
});
},
onRefresh() {
this.triggered = false;
},
onRestore() {
this.triggered = 'restore'; // 需要重置
},
/**
* 触摸开始
* @param {Object} e
*/
// touchstart(e) {
// this.touchstartPosition = e.changedTouches[0].clientY;
// },
/**
* 触摸结束
* @param {Object} e
*/
touchend(e) {
let end = e.changedTouches[0].clientY;
if ((this.scrollType == 'top' || this.scrollType == 'none') && end - this.touchstartPosition > 100) {
// this.switchCategory('prev');
} else if ((this.scrollType == 'bottom' || this.scrollType == 'none') && this.touchstartPosition - end >
100) {
// this.switchCategory('next');
}
}, },
/** getDiyInfo() {
* 切换一级分类
* @param {Object} index
*/
switchOneCategory(index) {
if (index >= this.categoryTree.length) return;
this.select = index;
this.categoryId = 'category-' + index;
// 阻止切换分类之后滚动事件也立即执行
this.scrollLock = true;
console.log(index)
// this.goodsList = []
// this.getgoodslist()
},
touchStart() {
this.scrollLock = false;
},
/**
* 监听滚动
* @param {Object} event
*/
listenScroll(event) {
if (this.scrollLock) return;
let scrollTop = event.detail.scrollTop;
if (this.heightArea.length) {
for (let i = 0; i < this.heightArea.length; i++) {
if (scrollTop >= this.heightArea[i][0] && scrollTop <= this.heightArea[i][1]) {
this.select = i;
break;
}
}
if (this.value.template != 1 && this.value.loadType == 'all' && this.heightArea[this.select][1] -
scrollTop - contentWrapHeight < 300) {
this.$refs.categoryItem[this.select].getGoodsList();
}
}
},
sethead(item,type){
var is_select = item.is_select
this.$api.sendRequest({
url: 'app.ajax_batchheads',
data: {
goods_id:item.actId,
is_select:is_select
},
success: res => {
this.$util.showToast({
title: res.result.message
});
this.getgoodslist()
},
fail: () => {
this.$util.showToast({
title: 'request:fail'
});
}
});
},
//获取分类列表
getCategory(){
this.$api.sendRequest({
url: '/merch/api/merch/getcategory',
data: {
is_type_show:1,
},
success: res => {
console.log( res.data)
this.categoryTree = res.data
},
fail: () => {
this.$util.showToast({
title: 'request:fail'
});
}
});
},
onRefresh() {
this.triggered = false;
},
onRestore() {
this.triggered = 'restore'; // 需要重置
},
/**
* 触摸开始
* @param {Object} e
*/
// touchstart(e) {
// this.touchstartPosition = e.changedTouches[0].clientY;
// },
/**
* 触摸结束
* @param {Object} e
*/
touchend(e) {
let end = e.changedTouches[0].clientY;
if ((this.scrollType == 'top' || this.scrollType == 'none') && end - this.touchstartPosition > 100) {
// this.switchCategory('prev');
} else if ((this.scrollType == 'bottom' || this.scrollType == 'none') && this.touchstartPosition - end >
100) {
// this.switchCategory('next');
}
},
getDiyInfo() {
}, },
toLogin() { toLogin() {
@@ -226,8 +226,8 @@
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import './public/category.scss'; @import './public/category.scss';
/deep/ .uni-popup__wrapper.uni-center { /deep/ .uni-popup__wrapper.uni-center {
background: rgba(0, 0, 0, 0.6); background: rgba(0, 0, 0, 0.6);

View File

@@ -1,159 +1,165 @@
<template> <template>
<page-meta :page-style="themeColor"></page-meta> <page-meta :page-style="themeColor"></page-meta>
<view class="page"> <view class="page">
<view class="help-title">{{ detail.article_title }}</view> <view class="help-title">{{ detail.article_title }}</view>
<view class="help-meta" v-if="detail.is_show_release_time == 1"> <view class="help-meta" v-if="detail.is_show_release_time == 1">
<text class="help-time">发表时间: {{ $util.timeStampTurnTime(detail.create_time) }}</text> <text class="help-time">发表时间: {{ $util.timeStampTurnTime(detail.create_time) }}</text>
</view> </view>
<view class="help-content"><rich-text :nodes="content"></rich-text></view> <view class="help-content">
<view class="bottom-area"> <!-- <rich-text :nodes="content"></rich-text> -->
<view v-if="detail.is_show_read_num == 1"> <ns-mp-html :content="content"></ns-mp-html>
阅读 </view>
<text class="price-font">{{ detail.read_num + detail.initial_read_num }}</text> <view class="bottom-area">
</view> <view v-if="detail.is_show_read_num == 1">
<view v-if="detail.is_show_dianzan_num == 1"> 阅读
<text class="price-font">{{ detail.dianzan_num + detail.initial_dianzan_num }}</text> <text class="price-font">{{ detail.read_num + detail.initial_read_num }}</text>
人已赞 </view>
</view> <view v-if="detail.is_show_dianzan_num == 1">
</view> <text class="price-font">{{ detail.dianzan_num + detail.initial_dianzan_num }}</text>
<loading-cover ref="loadingCover"></loading-cover> 人已赞
</view>
<!-- #ifdef MP-WEIXIN --> </view>
<!-- 小程序隐私协议 --> <!-- 悬浮按钮 -->
<privacy-popup ref="privacyPopup"></privacy-popup> <hover-nav></hover-nav>
<!-- #endif --> <loading-cover ref="loadingCover"></loading-cover>
</view>
</template> <!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<script> <privacy-popup ref="privacyPopup"></privacy-popup>
import htmlParser from '@/common/js/html-parser'; <!-- #endif -->
export default { </view>
data() { </template>
return {
articleId: 0, <script>
detail: {}, import htmlParser from '@/common/js/html-parser';
content: '' export default {
}; data() {
}, return {
onLoad(options) { articleId: 0,
this.articleId = options.article_id || 0; detail: {},
// 小程序扫码进入 content: ''
if (options.scene) { };
var sceneParams = decodeURIComponent(options.scene); },
this.articleId = sceneParams.split('-')[1]; onLoad(options) {
} this.articleId = options.article_id || 0;
if (this.articleId == 0) { // 小程序扫码进入
this.$util.redirectTo('/pages_tool/article/list', {}, 'redirectTo'); if (options.scene) {
} var sceneParams = decodeURIComponent(options.scene);
}, this.articleId = sceneParams.split('-')[1];
onShow() { }
this.getData(); if (this.articleId == 0) {
}, this.$util.redirectTo('/pages_tool/article/list', {}, 'redirectTo');
methods: { }
getData() { },
this.$api.sendRequest({ onShow() {
url: '/api/article/info', this.getData();
data: { },
article_id: this.articleId methods: {
}, getData() {
success: res => { this.$api.sendRequest({
if (res.code == 0 && res.data) { url: '/api/article/info',
this.detail = res.data; data: {
this.$langConfig.title(this.detail.article_title); article_id: this.articleId
this.content = htmlParser(this.detail.article_content); },
this.setPublicShare(); success: res => {
} else { if (res.code == 0 && res.data) {
this.$util.showToast({ this.detail = res.data;
title: res.message this.$langConfig.title(this.detail.article_title);
}); // this.content = htmlParser(this.detail.article_content);
setTimeout(() => { this.content = this.detail.article_content;
this.$util.redirectTo('/pages_tool/article/list', {}, 'redirectTo'); this.setPublicShare();
}, 2000); } else {
} this.$util.showToast({
if (this.$refs.loadingCover) this.$refs.loadingCover.hide(); title: res.message
}, });
fail: res => { setTimeout(() => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide(); this.$util.redirectTo('/pages_tool/article/list', {}, 'redirectTo');
} }, 2000);
}); }
}, if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
// 设置公众号分享 },
setPublicShare() { fail: res => {
let shareUrl = this.$config.h5Domain + '/pages_tool/article/detail?article_id=' + this.articleId; if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
this.$util.setPublicShare({ }
title: this.detail.article_title, });
desc: '', },
link: shareUrl, // 设置公众号分享
imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : '' setPublicShare() {
}); let shareUrl = this.$config.h5Domain + '/pages_tool/article/detail?article_id=' + this.articleId;
} this.$util.setPublicShare({
}, title: this.detail.article_title,
onShareAppMessage(res) { desc: '',
var title = this.detail.article_title; link: shareUrl,
var path = '/pages_tool/article/detail?article_id=' + this.articleId; imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : ''
return { });
title: title, }
path: path, },
success: res => {}, onShareAppMessage(res) {
fail: res => {} var title = this.detail.article_title;
}; var path = '/pages_tool/article/detail?article_id=' + this.articleId;
}, return {
//分享到朋友圈 title: title,
onShareTimeline() { path: path,
var title = this.detail.article_title; success: res => {},
var query = 'article_id=' + this.articleId; fail: res => {}
return { };
title: title, },
query: query, //分享到朋友圈
imageUrl: '' onShareTimeline() {
}; var title = this.detail.article_title;
} var query = 'article_id=' + this.articleId;
}; return {
</script> title: title,
query: query,
<style lang="scss"> imageUrl: ''
.page { };
width: 100%; }
height: 100%; };
padding: 30rpx; </script>
box-sizing: border-box;
background: #ffffff; <style lang="scss">
} .page {
width: 100%;
.help-title { height: 100%;
font-size: $font-size-toolbar; padding: 30rpx;
text-align: left; box-sizing: border-box;
font-weight: bold; background: #ffffff;
} }
.help-content { .help-title {
margin-top: $margin-updown; font-size: $font-size-toolbar;
word-break: break-all; text-align: left;
} font-weight: bold;
}
.help-meta {
text-align: left; .help-content {
margin-top: $margin-updown; margin-top: $margin-updown;
color: $color-tip; word-break: break-all;
}
.help-time {
font-size: $font-size-tag; .help-meta {
} text-align: left;
} margin-top: $margin-updown;
color: $color-tip;
.bottom-area {
display: flex; .help-time {
align-items: center; font-size: $font-size-tag;
justify-content: space-between; }
margin-top: 40rpx; }
.price-font { .bottom-area {
font-weight: normal !important; display: flex;
} align-items: center;
justify-content: space-between;
view { margin-top: 40rpx;
color: #999;
font-size: 24rpx; .price-font {
} font-weight: normal !important;
} }
view {
color: #999;
font-size: 24rpx;
}
}
</style> </style>

Some files were not shown because too many files have changed in this diff Show More