1234 changed files with 297168 additions and 3 deletions
@ -0,0 +1,13 @@ |
|||||
|
/unpackage |
||||
|
/.hbuilderx |
||||
|
/.idea |
||||
|
node_modules/ |
||||
|
dist/** |
||||
|
.project |
||||
|
unpackage/* |
||||
|
!unpackage/res/icons/* |
||||
|
.DS_Store |
||||
|
wxcomponents/**/*.vue |
||||
|
wxcomponents/**/*.css |
||||
|
.hbuilderx/ |
||||
|
*.rar |
||||
Binary file not shown.
@ -0,0 +1,392 @@ |
|||||
|
<script> |
||||
|
import auth from 'common/js/auth.js'; |
||||
|
import { Weixin } from 'common/js/wx-jssdk.js'; |
||||
|
// #ifdef APP-PLUS |
||||
|
import appUpdate from "@/config/appUpdate" |
||||
|
var jpushModule = uni.requireNativePlugin('JG-JPush'); |
||||
|
// #endif |
||||
|
|
||||
|
function getQueryParams(url) { |
||||
|
const paramArr = url.slice(url.indexOf("?") + 1).split("&"); |
||||
|
const params = {}; |
||||
|
paramArr.forEach((param) => { |
||||
|
const [key, val] = param.split("="); |
||||
|
params[key] = decodeURIComponent(val); |
||||
|
}); |
||||
|
return params; |
||||
|
} |
||||
|
|
||||
|
export default { |
||||
|
mixins: [auth], |
||||
|
// onLoad() { |
||||
|
// // 判断登录 |
||||
|
// if (!uni.getStorageSync('token')) { |
||||
|
// this.$util.redirectTo('/pages_tool/login/login'); |
||||
|
// } |
||||
|
// }, |
||||
|
onLaunch: function(e) { |
||||
|
|
||||
|
// #ifdef MP-ALIPAY |
||||
|
console.log(e, 'onLaunchonLaunchonLaunch'); |
||||
|
uni.removeStorageSync('schemeData') |
||||
|
if (e.path == "pages_tool/pay/index") { |
||||
|
uni.setStorageSync('schemeData', e.query); |
||||
|
} |
||||
|
// #endif |
||||
|
|
||||
|
// #ifdef APP-PLUS |
||||
|
if (!this.$isIOS) |
||||
|
setTimeout(() => { |
||||
|
if (jpushModule) { |
||||
|
jpushModule.initJPushService(); |
||||
|
jpushModule.setLoggerEnable(true); |
||||
|
var registerID; |
||||
|
jpushModule.getRegistrationID(result => { |
||||
|
registerID = result.registerID; |
||||
|
console.log(registerID, `registerID`); |
||||
|
if (registerID) { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/jpush/setRegistrationId', |
||||
|
data: { |
||||
|
registration_id: registerID |
||||
|
}, |
||||
|
success: res => { |
||||
|
console.log(res, `registerID_res`); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}, 30000); |
||||
|
|
||||
|
// #endif |
||||
|
uni.hideTabBar(); |
||||
|
uni.setStorageSync('DIY_VIEW_INDEX_popwindow_count', 1); |
||||
|
|
||||
|
// #ifdef MP |
||||
|
const updateManager = uni.getUpdateManager(); |
||||
|
updateManager.onCheckForUpdate(function(res) { |
||||
|
// 请求完新版本信息的回调 |
||||
|
}); |
||||
|
|
||||
|
updateManager.onUpdateReady(function(res) { |
||||
|
uni.showModal({ |
||||
|
title: '更新提示', |
||||
|
content: '新版本已经准备好,是否重启应用?', |
||||
|
success(res) { |
||||
|
if (res.confirm) { |
||||
|
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启 |
||||
|
updateManager.applyUpdate(); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
updateManager.onUpdateFailed(function(res) { |
||||
|
// 新的版本下载失败 |
||||
|
}); |
||||
|
// #endif |
||||
|
|
||||
|
// #ifdef H5 |
||||
|
if (uni.getSystemInfoSync().platform == 'ios') { |
||||
|
uni.setStorageSync('initUrl', location.href); |
||||
|
} |
||||
|
// #endif |
||||
|
|
||||
|
uni.onNetworkStatusChange(function(res) { |
||||
|
if (!res.isConnected) { |
||||
|
uni.showModal({ |
||||
|
title: '网络失去链接', |
||||
|
content: '请检查网络链接', |
||||
|
showCancel: false |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
this.$store.dispatch('init'); |
||||
|
|
||||
|
|
||||
|
// #ifdef APP-PLUS || H5 || MP-WEIXIN |
||||
|
const userType = uni.getStorageSync('user_type'); |
||||
|
if (userType && Number(userType) === 2) { |
||||
|
// 自动授权登录 |
||||
|
if (!uni.getStorageSync('token')) { |
||||
|
this.getAuthInfo(); |
||||
|
} else { |
||||
|
// 启动小程序/app 更新用户登录信息 |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/login/loginLog', |
||||
|
success(res) {} |
||||
|
}) |
||||
|
|
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/member/info', |
||||
|
complete: () => { |
||||
|
if (!uni.getStorageSync('token')) this.getAuthInfo(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
// #endif |
||||
|
|
||||
|
|
||||
|
// #ifdef APP-PLUS |
||||
|
// ios 通知打开 |
||||
|
setTimeout(() => { |
||||
|
if (jpushModule) { |
||||
|
jpushModule.addNotificationListener(result => { |
||||
|
let notificationEventType = result.notificationEventType |
||||
|
let extras = result.extras |
||||
|
if (notificationEventType === 'notificationOpened' && extras.schemes) { |
||||
|
this.checkArgs(extras.schemes); |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}, 30000); |
||||
|
|
||||
|
// #endif |
||||
|
}, |
||||
|
onLoad() { |
||||
|
console.log('onLoad'); |
||||
|
}, |
||||
|
onShow(e) { |
||||
|
uni.removeStorageSync('schemeData') |
||||
|
if (e.path == "pages_tool/pay/index") { |
||||
|
uni.setStorageSync('schemeData', e.query); |
||||
|
} |
||||
|
console.log('onShow', e); |
||||
|
// #ifdef APP-PLUS |
||||
|
setTimeout(() => { |
||||
|
// 清除角标 |
||||
|
if (jpushModule) |
||||
|
jpushModule.setBadge(0) |
||||
|
// 同步服务器角标数据 |
||||
|
plus.runtime.setBadgeNumber(0); |
||||
|
this.checkArgs(this.getArgs()); |
||||
|
}, 0); |
||||
|
// #endif |
||||
|
}, |
||||
|
onHide: function() {}, |
||||
|
methods: { |
||||
|
getArgs() { |
||||
|
// console.log(plus.runtime.launcher, plus.runtime.arguments, 'plus.runtime.launcher') |
||||
|
// const urlSchemeArgs = uni.getStorageSync('urlSchemeArgs') |
||||
|
// if (urlSchemeArgs === plus.runtime.arguments) return |
||||
|
if (plus.runtime.launcher === 'default') return |
||||
|
// uni.setStorageSync('urlSchemeArgs', plus.runtime.arguments) |
||||
|
plus.runtime.launcher = 'default' |
||||
|
return plus.runtime.arguments |
||||
|
}, |
||||
|
checkArgs(args) { |
||||
|
if (!args) return |
||||
|
const runtimeArguments = args.split('://') |
||||
|
if (runtimeArguments.length < 1) return |
||||
|
// const scheme = runtimeArguments[0] |
||||
|
const url = runtimeArguments[1] |
||||
|
let path = url.split('?') |
||||
|
if (path.length < 0) return |
||||
|
path = path[0] |
||||
|
const params = getQueryParams(decodeURIComponent(url)) |
||||
|
|
||||
|
if (path === 'target') { |
||||
|
// 判断登录 TODO |
||||
|
if (!uni.getStorageSync('token')) { |
||||
|
this.$util.showToast({ |
||||
|
title: '您尚未登录,请先进行登录', |
||||
|
icon: 'none', |
||||
|
}); |
||||
|
setTimeout(() => { |
||||
|
this.$util.redirectTo('/pages_tool/login/login'); |
||||
|
}, 1000) |
||||
|
return |
||||
|
} |
||||
|
console.log(params, 'params') |
||||
|
// 进行跳转 |
||||
|
this.$util.redirectTo(params.path, params); |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* 获取授权信息 |
||||
|
*/ |
||||
|
getAuthInfo() { |
||||
|
// #ifdef H5 |
||||
|
if (this.$util.isWeiXin()) { |
||||
|
this.$util.getUrlCode(urlParams => { |
||||
|
if (urlParams.source_member) |
||||
|
uni.setStorageSync('source_member', urlParams.source_member); |
||||
|
|
||||
|
if (urlParams.code == undefined) { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/wechat/api/wechat/authcode', |
||||
|
data: { |
||||
|
redirect_url: location.href, |
||||
|
scopes: 'snsapi_userinfo' |
||||
|
}, |
||||
|
success: res => { |
||||
|
if (res.code >= 0) { |
||||
|
location.href = res.data; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} else { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/wechat/api/wechat/authcodetoopenid', |
||||
|
data: { |
||||
|
code: urlParams.code |
||||
|
}, |
||||
|
success: res => { |
||||
|
if (res.code >= 0) { |
||||
|
let data = {}; |
||||
|
if (res.data.openid) data.wx_openid = res.data.openid; |
||||
|
if (res.data.unionid) data.wx_unionid = res.data.unionid; |
||||
|
if (res.data.userinfo) Object.assign(data, res.data.userinfo); |
||||
|
this.authLogin(data); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
// #endif |
||||
|
|
||||
|
// #ifdef MP |
||||
|
this.getCode(data => { |
||||
|
this.authLogin(data, 'authOnlyLogin'); |
||||
|
}); |
||||
|
// #endif |
||||
|
}, |
||||
|
/** |
||||
|
* 授权登录 |
||||
|
*/ |
||||
|
authLogin(data, type = 'authLogin') { |
||||
|
if (uni.getStorageSync('source_member')) |
||||
|
data.source_member = uni.getStorageSync('source_member'); |
||||
|
|
||||
|
uni.setStorage({ |
||||
|
key: 'authInfo', |
||||
|
data: data |
||||
|
}); |
||||
|
|
||||
|
this.$api.sendRequest({ |
||||
|
url: type == 'authLogin' ? '/api/login/auth' : '/api/login/authonlylogin', |
||||
|
data, |
||||
|
success: res => { |
||||
|
if (res.code >= 0) { |
||||
|
uni.setStorage({ |
||||
|
key: 'token', |
||||
|
data: res.data.token, |
||||
|
success: () => { |
||||
|
this.$store.dispatch('getCartNumber'); |
||||
|
this.$store.commit('setToken', res.data.token); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
/** |
||||
|
* 公众号分享设置 |
||||
|
*/ |
||||
|
shareConfig() { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/wechat/api/wechat/share', |
||||
|
data: { |
||||
|
url: window.location.href |
||||
|
}, |
||||
|
success: res => { |
||||
|
if (res.code == 0) { |
||||
|
var wxJS = new Weixin(); |
||||
|
wxJS.init(res.data.jssdk_config); |
||||
|
|
||||
|
let share_data = JSON.parse(JSON.stringify(res.data.share_config.data)); |
||||
|
if (share_data) { |
||||
|
wxJS.setShareData({ |
||||
|
title: share_data.title, |
||||
|
desc: share_data.desc, |
||||
|
link: share_data.link, |
||||
|
imgUrl: this.$util.img(share_data.imgUrl) |
||||
|
}, |
||||
|
res => { |
||||
|
console.log(res); |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
let hideOptionMenu = res.data.share_config.permission.hideOptionMenu; |
||||
|
let hideMenuItems = res.data.share_config.permission.hideMenuItems; |
||||
|
|
||||
|
if (hideOptionMenu) { |
||||
|
wxJS.weixin.hideOptionMenu(); //屏蔽分享好友等按钮 |
||||
|
} else { |
||||
|
wxJS.weixin.showOptionMenu(); //放开分享好友等按钮 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
fail: err => {} |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
$route: { |
||||
|
handler(newName, oldName) { |
||||
|
if (this.$util.isWeiXin()) { |
||||
|
this.shareConfig(); |
||||
|
} |
||||
|
}, |
||||
|
// 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法 |
||||
|
immediate: true |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
// @import 'uview-ui/index.scss'; |
||||
|
@import "@/uni_modules/uview-ui/index.scss"; |
||||
|
@import './common/css/iconfont.css'; |
||||
|
@import './common/css/icondiy.css'; // 自定义图标库 |
||||
|
@import './common/css/main.scss'; |
||||
|
|
||||
|
// ********** 这里要引用扩展图标库文件 ********** |
||||
|
@import './common/css/icon_extend/diy_default1.css'; |
||||
|
|
||||
|
.df { |
||||
|
display: flex; |
||||
|
} |
||||
|
|
||||
|
.aic { |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.jcsb { |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.jcsa { |
||||
|
justify-content: space-around; |
||||
|
} |
||||
|
|
||||
|
.jcc { |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.f1 { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.fn { |
||||
|
flex: none; |
||||
|
} |
||||
|
|
||||
|
.fdc { |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
|
||||
|
.fw { |
||||
|
flex-wrap: wrap; |
||||
|
} |
||||
|
|
||||
|
.jcf { |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
</style> |
||||
@ -1,3 +1,6 @@ |
|||||
# H5_QiCaiYao |
## 暂时注释的功能 |
||||
|
2024年10月25日需要打包一个apk到线上, 但是当前代码包含了一些不稳定的二期需求,所以对其进行注释,只保留支付功能的修改 |
||||
H5端齐采药项目,uniapp框架 |
|
||||
|
1. tabbar-视频 value.list = value.list.filter(item => item.text !=='视频') |
||||
|
2. 首页 —— 常购清单 value.list 改为 value.list.slice(0, value.list.length - 1) |
||||
|
3. 顺手购 , 只注释了html (搜索"顺手买一件") |
||||
@ -0,0 +1,23 @@ |
|||||
|
{ |
||||
|
"version": "3", |
||||
|
"prompt": "template", |
||||
|
"title": "用户协议和隐私政策", |
||||
|
"message": " 请你务必审慎阅读、充分理解“用户协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/> 你可阅读<a href=\"https://cbtadmin.jtyqt.com/h5/#/pages_tool/agreement/agreement?title=%E7%94%A8%E6%88%B7%E5%8D%8F%E8%AE%AE\">《用户协议》</a>和<a href=\"https://cbtadmin.jtyqt.com/h5/#/pages_tool/agreement/agreement?title=%E9%9A%90%E7%A7%81%E6%94%BF%E7%AD%96\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。", |
||||
|
"buttonAccept": "同意并接受", |
||||
|
"buttonRefuse": "不同意", |
||||
|
"hrefLoader": "system|default", |
||||
|
"backToExit": "false", |
||||
|
"disagreeMode": { |
||||
|
"support": false, |
||||
|
"loadNativePlugins": false, |
||||
|
"visitorEntry": false, |
||||
|
"showAlways": false |
||||
|
}, |
||||
|
"styles": { |
||||
|
"backgroundColor": "#ffffff", |
||||
|
"borderRadius": "5px", |
||||
|
"buttonAccept": { |
||||
|
"color": "#56a4e1" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
// 服务器基本路径设置
|
||||
|
export const SERVERIP = '' |
||||
|
|
||||
|
|
||||
@ -0,0 +1,18 @@ |
|||||
|
import { |
||||
|
SERVERIP |
||||
|
} from './http' |
||||
|
export const req = (url, data = {}, method = 'GET') => { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
uni.request({ |
||||
|
url: SERVERIP + url, |
||||
|
data: data, |
||||
|
method: method, |
||||
|
success(res) { |
||||
|
resolve(res) |
||||
|
}, |
||||
|
fail(err) { |
||||
|
reject(err) |
||||
|
} |
||||
|
}) |
||||
|
}) |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
import { req } from './request' |
||||
|
// export const $_login = (data) => req('/WeiXin/login',data,'post')
|
||||
|
|
||||
Binary file not shown.
@ -0,0 +1,76 @@ |
|||||
|
export default { |
||||
|
// 全局version,
|
||||
|
"globalVersionName": "1.000.176", |
||||
|
"globalVersionCode": "10001202", // 全局配置
|
||||
|
// app相关参数
|
||||
|
"app-plus": { |
||||
|
//项目名字或项目绝对路径
|
||||
|
project: "", |
||||
|
//打包平台 默认值android 值有"android","ios" 如果要打多个逗号隔开打包平台
|
||||
|
platform: "android", |
||||
|
//是否使用自定义基座 默认值false true自定义基座 false自定义证书
|
||||
|
iscustom: false, |
||||
|
//打包方式是否为安心打包默认值false,true安心打包,false传统打包
|
||||
|
safemode: true, |
||||
|
//android打包参数
|
||||
|
android: { |
||||
|
versionName: "", |
||||
|
versionCode: "", |
||||
|
//安卓包名
|
||||
|
packagename: "com.shenbeitang.www", |
||||
|
// "packagename": "com.anguoyaochang.www",
|
||||
|
//安卓打包类型 默认值0 0 使用自有证书 1 使用公共证书 2 使用老版证书
|
||||
|
androidpacktype: "0", |
||||
|
//安卓使用自有证书自有打包证书参数
|
||||
|
//安卓打包证书别名,自有证书打包填写的参数
|
||||
|
certalias: "__uni__9009737", |
||||
|
//安卓打包证书文件路径,自有证书打包填写的参数
|
||||
|
certfile: "ci/69c4b45540483f32c0978e50a63ba275.keystore", |
||||
|
//安卓打包证书密码,自有证书打包填写的参数
|
||||
|
certpassword: "EFoe4kFv", |
||||
|
//安卓平台要打的渠道包 取值有"google","yyb","360","huawei","xiaomi","oppo","vivo",如果要打多个逗号隔开
|
||||
|
channels: "", |
||||
|
}, |
||||
|
//ios打包参数
|
||||
|
ios: { |
||||
|
versionName: "1.000.165", |
||||
|
versionCode: "1000169", |
||||
|
//ios appid
|
||||
|
bundle: "com.shenbeitang.www", |
||||
|
//ios打包支持的设备类型 默认值iPhone 值有"iPhone","iPad" 如果要打多个逗号隔开打包平台
|
||||
|
supporteddevice: "iPhone", |
||||
|
//iOS使用自定义证书打包的profile文件路径
|
||||
|
profile: "ci/shenbeitang.mobileprovision", |
||||
|
// "profile": "ci/test.mobileprovision",
|
||||
|
//iOS使用自定义证书打包的p12文件路径
|
||||
|
certfile: "ci/shenbeitang_Chuxueyun.p12", |
||||
|
//iOS使用自定义证书打包的证书密码
|
||||
|
certpassword: "123456", |
||||
|
}, |
||||
|
//是否混淆 true混淆 false关闭
|
||||
|
isconfusion: true, |
||||
|
//开屏广告 true打开 false关闭
|
||||
|
splashads: false, |
||||
|
//悬浮红包广告true打开 false关闭
|
||||
|
rpads: false, |
||||
|
//push广告 true打开 false关闭
|
||||
|
pushads: false, |
||||
|
//加入换量联盟 true加入 false不加入
|
||||
|
exchange: false, |
||||
|
}, |
||||
|
// 小程序相关参数
|
||||
|
miniprogram: { |
||||
|
"mp-weixin": { |
||||
|
versionName: "", |
||||
|
versionCode: "", |
||||
|
appId: "wxf53bc93b7fc90601", |
||||
|
privateKeyPath: "./ci/private.wxf53bc93b7fc90601.key", |
||||
|
}, |
||||
|
}, |
||||
|
h5: { |
||||
|
domain: "cbtadmin.jtyqt.com", |
||||
|
path: "/", |
||||
|
distfilename: 'h5', |
||||
|
dist: '/www/wwwroot/cbtadmin.jtyqt.com/yaochang_php_v2/h5' |
||||
|
}, |
||||
|
}; |
||||
@ -0,0 +1,27 @@ |
|||||
|
-----BEGIN RSA PRIVATE KEY----- |
||||
|
MIIEpgIBAAKCAQEAuhQjNsrTDVvy4ibKNrZLNNpG+IWsPHVGDQmD/o//ydv4TFFF |
||||
|
fz9aSIEFw6ZCZTJnqJwQGYHjVVnUbCEdF3CSgPwY/aFSzbsaiAB7XQmAUHoyUTLv |
||||
|
eGhhw2wMNH6SRNzjJXBD8nHR+1WnePsLEe6azmbFqEJCyFwbCqZoAPVyolsU+IAk |
||||
|
jZaDDdn6TpZox+dQK88Mv+jdhtdhOmuS1tbESRdboaBDdHIWhU54QlvMQEouDK2V |
||||
|
deM114tL1D1JJYqHT+5UBZgrJ6mRtv+albsxsXxWP3uuqjISEsc+x8qPnXRrSctB |
||||
|
VibdgXNLmWbwiFfQpPPCG+KAOhbWRQSr1hks7wIDAQABAoIBAQCFu8VXMsweVNAp |
||||
|
4xD/42IHuTy6jm+r/+j5o7YetWVzsUkxqFNXUbPUWg5Hf+1GB8TiNE+J1YUKKYZ2 |
||||
|
tBHRb9GLLCPV3STCwU8fIaGHyzVSIZCaNQ5QrkxdBAF9lN4Q6ePCW34p982fYf77 |
||||
|
/wkEuUS/RLOX6w9OKowwykoDLmRV8/6seg8vtdphhNGWp+D0DHTs2AR02pOpsq6U |
||||
|
fylZITLgiqys9KwKtzfOZMoxgZQii9+SoLmq0sLcOk7MhfjdA+h53VZguXAWdq28 |
||||
|
O6d1W11rB7Fymrr9iXO7jX8qbPdWApaHNNYiKnYRWNDacwF++2x251koHmX1I421 |
||||
|
fYMfMKzhAoGBAPHZSrtzylt0uR7bx+zKe8dMLeaFqy5XzFWD/+wMUwL48L1gQ/V0 |
||||
|
RmU9sIneAZel/EuPvXjyzwwZkm4e4frU4mFvG9JK/ZU4L4ZMq5PhunkxQgzpEyZz |
||||
|
MMkl03R+mdP2RyE+sd4c4XHz0crY7sKLauhLRotCuoEmgnc12PfZ02LRAoGBAMT3 |
||||
|
c74QX2ynpmGma+SqW7JkD+kBxRCsE4+jdAy1gqbZ0dWdNlywkP1V6z+IC8zeARBf |
||||
|
xXtoCWMM1b59bjDeG3fFQZ8HhHGpdQ3XAythG3Dm284WxHbMnCbm018ExE2x8Fpj |
||||
|
Tcv0BNrfBGIV3IzrAvz1Yhm2o+D9eN1uYzVuGgO/AoGBAKhRDSTW2k+6NZhXZ5XR |
||||
|
+kFjMFLOVqujKS+e9X8nuKJJ9Oon1ERAzzlorLPW0Y7kU2mXOUuy2QxXw8RmM+op |
||||
|
PQCInnlF/aRbfR/fvk3mfKwZ7xkjIVPSOXLUo4zhC1gsf6aQhqPJv9FZ2nltbwXw |
||||
|
l8/hi9Ah+cEmtwgWbtFYRTjxAoGBAI56bZgsIcroTxvOFbf4X5JgfX3QkOupfhDm |
||||
|
bPkQh60IXZiHO566/nazIxP25opQgTaGAMVvEXM8ApXkB8SDthzibMCL4IuTyB+1 |
||||
|
zA4iFYaLCK9AmudQxRgC2x2dxh5pu/K2aL1DDAwDTRlitQKesa+oFUmCa3NCB58t |
||||
|
zcgFl/3jAoGBAKLqX2u3S9QhahdA4QKixYy3t4twsgeS5Z8X5k40j5sTip3VqvmH |
||||
|
UDWB6q5CA3NrhK2wa6A6cJjXug86cGcPAbGAXuzMae6F/K4czsQL/fdqHgEXFLsN |
||||
|
OkloythGbiXHpVfRZytdfYHa8WNC3oUI+rMSxEYqcKqcipDuyDMcbgTY |
||||
|
-----END RSA PRIVATE KEY----- |
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,124 @@ |
|||||
|
.collectPopupWindow { |
||||
|
position: relative; |
||||
|
height: 113rpx; |
||||
|
width: 510rpx; |
||||
|
margin-left: calc(100% - 530rpx); |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
text { |
||||
|
color: #ff4544 !important; |
||||
|
font-size: 24rpx !important; |
||||
|
position: absolute; |
||||
|
top: 48rpx; |
||||
|
right: 25rpx; |
||||
|
} |
||||
|
} |
||||
|
.zhezhao { |
||||
|
width: 100vw; |
||||
|
height: 100vh; |
||||
|
background-color: transparent; |
||||
|
} |
||||
|
image { |
||||
|
max-width: 100% !important; |
||||
|
max-height: 100% !important; |
||||
|
} |
||||
|
.diy-wrap { |
||||
|
/* #ifdef H5 */ |
||||
|
height: calc(100vh - 88rpx); |
||||
|
/* #endif */ |
||||
|
/* #ifdef MP-WEIXIN || MP-ALIPAY*/ |
||||
|
height: 100vh; |
||||
|
/* #endif */ |
||||
|
} |
||||
|
|
||||
|
.page-img { |
||||
|
background-size: contain !important; |
||||
|
background-repeat: no-repeat !important; |
||||
|
} |
||||
|
|
||||
|
.page-header { |
||||
|
background-size: contain !important; |
||||
|
background-repeat: no-repeat !important; |
||||
|
background-position: top center; |
||||
|
background-attachment: fixed; |
||||
|
} |
||||
|
|
||||
|
.bg-index { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
box-sizing: border-box; |
||||
|
background-size: contain !important; |
||||
|
background-repeat: no-repeat !important; |
||||
|
} |
||||
|
|
||||
|
.wap-floating { |
||||
|
text { |
||||
|
display: block; |
||||
|
font-size: 60rpx; |
||||
|
color: #ffffff; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
.wap-floating-collect .uni-popup__mask { |
||||
|
background: transparent; |
||||
|
} |
||||
|
|
||||
|
::-webkit-scrollbar { |
||||
|
width: 0; |
||||
|
height: 0; |
||||
|
color: transparent; |
||||
|
} |
||||
|
|
||||
|
.popup-box { |
||||
|
width: 450rpx; |
||||
|
background: #ffffff; |
||||
|
border-radius: $border-radius; |
||||
|
overflow: hidden; |
||||
|
|
||||
|
.close_title { |
||||
|
width: 100%; |
||||
|
text-align: center; |
||||
|
height: 70rpx; |
||||
|
line-height: 70rpx; |
||||
|
font-size: $font-size-base; |
||||
|
} |
||||
|
|
||||
|
.close_content { |
||||
|
width: 100%; |
||||
|
max-height: 500rpx; |
||||
|
padding: $padding; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.close_content_box { |
||||
|
width: 100%; |
||||
|
max-height: 460rpx; |
||||
|
line-height: 1.3; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.noStore-text { |
||||
|
color: #000000 !important; |
||||
|
} |
||||
|
|
||||
|
.isStore-top { |
||||
|
margin-bottom: 10rpx; |
||||
|
} |
||||
|
.keep-on-record { |
||||
|
text-align: center; |
||||
|
padding-bottom: 20rpx; |
||||
|
image { |
||||
|
width: 150rpx; |
||||
|
height: 60rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.padding-bottom{ |
||||
|
padding-bottom: 40rpx !important; |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,69 @@ |
|||||
|
@font-face { |
||||
|
font-family: "icondiy-my-template"; |
||||
|
src: url('https://cdn3.codesign.qq.com/icons/r2nL6jg1z80pJXV/latest/iconfont.eot?t=20d1e70f3aeb7dcbee56c813164786bc'); /* IE9 */ |
||||
|
src: url('https://cdn3.codesign.qq.com/icons/r2nL6jg1z80pJXV/latest/iconfont.eot?t=20d1e70f3aeb7dcbee56c813164786bc#iefix') format('embedded-opentype'), /* IE6-IE8 */ |
||||
|
url('https://cdn3.codesign.qq.com/icons/r2nL6jg1z80pJXV/latest/iconfont.woff?t=20d1e70f3aeb7dcbee56c813164786bc') format('woff2'), |
||||
|
url('https://cdn3.codesign.qq.com/icons/r2nL6jg1z80pJXV/latest/iconfont.woff?t=20d1e70f3aeb7dcbee56c813164786bc') format('woff'), /* chrome、firefox */ |
||||
|
url('https://cdn3.codesign.qq.com/icons/r2nL6jg1z80pJXV/latest/iconfont.ttf?t=20d1e70f3aeb7dcbee56c813164786bc') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ |
||||
|
url('https://cdn3.codesign.qq.com/icons/r2nL6jg1z80pJXV/latest/iconfont.svg?t=20d1e70f3aeb7dcbee56c813164786bc#icondiy-my-template') format('svg'); /* iOS 4.1- */ |
||||
|
} |
||||
|
|
||||
|
.icondiy-my-template { |
||||
|
font-family: "icondiy-my-template" !important; |
||||
|
font-size: 16px; |
||||
|
font-style: normal; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; |
||||
|
} |
||||
|
|
||||
|
.icon-furniture-taideng:before { |
||||
|
content: "\e001"; |
||||
|
} |
||||
|
.icon-furniture-deng:before { |
||||
|
content: "\e002"; |
||||
|
} |
||||
|
.icon-furniture-szt:before { |
||||
|
content: "\e003"; |
||||
|
} |
||||
|
.icon-furniture-safa:before { |
||||
|
content: "\e004"; |
||||
|
} |
||||
|
.icon-furniture-bed:before { |
||||
|
content: "\e005"; |
||||
|
} |
||||
|
.icon-furniture-yaoyi:before { |
||||
|
content: "\e006"; |
||||
|
} |
||||
|
.icon-furniture-guizi:before { |
||||
|
content: "\e007"; |
||||
|
} |
||||
|
.icon-furniture-lunyi:before { |
||||
|
content: "\e008"; |
||||
|
} |
||||
|
.icon-furniture-fj:before { |
||||
|
content: "\e009"; |
||||
|
} |
||||
|
.icon-furniture-xicaichi:before { |
||||
|
content: "\e00a"; |
||||
|
} |
||||
|
.icon-building-glou:before { |
||||
|
content: "\e00b"; |
||||
|
} |
||||
|
.icon-building-gaolou:before { |
||||
|
content: "\e00c"; |
||||
|
} |
||||
|
.icon-building-glt:before { |
||||
|
content: "\e00d"; |
||||
|
} |
||||
|
.icon-animal-hippo:before { |
||||
|
content: "\e00e"; |
||||
|
} |
||||
|
.icon-animal-pig:before { |
||||
|
content: "\e00f"; |
||||
|
} |
||||
|
.icon-animal-dolphin:before { |
||||
|
content: "\e010"; |
||||
|
} |
||||
|
.icon-animal-duck:before { |
||||
|
content: "\e011"; |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,427 @@ |
|||||
|
@font-face { |
||||
|
font-family: "iconfont"; |
||||
|
src: url('https://cdn3.codesign.qq.com/icons/1Yyg5Zpxm6Z2lKv/latest/iconfont.eot?t=1a4474d1fa0fe7c3cdff9aa0cc9c7258'); /* IE9 */ |
||||
|
src: url('https://cdn3.codesign.qq.com/icons/1Yyg5Zpxm6Z2lKv/latest/iconfont.eot?t=1a4474d1fa0fe7c3cdff9aa0cc9c7258#iefix') format('embedded-opentype'), /* IE6-IE8 */ |
||||
|
url('https://cdn3.codesign.qq.com/icons/1Yyg5Zpxm6Z2lKv/latest/iconfont.woff?t=1a4474d1fa0fe7c3cdff9aa0cc9c7258') format('woff2'), |
||||
|
url('https://cdn3.codesign.qq.com/icons/1Yyg5Zpxm6Z2lKv/latest/iconfont.woff?t=1a4474d1fa0fe7c3cdff9aa0cc9c7258') format('woff'), /* chromeã€firefox */ |
||||
|
url('https://cdn3.codesign.qq.com/icons/1Yyg5Zpxm6Z2lKv/latest/iconfont.ttf?t=1a4474d1fa0fe7c3cdff9aa0cc9c7258') format('truetype'), /* chromeã€firefoxã€operaã€Safari, Android, iOS 4.2+*/ |
||||
|
url('https://cdn3.codesign.qq.com/icons/1Yyg5Zpxm6Z2lKv/latest/iconfont.svg?t=1a4474d1fa0fe7c3cdff9aa0cc9c7258#iconfont') format('svg'); /* iOS 4.1- */ |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.iconfont { |
||||
|
font-family: "iconfont" !important; |
||||
|
font-size: 16px; |
||||
|
font-style: normal; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; |
||||
|
} |
||||
|
|
||||
|
.icon-futou:before { |
||||
|
content: "\e003"; |
||||
|
} |
||||
|
.icon-chenggong:before { |
||||
|
content: "\e004"; |
||||
|
} |
||||
|
.icon-dingdan4:before { |
||||
|
content: "\e005"; |
||||
|
} |
||||
|
.icon-fuxuankuang1:before { |
||||
|
content: "\e006"; |
||||
|
} |
||||
|
.icon-gantanhao:before { |
||||
|
content: "\e007"; |
||||
|
} |
||||
|
.icon-fuxuankuang2:before { |
||||
|
content: "\e008"; |
||||
|
} |
||||
|
.icon-kefu:before { |
||||
|
content: "\e009"; |
||||
|
} |
||||
|
.icon-kanjia:before { |
||||
|
content: "\e00a"; |
||||
|
} |
||||
|
.icon-kanjiachenggong:before { |
||||
|
content: "\e00b"; |
||||
|
} |
||||
|
.icon-qrcode:before { |
||||
|
content: "\e00c"; |
||||
|
} |
||||
|
.icon-gonggao:before { |
||||
|
content: "\e00d"; |
||||
|
} |
||||
|
.icon-pintuan2:before { |
||||
|
content: "\e00e"; |
||||
|
} |
||||
|
.icon-shangpin:before { |
||||
|
content: "\e00f"; |
||||
|
} |
||||
|
.icon-right1:before { |
||||
|
content: "\e010"; |
||||
|
} |
||||
|
.icon-sousuo3:before { |
||||
|
content: "\e011"; |
||||
|
} |
||||
|
.icon-tutechan:before { |
||||
|
content: "\e012"; |
||||
|
} |
||||
|
.icon-tuangou:before { |
||||
|
content: "\e013"; |
||||
|
} |
||||
|
.icon-xiangshangzhanhang:before { |
||||
|
content: "\e014"; |
||||
|
} |
||||
|
.icon-yaoqinghaoyou:before { |
||||
|
content: "\e015"; |
||||
|
} |
||||
|
.icon-biaoqing_nanguo:before { |
||||
|
content: "\e016"; |
||||
|
} |
||||
|
.icon-fenxiang4:before { |
||||
|
content: "\e017"; |
||||
|
} |
||||
|
.icon-fold:before { |
||||
|
content: "\e018"; |
||||
|
} |
||||
|
.icon-gantanhao1:before { |
||||
|
content: "\e019"; |
||||
|
} |
||||
|
.icon-icon:before { |
||||
|
content: "\e01a"; |
||||
|
} |
||||
|
.icon-huiyuan:before { |
||||
|
content: "\e01b"; |
||||
|
} |
||||
|
.icon-jian:before { |
||||
|
content: "\e01c"; |
||||
|
} |
||||
|
.icon-pintuanfanli:before { |
||||
|
content: "\e01d"; |
||||
|
} |
||||
|
.icon-jia:before { |
||||
|
content: "\e01e"; |
||||
|
} |
||||
|
.icon-seckill:before { |
||||
|
content: "\e01f"; |
||||
|
} |
||||
|
.icon-wode-tuangou:before { |
||||
|
content: "\e020"; |
||||
|
} |
||||
|
.icon-shuaxin:before { |
||||
|
content: "\e021"; |
||||
|
} |
||||
|
.icon-wodeyushou:before { |
||||
|
content: "\e022"; |
||||
|
} |
||||
|
.icon-youhuiquan1:before { |
||||
|
content: "\e023"; |
||||
|
} |
||||
|
.icon-zhuantihuodong:before { |
||||
|
content: "\e024"; |
||||
|
} |
||||
|
.icon-ziyuan1:before { |
||||
|
content: "\e025"; |
||||
|
} |
||||
|
.icon-yonghu3:before { |
||||
|
content: "\e026"; |
||||
|
} |
||||
|
.icon-caidan:before { |
||||
|
content: "\e027"; |
||||
|
} |
||||
|
.icon-erweima:before { |
||||
|
content: "\e028"; |
||||
|
} |
||||
|
.icon-danxuan-xuanzhong:before { |
||||
|
content: "\e029"; |
||||
|
} |
||||
|
.icon-dingdan2:before { |
||||
|
content: "\e02a"; |
||||
|
} |
||||
|
.icon-sanjiao:before { |
||||
|
content: "\e02b"; |
||||
|
} |
||||
|
.icon-shangpin-:before { |
||||
|
content: "\e02c"; |
||||
|
} |
||||
|
.icon-shouye1:before { |
||||
|
content: "\e02d"; |
||||
|
} |
||||
|
.icon-shangsanjiao-copy:before { |
||||
|
content: "\e02e"; |
||||
|
} |
||||
|
.icon-tedianquanchangbaoyou:before { |
||||
|
content: "\e02f"; |
||||
|
} |
||||
|
.icon-wenhao:before { |
||||
|
content: "\e030"; |
||||
|
} |
||||
|
.icon-weixin1:before { |
||||
|
content: "\e031"; |
||||
|
} |
||||
|
.icon-yue:before { |
||||
|
content: "\e032"; |
||||
|
} |
||||
|
.icon-zhekou:before { |
||||
|
content: "\e033"; |
||||
|
} |
||||
|
.icon-fangkuai-fill:before { |
||||
|
content: "\e034"; |
||||
|
} |
||||
|
.icon-zhibojieshu:before { |
||||
|
content: "\e035"; |
||||
|
} |
||||
|
.icon-gouwuche2:before { |
||||
|
content: "\e036"; |
||||
|
} |
||||
|
.icon-ellipsis:before { |
||||
|
content: "\e037"; |
||||
|
} |
||||
|
.icon-guanzhu:before { |
||||
|
content: "\e038"; |
||||
|
} |
||||
|
.icon-jifen-:before { |
||||
|
content: "\e039"; |
||||
|
} |
||||
|
.icon-dianhua2:before { |
||||
|
content: "\e03a"; |
||||
|
} |
||||
|
.icon-hongbao:before { |
||||
|
content: "\e03b"; |
||||
|
} |
||||
|
.icon-qiandao1:before { |
||||
|
content: "\e03c"; |
||||
|
} |
||||
|
.icon-jifen2:before { |
||||
|
content: "\e03d"; |
||||
|
} |
||||
|
.icon-jifen3:before { |
||||
|
content: "\e03e"; |
||||
|
} |
||||
|
.icon-fuzhilianjie:before { |
||||
|
content: "\e03f"; |
||||
|
} |
||||
|
.icon-jiahao01:before { |
||||
|
content: "\e040"; |
||||
|
} |
||||
|
.icon-like:before { |
||||
|
content: "\e041"; |
||||
|
} |
||||
|
.icon-likefill:before { |
||||
|
content: "\e042"; |
||||
|
} |
||||
|
.icon-list:before { |
||||
|
content: "\e043"; |
||||
|
} |
||||
|
.icon-right:before { |
||||
|
content: "\e044"; |
||||
|
} |
||||
|
.icon-round-close:before { |
||||
|
content: "\e045"; |
||||
|
} |
||||
|
.icon-shangchuan:before { |
||||
|
content: "\e046"; |
||||
|
} |
||||
|
.icon-tupian:before { |
||||
|
content: "\e047"; |
||||
|
} |
||||
|
.icon-xuanzhuan:before { |
||||
|
content: "\e048"; |
||||
|
} |
||||
|
.icon-add1:before { |
||||
|
content: "\e049"; |
||||
|
} |
||||
|
.icon-weizhi:before { |
||||
|
content: "\e04a"; |
||||
|
} |
||||
|
.icon-close-guanbi:before { |
||||
|
content: "\e04b"; |
||||
|
} |
||||
|
.icon-apps:before { |
||||
|
content: "\e04c"; |
||||
|
} |
||||
|
.icon-biaoqing:before { |
||||
|
content: "\e04d"; |
||||
|
} |
||||
|
.icon-bianji:before { |
||||
|
content: "\e04e"; |
||||
|
} |
||||
|
.icon-cart-on:before { |
||||
|
content: "\e04f"; |
||||
|
} |
||||
|
.icon-close:before { |
||||
|
content: "\e050"; |
||||
|
} |
||||
|
.icon-checkboxblank:before { |
||||
|
content: "\e051"; |
||||
|
} |
||||
|
.icon-dianzan:before { |
||||
|
content: "\e052"; |
||||
|
} |
||||
|
.icon-dingwei1:before { |
||||
|
content: "\e053"; |
||||
|
} |
||||
|
.icon-iconangledown:before { |
||||
|
content: "\e055"; |
||||
|
} |
||||
|
.icon-dizhi:before { |
||||
|
content: "\e056"; |
||||
|
} |
||||
|
.icon-shouji:before { |
||||
|
content: "\e058"; |
||||
|
} |
||||
|
.icon-icon7:before { |
||||
|
content: "\e059"; |
||||
|
} |
||||
|
.icon-iconangledown-copy:before { |
||||
|
content: "\e05a"; |
||||
|
} |
||||
|
.icon-youhuiquan:before { |
||||
|
content: "\e05c"; |
||||
|
} |
||||
|
.icon-ziyuan:before { |
||||
|
content: "\e05d"; |
||||
|
} |
||||
|
.icon-zhaoxiangji:before { |
||||
|
content: "\e05e"; |
||||
|
} |
||||
|
.icon-yuan_checkbox:before { |
||||
|
content: "\e05f"; |
||||
|
} |
||||
|
.icon-back_light:before { |
||||
|
content: "\e060"; |
||||
|
} |
||||
|
.icon-yuan_checked:before { |
||||
|
content: "\e061"; |
||||
|
} |
||||
|
.icon-bangzhu:before { |
||||
|
content: "\e062"; |
||||
|
} |
||||
|
.icon-delete:before { |
||||
|
content: "\e064"; |
||||
|
} |
||||
|
.icon-dianzan1:before { |
||||
|
content: "\e065"; |
||||
|
} |
||||
|
.icon-dianpu:before { |
||||
|
content: "\e066"; |
||||
|
} |
||||
|
.icon-mendian:before { |
||||
|
content: "\e067"; |
||||
|
} |
||||
|
.icon-shaixuan:before { |
||||
|
content: "\e069"; |
||||
|
} |
||||
|
.icon-shijian:before { |
||||
|
content: "\e06a"; |
||||
|
} |
||||
|
.icon-shijian1:before { |
||||
|
content: "\e06b"; |
||||
|
} |
||||
|
.icon-sousuo:before { |
||||
|
content: "\e06c"; |
||||
|
} |
||||
|
.icon-shezhi:before { |
||||
|
content: "\e06d"; |
||||
|
} |
||||
|
.icon-dianhua:before { |
||||
|
content: "\e06e"; |
||||
|
} |
||||
|
.icon-dui:before { |
||||
|
content: "\e06f"; |
||||
|
} |
||||
|
.icon-yaoqing:before { |
||||
|
content: "\e070"; |
||||
|
} |
||||
|
.icon-zhongchaping:before { |
||||
|
content: "\e071"; |
||||
|
} |
||||
|
.icon-fenxiang:before { |
||||
|
content: "\e072"; |
||||
|
} |
||||
|
.icon-fuzhi:before { |
||||
|
content: "\e073"; |
||||
|
} |
||||
|
.icon-hexiao:before { |
||||
|
content: "\e074"; |
||||
|
} |
||||
|
.icon-share:before { |
||||
|
content: "\e075"; |
||||
|
} |
||||
|
.icon-haoping1:before { |
||||
|
content: "\e076"; |
||||
|
} |
||||
|
.icon-gouwuche:before { |
||||
|
content: "\e077"; |
||||
|
} |
||||
|
.icon-share-friend:before { |
||||
|
content: "\e078"; |
||||
|
} |
||||
|
.icon-jiang-copy:before { |
||||
|
content: "\e079"; |
||||
|
} |
||||
|
.icon-location:before { |
||||
|
content: "\e07a"; |
||||
|
} |
||||
|
.icon-jianshao:before { |
||||
|
content: "\e07b"; |
||||
|
} |
||||
|
.icon-guanbi:before { |
||||
|
content: "\e07c"; |
||||
|
} |
||||
|
.icon-gz:before { |
||||
|
content: "\e07d"; |
||||
|
} |
||||
|
.icon-haowuquan:before { |
||||
|
content: "\e07e"; |
||||
|
} |
||||
|
.icon-search:before { |
||||
|
content: "\e07f"; |
||||
|
} |
||||
|
.icon-jilu:before { |
||||
|
content: "\e080"; |
||||
|
} |
||||
|
.icon-pengyouquan:before { |
||||
|
content: "\e081"; |
||||
|
} |
||||
|
.icon-saoma:before { |
||||
|
content: "\e083"; |
||||
|
} |
||||
|
.icon-shouji1:before { |
||||
|
content: "\e084"; |
||||
|
} |
||||
|
.icon-shurutianxiebi:before { |
||||
|
content: "\e085"; |
||||
|
} |
||||
|
.icon-tiaoxingmasaomiao:before { |
||||
|
content: "\e087"; |
||||
|
} |
||||
|
.icon-shuru:before { |
||||
|
content: "\e088"; |
||||
|
} |
||||
|
.icon-unfold:before { |
||||
|
content: "\e089"; |
||||
|
} |
||||
|
.icon-dianhua1:before { |
||||
|
content: "\e08a"; |
||||
|
} |
||||
|
.icon-weixin:before { |
||||
|
content: "\e08b"; |
||||
|
} |
||||
|
.icon-yonghu:before { |
||||
|
content: "\e08c"; |
||||
|
} |
||||
|
.icon-bangzhu1:before { |
||||
|
content: "\e08d"; |
||||
|
} |
||||
|
.icon-zhifubaozhifu-:before { |
||||
|
content: "\e08e"; |
||||
|
} |
||||
|
.icon-add-fill:before { |
||||
|
content: "\e08f"; |
||||
|
} |
||||
|
.icon-zhibozhong:before { |
||||
|
content: "\e090"; |
||||
|
} |
||||
|
.icon-warn:before { |
||||
|
content: "\e091"; |
||||
|
} |
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
@ -0,0 +1,94 @@ |
|||||
|
var jpushModule = uni.requireNativePlugin("JG-JPush") |
||||
|
export default { |
||||
|
onLaunch: function() { |
||||
|
console.log('App Launch') |
||||
|
if (uni.getSystemInfoSync().platform == "ios") { |
||||
|
// 请求定位权限
|
||||
|
let locationServicesEnabled = jpushModule.locationServicesEnabled() |
||||
|
let locationAuthorizationStatus = jpushModule.getLocationAuthorizationStatus() |
||||
|
console.log('locationAuthorizationStatus', locationAuthorizationStatus) |
||||
|
if (locationServicesEnabled == true && locationAuthorizationStatus < 3) { |
||||
|
jpushModule.requestLocationAuthorization((result) => { |
||||
|
console.log('定位权限', result.status) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
jpushModule.requestNotificationAuthorization((result) => { |
||||
|
let status = result.status |
||||
|
if (status < 2) { |
||||
|
uni.showToast({ |
||||
|
icon: 'none', |
||||
|
title: '您还没有打开通知权限', |
||||
|
duration: 3000 |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
jpushModule.addGeofenceListener(result => { |
||||
|
let code = result.code |
||||
|
let type = result.type |
||||
|
let geofenceId = result.geofenceId |
||||
|
let userInfo = result.userInfo |
||||
|
uni.showToast({ |
||||
|
icon: 'none', |
||||
|
title: '触发地理围栏', |
||||
|
duration: 3000 |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
jpushModule.initJPushService(); |
||||
|
jpushModule.setLoggerEnable(true); |
||||
|
jpushModule.addConnectEventListener(result => { |
||||
|
let connectEnable = result.connectEnable |
||||
|
uni.$emit('connectStatusChange', connectEnable) |
||||
|
}); |
||||
|
|
||||
|
jpushModule.addNotificationListener(result => { |
||||
|
let notificationEventType = result.notificationEventType |
||||
|
let messageID = result.messageID |
||||
|
let title = result.title |
||||
|
let content = result.content |
||||
|
let extras = result.extras |
||||
|
|
||||
|
uni.showToast({ |
||||
|
icon: 'none', |
||||
|
title: JSON.stringify(result), |
||||
|
duration: 3000 |
||||
|
}) |
||||
|
}); |
||||
|
|
||||
|
jpushModule.addCustomMessageListener(result => { |
||||
|
let type = result.type |
||||
|
let messageType = result.messageType |
||||
|
let content = result.content |
||||
|
uni.showToast({ |
||||
|
icon: 'none', |
||||
|
title: JSON.stringify(result), |
||||
|
duration: 3000 |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
jpushModule.addLocalNotificationListener(result => { |
||||
|
let messageID = result.messageID |
||||
|
let title = result.title |
||||
|
let content = result.content |
||||
|
let extras = result.extras |
||||
|
uni.showToast({ |
||||
|
icon: 'none', |
||||
|
title: JSON.stringify(result), |
||||
|
duration: 3000 |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
}, |
||||
|
onShow: function() { |
||||
|
console.log('App Show') |
||||
|
}, |
||||
|
onHide: function() { |
||||
|
console.log('App Hide') |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
authInfo: {} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
/** |
||||
|
* 获取用户登录凭证code |
||||
|
*/ |
||||
|
getCode(callback) { |
||||
|
// 微信小程序
|
||||
|
// #ifdef MP-WEIXIN
|
||||
|
uni.login({ |
||||
|
provider: 'weixin', |
||||
|
timeout: 3000, |
||||
|
success: res => { |
||||
|
if (res.code) { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/weapp/api/weapp/authcodetoopenid', |
||||
|
data: { |
||||
|
code: res.code |
||||
|
}, |
||||
|
success: res => { |
||||
|
if (res.code >= 0) { |
||||
|
if (res.data.openid) this.authInfo.weapp_openid = res.data.openid; |
||||
|
if (res.data.unionid) this.authInfo.wx_unionid = res.data.unionid; |
||||
|
typeof callback == 'function' && callback(this.authInfo); |
||||
|
} else { |
||||
|
this.$util.showToast({ |
||||
|
title: '小程序配置错误' |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
fail: () => { |
||||
|
this.$util.showToast({ |
||||
|
title: '请求失败' |
||||
|
}); |
||||
|
} |
||||
|
}) |
||||
|
// #endif
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
import Vue from 'vue' |
||||
|
|
||||
|
/** |
||||
|
* 定义空的vue实例,作为 eventbus实现非父子组件之间的通信(vue2.x中去掉了broadcast) |
||||
|
*/ |
||||
|
var eventBus = new Vue({}); |
||||
|
export default eventBus; |
||||
@ -0,0 +1,24 @@ |
|||||
|
import Config from '@/config/index.js'; |
||||
|
var config = { |
||||
|
|
||||
|
// api请求地址
|
||||
|
baseUrl: Config.baseUrl, |
||||
|
|
||||
|
// 图片域名
|
||||
|
imgDomain: Config.imgDomain, |
||||
|
|
||||
|
// H5端域名
|
||||
|
h5Domain: '{{$h5Domain}}', |
||||
|
|
||||
|
// 腾讯地图key
|
||||
|
mpKey: '{{$mpKey}}', |
||||
|
|
||||
|
//客服地址
|
||||
|
webSocket: '{{$webSocket}}', |
||||
|
|
||||
|
//本地端主动给服务器ping的时间, 0 则不开启 , 单位秒
|
||||
|
pingInterval: 1500, |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
export default config; |
||||
@ -0,0 +1,412 @@ |
|||||
|
import WxMap from 'common/js/map-wx-jssdk.js'; |
||||
|
|
||||
|
let systemInfo = uni.getSystemInfoSync(); |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
diyData: { |
||||
|
global: { |
||||
|
title: '', |
||||
|
popWindow: { |
||||
|
imageUrl: '', |
||||
|
count: -1, |
||||
|
link: {}, |
||||
|
imgWidth: '', |
||||
|
imgHeight: '' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
memberId: 0, |
||||
|
name: '', |
||||
|
isDefault: '', |
||||
|
store: {}, //首页展示的门店详情
|
||||
|
storeId: 0, //首页展示的门店id
|
||||
|
pageHeight: '0', |
||||
|
headerHeight: '0', |
||||
|
bottomHeight: '0', |
||||
|
topIndexValue: null, |
||||
|
statusBarHeight: systemInfo.statusBarHeight, |
||||
|
collectTop: 44, |
||||
|
showTip: false, |
||||
|
mpCollect: false, |
||||
|
mpShareData: null, //小程序分享数据
|
||||
|
scrollTop: 0, // 滚动位置
|
||||
|
paddingTop: (44 + systemInfo.statusBarHeight) + 'px', |
||||
|
marginTop: -(44 + systemInfo.statusBarHeight) + 'px' |
||||
|
}; |
||||
|
}, |
||||
|
onLoad(data) { |
||||
|
this.name = data.name || ''; |
||||
|
this.isDefault = data.is_default || ''; |
||||
|
this.storeId = data.store_id || 0; |
||||
|
|
||||
|
if (data.source_member) uni.setStorageSync('source_member', data.source_member); |
||||
|
|
||||
|
// 小程序扫码进入
|
||||
|
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]); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 监听同步购物车
|
||||
|
uni.$on('syncCartList', () => { |
||||
|
try { |
||||
|
this.$nextTick(() => { |
||||
|
if (this.$refs.diyGroup.$refs.ManyGoodsList[0].$refs.diyGoodsList) { |
||||
|
this.$refs.diyGroup.$refs.ManyGoodsList[0].$refs.diyGoodsList.syncCartList(); |
||||
|
} |
||||
|
}) |
||||
|
} catch (error) { |
||||
|
console.log(error, 'error'); |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.init(); |
||||
|
}, |
||||
|
onShow() { |
||||
|
try { |
||||
|
this.$nextTick(() => { |
||||
|
this.$refs.diyGroup.$refs.ManyGoodsList[0].$refs.diyGoodsList.syncCartList(); |
||||
|
}) |
||||
|
} catch (error) { |
||||
|
console.log(error, 'error'); |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
bgColor() { |
||||
|
let str = ''; |
||||
|
if (this.diyData && this.diyData.global) { |
||||
|
str = this.diyData.global.pageBgColor; |
||||
|
} |
||||
|
return str; |
||||
|
}, |
||||
|
bgImg() { |
||||
|
let str = ''; |
||||
|
if (this.diyData && this.diyData.global) { |
||||
|
str = this.diyData.global.topNavBg ? 'url(' + this.$util.img(this.diyData.global.bgUrl) + ')' : this |
||||
|
.diyData.global.pageBgColor; |
||||
|
} |
||||
|
return str; |
||||
|
}, |
||||
|
bgUrl() { |
||||
|
let str = ''; |
||||
|
if (this.diyData && this.diyData.global) { |
||||
|
str = this.diyData.global.topNavBg ? 'transparent' : this.diyData.global.bgUrl; |
||||
|
} |
||||
|
return str; |
||||
|
}, |
||||
|
bgNav() { |
||||
|
if (this.diyData.global.topNavColor) { |
||||
|
return { |
||||
|
background: this.diyData.global.topNavColor |
||||
|
}; |
||||
|
} else { |
||||
|
return { |
||||
|
background: '#ffffff' |
||||
|
}; |
||||
|
} |
||||
|
}, |
||||
|
backgroundUrl() { |
||||
|
var str = this.diyData.global.bgUrl && this.diyData.global.bgUrl != 'transparent' ? 'url(' + this.$util.img( |
||||
|
this.diyData.global.bgUrl) + ') ' : ''; |
||||
|
return str; |
||||
|
}, |
||||
|
textNavColor() { |
||||
|
if (this.diyData && this.diyData.global && this.diyData.global.textNavColor) { |
||||
|
return this.diyData.global.textNavColor; |
||||
|
} else { |
||||
|
return '#ffffff'; |
||||
|
} |
||||
|
}, |
||||
|
openBottomNav() { |
||||
|
let str = false; |
||||
|
if (this.diyData && this.diyData.global) { |
||||
|
str = this.diyData.global.openBottomNav; |
||||
|
} |
||||
|
return str; |
||||
|
}, |
||||
|
globalS() { |
||||
|
return this.diyData.global; |
||||
|
}, |
||||
|
//计算首页弹框的显示宽高
|
||||
|
popWindowStyle() { |
||||
|
// 做大展示宽高
|
||||
|
let max_width = 290; |
||||
|
let max_height = 410; |
||||
|
// 参照宽高
|
||||
|
let refer_width = 290; |
||||
|
let refer_height = 290; |
||||
|
|
||||
|
let scale = this.diyData.global.popWindow.imgHeight / this.diyData.global.popWindow.imgWidth; |
||||
|
let width, height; |
||||
|
if (scale < refer_height / refer_width) { |
||||
|
width = max_width; |
||||
|
height = width * scale; |
||||
|
} else { |
||||
|
height = max_height; |
||||
|
width = height / scale; |
||||
|
} |
||||
|
|
||||
|
let obj = ''; |
||||
|
if (this.diyData.global.popWindow && this.diyData.global.popWindow.count != -1 && this.diyData.global |
||||
|
.popWindow.imageUrl) { |
||||
|
obj += 'height:' + (height * 2) + 'rpx;'; |
||||
|
obj += 'width:' + (width * 2) + 'rpx;'; |
||||
|
} |
||||
|
return obj; |
||||
|
}, |
||||
|
scrollHeight() { |
||||
|
if (this.pageHeight != undefined && this.headerHeight != undefined && this.bottomHeight != undefined) { |
||||
|
return 'calc(' + this.pageHeight * 2 + 'rpx - ' + this.headerHeight + ' - ' + this.bottomHeight + ')'; |
||||
|
} else { |
||||
|
return '100vh'; |
||||
|
} |
||||
|
}, |
||||
|
scrollTopHeight() { |
||||
|
if (this.pageHeight != undefined && this.headerHeight != undefined && this.bottomHeight != undefined) { |
||||
|
return 'calc(' + this.pageHeight * 2 + 'rpx - ' + this.headerHeight + ' - ' + this.bottomHeight + |
||||
|
' - 80rpx)'; |
||||
|
} else { |
||||
|
return '100vh'; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
init() { |
||||
|
|
||||
|
//首页
|
||||
|
if (uni.getStorageSync('token')) { |
||||
|
this.$util.getMemberId().then(resolve => { |
||||
|
this.memberId = resolve; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
this.store = uni.getStorageSync('store') ? uni.getStorageSync('store') : null; |
||||
|
if (this.store) this.storeId = this.store.store_id; |
||||
|
|
||||
|
this.getDiyInfo(); |
||||
|
// this.getHeight();
|
||||
|
if (this.route == "pages/member/index") { |
||||
|
uni.$on('changeStore', data => { |
||||
|
if (data) { |
||||
|
this.getDiyInfo(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
console.log(this.diyData.global.popWindow, 123); |
||||
|
//记录分享关系
|
||||
|
if (uni.getStorageSync('token') && uni.getStorageSync('source_member')) { |
||||
|
this.$util.onSourceMember(uni.getStorageSync('source_member')); |
||||
|
} |
||||
|
|
||||
|
//小程序分享
|
||||
|
// #ifdef MP-WEIXIN
|
||||
|
this.$util.getMpShare().then(res => { |
||||
|
this.mpShareData = res; |
||||
|
}); |
||||
|
// #endif
|
||||
|
}, |
||||
|
// scroll(e) {
|
||||
|
// this.scrollTop = e.detail.scrollTop;
|
||||
|
// },
|
||||
|
callback() { |
||||
|
if (this.$refs.indexPage) { |
||||
|
this.$refs.indexPage.initPageIndex(); |
||||
|
} |
||||
|
}, |
||||
|
//计算高度
|
||||
|
getHeight() { |
||||
|
var self = this; |
||||
|
//获取页面可用区域的高度
|
||||
|
uni.getSystemInfo({ |
||||
|
success: res => { |
||||
|
this.pageHeight = res.screenHeight; |
||||
|
} |
||||
|
}); |
||||
|
// #ifdef MP || APP-PLUS
|
||||
|
this.$nextTick(() => { |
||||
|
const query = uni.createSelectorQuery().in(this); |
||||
|
query |
||||
|
.select('.page-header') |
||||
|
.boundingClientRect(data => { |
||||
|
if (data) { |
||||
|
this.headerHeight = data.height * 2 + 'rpx'; |
||||
|
// 从状态栏高度开始算
|
||||
|
this.paddingTop = data.height + 'px'; |
||||
|
this.marginTop = -data.height + 'px'; |
||||
|
} |
||||
|
}) |
||||
|
.exec(); |
||||
|
}); |
||||
|
// #endif
|
||||
|
this.$nextTick(() => { |
||||
|
const query = uni.createSelectorQuery().in(this); |
||||
|
query |
||||
|
.select('.page-bottom') |
||||
|
.boundingClientRect(data => { |
||||
|
this.bottomHeight = 110 + 'rpx'; |
||||
|
}) |
||||
|
.exec(); |
||||
|
}); |
||||
|
|
||||
|
}, |
||||
|
getDiyInfo() { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/diyview/info', |
||||
|
data: { |
||||
|
name: this.name, |
||||
|
is_default: this.isDefault |
||||
|
}, |
||||
|
success: res => { |
||||
|
// console.log(JSON.parse(res.data.value));
|
||||
|
// console.log(JSON.parse(res.data.value),`diy`);
|
||||
|
if (res.code != 0 || !res.data) { |
||||
|
if (this.$refs.loadingCover) this.$refs.loadingCover.hide(); |
||||
|
this.diyData = {}; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
let diyDatavalue = res.data; |
||||
|
// console.log(JSON.parse(diyDatavalue.value))
|
||||
|
//处理后台组件input输入单引号问题 -- 英文状态下
|
||||
|
// diyDatavalue.value = diyDatavalue.value.replace(/\@/g, "'");
|
||||
|
if (diyDatavalue.value) { |
||||
|
// uni.setStorageSync(this.name, diyDatavalue.value);
|
||||
|
this.diyData = JSON.parse(diyDatavalue.value); |
||||
|
console.log(this.diyData); |
||||
|
this.diyData.compExtend = diyDatavalue.comp_extend; // 自定义扩展组件
|
||||
|
this.$langConfig.title(this.diyData.global.title); |
||||
|
this.mpCollect = this.diyData.global.mpCollect; |
||||
|
if (this.diyData.global.popWindow && this.diyData.global.popWindow.imageUrl) { |
||||
|
// 弹框形式,首次弹出 1,每次弹出 0
|
||||
|
setTimeout(() => { |
||||
|
if (this.diyData.global.popWindow.count == 1) { |
||||
|
var popwindow_count = uni.getStorageSync(this.name + |
||||
|
'_popwindow_count'); |
||||
|
if ((this.$refs.uniPopupWindow && popwindow_count == '') || ( |
||||
|
this.$refs.uniPopupWindow && popwindow_count == 1)) { |
||||
|
this.$refs.uniPopupWindow.open(); |
||||
|
uni.setStorageSync(this.name + '_popwindow_count', 1); |
||||
|
} |
||||
|
} else if (this.diyData.global.popWindow.count == 0) { |
||||
|
this.$refs.uniPopupWindow.open(); |
||||
|
uni.setStorageSync(this.name + '_popwindow_count', 0); |
||||
|
} |
||||
|
}, 500); |
||||
|
} |
||||
|
|
||||
|
for (var i = 0; i < this.diyData.value.length; i++) { |
||||
|
if (this.diyData.value[i].componentName == 'TopCategory') { |
||||
|
this.topIndexValue = this.diyData.value[i]; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// #ifdef MP
|
||||
|
//小程序收藏
|
||||
|
if (!uni.getStorageSync('isCollect') && this.diyData.global.mpCollect) { |
||||
|
this.$refs.collectPopupWindow.open(); |
||||
|
this.showTip = true; |
||||
|
} |
||||
|
// #endif
|
||||
|
|
||||
|
|
||||
|
if (this.diyData.value) { |
||||
|
this.diyData.value.forEach(item => { |
||||
|
if (item.componentName == "FloatBtn") { |
||||
|
this.floatData = item |
||||
|
// console.log('this.floatData', this.floatData);
|
||||
|
uni.setStorageSync('floatData', this.floatData); |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
setTimeout(() => { |
||||
|
if (this.$refs.loadingCover) this.$refs.loadingCover.hide(); |
||||
|
}, 150); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
closePopupWindow() { |
||||
|
this.$refs.uniPopupWindow.close(); |
||||
|
uni.setStorageSync(this.name + '_popwindow_count', -1); |
||||
|
}, |
||||
|
closeCollectPopupWindow() { |
||||
|
this.$refs.collectPopupWindow.close(); |
||||
|
uni.setStorageSync('isCollect', true); |
||||
|
}, |
||||
|
uniPopupWindowFn() { |
||||
|
if (this.diyData.global.popWindow.adv_id > 0) { |
||||
|
this.advpoint(this.diyData.global.popWindow.adv_id) |
||||
|
} |
||||
|
this.$util.diyRedirectTo(this.diyData.global.popWindow.link); |
||||
|
this.closePopupWindow(); |
||||
|
}, |
||||
|
advpoint(adv_id) { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/adv/advpoint', |
||||
|
data: { |
||||
|
adv_id, |
||||
|
}, |
||||
|
success: res => {} |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
onPageScroll(e) { |
||||
|
if (this.$refs.topNav) { |
||||
|
if (e.scrollTop >= 20) { |
||||
|
this.$refs.topNav.navTopBg(); |
||||
|
} else { |
||||
|
this.$refs.topNav.unSetnavTopBg(); |
||||
|
} |
||||
|
} |
||||
|
e.scrollTop > 20 ? this.$store.state.navbarBgColor = '#fff' : this.$store.state.navbarBgColor = 'transparent' |
||||
|
}, |
||||
|
//分享给好友
|
||||
|
onShareAppMessage() { |
||||
|
return this.mpShareData.appMessage; |
||||
|
}, |
||||
|
//分享到朋友圈
|
||||
|
onShareTimeline() { |
||||
|
return this.mpShareData.timeLine; |
||||
|
}, |
||||
|
onPullDownRefresh() { |
||||
|
if (this.route == "pages/member/index") { |
||||
|
console.log(`我的下拉刷新啦`); |
||||
|
this.memberView = false |
||||
|
this.$nextTick(() => { |
||||
|
this.memberView = true |
||||
|
uni.stopPullDownRefresh(); |
||||
|
}) |
||||
|
} else { |
||||
|
this.divTrue = true; |
||||
|
console.log(`首页下拉刷新啦`); |
||||
|
this.$nextTick(() => { |
||||
|
uni.stopPullDownRefresh(); |
||||
|
this.getDiyInfo(); |
||||
|
this.$refs.diyGroup.$refs.ManyGoodsList[0].$refs.diyGoodsList.getGoodsList(); |
||||
|
}) |
||||
|
this.$refs.uniPopupWindow.open(); |
||||
|
} |
||||
|
}, |
||||
|
onReachBottom() { |
||||
|
this.$refs.diyGroup.$refs.ManyGoodsList[0].$refs.diyGoodsList0 && this.$refs.diyGroup.$refs.ManyGoodsList[0] |
||||
|
.$refs.diyGoodsList0.nextGoodsList(); |
||||
|
this.$refs.diyGroup.$refs.ManyGoodsList[0].$refs.diyGoodsList1 && this.$refs.diyGroup.$refs.ManyGoodsList[0] |
||||
|
.$refs.diyGoodsList1.nextGoodsList(); |
||||
|
this.$refs.diyGroup.$refs.ManyGoodsList[0].$refs.diyGoodsList2 && this.$refs.diyGroup.$refs.ManyGoodsList[0] |
||||
|
.$refs.diyGoodsList2.nextGoodsList(); |
||||
|
this.$refs.diyGroup.$refs.ManyGoodsList[0].$refs.diyGoodsList3 && this.$refs.diyGroup.$refs.ManyGoodsList[0] |
||||
|
.$refs.diyGoodsList3.nextGoodsList(); |
||||
|
this.$refs.diyGroup.$refs.ManyGoodsList[0].$refs.diyGoodsList4 && this.$refs.diyGroup.$refs.ManyGoodsList[0] |
||||
|
.$refs.diyGoodsList4.nextGoodsList(); |
||||
|
this.$refs.diyGroup.$refs.ManyGoodsList[0].$refs.diyGoodsList5 && this.$refs.diyGroup.$refs.ManyGoodsList[0] |
||||
|
.$refs.diyGoodsList5.nextGoodsList(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
import Vue from 'vue' |
||||
|
export const EventBus = new Vue() |
||||
|
export default EventBus; |
||||
@ -0,0 +1,128 @@ |
|||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
// 页面样式,动态设置主色调
|
||||
|
themeColor: '' ,//''--base-color:#fa5d14;--base-help-color:#ff7e00;'
|
||||
|
tabBarHeight: '0px' |
||||
|
} |
||||
|
}, |
||||
|
onLoad() { |
||||
|
}, |
||||
|
onShow() { |
||||
|
// 刷新多语言
|
||||
|
|
||||
|
this.$langConfig.refresh(); |
||||
|
let time = setInterval(() => { |
||||
|
let theme = uni.getStorageSync('theme_style'); |
||||
|
if (theme.main_color) { |
||||
|
this.themeColorSet() |
||||
|
clearInterval(time); |
||||
|
} |
||||
|
}, 50); |
||||
|
if (this.themeColor) this.getTabbarHeight(); |
||||
|
if(uni.getStorageSync('token')){ |
||||
|
this.$store.dispatch('getUserInfo') |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
themeStyle() { |
||||
|
return uni.getStorageSync('theme_style'); |
||||
|
}, |
||||
|
//插件是否存在
|
||||
|
addonIsExist() { |
||||
|
return uni.getStorageSync('addon_is_exist'); |
||||
|
}, |
||||
|
tabBarList() { |
||||
|
return this.$store.state.tabBarList |
||||
|
}, |
||||
|
siteInfo() { |
||||
|
return uni.getStorageSync('siteInfo'); |
||||
|
}, |
||||
|
storeToken() { |
||||
|
return this.$store.state.token; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
themeColorSet(){ |
||||
|
let theme = uni.getStorageSync('theme_style'); |
||||
|
this.themeColor = `--base-color:${theme.main_color};--base-help-color:${theme.aux_color};--tab-bar-height:${this.tabBarHeight};`; |
||||
|
Object.keys(theme).forEach(key => { |
||||
|
let data = theme[key]; |
||||
|
if(typeof(data) == "object"){ |
||||
|
Object.keys(data).forEach(k => { |
||||
|
this.themeColor += '--'+k.replace(/_/g, "-")+':'+data[k]+';'; |
||||
|
}); |
||||
|
}else if(typeof(key) == "string" && key){ |
||||
|
this.themeColor += '--'+key.replace(/_/g, "-")+':'+data+';'; |
||||
|
} |
||||
|
}); |
||||
|
for(let i = 9; i >= 5; i--) { |
||||
|
let color = this.$util.colourBlend(theme.main_color, '#ffffff', (i / 10)); |
||||
|
this.themeColor += `--base-color-light-${i}:${color};`; |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
// 颜色变浅(>0)、变深函数(<0)
|
||||
|
lightenDarkenColor(color, amount) { |
||||
|
var usePound = false; |
||||
|
|
||||
|
if (color[0] == "#") { |
||||
|
color = color.slice(1); |
||||
|
usePound = true; |
||||
|
} |
||||
|
|
||||
|
var num = parseInt(color, 16); |
||||
|
|
||||
|
var r = (num >> 16) + amount; |
||||
|
|
||||
|
if (r > 255) r = 255; |
||||
|
else if (r < 0) r = 0; |
||||
|
|
||||
|
var b = ((num >> 8) & 0x00FF) + amount; |
||||
|
|
||||
|
if (b > 255) b = 255; |
||||
|
else if (b < 0) b = 0; |
||||
|
|
||||
|
var g = (num & 0x0000FF) + amount; |
||||
|
|
||||
|
if (g > 255) g = 255; |
||||
|
else if (g < 0) g = 0; |
||||
|
|
||||
|
return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16); |
||||
|
|
||||
|
}, |
||||
|
/** |
||||
|
* 获取tabbar高度 |
||||
|
*/ |
||||
|
getTabbarHeight(){ |
||||
|
try { |
||||
|
const query = uni.createSelectorQuery().in(this); |
||||
|
query.select('#tab-bar').boundingClientRect(data => { |
||||
|
if (data) { |
||||
|
this.tabBarHeight = data.height + 'px' |
||||
|
this.themeColorSet(); |
||||
|
} |
||||
|
}).exec(); |
||||
|
} catch(e) { |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
filters: { |
||||
|
/** |
||||
|
* 金额格式化输出 |
||||
|
* @param {Object} money |
||||
|
*/ |
||||
|
moneyFormat(money) { |
||||
|
if (isNaN(parseFloat(money))) return money; |
||||
|
return parseFloat(money).toFixed(2); |
||||
|
} |
||||
|
}, |
||||
|
onReady(){ |
||||
|
let num = 0; |
||||
|
let timer = setInterval(() => { |
||||
|
this.getTabbarHeight() |
||||
|
num += 1; |
||||
|
if (this.tabBarHeight != '0px' || num == 10) clearInterval(timer) |
||||
|
}, 100) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,379 @@ |
|||||
|
// 商品详情业务
|
||||
|
// import htmlParser from '@/common/js/html-parser';
|
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
skuId: 0, |
||||
|
goodsId: 0, |
||||
|
// 商品详情
|
||||
|
goodsSkuDetail: { |
||||
|
goods_id: 0, |
||||
|
goods_service: [] |
||||
|
}, |
||||
|
preview: 0, //是否开启预览,0:不开启,1:开启
|
||||
|
token: "", |
||||
|
//评价
|
||||
|
contactData: { |
||||
|
title: '', |
||||
|
path: '', |
||||
|
img: '' |
||||
|
}, |
||||
|
|
||||
|
shareQuery: '', // 分享参数
|
||||
|
shareUrl: '', // 分享链接
|
||||
|
|
||||
|
source_member: 0, //分享人的id
|
||||
|
chatRoomParams: {}, // 联系客服参数
|
||||
|
isIphoneX: false, //判断手机是否是iphoneX以上
|
||||
|
// cartCount: 0, // 购物车商品数量
|
||||
|
whetherCollection: 0, |
||||
|
memberId: 0, |
||||
|
posterParams: {}, //海报所需参数
|
||||
|
shareImg: '', |
||||
|
deliveryType: null |
||||
|
} |
||||
|
}, |
||||
|
onLoad(data) { |
||||
|
this.preview = data.preview || 0; |
||||
|
this.token = uni.getStorageSync('token'); |
||||
|
this.isIphoneX = this.$util.uniappIsIPhoneX(); |
||||
|
|
||||
|
if (data.source_member) { |
||||
|
uni.setStorageSync('source_member', data.source_member); |
||||
|
this.source_member = data.source_member; |
||||
|
} |
||||
|
//记录分享关系
|
||||
|
if (this.token && uni.getStorageSync('source_member')) { |
||||
|
this.$util.onSourceMember(uni.getStorageSync('source_member')); |
||||
|
} |
||||
|
|
||||
|
// 小程序扫码进入
|
||||
|
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('is_test') != -1) uni.setStorageSync('is_test', 1); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
cartCount() { |
||||
|
return this.$store.state.cartNumber; |
||||
|
}, |
||||
|
}, |
||||
|
onShow() { |
||||
|
if (this.token) { |
||||
|
this.getCartCount(); |
||||
|
|
||||
|
this.$util.getMemberId().then(resolve => { |
||||
|
this.memberId = resolve; |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
memberId: function() { |
||||
|
if (this.goodsSkuDetail.goods_id) this.setPublicShare(); |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
|
||||
|
// 处理商品详情数据
|
||||
|
handleGoodsSkuData() { |
||||
|
this.$langConfig.title(this.goodsSkuDetail.goods_name); |
||||
|
|
||||
|
|
||||
|
if (uni.getStorageSync('token')) { |
||||
|
this.getWhetherCollection(); |
||||
|
this.modifyGoodsInfo(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// 初始化商品详情视图数据
|
||||
|
this.$refs.goodsDetailView.init({ |
||||
|
sku_id: this.skuId, |
||||
|
goods_id: this.goodsSkuDetail.goods_id, |
||||
|
preview: this.preview, |
||||
|
source_member: this.source_member, |
||||
|
posterParams: this.posterParams, |
||||
|
posterApi: this.posterApi, |
||||
|
shareUrl: this.shareUrl, |
||||
|
memberId: this.memberId, |
||||
|
goodsRoute: this.goodsRoute |
||||
|
}); |
||||
|
|
||||
|
//媒体
|
||||
|
if (this.goodsSkuDetail.video_url) this.switchMedia = "video"; |
||||
|
|
||||
|
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.goods_spec_format && this.goodsSkuDetail.goods_image) { |
||||
|
|
||||
|
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); |
||||
|
} |
||||
|
|
||||
|
this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件"; |
||||
|
|
||||
|
// 当前商品SKU规格
|
||||
|
if (this.goodsSkuDetail.sku_spec_format) this.goodsSkuDetail.sku_spec_format = JSON.parse(this |
||||
|
.goodsSkuDetail.sku_spec_format); |
||||
|
|
||||
|
// 商品属性
|
||||
|
if (this.goodsSkuDetail.goods_attr_format) { |
||||
|
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 = htmlParser(this
|
||||
|
// .goodsSkuDetail.goods_content);
|
||||
|
|
||||
|
//商品服务
|
||||
|
if (this.goodsSkuDetail.goods_service) { |
||||
|
for (let i in this.goodsSkuDetail.goods_service) { |
||||
|
this.goodsSkuDetail.goods_service[i]['icon'] = this.goodsSkuDetail.goods_service[i]['icon'] ? JSON |
||||
|
.parse(this.goodsSkuDetail.goods_service[i]['icon']) : ''; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
this.contactData = { |
||||
|
title: this.goodsSkuDetail.sku_name, |
||||
|
path: this.shareUrl, |
||||
|
img: this.$util.img(this.goodsSkuDetail.sku_image, { |
||||
|
size: 'big' |
||||
|
}) |
||||
|
} |
||||
|
if (this.$refs.goodsPromotion) this.$refs.goodsPromotion.refresh(this.goodsSkuDetail |
||||
|
.goods_promotion); |
||||
|
|
||||
|
if (this.goodsRoute != '/page_goods/detail/detail') this.setPublicShare(); |
||||
|
|
||||
|
this.getBarrageData(); |
||||
|
if (this.goodsSkuDetail.is_virtual == 0) this.getEnabledExpressType(); |
||||
|
}, |
||||
|
/** |
||||
|
* 刷新商品详情数据 |
||||
|
* @param {Object} goodsSkuDetail |
||||
|
*/ |
||||
|
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) { |
||||
|
|
||||
|
// 初始化商品详情视图数据
|
||||
|
this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件"; |
||||
|
|
||||
|
// 解决轮播图数量不一致时,切换到第一个
|
||||
|
if (this.swiperCurrent > this.goodsSkuDetail.sku_images.length) { |
||||
|
this.swiperAutoplay = true; |
||||
|
this.swiperCurrent = 1; |
||||
|
setTimeout(() => { |
||||
|
this.swiperAutoplay = false; |
||||
|
}, 40); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
this.$langConfig.title(this.goodsSkuDetail.sku_name); |
||||
|
|
||||
|
}, |
||||
|
goodsDetailViewInit() { |
||||
|
// 初始化商品详情视图数据
|
||||
|
this.$refs.goodsDetailView.init({ |
||||
|
sku_id: this.skuId, |
||||
|
goods_id: this.goodsSkuDetail.goods_id, |
||||
|
preview: this.preview, |
||||
|
source_member: this.source_member, |
||||
|
posterParams: this.posterParams, |
||||
|
posterApi: this.posterApi, |
||||
|
shareUrl: this.shareUrl, |
||||
|
memberId: this.memberId, |
||||
|
goodsRoute: this.goodsRoute |
||||
|
}); |
||||
|
}, |
||||
|
goHome() { |
||||
|
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
||||
|
this.$util.redirectTo('/pages/index/index'); |
||||
|
}, |
||||
|
goCart() { |
||||
|
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
||||
|
// this.$util.redirectTo('/pages/goods/cart');
|
||||
|
uni.navigateTo({ |
||||
|
url: '/pages/goods/cartCopy' |
||||
|
}) |
||||
|
}, |
||||
|
//获取购物车数量
|
||||
|
getCartCount() { |
||||
|
// console.log(1212);
|
||||
|
this.$store.dispatch('getCartNumber'); |
||||
|
}, |
||||
|
|
||||
|
//-------------------------------------关注-------------------------------------
|
||||
|
//更新商品信息
|
||||
|
modifyGoodsInfo() { |
||||
|
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
||||
|
//更新商品点击量
|
||||
|
this.$api.sendRequest({ |
||||
|
url: "/api/goods/modifyclicks", |
||||
|
data: { |
||||
|
sku_id: this.skuId |
||||
|
}, |
||||
|
success: res => {} |
||||
|
}); |
||||
|
|
||||
|
//添加足迹
|
||||
|
this.$api.sendRequest({ |
||||
|
url: "/api/goodsbrowse/add", |
||||
|
data: { |
||||
|
goods_id: this.goodsSkuDetail.goods_id, |
||||
|
sku_id: this.skuId |
||||
|
}, |
||||
|
success: res => {} |
||||
|
}); |
||||
|
}, |
||||
|
//-------------------------------------关注-------------------------------------
|
||||
|
|
||||
|
//获取用户是否关注
|
||||
|
getWhetherCollection() { |
||||
|
this.$api.sendRequest({ |
||||
|
url: "/api/goodscollect/iscollect", |
||||
|
data: { |
||||
|
goods_id: this.goodsSkuDetail.goods_id |
||||
|
}, |
||||
|
success: res => { |
||||
|
this.whetherCollection = res.data; |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
editCollection() { |
||||
|
if (this.$refs.goodsDetailView) { |
||||
|
this.whetherCollection = this.$refs.goodsDetailView.collection(); |
||||
|
} |
||||
|
}, |
||||
|
openSharePopup() { |
||||
|
if (this.$refs.goodsDetailView) { |
||||
|
this.$refs.goodsDetailView.openSharePopup(); |
||||
|
} |
||||
|
}, |
||||
|
getMemberId() { |
||||
|
this.$api.sendRequest({ |
||||
|
url: "/api/member/id", |
||||
|
success: res => { |
||||
|
if (res.code >= 0) { |
||||
|
this.memberId = res.data; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
//弹幕
|
||||
|
getBarrageData() { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/goods/goodsbarrage', |
||||
|
data: { |
||||
|
goods_id: this.goodsSkuDetail.goods_id |
||||
|
}, |
||||
|
success: res => { |
||||
|
if (res.code == 0 && res.data) { |
||||
|
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) |
||||
|
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.memberId) shareUrl += '&source_member=' + this.memberId; |
||||
|
|
||||
|
this.$util.setPublicShare({ |
||||
|
title: this.goodsSkuDetail.goods_name, |
||||
|
desc: '', |
||||
|
link: shareUrl, |
||||
|
imgUrl: typeof this.goodsSkuDetail.goods_image == 'object' ? this.goodsSkuDetail.goods_image[ |
||||
|
0] : this.goodsSkuDetail.goods_image.split(',')[0] |
||||
|
}) |
||||
|
}, |
||||
|
/** |
||||
|
* 查询启用的配送方式 |
||||
|
*/ |
||||
|
getEnabledExpressType() { |
||||
|
this.$api.sendRequest({ |
||||
|
url: "/api/config/enabledexpresstype", |
||||
|
success: res => { |
||||
|
if (res.code == 0 && res.data) this.deliveryType = res.data; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* 自定义分享内容 |
||||
|
* @param {Object} res |
||||
|
*/ |
||||
|
onShareAppMessage(res) { |
||||
|
var path = this.shareUrl; |
||||
|
if (this.memberId) path += '&source_member=' + this.memberId; |
||||
|
return { |
||||
|
title: this.goodsSkuDetail.sku_name, |
||||
|
imageUrl: this.shareImg ? this.$util.img(this.shareImg) : this.$util.img(this.goodsSkuDetail.sku_image, { |
||||
|
size: 'big' |
||||
|
}), |
||||
|
path: path, |
||||
|
success: res => {}, |
||||
|
fail: res => {} |
||||
|
}; |
||||
|
}, |
||||
|
// 分享到微信朋友圈
|
||||
|
// #ifdef MP-WEIXIN
|
||||
|
onShareTimeline() { |
||||
|
let query = this.shareQuery; |
||||
|
if (this.memberId) query += '&source_member=' + this.memberId; |
||||
|
return { |
||||
|
title: this.goodsSkuDetail.sku_name, |
||||
|
query: query, |
||||
|
imageUrl: this.$util.img(this.goodsSkuDetail.sku_image, { |
||||
|
size: 'big' |
||||
|
}) |
||||
|
}; |
||||
|
} |
||||
|
// #endif
|
||||
|
} |
||||
@ -0,0 +1,188 @@ |
|||||
|
import Config from './config.js' |
||||
|
import Util from './util.js' |
||||
|
import store from '@/store/index.js' |
||||
|
import { showLoading, hideLoading } from "./prompt-ui.js" |
||||
|
|
||||
|
// #ifdef H5
|
||||
|
const app_type = Util.isWeiXin() ? 'wechat' : 'h5'; |
||||
|
const app_type_name = Util.isWeiXin() ? '微信公众号' : 'H5'; |
||||
|
// #endif
|
||||
|
|
||||
|
// #ifdef MP-WEIXIN
|
||||
|
const app_type = 'wechat'; |
||||
|
const app_type_name = 'WECHAT'; |
||||
|
// #endif
|
||||
|
|
||||
|
// #ifdef MP-ALIPAY
|
||||
|
const app_type = 'aliapp'; |
||||
|
const app_type_name = '支付宝小程序'; |
||||
|
// #endif
|
||||
|
|
||||
|
// #ifdef MP-BAIDU
|
||||
|
const app_type = 'baiduapp'; |
||||
|
const app_type_name = '百度小程序'; |
||||
|
// #endif
|
||||
|
|
||||
|
// #ifdef MP-TOUTIAO
|
||||
|
const app_type = 'MP-TOUTIAO'; |
||||
|
const app_type_name = '头条小程序'; |
||||
|
// #endif
|
||||
|
|
||||
|
// #ifdef MP-QQ
|
||||
|
const app_type = 'MP-QQ'; |
||||
|
const app_type_name = 'QQ小程序'; |
||||
|
// #endif
|
||||
|
|
||||
|
// #ifdef APP-PLUS
|
||||
|
const app_type = 'weapp'; |
||||
|
const app_type_name = 'WEAPP'; |
||||
|
// #endif
|
||||
|
|
||||
|
|
||||
|
const createLog = (url, req, res) => { |
||||
|
console.log( |
||||
|
`%c ${url}`, |
||||
|
'padding: 2px 4px; border-radius: 3px 0 0 3px; color: #fff; background: #b23ff7; font-weight: bold;', |
||||
|
req, |
||||
|
res |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default { |
||||
|
sendRequest(params) { |
||||
|
var method = params.data != undefined ? 'POST' : 'GET', // 请求方式
|
||||
|
url = Config.baseUrl + params.url, // 请求路径
|
||||
|
data = { |
||||
|
app_type, |
||||
|
app_type_name |
||||
|
}; |
||||
|
|
||||
|
// token
|
||||
|
if (uni.getStorageSync('token')) data.token = uni.getStorageSync('token'); |
||||
|
// 店铺id
|
||||
|
if (uni.getStorageSync('myStore')) data.store_id = uni.getStorageSync('myStore').id; |
||||
|
// 参数
|
||||
|
if (params.data != undefined) Object.assign(data, params.data); |
||||
|
|
||||
|
showLoading(); |
||||
|
if (params.async === false) { |
||||
|
//同步
|
||||
|
return new Promise((resolve, reject) => { |
||||
|
uni.request({ |
||||
|
url: url, |
||||
|
method: method, |
||||
|
data: data, |
||||
|
header: params.header || { |
||||
|
'Accept': 'application/json', |
||||
|
'content-type': 'application/x-www-form-urlencoded;application/json' |
||||
|
}, |
||||
|
dataType: params.dataType || 'json', |
||||
|
responseType: params.responseType || 'text', |
||||
|
success: (res) => { |
||||
|
try { |
||||
|
res.data = JSON.parse(res.data); |
||||
|
createLog(params.url, data, res.data) |
||||
|
} catch (e) { |
||||
|
|
||||
|
} |
||||
|
if (res.data.code == -3 && store.state.siteState > 0) { |
||||
|
store.commit('setSiteState', -3) |
||||
|
Util.redirectTo('/pages_tool/storeclose/storeclose', {}, 'reLaunch'); |
||||
|
return; |
||||
|
} |
||||
|
if (res.data.refreshtoken) { |
||||
|
uni.setStorage({ |
||||
|
key: 'token', |
||||
|
data: res.data.refreshtoken |
||||
|
}); |
||||
|
} |
||||
|
if (res.data.code == -10009 || res.data.code == -10010) { |
||||
|
uni.removeStorage({ |
||||
|
key: 'token' |
||||
|
}) |
||||
|
} |
||||
|
resolve(res.data); |
||||
|
}, |
||||
|
fail: (res) => { |
||||
|
reject(res); |
||||
|
}, |
||||
|
complete: (res) => { |
||||
|
hideLoading(); |
||||
|
reject(res); |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
} else { |
||||
|
//异步
|
||||
|
uni.request({ |
||||
|
url: url, |
||||
|
method: method, |
||||
|
data: data, |
||||
|
header: params.header || { |
||||
|
'Accept': 'application/json', |
||||
|
'content-type': 'application/x-www-form-urlencoded;application/json' |
||||
|
}, |
||||
|
dataType: params.dataType || 'json', |
||||
|
responseType: params.responseType || 'text', |
||||
|
success: (res) => { |
||||
|
try { |
||||
|
res.data = JSON.parse(res.data); |
||||
|
createLog(params.url, data, res.data) |
||||
|
} catch (e) { |
||||
|
//TODO handle the exception
|
||||
|
// console.log('api error:', e);
|
||||
|
} |
||||
|
|
||||
|
if (res.data.code != 0) { |
||||
|
console.log('-------', url) |
||||
|
} |
||||
|
if (res.data.code == -3 && store.state.siteState > 0) { |
||||
|
store.commit('setSiteState', -3) |
||||
|
Util.redirectTo('/pages_tool/storeclose/storeclose', {}, 'reLaunch'); |
||||
|
return; |
||||
|
} |
||||
|
if (res.data.refreshtoken) { |
||||
|
uni.setStorage({ |
||||
|
key: 'token', |
||||
|
data: res.data.refreshtoken |
||||
|
}); |
||||
|
} |
||||
|
if (res.data.code == -10009 || res.data.code == -10010) { |
||||
|
uni.removeStorage({ |
||||
|
key: 'token' |
||||
|
}) |
||||
|
} |
||||
|
if (res.data.code == 8 || res.data.code == 1) { |
||||
|
|
||||
|
return |
||||
|
} |
||||
|
if (res.data.code == -1 && res.data.message == "您尚未登录,请先进行登录") { |
||||
|
uni.showToast({ |
||||
|
title: res.data.message || '您尚未登录,请先进行登录', |
||||
|
icon: "none", |
||||
|
}) |
||||
|
setTimeout(() => { |
||||
|
Util.redirectTo('/pages_tool/login/login'); |
||||
|
}, 1000) |
||||
|
} |
||||
|
if (res.data.code != 0 || res.data.code == -1) { |
||||
|
uni.showToast({ |
||||
|
title: res.data.message || '系统错误', |
||||
|
icon: "none", |
||||
|
}) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
typeof params.success == 'function' && params.success(res.data); |
||||
|
}, |
||||
|
fail: (res) => { |
||||
|
typeof params.fail == 'function' && params.fail(res); |
||||
|
}, |
||||
|
complete: (res) => { |
||||
|
hideLoading(); |
||||
|
typeof params.complete == 'function' && params.complete(res); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
# jweixin-module |
||||
|
|
||||
|
微信JS-SDK |
||||
|
|
||||
|
## 安装 |
||||
|
|
||||
|
### NPM |
||||
|
|
||||
|
```shell |
||||
|
npm install jweixin-module --save |
||||
|
``` |
||||
|
|
||||
|
### UMD |
||||
|
|
||||
|
```http |
||||
|
https://unpkg.com/jweixin-module/out/index.js |
||||
|
``` |
||||
|
|
||||
|
## 使用 |
||||
|
|
||||
|
```js |
||||
|
var wx = require('jweixin-module') |
||||
|
wx.ready(function(){ |
||||
|
// TODO |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
## 完整API |
||||
|
|
||||
|
>[微信JS-SDK说明文档](https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115) |
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,60 @@ |
|||||
|
{ |
||||
|
"_from": "jweixin-module", |
||||
|
"_id": "jweixin-module@1.4.1", |
||||
|
"_inBundle": false, |
||||
|
"_integrity": "sha512-2R2oa1lYhAsclfjKSf3DP4ZiP1dcrQUbM7aklbeJA+UAg/LS7MqoA6UbTy1cs4sbB34z62K4bKW0Z9iazD8ejg==", |
||||
|
"_location": "/jweixin-module", |
||||
|
"_phantomChildren": {}, |
||||
|
"_requested": { |
||||
|
"type": "tag", |
||||
|
"registry": true, |
||||
|
"raw": "jweixin-module", |
||||
|
"name": "jweixin-module", |
||||
|
"escapedName": "jweixin-module", |
||||
|
"rawSpec": "", |
||||
|
"saveSpec": null, |
||||
|
"fetchSpec": "latest" |
||||
|
}, |
||||
|
"_requiredBy": [ |
||||
|
"#USER", |
||||
|
"/" |
||||
|
], |
||||
|
"_resolved": "https://registry.npmjs.org/jweixin-module/-/jweixin-module-1.4.1.tgz", |
||||
|
"_shasum": "1fc8fa42622243f6c35651d272cd587debf56cd1", |
||||
|
"_spec": "jweixin-module", |
||||
|
"_where": "E:\\demo\\niushop_uniapp", |
||||
|
"author": { |
||||
|
"name": "Shengqiang Guo" |
||||
|
}, |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/zhetengbiji/jweixin-module/issues" |
||||
|
}, |
||||
|
"bundleDependencies": false, |
||||
|
"deprecated": false, |
||||
|
"description": "微信JS-SDK", |
||||
|
"devDependencies": { |
||||
|
"textfile": "^1.2.0", |
||||
|
"uglify-js": "^3.4.9" |
||||
|
}, |
||||
|
"homepage": "https://github.com/zhetengbiji/jweixin-module#readme", |
||||
|
"keywords": [ |
||||
|
"wxjssdk", |
||||
|
"weixin", |
||||
|
"jweixin", |
||||
|
"wechat", |
||||
|
"jssdk", |
||||
|
"wx" |
||||
|
], |
||||
|
"license": "ISC", |
||||
|
"main": "out/index.js", |
||||
|
"name": "jweixin-module", |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/zhetengbiji/jweixin-module.git" |
||||
|
}, |
||||
|
"scripts": { |
||||
|
"build": "node build", |
||||
|
"prepublish": "npm run build" |
||||
|
}, |
||||
|
"version": "1.4.1" |
||||
|
} |
||||
@ -0,0 +1,129 @@ |
|||||
|
const langList = ['zh-cn', 'en-us']; |
||||
|
|
||||
|
var locale ="zh-cn"; //设置语言
|
||||
|
// uni.getStorageSync('lang') ||
|
||||
|
|
||||
|
export default { |
||||
|
langList: ['zh-cn', 'en-us'], |
||||
|
/** |
||||
|
* * 解析多语言 |
||||
|
* @param {Object} field |
||||
|
*/ |
||||
|
lang(field) { |
||||
|
let _this = getCurrentPages()[getCurrentPages().length - 1]; |
||||
|
if (!_this) return; |
||||
|
|
||||
|
var value = ''; |
||||
|
let newRoute; |
||||
|
try { |
||||
|
//公共语言包
|
||||
|
var lang = require('../../lang/' + locale + '/common.js').lang; |
||||
|
|
||||
|
//当前页面语言包
|
||||
|
let route = _this.route.split("/"); |
||||
|
newRoute = route.slice(1, route.length); |
||||
|
let currentPageLang = require('../../lang/' + locale + '/' + newRoute.join("/") + '.js').lang; |
||||
|
|
||||
|
for (let f in currentPageLang) { |
||||
|
lang[f] = currentPageLang[f]; |
||||
|
} |
||||
|
|
||||
|
var arr = field.split("."); |
||||
|
if (arr.length > 1) { |
||||
|
for (let i in arr) { |
||||
|
var next = parseInt(i) + 1; |
||||
|
if (next < arr.length) { |
||||
|
value = lang[arr[i]][arr[next]]; |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
value = lang[field]; |
||||
|
} |
||||
|
} catch (e) { |
||||
|
|
||||
|
if (field.indexOf("common.") != -1 || field.indexOf("tabBar.") != -1) { |
||||
|
value = lang[field]; |
||||
|
} else { |
||||
|
value = field; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (arguments.length > 1) { |
||||
|
//有参数,需要替换
|
||||
|
for (var i = 1; i < arguments.length; i++) { |
||||
|
value = value.replace("{" + (i - 1) + "}", arguments[i]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (value == undefined || (value == 'title' && field == 'title')) value = ''; // field
|
||||
|
return value; |
||||
|
}, |
||||
|
//切换语言
|
||||
|
change(value) { |
||||
|
let _this = getCurrentPages()[getCurrentPages().length - 1]; |
||||
|
if (!_this) return; |
||||
|
|
||||
|
uni.setStorageSync("lang", value); |
||||
|
locale ="zh-cn"; //设置语言
|
||||
|
// uni.getStorageSync('lang') ||
|
||||
|
|
||||
|
this.refresh(); |
||||
|
|
||||
|
uni.reLaunch({ |
||||
|
url: '/pages/member/index' |
||||
|
}); |
||||
|
}, |
||||
|
//刷新标题、tabbar
|
||||
|
refresh() { |
||||
|
let _this = getCurrentPages()[getCurrentPages().length - 1]; |
||||
|
if (!_this) return; |
||||
|
|
||||
|
this.title(this.lang("title")); |
||||
|
|
||||
|
//设置tabbar的文字语言
|
||||
|
uni.setTabBarItem({ |
||||
|
index: 0, |
||||
|
text: '首页' |
||||
|
}); |
||||
|
uni.setTabBarItem({ |
||||
|
index: 1, |
||||
|
text: '分类' |
||||
|
}); |
||||
|
uni.setTabBarItem({ |
||||
|
index: 2, |
||||
|
text: '购物车' |
||||
|
}); |
||||
|
uni.setTabBarItem({ |
||||
|
index: 3, |
||||
|
text: '我的' |
||||
|
}); |
||||
|
}, |
||||
|
title(str) { |
||||
|
if (str) { |
||||
|
uni.setNavigationBarTitle({ |
||||
|
title: str, |
||||
|
success: function(res){ |
||||
|
}, |
||||
|
fail: function(err){ |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
// 获取语言包列表
|
||||
|
list() { |
||||
|
var list = []; |
||||
|
try { |
||||
|
//公共语言包
|
||||
|
for (var i = 0; i < langList.length; i++) { |
||||
|
let item = require('../../lang/' + langList[i] + '/common.js').lang |
||||
|
list.push({ |
||||
|
name: item.common.name, |
||||
|
value: langList[i] |
||||
|
}); |
||||
|
} |
||||
|
} catch (e) { |
||||
|
// "没有找到语言包:", '../../lang/' + locale + '/common.js'
|
||||
|
} |
||||
|
return list; |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,11 @@ |
|||||
|
function timesfm(num){ |
||||
|
let now=new Date(num) |
||||
|
let n=now.getFullYear() |
||||
|
let y=now.getMonth()+1 |
||||
|
let r =now.getDate(); |
||||
|
let s=now.getHours()>=10?now.getHours():0+''+now.getHours(); |
||||
|
let f=now.getMinutes()>=10?now.getMinutes():0+''+now.getMinutes(); |
||||
|
let m=now.getSeconds()>=10?now.getSeconds():0+''+now.getSeconds(); |
||||
|
return n+'-'+y+'-'+r+' '+s+':'+f+':'+m |
||||
|
} |
||||
|
module.exports = timesfm; |
||||
@ -0,0 +1,107 @@ |
|||||
|
import TransformCoordinate from './transformCoordinate.js' |
||||
|
|
||||
|
function openMapByDefault(latitude, longitude, name) { |
||||
|
uni.openLocation({ |
||||
|
latitude: latitude, |
||||
|
longitude: longitude, |
||||
|
name: name, |
||||
|
fail: (e) => { |
||||
|
uni.showModal({ |
||||
|
content: '打开地图失败,请稍后重试' |
||||
|
}) |
||||
|
}, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
function openMapByAndroid(latitude, longitude, name) { |
||||
|
let url = ''; // 回调地址
|
||||
|
let identity = ''; // 程序名称
|
||||
|
if (plus.runtime.isApplicationExist({ |
||||
|
pname: 'com.baidu.BaiduMap' |
||||
|
})) { // baidumap
|
||||
|
url = |
||||
|
`baidumap://map/marker?location=${latitude},${longitude}&title=${name}&coord_type=gcj02&src=andr.baidu.openAPIdemo` |
||||
|
identity = 'com.baidu.BaiduMap' |
||||
|
openURL(url, identity) |
||||
|
} else if (plus.runtime.isApplicationExist({ |
||||
|
pname: 'com.autonavi.minimap' |
||||
|
})) { // 高德
|
||||
|
url = `androidamap://viewMap?sourceApplication=appname&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0` |
||||
|
identity = 'com.autonavi.minimap' |
||||
|
openURL(url, identity) |
||||
|
} else { |
||||
|
openMapByDefault(latitude, longitude, name) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function openMapByIos(latitude, longitude, name) { |
||||
|
let url = ''; // 回调地址
|
||||
|
let errorCB = ''; // url失败的回调地址
|
||||
|
let identity = ''; // 程序名称
|
||||
|
|
||||
|
if (plus.runtime.isApplicationExist({ |
||||
|
action: 'baidumap://' |
||||
|
})) { // baidumap
|
||||
|
url = |
||||
|
`baidumap://map/marker?location=${latitude},${longitude}&title=${name}&content=${name}&src=ios.baidu.openAPIdemo&coord_type=gcj02`; |
||||
|
openURL(url, identity) |
||||
|
} else if (plus.runtime.isApplicationExist({ |
||||
|
action: 'iosamap://' |
||||
|
})) { // 高德
|
||||
|
url = `iosamap://viewMap?sourceApplication=applicationName&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0` |
||||
|
openURL(url, identity) |
||||
|
} else { |
||||
|
openMapByDefault(latitude, longitude, name) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function openURL(url, identity) { |
||||
|
let newurl = encodeURI(url); |
||||
|
plus.runtime.openURL(newurl, function(res) { |
||||
|
uni.showModal({ |
||||
|
content: res.message |
||||
|
}) |
||||
|
}, identity); |
||||
|
} |
||||
|
|
||||
|
function getCoordByType(longitude, latitude, coord_type) { |
||||
|
switch (coord_type) { |
||||
|
case 'gcj02': |
||||
|
return [longitude, latitude] |
||||
|
break; |
||||
|
case 'bd09': |
||||
|
return TransformCoordinate.bd09togcj02(longitude, latitude) |
||||
|
break; |
||||
|
case 'wgs84': |
||||
|
return TransformCoordinate.wgs84togcj02(longitude, latitude) |
||||
|
break; |
||||
|
default: |
||||
|
return [longitude, latitude] |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
export default { |
||||
|
/* 打开地图 */ |
||||
|
openMap(latitude, longitude, name, coord_type = 'gcj02') { |
||||
|
let arr = getCoordByType(longitude, latitude, coord_type) |
||||
|
// #ifdef APP-PLUS
|
||||
|
switch (uni.getSystemInfoSync().platform) { |
||||
|
case 'android': |
||||
|
console.log('运行Android上') |
||||
|
openMapByAndroid(arr[1], arr[0], name) |
||||
|
break; |
||||
|
case 'ios': |
||||
|
console.log('运行iOS上') |
||||
|
openMapByIos(arr[1], arr[0], name) |
||||
|
break; |
||||
|
default: |
||||
|
openMapByDefault(arr[1], arr[0], name) |
||||
|
console.log('运行在开发者工具上') |
||||
|
break; |
||||
|
} |
||||
|
// #endif
|
||||
|
// #ifndef APP-PLUS
|
||||
|
openMapByDefault(arr[1], arr[0], name) |
||||
|
// #endif
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,124 @@ |
|||||
|
/** |
||||
|
* Created by Wandergis on 2015/7/8. |
||||
|
* 提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换 |
||||
|
*/ |
||||
|
|
||||
|
//定义一些常量
|
||||
|
var x_PI = 3.14159265358979324 * 3000.0 / 180.0; |
||||
|
var PI = 3.1415926535897932384626; |
||||
|
var a = 6378245.0; |
||||
|
var ee = 0.00669342162296594323; |
||||
|
|
||||
|
/** |
||||
|
* 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换 |
||||
|
* 即 百度 转 谷歌、高德 |
||||
|
* @param bd_lon |
||||
|
* @param bd_lat |
||||
|
* @returns {*[]} |
||||
|
*/ |
||||
|
function bd09togcj02(bd_lon, bd_lat) { |
||||
|
var x_pi = 3.14159265358979324 * 3000.0 / 180.0; |
||||
|
var x = bd_lon - 0.0065; |
||||
|
var y = bd_lat - 0.006; |
||||
|
var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); |
||||
|
var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); |
||||
|
var gg_lng = z * Math.cos(theta); |
||||
|
var gg_lat = z * Math.sin(theta); |
||||
|
return [gg_lng, gg_lat] |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换 |
||||
|
* 即谷歌、高德 转 百度 |
||||
|
* @param lng |
||||
|
* @param lat |
||||
|
* @returns {*[]} |
||||
|
*/ |
||||
|
function gcj02tobd09(lng, lat) { |
||||
|
var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI); |
||||
|
var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI); |
||||
|
var bd_lng = z * Math.cos(theta) + 0.0065; |
||||
|
var bd_lat = z * Math.sin(theta) + 0.006; |
||||
|
return [bd_lng, bd_lat] |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* WGS84转GCj02 |
||||
|
* @param lng |
||||
|
* @param lat |
||||
|
* @returns {*[]} |
||||
|
*/ |
||||
|
function wgs84togcj02(lng, lat) { |
||||
|
if (out_of_china(lng, lat)) { |
||||
|
return [lng, lat] |
||||
|
} else { |
||||
|
var dlat = transformlat(lng - 105.0, lat - 35.0); |
||||
|
var dlng = transformlng(lng - 105.0, lat - 35.0); |
||||
|
var radlat = lat / 180.0 * PI; |
||||
|
var magic = Math.sin(radlat); |
||||
|
magic = 1 - ee * magic * magic; |
||||
|
var sqrtmagic = Math.sqrt(magic); |
||||
|
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); |
||||
|
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); |
||||
|
var mglat = lat + dlat; |
||||
|
var mglng = lng + dlng; |
||||
|
return [mglng, mglat] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* GCJ02 转换为 WGS84 |
||||
|
* @param lng |
||||
|
* @param lat |
||||
|
* @returns {*[]} |
||||
|
*/ |
||||
|
function gcj02towgs84(lng, lat) { |
||||
|
if (out_of_china(lng, lat)) { |
||||
|
return [lng, lat] |
||||
|
} else { |
||||
|
var dlat = transformlat(lng - 105.0, lat - 35.0); |
||||
|
var dlng = transformlng(lng - 105.0, lat - 35.0); |
||||
|
var radlat = lat / 180.0 * PI; |
||||
|
var magic = Math.sin(radlat); |
||||
|
magic = 1 - ee * magic * magic; |
||||
|
var sqrtmagic = Math.sqrt(magic); |
||||
|
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); |
||||
|
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); |
||||
|
mglat = lat + dlat; |
||||
|
mglng = lng + dlng; |
||||
|
return [lng * 2 - mglng, lat * 2 - mglat] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function transformlat(lng, lat) { |
||||
|
var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng)); |
||||
|
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; |
||||
|
ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0; |
||||
|
ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0; |
||||
|
return ret |
||||
|
} |
||||
|
|
||||
|
function transformlng(lng, lat) { |
||||
|
var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng)); |
||||
|
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; |
||||
|
ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0; |
||||
|
ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0; |
||||
|
return ret |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 判断是否在国内,不在国内则不做偏移 |
||||
|
* @param lng |
||||
|
* @param lat |
||||
|
* @returns {boolean} |
||||
|
*/ |
||||
|
function out_of_china(lng, lat) { |
||||
|
return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false); |
||||
|
} |
||||
|
|
||||
|
export default { |
||||
|
bd09togcj02: bd09togcj02, // 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
|
||||
|
gcj02tobd09: gcj02tobd09, // 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
|
||||
|
wgs84togcj02: wgs84togcj02, //
|
||||
|
gcj02towgs84: gcj02towgs84, |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
(function() { |
||||
|
var u = navigator.userAgent, |
||||
|
w = window.innerWidth; |
||||
|
if (w >= 960) { |
||||
|
window.innerWidth = 960; |
||||
|
window.onload = function() { |
||||
|
window.innerWidth = 960; |
||||
|
} |
||||
|
} |
||||
|
})(); |
||||
@ -0,0 +1,51 @@ |
|||||
|
let loadingCount = 0; |
||||
|
let timer = null; // 避免多次loading
|
||||
|
let loadingTimer = null; |
||||
|
let custom = false; |
||||
|
|
||||
|
// 开启loading
|
||||
|
export const showLoading = () => { |
||||
|
return |
||||
|
// 设置加载动画区域
|
||||
|
if (loadingCount === 0 && !timer) { |
||||
|
// TODO locale
|
||||
|
if (custom) { |
||||
|
app.$emit("showLoading"); |
||||
|
} else { |
||||
|
uni.showLoading({ title: '加载中...' }) |
||||
|
} |
||||
|
// if (loadingTimer) clearTimeout(loadingTimer);
|
||||
|
// // 3秒超时 关闭loading
|
||||
|
// loadingTimer = setTimeout(() => {
|
||||
|
// hideLoading()
|
||||
|
// }, 3000)
|
||||
|
} |
||||
|
if (timer) clearTimeout(timer); |
||||
|
loadingCount++; |
||||
|
}; |
||||
|
|
||||
|
// 隐藏loading
|
||||
|
export const hideLoading = () => { |
||||
|
return |
||||
|
if (loadingCount <= 0) return; |
||||
|
loadingCount--; |
||||
|
if (loadingCount === 0) { |
||||
|
timer = setTimeout(() => { |
||||
|
// TODO locale
|
||||
|
if (custom) { |
||||
|
app.$emit("hideLoading"); |
||||
|
} else { |
||||
|
uni.hideLoading() |
||||
|
} |
||||
|
|
||||
|
timer = null; |
||||
|
}, 500); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// 清空loading
|
||||
|
export const clearLoading = () => { |
||||
|
loadingCount = 0; |
||||
|
uni.hideLoading() |
||||
|
}; |
||||
|
|
||||
@ -0,0 +1,28 @@ |
|||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
showTop: false, |
||||
|
scrollTop: 0, |
||||
|
oldLocation: 0 |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
scrollToTopNative() { |
||||
|
uni.pageScrollTo({ |
||||
|
duration: 200, |
||||
|
scrollTop: 0 |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
onReachBottom() { |
||||
|
if(this.$refs.goodrecommend) this.$refs.goodrecommend.getLikeList(10) |
||||
|
}, |
||||
|
onPageScroll(e) { |
||||
|
this.oldLocation = e.scrollTop; |
||||
|
if (e.scrollTop > 400) { |
||||
|
this.showTop = true; |
||||
|
} else { |
||||
|
this.showTop = false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,207 @@ |
|||||
|
import config from './config.js' |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
timeoutObj: null, //ping定时器
|
||||
|
servicer_id: null, //绑定
|
||||
|
pingInterval: config.pingInterval //本地端主动给服务器ping的时间, 0 则不开启
|
||||
|
} |
||||
|
}, |
||||
|
onLoad() { |
||||
|
let that = this; |
||||
|
// 因为图片上传,所以不能onhide关闭长链接,但是每次打开客服都会有重复请求,所以优先关闭再去打开长链接
|
||||
|
uni.closeSocket(); |
||||
|
// .判断是否已连接
|
||||
|
that.checkOpenSocket(); |
||||
|
// uni.onSocketClose(function(res) {
|
||||
|
// console.log('WebSocket 已关闭!');
|
||||
|
// });
|
||||
|
}, |
||||
|
methods: { |
||||
|
// 判断是否已连接
|
||||
|
checkOpenSocket() { |
||||
|
console.log('判断是否已连接') |
||||
|
// alert('判断是否已连接')
|
||||
|
let self = this; |
||||
|
uni.sendSocketMessage({ |
||||
|
data: 'ping', |
||||
|
success: (res) => { |
||||
|
console.log('连接成功,检查') |
||||
|
// alert('连接成功,检查')
|
||||
|
// self.getChatList();
|
||||
|
return; |
||||
|
}, |
||||
|
fail: (err) => { // 未连接打开websocket连接
|
||||
|
console.log('连接失败') |
||||
|
// alert('连接失败')
|
||||
|
self.openConnection(); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
openConnection() { // 打开连接
|
||||
|
console.log('打开连接') |
||||
|
// alert('打开连接')
|
||||
|
// uni.closeSocket(); // 确保已经关闭后再重新打开
|
||||
|
uni.connectSocket({ |
||||
|
url: config.webSocket, |
||||
|
method: 'POST', |
||||
|
success(res) { |
||||
|
console.log('连接成功 connectSocket=', res); |
||||
|
// alert('连接成功 connectSocket=', res);
|
||||
|
}, |
||||
|
fail(err) { |
||||
|
console.log('连接失败 connectSocket=', err); |
||||
|
} |
||||
|
}); |
||||
|
// uni.onSocketOpen((res) => {
|
||||
|
// console.log('连接成功', res);
|
||||
|
// });
|
||||
|
this.onSocketMessage(); // 打开成功监听服务器返回的消息
|
||||
|
}, |
||||
|
// 打开成功监听服务器返回的消息
|
||||
|
onSocketMessage() { // 消息
|
||||
|
console.log("开始监听"); |
||||
|
|
||||
|
let that = this; |
||||
|
this.pingInterval = config.pingInterval; |
||||
|
this.timeoutObj = null; |
||||
|
uni.onSocketMessage((res) => { //type:init,connect,close,string,order,goods
|
||||
|
let msg = JSON.parse(res.data); |
||||
|
console.log("监听该服务器消息", res) |
||||
|
if (msg.type == 'close') { |
||||
|
clearInterval(that.timeoutObj); |
||||
|
that.timeoutObj = null; |
||||
|
uni.closeSocket(); |
||||
|
return; |
||||
|
} |
||||
|
this.reset(); |
||||
|
this.getSocketMsg(res.data); // 监听到有新服务器消息
|
||||
|
}); |
||||
|
}, |
||||
|
// 监听到有新服务器消息
|
||||
|
getSocketMsg(reData) { // 监听到服务器消息
|
||||
|
let that = this; |
||||
|
// console.log(reData)
|
||||
|
let giveMsg = JSON.parse(reData); |
||||
|
let data = { |
||||
|
isItMe: false, |
||||
|
}; |
||||
|
data.contentType = giveMsg.type; |
||||
|
// alert(data.contentType)
|
||||
|
if (giveMsg.type == 'init') { |
||||
|
// alert(123)
|
||||
|
that.$api.sendRequest({ |
||||
|
url: '/servicer/api/chat/bind', |
||||
|
data: { |
||||
|
client_id: giveMsg.data.client_id, |
||||
|
site_id: that.siteId |
||||
|
}, |
||||
|
success(res) { |
||||
|
if (res.code == 0) { |
||||
|
that.servicer_id = res.data.servicer_id; |
||||
|
} else { |
||||
|
that.servicer_id = 0; |
||||
|
} |
||||
|
that.getChatList(); |
||||
|
} |
||||
|
}) |
||||
|
} else if (giveMsg.type == 'connect') { |
||||
|
// that.servicer_id = giveMsg.data.servicer_id;
|
||||
|
// let NewArr = that.messageList;
|
||||
|
// let index = null;
|
||||
|
// for (let i = 0; i < NewArr.length; i++) {
|
||||
|
// if (NewArr[i].contentType == 'online' || NewArr[i].contentType == 'noline') {
|
||||
|
// index = i;
|
||||
|
// }
|
||||
|
// }
|
||||
|
// NewArr.splice(index, 1)
|
||||
|
// that.messageList = NewArr;
|
||||
|
// let obj = {}
|
||||
|
// if (that.servicer_id > 0) {
|
||||
|
// obj.contentType = 'online';
|
||||
|
// } else if (that.servicer_id == 0) {
|
||||
|
// obj.contentType = 'noline';
|
||||
|
// }
|
||||
|
// that.messageList.push(obj);
|
||||
|
return false; |
||||
|
} else if (giveMsg.type == 'string') { |
||||
|
data.content = giveMsg.data.servicer_say; |
||||
|
} else if (giveMsg.type == 'image') { |
||||
|
data.image = giveMsg.data.servicer_say; |
||||
|
} else if (giveMsg.type == 'order') { |
||||
|
data.order_id = giveMsg.data.order_id; |
||||
|
} else if (giveMsg.type == 'goodssku') { |
||||
|
data.sku_id = giveMsg.data.goods_sku_id; |
||||
|
} |
||||
|
if (giveMsg.type == 'init') return; |
||||
|
that.messageList.push(data); |
||||
|
that.$nextTick(() => { |
||||
|
that.setPageScrollTo() |
||||
|
}) |
||||
|
}, |
||||
|
// 检测心跳reset
|
||||
|
reset() { |
||||
|
console.log("检测心跳") |
||||
|
clearInterval(this.timeoutObj); |
||||
|
this.start(); // 启动心跳
|
||||
|
}, |
||||
|
// 启动心跳 start
|
||||
|
start() { |
||||
|
console.log("启动心跳") |
||||
|
let self = this; |
||||
|
this.timeoutObj = setInterval(function() { |
||||
|
uni.sendSocketMessage({ |
||||
|
data: 'ping', |
||||
|
success: (res) => { |
||||
|
console.log('连接中....'); |
||||
|
}, |
||||
|
fail: (err) => { |
||||
|
console.log('连接失败重新连接....'); |
||||
|
self.openConnection(); |
||||
|
} |
||||
|
}); |
||||
|
}, this.pingInterval); |
||||
|
} |
||||
|
}, |
||||
|
// onHide() {
|
||||
|
// // alert("关闭")
|
||||
|
// // 改之前的
|
||||
|
// // console.log("我出发了")
|
||||
|
// // this.checkOpenSocket();
|
||||
|
// clearInterval(this.timeoutObj);
|
||||
|
// this.timeoutObj = null;
|
||||
|
// this.$api.sendRequest({
|
||||
|
// url: '/servicer/api/chat/bye',
|
||||
|
// data: {
|
||||
|
// servicer_id: this.servicer_id,
|
||||
|
// site_id: this.siteId
|
||||
|
// },
|
||||
|
// success(res) {
|
||||
|
// uni.closeSocket();
|
||||
|
// },
|
||||
|
// fail: (err) => {
|
||||
|
// uni.closeSocket();
|
||||
|
// }
|
||||
|
// });
|
||||
|
// },
|
||||
|
onUnload() { |
||||
|
// alert("关闭")
|
||||
|
clearInterval(this.timeoutObj); |
||||
|
this.timeoutObj = null; |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/servicer/api/chat/bye', |
||||
|
data: { |
||||
|
servicer_id: this.servicer_id, |
||||
|
site_id: this.siteId |
||||
|
}, |
||||
|
success(res) { |
||||
|
// alert("关闭1")
|
||||
|
uni.closeSocket(); |
||||
|
}, |
||||
|
fail: (err) => { |
||||
|
// alert("关闭2")
|
||||
|
uni.closeSocket(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,387 @@ |
|||||
|
export default { |
||||
|
'default':{ |
||||
|
//红色
|
||||
|
name:'default', |
||||
|
main_color : '#F4391c', |
||||
|
aux_color : '#F7B500', |
||||
|
bg_color: '#FF4646',//主题背景
|
||||
|
bg_color_shallow: '#FF4646',//主题背景渐变浅色
|
||||
|
promotion_color: '#FF4646',//活动背景
|
||||
|
promotion_aux_color: '#F7B500',//活动背景辅色
|
||||
|
main_color_shallow: '#FFF4F4',//淡背景
|
||||
|
price_color: 'rgb(252,82,39)',//价格颜色
|
||||
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||
|
goods_detail : { |
||||
|
goods_price : 'rgb(252,82,39,1)',//价格
|
||||
|
promotion_tag:'#FF4646', |
||||
|
goods_card_bg:'#201A18',//会员卡背景
|
||||
|
goods_card_bg_shallow:'#7C7878',//会员卡背景浅色
|
||||
|
goods_card_color:'#FFD792', |
||||
|
goods_coupon:'#FC5227', |
||||
|
goods_cart_num_corner :'#FC5227',//购物车数量角标
|
||||
|
goods_btn_color:'#FF4646',//按钮颜色
|
||||
|
goods_btn_color_shallow:'#F7B500',//副按钮颜色
|
||||
|
}, |
||||
|
pintuan:{ |
||||
|
pintuan_label_bg:'#F7B500', |
||||
|
pintuan_label_color:'#FFFFFF', |
||||
|
pintuan_color:'#FA6400', |
||||
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||
|
}, |
||||
|
super_member: { |
||||
|
super_member_start_bg: '#7c7878', |
||||
|
super_member_end_bg: '#201a18', |
||||
|
super_member_start_text_color: '#FFDBA6', |
||||
|
super_member_end_text_color: '#FFEBCA', |
||||
|
}, |
||||
|
bargain:{ |
||||
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
seckill:{ |
||||
|
seckill_promotion_color: '#F83530',//活动背景
|
||||
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
giftcard:{ |
||||
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||
|
}, |
||||
|
}, |
||||
|
'green':{ |
||||
|
name:'green', |
||||
|
main_color : '#19C650', |
||||
|
aux_color : '#FA6400', |
||||
|
bg_color: '#19C650', |
||||
|
bg_color_shallow: '#19C650', |
||||
|
promotion_color: '#19C650', |
||||
|
promotion_aux_color: '#FA6400', |
||||
|
main_color_shallow: '#F0FFF5',//淡背景
|
||||
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||
|
goods_detail : { |
||||
|
goods_price : 'rgba(252,82,39,1)',//价格
|
||||
|
promotion_tag:'#19C650', |
||||
|
goods_card_bg:'#201A18',//会员卡背景
|
||||
|
goods_card_bg_shallow:'#7C7878',//会员卡背景浅色
|
||||
|
goods_card_color:'#FFD792', |
||||
|
goods_coupon:'#FC5227', |
||||
|
goods_cart_num_corner :'#FC5227',//购物车数量角标
|
||||
|
goods_btn_color:'#19C650',//按钮颜色
|
||||
|
goods_btn_color_shallow:'#FA6400',//副按钮颜色
|
||||
|
}, |
||||
|
pintuan:{ |
||||
|
pintuan_label_bg:'#F7B500', |
||||
|
pintuan_label_color:'#FFFFFF', |
||||
|
pintuan_color:'#FA6400', |
||||
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||
|
}, |
||||
|
super_member: { |
||||
|
super_member_start_bg: '#7c7878', |
||||
|
super_member_end_bg: '#201a18', |
||||
|
super_member_start_text_color: '#FFDBA6', |
||||
|
super_member_end_text_color: '#FFEBCA', |
||||
|
}, |
||||
|
bargain:{ |
||||
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
seckill:{ |
||||
|
seckill_promotion_color: '#F83530',//活动背景
|
||||
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
giftcard:{ |
||||
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||
|
}, |
||||
|
}, |
||||
|
'blue':{ |
||||
|
name:'blue', |
||||
|
main_color : '#21BBF3', |
||||
|
aux_color : '#FA6400', |
||||
|
bg_color: '#21BBF3', |
||||
|
bg_color_shallow: '#21BBF3', |
||||
|
promotion_color: '#21BBF3 ', |
||||
|
promotion_aux_color: '#FA6400', |
||||
|
main_color_shallow: '#E2F3FF', |
||||
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||
|
goods_detail : { |
||||
|
goods_price : 'rgba(252,82,39,1)',//价格
|
||||
|
promotion_tag:'#21BBF3', |
||||
|
goods_card_bg:'#201A18',//会员卡背景
|
||||
|
goods_card_bg_shallow:'#7C7878',//会员卡背景浅色
|
||||
|
goods_card_color:'#FFD792', |
||||
|
goods_coupon:'#FC5227', |
||||
|
goods_cart_num_corner :'#FC5227',//购物车数量角标
|
||||
|
goods_btn_color:'#36ABFF',//按钮颜色
|
||||
|
goods_btn_color_shallow:'#FA6400',//副按钮颜色
|
||||
|
}, |
||||
|
pintuan:{ |
||||
|
pintuan_label_bg:'#F7B500', |
||||
|
pintuan_label_color:'#FFFFFF', |
||||
|
pintuan_color:'#FA6400', |
||||
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||
|
}, |
||||
|
super_member: { |
||||
|
super_member_start_bg: '#7c7878', |
||||
|
super_member_end_bg: '#201a18', |
||||
|
super_member_start_text_color: '#FFDBA6', |
||||
|
super_member_end_text_color: '#FFEBCA', |
||||
|
}, |
||||
|
bargain:{ |
||||
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
seckill:{ |
||||
|
seckill_promotion_color: '#F83530',//活动背景
|
||||
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
giftcard:{ |
||||
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||
|
}, |
||||
|
}, |
||||
|
'pink':{ |
||||
|
name:'pink', |
||||
|
main_color : '#FF407E', |
||||
|
aux_color : '#F7B500', |
||||
|
bg_color: '#FF407E',//主题背景
|
||||
|
bg_color_shallow: '#FF407E',//主题背景渐变浅色
|
||||
|
promotion_color: '#FF407E',//活动背景
|
||||
|
promotion_aux_color: '#F7B500',//活动背景辅色
|
||||
|
main_color_shallow: '#FFF5F8',//淡背景
|
||||
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||
|
goods_detail : { |
||||
|
goods_price : 'rgba(252,82,39,1)',//价格
|
||||
|
promotion_tag:'#FF407E', |
||||
|
goods_card_bg:'#201A18',//会员卡背景
|
||||
|
goods_card_bg_shallow:'#7C7878',//会员卡背景浅色
|
||||
|
goods_card_color:'#FFD792', |
||||
|
goods_coupon:'#FC5227', |
||||
|
goods_cart_num_corner :'#FC5227',//购物车数量角标
|
||||
|
goods_btn_color:'#FF407E',//按钮颜色
|
||||
|
goods_btn_color_shallow:'#F7B500',//副按钮颜色
|
||||
|
}, |
||||
|
pintuan:{ |
||||
|
pintuan_label_bg:'#F7B500', |
||||
|
pintuan_label_color:'#FFFFFF', |
||||
|
pintuan_color:'#FA6400', |
||||
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||
|
}, |
||||
|
super_member: { |
||||
|
super_member_start_bg: '#7c7878', |
||||
|
super_member_end_bg: '#201a18', |
||||
|
super_member_start_text_color: '#FFDBA6', |
||||
|
super_member_end_text_color: '#FFEBCA', |
||||
|
}, |
||||
|
bargain:{ |
||||
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
seckill:{ |
||||
|
seckill_promotion_color: '#F83530',//活动背景
|
||||
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
giftcard:{ |
||||
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||
|
}, |
||||
|
}, |
||||
|
'gold':{ |
||||
|
name:'gold', |
||||
|
main_color : '#CFAF70', |
||||
|
aux_color : '#444444', |
||||
|
bg_color: '#CFAF70',//主题背景
|
||||
|
bg_color_shallow: '#CFAF70',//主题背景渐变浅色
|
||||
|
promotion_color: '#CFAF70',//活动背景
|
||||
|
promotion_aux_color: '#444444',//活动背景辅色
|
||||
|
main_color_shallow: '#FFFAF1',//淡背景
|
||||
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||
|
goods_detail : { |
||||
|
goods_price : 'rgba(252,82,39,1)',//价格
|
||||
|
promotion_tag:'#CFAF70', |
||||
|
goods_card_bg:'#201A18',//会员卡背景
|
||||
|
goods_card_bg_shallow:'#7C7878',//会员卡背景浅色
|
||||
|
goods_card_color:'#FFD792', |
||||
|
goods_coupon:'#FC5227', |
||||
|
goods_cart_num_corner :'#FC5227',//购物车数量角标
|
||||
|
goods_btn_color:'#CFAF70',//按钮颜色
|
||||
|
goods_btn_color_shallow:'#444444',//副按钮颜色
|
||||
|
}, |
||||
|
pintuan:{ |
||||
|
pintuan_label_bg:'#F7B500', |
||||
|
pintuan_label_color:'#FFFFFF', |
||||
|
pintuan_color:'#FA6400', |
||||
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||
|
}, |
||||
|
super_member: { |
||||
|
super_member_start_bg: '#7c7878', |
||||
|
super_member_end_bg: '#201a18', |
||||
|
super_member_start_text_color: '#FFDBA6', |
||||
|
super_member_end_text_color: '#FFEBCA', |
||||
|
}, |
||||
|
bargain:{ |
||||
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
seckill:{ |
||||
|
seckill_promotion_color: '#F83530',//活动背景
|
||||
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
giftcard:{ |
||||
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||
|
}, |
||||
|
}, |
||||
|
'purple':{ |
||||
|
name:'purple', |
||||
|
main_color : '#A253FF', |
||||
|
aux_color : '#222222', |
||||
|
bg_color: '#A253FF',//主题背景
|
||||
|
bg_color_shallow: '#A253FF',//主题背景渐变浅色
|
||||
|
promotion_color: '#A253FF',//活动背景
|
||||
|
promotion_aux_color: '#222222',//活动背景辅色
|
||||
|
main_color_shallow: '#F8F3FF',//淡背景
|
||||
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||
|
goods_detail : { |
||||
|
goods_price : 'rgba(252,82,39,1)',//价格
|
||||
|
promotion_tag:'#A253FF', |
||||
|
goods_card_bg:'#201A18',//会员卡背景
|
||||
|
goods_card_bg_shallow:'#7C7878',//会员卡背景浅色
|
||||
|
goods_card_color:'#FFD792', |
||||
|
goods_coupon:'#FC5227', |
||||
|
goods_cart_num_corner :'#FC5227',//购物车数量角标
|
||||
|
goods_btn_color:'#A253FF',//按钮颜色
|
||||
|
goods_btn_color_shallow:'#222222',//副按钮颜色
|
||||
|
}, |
||||
|
pintuan:{ |
||||
|
pintuan_label_bg:'#F7B500', |
||||
|
pintuan_label_color:'#FFFFFF', |
||||
|
pintuan_color:'#FA6400', |
||||
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||
|
}, |
||||
|
super_member: { |
||||
|
super_member_start_bg: '#7c7878', |
||||
|
super_member_end_bg: '#201a18', |
||||
|
super_member_start_text_color: '#FFDBA6', |
||||
|
super_member_end_text_color: '#FFEBCA', |
||||
|
}, |
||||
|
bargain:{ |
||||
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
seckill:{ |
||||
|
seckill_promotion_color: '#F83530',//活动背景
|
||||
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
giftcard:{ |
||||
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||
|
}, |
||||
|
}, |
||||
|
'yellow':{ |
||||
|
name:'yellow', |
||||
|
main_color : '#FFD009', |
||||
|
aux_color : '#1D262E', |
||||
|
bg_color: '#FFD009',//主题背景
|
||||
|
bg_color_shallow: '#FFD009',//主题背景渐变浅色
|
||||
|
promotion_color: '#FFD009',//活动背景
|
||||
|
promotion_aux_color: '#1D262E',//活动背景辅色
|
||||
|
main_color_shallow: '#FFFBEF',//淡背景
|
||||
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||
|
btn_text_color: '#303133',//按钮文字颜色
|
||||
|
goods_detail : { |
||||
|
goods_price : 'rgba(252,82,39,1)',//价格
|
||||
|
promotion_tag:'#FFD009', |
||||
|
goods_card_bg:'#201A18',//会员卡背景
|
||||
|
goods_card_bg_shallow:'#7C7878',//会员卡背景浅色
|
||||
|
goods_card_color:'#FFD792', |
||||
|
goods_coupon:'#FC5227', |
||||
|
goods_cart_num_corner :'#FC5227',//购物车数量角标
|
||||
|
goods_btn_color:'#FFD009',//按钮颜色
|
||||
|
goods_btn_color_shallow:'#1D262E',//副按钮颜色
|
||||
|
}, |
||||
|
pintuan:{ |
||||
|
pintuan_label_bg:'#F7B500', |
||||
|
pintuan_label_color:'#FFFFFF', |
||||
|
pintuan_color:'#FA6400', |
||||
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||
|
}, |
||||
|
super_member: { |
||||
|
super_member_start_bg: '#7c7878', |
||||
|
super_member_end_bg: '#201a18', |
||||
|
super_member_start_text_color: '#FFDBA6', |
||||
|
super_member_end_text_color: '#FFEBCA', |
||||
|
}, |
||||
|
bargain:{ |
||||
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
seckill:{ |
||||
|
seckill_promotion_color: '#F83530',//活动背景
|
||||
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
giftcard:{ |
||||
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||
|
}, |
||||
|
}, |
||||
|
'black':{ |
||||
|
name:'black', |
||||
|
main_color : '#222222', |
||||
|
aux_color : '#FFFFFF', |
||||
|
bg_color: '#222222',//主题背景
|
||||
|
bg_color_shallow: '#333333',//主题背景渐变浅色
|
||||
|
promotion_color: '#222222',//活动背景
|
||||
|
promotion_aux_color: '#FA8B00',//活动背景辅色
|
||||
|
main_color_shallow: '#efefef',//淡背景
|
||||
|
price_color: 'rgba(255,0,0,1)',//价格颜色
|
||||
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||
|
goods_detail : { |
||||
|
goods_price : 'rgba(255,0,0,1)',//价格
|
||||
|
promotion_tag:'#222222', |
||||
|
goods_card_bg:'#201A18',//会员卡背景
|
||||
|
goods_card_bg_shallow:'#7C7878',//会员卡背景浅色
|
||||
|
goods_card_color:'#FFD792', |
||||
|
goods_coupon:'#222222', |
||||
|
goods_cart_num_corner :'#FF0000',//购物车数量角标
|
||||
|
goods_btn_color:'#222222',//按钮颜色
|
||||
|
goods_btn_color_shallow:'#FA8B00',//副按钮颜色
|
||||
|
}, |
||||
|
pintuan:{ |
||||
|
pintuan_label_bg:'#F7B500', |
||||
|
pintuan_label_color:'#FFFFFF', |
||||
|
pintuan_color:'#FA6400', |
||||
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||
|
}, |
||||
|
super_member: { |
||||
|
super_member_start_bg: '#fadcb5', |
||||
|
super_member_end_bg: '#f6bd74', |
||||
|
super_member_start_text_color: '#ab6126', |
||||
|
super_member_end_text_color: '#d19336', |
||||
|
}, |
||||
|
bargain:{ |
||||
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
seckill:{ |
||||
|
seckill_promotion_color: '#F83530',//活动背景
|
||||
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||
|
}, |
||||
|
giftcard:{ |
||||
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||
|
}, |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
function times(num){ |
||||
|
let now=new Date(num) |
||||
|
let n=now.getFullYear() |
||||
|
let y=now.getMonth()+1>=10?now.getMonth()+1:0+''+(now.getMonth()+1); |
||||
|
var r =now.getDate()>=10?now.getDate():0+''+now.getDate(); |
||||
|
return n+'-'+y+'-'+r |
||||
|
} |
||||
|
module.exports = times; |
||||
File diff suppressed because it is too large
@ -0,0 +1,166 @@ |
|||||
|
/** |
||||
|
数据验证(表单验证) |
||||
|
*/ |
||||
|
module.exports = { |
||||
|
error: '', |
||||
|
check: function(data, rule) { |
||||
|
for (var i = 0; i < rule.length; i++) { |
||||
|
if (!rule[i].checkType) { |
||||
|
return true; |
||||
|
} |
||||
|
if (!rule[i].name) { |
||||
|
return true; |
||||
|
} |
||||
|
if (!rule[i].errorMsg) { |
||||
|
return true; |
||||
|
} |
||||
|
if (!data[rule[i].name]) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
switch (rule[i].checkType) { |
||||
|
case 'custom': |
||||
|
if (typeof rule[i].validate == 'function') { |
||||
|
if (!rule[i].validate(data[rule[i].name])) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
case 'required': |
||||
|
var reg = new RegExp('/[\S]+/'); |
||||
|
if (reg.test(data[rule[i].name])) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'string': |
||||
|
var reg = new RegExp('^.{' + rule[i].checkRule + '}$'); |
||||
|
if (!reg.test(data[rule[i].name])) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'int': |
||||
|
var reg = new RegExp('^(-[1-9]|[1-9])[0-9]{' + rule[i].checkRule + '}$'); |
||||
|
if (!reg.test(data[rule[i].name])) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
break; |
||||
|
case 'between': |
||||
|
if (!this.isNumber(data[rule[i].name])) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
var minMax = rule[i].checkRule.split(','); |
||||
|
minMax[0] = Number(minMax[0]); |
||||
|
minMax[1] = Number(minMax[1]); |
||||
|
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'betweenD': |
||||
|
var reg = /^-?[1-9][0-9]?$/; |
||||
|
if (!reg.test(data[rule[i].name])) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
var minMax = rule[i].checkRule.split(','); |
||||
|
minMax[0] = Number(minMax[0]); |
||||
|
minMax[1] = Number(minMax[1]); |
||||
|
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'betweenF': |
||||
|
var reg = /^-?[0-9][0-9]?.+[0-9]+$/; |
||||
|
if (!reg.test(data[rule[i].name])) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
var minMax = rule[i].checkRule.split(','); |
||||
|
minMax[0] = Number(minMax[0]); |
||||
|
minMax[1] = Number(minMax[1]); |
||||
|
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'same': |
||||
|
if (data[rule[i].name] != rule[i].checkRule) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'notsame': |
||||
|
if (data[rule[i].name] == rule[i].checkRule) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'email': |
||||
|
var reg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/; |
||||
|
if (!reg.test(data[rule[i].name])) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'phoneno': |
||||
|
var reg = /^[1](([3][0-9])|([4][5-9])|([5][0-3,5-9])|([6][5,6])|([7][0-8])|([8][0-9])|([9][0-9]))[0-9]{8}$/; |
||||
|
if (!reg.test(data[rule[i].name])) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'zipcode': |
||||
|
var reg = /^[0-9]{6}$/; |
||||
|
if (!reg.test(data[rule[i].name])) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'reg': |
||||
|
var reg = new RegExp(rule[i].checkRule); |
||||
|
if (!reg.test(data[rule[i].name])) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'in': |
||||
|
if (rule[i].checkRule.indexOf(data[rule[i].name]) == -1) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'notnull': |
||||
|
if (data[rule[i].name] == 0 || data[rule[i].name] == undefined || data[rule[i].name] == null || data[rule[i].name] |
||||
|
.length < 1) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'lengthMin': |
||||
|
if (data[rule[i].name].length < rule[i].checkRule) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'lengthMax': |
||||
|
if (data[rule[i].name].length > rule[i].checkRule) { |
||||
|
this.error = rule[i].errorMsg; |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
return true; |
||||
|
}, |
||||
|
isNumber: function(checkVal) { |
||||
|
var reg = /^-?[1-9][0-9]?.?[0-9]*$/; |
||||
|
return reg.test(checkVal); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,115 @@ |
|||||
|
/** |
||||
|
* 微信jssdk调用 |
||||
|
*/ |
||||
|
let Weixin = function() { |
||||
|
var wx = require('./jweixin-module'); |
||||
|
|
||||
|
this.weixin = wx; |
||||
|
|
||||
|
this.init = function(params) { |
||||
|
wx.config({ |
||||
|
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
|
||||
|
appId: params.appId, // 必填,公众号的唯一标识
|
||||
|
timestamp: params.timestamp, // 必填,生成签名的时间戳
|
||||
|
nonceStr: params.nonceStr, // 必填,生成签名的随机串
|
||||
|
signature: params.signature, // 必填,签名
|
||||
|
jsApiList: ['chooseWXPay', 'openAddress', 'updateAppMessageShareData', 'updateTimelineShareData', 'scanQRCode','hideMenuItems'] // 必填,需要使用的JS接口列表
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 发起支付 |
||||
|
* @param {Object} jsApiParame |
||||
|
* @param {Object} callback |
||||
|
*/ |
||||
|
this.pay = function(jsApiParame, callback, cancel) { |
||||
|
wx.ready(function() { |
||||
|
wx.chooseWXPay({ |
||||
|
timestamp: jsApiParame.timestamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
|
||||
|
nonceStr: jsApiParame.nonceStr, // 支付签名随机串,不长于 32 位
|
||||
|
package: jsApiParame.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
|
||||
|
signType: jsApiParame.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
|
||||
|
paySign: jsApiParame.paySign, // 支付签名
|
||||
|
success: function(res) { |
||||
|
typeof callback == 'function' && callback(res); |
||||
|
}, |
||||
|
cancel: function(res){ |
||||
|
typeof cancel == 'function' && cancel(res); |
||||
|
} |
||||
|
}); |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取收货地址 |
||||
|
* @param {Object} callback |
||||
|
*/ |
||||
|
this.openAddress = function(callback) { |
||||
|
wx.ready(function() { |
||||
|
wx.openAddress({ |
||||
|
success: function(res) { |
||||
|
typeof callback == 'function' && callback(res); |
||||
|
}, |
||||
|
fail: (res) => { |
||||
|
alert(JSON.stringify(res)) |
||||
|
} |
||||
|
}); |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 分享给好友 |
||||
|
* @param {Object} params |
||||
|
* @param {Object} callback |
||||
|
*/ |
||||
|
this.setShareData = function(params, callback) { |
||||
|
|
||||
|
wx.ready(function() { |
||||
|
// 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
|
||||
|
wx.updateAppMessageShareData({ |
||||
|
title: params.title || '', // 分享标题
|
||||
|
desc: params.desc || '', // 分享描述
|
||||
|
link: params.link || '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
||||
|
imgUrl: params.imgUrl || '', // 分享图标
|
||||
|
success: function(res) { |
||||
|
typeof callback == 'function' && callback(res); |
||||
|
}, |
||||
|
fail:function(err){ |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
// 自定义“分享到朋友圈”及“分享到QQ空间”按钮的分享内容
|
||||
|
wx.updateTimelineShareData({ |
||||
|
title: params.title || '', // 分享标题
|
||||
|
link: params.link || '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
||||
|
imgUrl: params.imgUrl || '', // 分享图标
|
||||
|
success: function(res) { |
||||
|
typeof callback == 'function' && callback(res); |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 扫一扫 |
||||
|
* @param {Object} callback |
||||
|
*/ |
||||
|
this.scanQRCode = function(callback) { |
||||
|
wx.ready(function() { |
||||
|
wx.scanQRCode({ |
||||
|
needResult: 1, |
||||
|
scanType: ["qrCode"], |
||||
|
success: function(res) { |
||||
|
typeof callback == 'function' && callback(res); |
||||
|
} |
||||
|
}); |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export { |
||||
|
Weixin |
||||
|
} |
||||
@ -0,0 +1,185 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<view class="box-slideLeft" > |
||||
|
<view class="touch-item touch-slideLeft " @touchstart="touchS" @touchmove="touchM" @touchend="touchE" :style="item_show.txtStyle"> |
||||
|
<slot /> |
||||
|
</view> |
||||
|
|
||||
|
<view class="touch-item del-box-touch-slideLeft cf-shuCenter" @click="delItem(item_show)"> |
||||
|
<view class="iconfont icon-shanchu"></view> |
||||
|
</view> |
||||
|
|
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
|
||||
|
export default { |
||||
|
components: { |
||||
|
|
||||
|
}, |
||||
|
props: { |
||||
|
|
||||
|
data_transit: { |
||||
|
type: Object, |
||||
|
default () { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
//可不传参 |
||||
|
item: { |
||||
|
type: Object, |
||||
|
default () { |
||||
|
return {} |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
computed: { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
data() { |
||||
|
return { |
||||
|
|
||||
|
item_show : {}, |
||||
|
delBtnWidth: 60, //删除按钮宽度单位(rpx) |
||||
|
startX: '', |
||||
|
}; |
||||
|
}, |
||||
|
created:function(){ |
||||
|
//专门处理检查对象中,某字段是否存在的,如果存在返回 true 不存在返回 false |
||||
|
let that = this ; |
||||
|
let item = that.item ; |
||||
|
if(!item.hasOwnProperty("txtStyle")){ |
||||
|
this.$set(this.item,'txtStyle','');//不需要初始化了 |
||||
|
} |
||||
|
this.item_show = this.item ; |
||||
|
}, |
||||
|
watch: { |
||||
|
item(e){ |
||||
|
this.item_show = e ; |
||||
|
}, |
||||
|
}, |
||||
|
methods: { |
||||
|
//点击删除按钮事件 |
||||
|
delItem: function(e) { |
||||
|
let that = this; |
||||
|
let data ={ |
||||
|
item : e , |
||||
|
data : that.data_transit , |
||||
|
}; |
||||
|
this.$emit('delItem', data); |
||||
|
}, |
||||
|
touchS: function(e) { |
||||
|
let that = this; |
||||
|
|
||||
|
if (e.touches.length == 1) { |
||||
|
//设置触摸起始点水平方向位置 |
||||
|
this.startX = e.touches[0].clientX |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
touchM: function(e) { |
||||
|
let that = this; |
||||
|
|
||||
|
if (e.touches.length == 1) { |
||||
|
//手指移动时水平方向位置 |
||||
|
var moveX = e.touches[0].clientX; |
||||
|
//手指起始点位置与移动期间的差值 |
||||
|
var disX = this.startX - moveX; |
||||
|
var delBtnWidth = this.delBtnWidth; |
||||
|
var txtStyle = ""; |
||||
|
if (disX == 0 || disX < 0) { //如果移动距离小于等于0,说明向右滑动,文本层位置不变 |
||||
|
txtStyle = "left:0px"; |
||||
|
} else if (disX > 0) { //移动距离大于0,文本层left值等于手指移动距离 |
||||
|
txtStyle = "left:-" + disX + "px"; |
||||
|
if (disX >= delBtnWidth) { |
||||
|
//控制手指移动距离最大值为删除按钮的宽度 |
||||
|
txtStyle = "left:-" + delBtnWidth + "px"; |
||||
|
} |
||||
|
} |
||||
|
//获取手指触摸的是哪一项 |
||||
|
|
||||
|
that.item_show.txtStyle = txtStyle; |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
touchE: function(e) { |
||||
|
let that = this; |
||||
|
if (e.changedTouches.length == 1) { |
||||
|
//手指移动结束后水平位置 |
||||
|
var endX = e.changedTouches[0].clientX; |
||||
|
//触摸开始与结束,手指移动的距离 |
||||
|
var disX = this.startX - endX; |
||||
|
var delBtnWidth = this.delBtnWidth; |
||||
|
//如果距离小于删除按钮的1/2,不显示删除按钮 |
||||
|
var txtStyle = disX > delBtnWidth / 2 ? "left:-" + delBtnWidth + "px" : "left:0px"; |
||||
|
//获取手指触摸的是哪一项 |
||||
|
that.item_show.txtStyle = txtStyle; |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
@import './iconfont.css';//便于有删除图标 |
||||
|
|
||||
|
.box-slideLeft { |
||||
|
view { |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
|
||||
|
.touch-item { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
padding: 10px 10px 10px; |
||||
|
background-color: #FFFFFF; |
||||
|
// border-radius: 10px; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.touch-slideLeft { |
||||
|
position: relative; |
||||
|
width: 100%; |
||||
|
z-index: 5; |
||||
|
transition: left 0.2s ease-in-out; |
||||
|
white-space: nowrap; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
} |
||||
|
.del-box-touch-slideLeft { |
||||
|
right: 0; |
||||
|
float: left; |
||||
|
width: 70px; |
||||
|
height: 100%; |
||||
|
line-height: 101px; |
||||
|
background-color: #EA5863; |
||||
|
border-radius: 0 10px 10px 0; |
||||
|
color: #fff; |
||||
|
font-size: 18px; |
||||
|
font-weight: lighter; |
||||
|
text-align: center; |
||||
|
} |
||||
|
.icon-shanchu{ |
||||
|
font-size: 44upx; |
||||
|
} |
||||
|
|
||||
|
.cf-shuCenter{ |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
</style> |
||||
|
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,498 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<view @touchmove.prevent.stop> |
||||
|
<uni-popup ref="bindMobile" :custom="true" :mask-click="true"> |
||||
|
<view class="bind-wrap"> |
||||
|
<!-- #ifdef H5 --> |
||||
|
<view class="head">检测到您还未绑定手机号码</view> |
||||
|
<view class="form-wrap"> |
||||
|
<view class="label">手机号码</view> |
||||
|
<view class="form-item"> |
||||
|
<view class="input-wrap"> |
||||
|
<input |
||||
|
type="number" |
||||
|
placeholder="请输入您的手机号码" |
||||
|
placeholder-class="placeholder" |
||||
|
v-model="formData.mobile" |
||||
|
/> |
||||
|
</view> |
||||
|
</view> |
||||
|
<block v-if="captchaConfig"> |
||||
|
<view class="label">验证码</view> |
||||
|
<view class="form-item"> |
||||
|
<view class="input-wrap"> |
||||
|
<input |
||||
|
type="number" |
||||
|
placeholder="请输入验证码" |
||||
|
placeholder-class="placeholder" |
||||
|
v-model="formData.vercode" |
||||
|
/> |
||||
|
</view> |
||||
|
<image |
||||
|
:src="captcha.img" |
||||
|
class="captcha" |
||||
|
@click="getCaptcha" |
||||
|
></image> |
||||
|
</view> |
||||
|
</block> |
||||
|
<view class="label">动态码</view> |
||||
|
<view class="form-item"> |
||||
|
<view class="input-wrap"> |
||||
|
<input |
||||
|
type="number" |
||||
|
placeholder="请输入动态码" |
||||
|
placeholder-class="placeholder" |
||||
|
v-model="formData.dynacode" |
||||
|
/> |
||||
|
</view> |
||||
|
<view class="send color-base-text" @click="sendMobileCode"> |
||||
|
{{ dynacodeData.codeText }} |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="footer"> |
||||
|
<view class="confirm" @click="confirm">确定</view> |
||||
|
<view @click="cancel" class="cancel">取消</view> |
||||
|
</view> |
||||
|
<!-- #endif --> |
||||
|
|
||||
|
<!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU --> |
||||
|
<view class="bind-tip-icon"> |
||||
|
<image |
||||
|
:src="$util.img('public/uniapp/member/login.png')" |
||||
|
mode="widthFix" |
||||
|
></image> |
||||
|
</view> |
||||
|
<view class="bind-tips">为了方便您接收订单等信息,需要绑定您的手机号码</view> |
||||
|
<button |
||||
|
open-type="getPhoneNumber" |
||||
|
class="auth-login ns-btn-default-all color-base-bg" |
||||
|
@getphonenumber="mobileAuthLogin" |
||||
|
> |
||||
|
<text>点击绑定手机号码</text> |
||||
|
</button> |
||||
|
<!-- #endif --> |
||||
|
</view> |
||||
|
</uni-popup> |
||||
|
</view> |
||||
|
<register-reward ref="registerReward"></register-reward> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import uniPopup from '../uni-popup/uni-popup.vue'; |
||||
|
import validate from 'common/js/validate.js'; |
||||
|
import registerReward from '../register-reward/register-reward.vue'; |
||||
|
|
||||
|
export default { |
||||
|
name: 'bind-mobile', |
||||
|
components: { |
||||
|
uniPopup, |
||||
|
registerReward |
||||
|
}, |
||||
|
mixins: [validate], |
||||
|
data() { |
||||
|
return { |
||||
|
captchaConfig: 0, |
||||
|
captcha: { |
||||
|
id: '', |
||||
|
img: '' |
||||
|
}, |
||||
|
dynacodeData: { |
||||
|
seconds: 120, |
||||
|
timer: null, |
||||
|
codeText: '获取动态码', |
||||
|
isSend: false |
||||
|
}, |
||||
|
formData: { |
||||
|
key: '', |
||||
|
mobile: '', |
||||
|
vercode: '', |
||||
|
dynacode: '' |
||||
|
}, |
||||
|
isSub: false |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.getCaptchaConfig(); |
||||
|
}, |
||||
|
methods: { |
||||
|
open() { |
||||
|
this.$refs.bindMobile.open(); |
||||
|
}, |
||||
|
cancel() { |
||||
|
this.$refs.bindMobile.close(); |
||||
|
}, |
||||
|
confirm() { |
||||
|
let authData = uni.getStorageSync('authInfo'); |
||||
|
let data = { |
||||
|
mobile: this.formData.mobile, |
||||
|
key: this.formData.key, |
||||
|
code: this.formData.dynacode |
||||
|
}; |
||||
|
if (this.captcha.id != '') { |
||||
|
data.captcha_id = this.captcha.id; |
||||
|
data.captcha_code = this.formData.vercode; |
||||
|
} |
||||
|
|
||||
|
if (authData) Object.assign(data, authData); |
||||
|
if (authData.avatarUrl) data.headimg = authData.avatarUrl; |
||||
|
if (authData.nickName) data.nickname = authData.nickName; |
||||
|
|
||||
|
if (uni.getStorageSync('source_member')) |
||||
|
data.source_member = uni.getStorageSync('source_member'); |
||||
|
|
||||
|
if (this.verify(data)) { |
||||
|
if (this.isSub) return; |
||||
|
this.isSub = true; |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/tripartite/mobile', |
||||
|
data, |
||||
|
success: res => { |
||||
|
if (res.code >= 0) { |
||||
|
uni.setStorage({ |
||||
|
key: 'token', |
||||
|
data: res.data.token, |
||||
|
success: () => { |
||||
|
this.$store.commit('setToken', res.data.token); |
||||
|
this.$store.dispatch('getCartNumber'); |
||||
|
} |
||||
|
}); |
||||
|
this.$refs.bindMobile.close(); |
||||
|
|
||||
|
if (res.data.is_register && this.$refs.registerReward.getReward()) { |
||||
|
this.$refs.registerReward.open(); |
||||
|
} |
||||
|
} else { |
||||
|
this.isSub = false; |
||||
|
this.getCaptcha(); |
||||
|
this.$util.showToast({ title: res.message }); |
||||
|
} |
||||
|
}, |
||||
|
fail: res => { |
||||
|
this.isSub = false; |
||||
|
this.getCaptcha(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* 表单验证 |
||||
|
* @param {Object} data |
||||
|
*/ |
||||
|
verify(data) { |
||||
|
let rule = [ |
||||
|
{ name: 'mobile', checkType: 'required', errorMsg: '请输入手机号' }, |
||||
|
{ name: 'mobile', checkType: 'phoneno', errorMsg: '请输入正确的手机号' } |
||||
|
]; |
||||
|
if (this.captchaConfig == 1) { |
||||
|
if (this.captcha.id != '') |
||||
|
rule.push({ |
||||
|
name: 'captcha_code', |
||||
|
checkType: 'required', |
||||
|
errorMsg: this.$lang('captchaPlaceholder') |
||||
|
}); |
||||
|
} |
||||
|
rule.push({ |
||||
|
name: 'code', |
||||
|
checkType: 'required', |
||||
|
errorMsg: this.$lang('dynacodePlaceholder') |
||||
|
}); |
||||
|
|
||||
|
var checkRes = validate.check(data, rule); |
||||
|
if (checkRes) { |
||||
|
return true; |
||||
|
} else { |
||||
|
this.$util.showToast({ title: validate.error }); |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* 获取验证码配置 |
||||
|
*/ |
||||
|
getCaptchaConfig() { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/config/getCaptchaConfig', |
||||
|
success: res => { |
||||
|
if (res.code >= 0) { |
||||
|
this.captchaConfig = res.data.data.value.shop_reception_login; |
||||
|
if (this.captchaConfig) this.getCaptcha(); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
/** |
||||
|
* 获取验证码 |
||||
|
*/ |
||||
|
getCaptcha() { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/captcha/captcha', |
||||
|
data: { |
||||
|
captcha_id: this.captcha.id |
||||
|
}, |
||||
|
success: res => { |
||||
|
if (res.code >= 0) { |
||||
|
this.captcha = res.data; |
||||
|
this.captcha.img = this.captcha.img.replace(/\r\n/g, ''); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
/** |
||||
|
* 发送手机动态码 |
||||
|
*/ |
||||
|
sendMobileCode() { |
||||
|
if (this.dynacodeData.seconds != 120 || this.dynacodeData.isSend) return; |
||||
|
var data = { |
||||
|
mobile: this.formData.mobile, |
||||
|
captcha_id: this.captcha.id, |
||||
|
captcha_code: this.formData.vercode |
||||
|
}; |
||||
|
var rule = [ |
||||
|
{ name: 'mobile', checkType: 'required', errorMsg: '请输入手机号' }, |
||||
|
{ name: 'mobile', checkType: 'phoneno', errorMsg: '请输入正确的手机号' } |
||||
|
]; |
||||
|
if (this.captchaConfig == 1) { |
||||
|
rule.push({ |
||||
|
name: 'captcha_code', |
||||
|
checkType: 'required', |
||||
|
errorMsg: '请输入验证码' |
||||
|
}); |
||||
|
} |
||||
|
var checkRes = validate.check(data, rule); |
||||
|
if (!checkRes) { |
||||
|
this.$util.showToast({ title: validate.error }); |
||||
|
return; |
||||
|
} |
||||
|
this.dynacodeData.isSend = true; |
||||
|
|
||||
|
if (this.dynacodeData.seconds == 120) { |
||||
|
this.dynacodeData.timer = setInterval(() => { |
||||
|
this.dynacodeData.seconds--; |
||||
|
this.dynacodeData.codeText = this.dynacodeData.seconds + 's后可重新获取'; |
||||
|
}, 1000); |
||||
|
} |
||||
|
|
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/tripartite/mobileCode', |
||||
|
data: data, |
||||
|
success: res => { |
||||
|
if (res.code >= 0) { |
||||
|
this.formData.key = res.data.key; |
||||
|
} else { |
||||
|
this.$util.showToast({ title: res.message }); |
||||
|
this.refreshDynacodeData(); |
||||
|
} |
||||
|
}, |
||||
|
fail: () => { |
||||
|
this.$util.showToast({ title: 'request:fail' }); |
||||
|
this.refreshDynacodeData(); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
mobileAuthLogin(e) { |
||||
|
if (e.detail.errMsg == 'getPhoneNumber:ok') { |
||||
|
let authData = uni.getStorageSync('authInfo'); |
||||
|
var data = { |
||||
|
iv: e.detail.iv, |
||||
|
encryptedData: e.detail.encryptedData |
||||
|
}; |
||||
|
if (authData) Object.assign(data, authData); |
||||
|
if (authData.avatarUrl) data.headimg = authData.avatarUrl; |
||||
|
if (authData.nickName) data.nickname = authData.nickName; |
||||
|
if (uni.getStorageSync('source_member')) |
||||
|
data.source_member = uni.getStorageSync('source_member'); |
||||
|
|
||||
|
if (this.isSub) return; |
||||
|
this.isSub = true; |
||||
|
|
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/tripartite/mobileauth', |
||||
|
data, |
||||
|
success: res => { |
||||
|
if (res.code >= 0) { |
||||
|
uni.setStorage({ |
||||
|
key: 'token', |
||||
|
data: res.data.token, |
||||
|
success: () => { |
||||
|
this.$store.dispatch('getCartNumber'); |
||||
|
this.$store.commit('setToken', res.data.token); |
||||
|
} |
||||
|
}); |
||||
|
this.$refs.bindMobile.close(); |
||||
|
if (res.data.is_register && this.$refs.registerReward.getReward()) { |
||||
|
this.$refs.registerReward.open(); |
||||
|
} |
||||
|
} else { |
||||
|
this.isSub = false; |
||||
|
this.$util.showToast({ title: res.message }); |
||||
|
} |
||||
|
}, |
||||
|
fail: res => { |
||||
|
this.isSub = false; |
||||
|
this.$util.showToast({ title: 'request:fail' }); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
refreshDynacodeData() { |
||||
|
this.getCaptcha(); |
||||
|
clearInterval(this.dynacodeData.timer); |
||||
|
this.dynacodeData = { |
||||
|
seconds: 120, |
||||
|
timer: null, |
||||
|
codeText: '获取动态码', |
||||
|
isSend: false |
||||
|
}; |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
'dynacodeData.seconds': { |
||||
|
handler(newValue, oldValue) { |
||||
|
if (newValue == 0) { |
||||
|
this.refreshDynacodeData(); |
||||
|
} |
||||
|
}, |
||||
|
immediate: true, |
||||
|
deep: true |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.bind-wrap { |
||||
|
background: #fff; |
||||
|
box-sizing: border-box; |
||||
|
border-radius: 20rpx; |
||||
|
overflow: hidden; |
||||
|
width: calc(100vw - 168rpx); |
||||
|
margin: 0 auto; |
||||
|
|
||||
|
.head { |
||||
|
text-align: center; |
||||
|
height: 118rpx; |
||||
|
line-height: 118rpx; |
||||
|
background-color: #f6f6f6; |
||||
|
color: #333333; |
||||
|
font-size: 36rpx; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
|
||||
|
.form-wrap { |
||||
|
padding: 30rpx 70rpx; |
||||
|
|
||||
|
.label { |
||||
|
color: #000; |
||||
|
font-size: $font-size-base; |
||||
|
line-height: 1.3; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.form-item { |
||||
|
margin: 24rpx 0; |
||||
|
display: flex; |
||||
|
align-items: flex-end; |
||||
|
|
||||
|
.input-wrap { |
||||
|
padding-bottom: 30rpx; |
||||
|
border-bottom: 2rpx solid #f2f2f2; |
||||
|
flex: 1; |
||||
|
width: 0; |
||||
|
margin-right: 20rpx; |
||||
|
|
||||
|
&:last-child { |
||||
|
margin-right: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.placeholder { |
||||
|
font-size: $font-size-tag; |
||||
|
color: #a3a3a3; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
input { |
||||
|
font-size: $font-size-tag; |
||||
|
} |
||||
|
|
||||
|
.send { |
||||
|
border: 2rpx solid $base-color; |
||||
|
height: 60rpx; |
||||
|
line-height: 60rpx; |
||||
|
border-radius: 60rpx; |
||||
|
font-size: $font-size-tag; |
||||
|
text-align: center; |
||||
|
padding: 0 40rpx; |
||||
|
} |
||||
|
|
||||
|
.captcha { |
||||
|
margin: 4rpx; |
||||
|
height: 52rpx; |
||||
|
width: 140rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.footer { |
||||
|
.confirm { |
||||
|
height: 78rpx; |
||||
|
line-height: 78rpx; |
||||
|
border-radius: 78rpx; |
||||
|
text-align: center; |
||||
|
background: $base-color; |
||||
|
color: #fff; |
||||
|
margin: 0 54rpx; |
||||
|
} |
||||
|
.cancel { |
||||
|
text-align: center; |
||||
|
padding: 30rpx 0; |
||||
|
font-size: 24rpx; |
||||
|
line-height: 1; |
||||
|
color: #666; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.bind-tips { |
||||
|
color: #aaa; |
||||
|
font-size: $font-size-base; |
||||
|
padding: 20rpx 50rpx; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.auth-login { |
||||
|
width: calc(100% - 100rpx); |
||||
|
margin: 20rpx auto 50rpx auto; |
||||
|
height: 80rpx; |
||||
|
line-height: 80rpx; |
||||
|
border-radius: 80rpx; |
||||
|
} |
||||
|
|
||||
|
.bind-tip-icon { |
||||
|
padding-top: 80rpx; |
||||
|
width: 100%; |
||||
|
text-align: center; |
||||
|
|
||||
|
image { |
||||
|
width: 300rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.ns-btn-default-all { |
||||
|
width: 100%; |
||||
|
height: 70rpx; |
||||
|
border-radius: $border-radius; |
||||
|
text-align: center; |
||||
|
line-height: 70rpx; |
||||
|
color: #ffffff; |
||||
|
font-size: $font-size-base; |
||||
|
} |
||||
|
</style> |
||||
|
<style scoped> |
||||
|
/deep/ .reward-popup .uni-popup__wrapper-box { |
||||
|
background: none !important; |
||||
|
max-width: unset !important; |
||||
|
max-height: unset !important; |
||||
|
overflow: unset !important; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,233 @@ |
|||||
|
<template> |
||||
|
<u-overlay :show="cutShow"> |
||||
|
<div class="view"> |
||||
|
<div class="box"> |
||||
|
<ns-empty |
||||
|
text="暂无通过的店铺~" |
||||
|
:isIndex="false" |
||||
|
v-if="!storeList.length && !loading" |
||||
|
></ns-empty> |
||||
|
|
||||
|
<div |
||||
|
:class="active == item.id ? 'row_active' : 'row'" |
||||
|
v-for="(item, index) in storeList" |
||||
|
:key="index" |
||||
|
@click="changeActive(item)" |
||||
|
> |
||||
|
<!-- <image class="avatar" :src="$util.img('/upload/weapp/user/wx.png')"></image> --> |
||||
|
<div class="name">{{ item.title }}</div> |
||||
|
<div class="label" v-if="item.label">{{ item.label }}</div> |
||||
|
<image |
||||
|
class="gou" |
||||
|
:src="$util.img('/upload/weapp/user/gou2.png')" |
||||
|
mode="" |
||||
|
></image> |
||||
|
</div> |
||||
|
|
||||
|
<div class="btn_box"> |
||||
|
<div class="cancel" @click="cutShow = false">取消</div> |
||||
|
<div class="look_all" @click="look_all">查看全部</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</u-overlay> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
cutShow: false, |
||||
|
data: [], |
||||
|
active: '', |
||||
|
storeList: [], |
||||
|
loading: false |
||||
|
}; |
||||
|
}, |
||||
|
methods: { |
||||
|
start() { |
||||
|
this.cutShow = true; |
||||
|
this.getStoreList(); |
||||
|
}, |
||||
|
//已经通过审核的店铺 |
||||
|
getStoreList() { |
||||
|
this.loading = true; |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/member/getStoreList', |
||||
|
data: { |
||||
|
status: 1 |
||||
|
}, |
||||
|
success: ({ data }) => { |
||||
|
this.storeList = data; |
||||
|
if (data.length) { |
||||
|
let myStore = uni.getStorageSync('myStore'); |
||||
|
if (myStore) { |
||||
|
this.active = myStore.id; |
||||
|
} else { |
||||
|
this.active = data[0].id; |
||||
|
uni.setStorageSync('myStore', data[0]); |
||||
|
console.log(this.active, 111111); |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
let storeObj = { |
||||
|
id: 0, |
||||
|
} |
||||
|
uni.setStorageSync('myStore', storeObj); |
||||
|
} |
||||
|
}, |
||||
|
complete: res => { |
||||
|
this.loading = false; |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
//切换店铺 |
||||
|
changeActive(item) { |
||||
|
uni.setStorageSync('myStore', item); |
||||
|
this.active = item.id; |
||||
|
this.cutShow = false; |
||||
|
// this.$parent.$parent.init(); |
||||
|
uni.$emit('changeStore', true); |
||||
|
}, |
||||
|
close() { |
||||
|
this.$emit('close'); |
||||
|
}, |
||||
|
look_all() { |
||||
|
this.cutShow = false; |
||||
|
uni.navigateTo({ |
||||
|
url: '/pages_tool/member/store/all_store' |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.view { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
height: 100vh; |
||||
|
line-height: 1; |
||||
|
.box { |
||||
|
width: 540rpx; |
||||
|
background-color: #fff; |
||||
|
border-radius: 24rpx; |
||||
|
padding: 24rpx; |
||||
|
max-height: 700rpx; |
||||
|
overflow: auto; |
||||
|
.row_active { |
||||
|
margin-top: 24rpx; |
||||
|
|
||||
|
height: 92rpx; |
||||
|
background: rgba(33, 187, 243, 0.08); |
||||
|
border-radius: 16rpx; |
||||
|
border: 2rpx solid $base-color; |
||||
|
|
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
|
||||
|
position: relative; |
||||
|
.avatar { |
||||
|
width: 48rpx; |
||||
|
height: 48rpx; |
||||
|
margin-left: 24rpx; |
||||
|
} |
||||
|
.name { |
||||
|
margin-left: 16rpx; |
||||
|
} |
||||
|
.label { |
||||
|
margin-left: 20rpx; |
||||
|
border-radius: 8rpx; |
||||
|
border: 1rpx solid rgba(33, 187, 243, 0.2); |
||||
|
|
||||
|
height: 32rpx; |
||||
|
font-size: 22rpx; |
||||
|
font-family: PingFangSC-Regular, PingFang SC; |
||||
|
font-weight: 400; |
||||
|
color: $base-color; |
||||
|
line-height: 32rpx; |
||||
|
} |
||||
|
.gou { |
||||
|
width: 32rpx; |
||||
|
height: 32rpx; |
||||
|
position: absolute; |
||||
|
right: 0rpx; |
||||
|
bottom: -3rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.row { |
||||
|
margin-top: 24rpx; |
||||
|
border: 2rpx solid #fff; |
||||
|
height: 92rpx; |
||||
|
background: #f7f7f7; |
||||
|
border-radius: 16rpx; |
||||
|
|
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
.avatar { |
||||
|
width: 48rpx; |
||||
|
height: 48rpx; |
||||
|
margin-left: 24rpx; |
||||
|
} |
||||
|
.name { |
||||
|
margin-left: 16rpx; |
||||
|
} |
||||
|
|
||||
|
.label { |
||||
|
margin-left: 20rpx; |
||||
|
border-radius: 8rpx; |
||||
|
border: 1rpx solid rgba(33, 187, 243, 0.2); |
||||
|
|
||||
|
height: 32rpx; |
||||
|
font-size: 22rpx; |
||||
|
font-family: PingFangSC-Regular, PingFang SC; |
||||
|
font-weight: 400; |
||||
|
color: $base-color; |
||||
|
line-height: 32rpx; |
||||
|
} |
||||
|
.gou { |
||||
|
width: 32rpx; |
||||
|
height: 32rpx; |
||||
|
display: none; |
||||
|
} |
||||
|
} |
||||
|
.btn_box { |
||||
|
margin-top: 56rpx; |
||||
|
display: flex; |
||||
|
justify-content: space-evenly; |
||||
|
.cancel { |
||||
|
width: 206rpx; |
||||
|
height: 72rpx; |
||||
|
border-radius: 40rpx; |
||||
|
border: 2rpx solid #e8e8e8; |
||||
|
|
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
|
||||
|
font-size: 28rpx; |
||||
|
font-family: PingFangSC-Regular, PingFang SC; |
||||
|
font-weight: 400; |
||||
|
color: #222222; |
||||
|
} |
||||
|
.look_all { |
||||
|
width: 206rpx; |
||||
|
height: 72rpx; |
||||
|
background: $base-color; |
||||
|
border-radius: 40rpx; |
||||
|
|
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
|
||||
|
font-size: 28rpx; |
||||
|
font-family: PingFangSC-Medium, PingFang SC; |
||||
|
font-weight: 500; |
||||
|
color: #ffffff; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,183 @@ |
|||||
|
<template> |
||||
|
<view class="article-wrap" :style="warpCss" v-if="list.length > 0"> |
||||
|
<view :class="['list-wrap', value.style]" :style="warpCss"> |
||||
|
<view :class="['item', value.ornament.type]" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :style="itemCss"> |
||||
|
<view class="article-img"> |
||||
|
<image class="cover-img" :src="$util.img(item.cover_img)" mode="widthFix" @error="imgError(index)"></image> |
||||
|
</view> |
||||
|
<view class="info-wrap"> |
||||
|
<text class="title">{{ item.article_title }}</text> |
||||
|
<view class="read-wrap"> |
||||
|
<block v-if="item.category_name"> |
||||
|
<text class="category-icon"></text> |
||||
|
<text>{{ item.category_name }}</text> |
||||
|
</block> |
||||
|
<text class="date">{{ $util.timeStampTurnTime(item.create_time, 'date') }}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 文章 |
||||
|
export default { |
||||
|
name: 'diy-article', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
list: [] |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.getBrandList(); |
||||
|
}, |
||||
|
computed: { |
||||
|
warpCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
if (this.value.componentAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
return obj; |
||||
|
}, |
||||
|
// 子项样式 |
||||
|
itemCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.elementBgColor + ';'; |
||||
|
if (this.value.elementAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
if (this.value.ornament.type == 'shadow') { |
||||
|
obj += 'box-shadow:' + '0 0 10rpx ' + this.value.ornament.color; |
||||
|
} |
||||
|
if (this.value.ornament.type == 'stroke') { |
||||
|
obj += 'border:' + '2rpx solid ' + this.value.ornament.color; |
||||
|
} |
||||
|
return obj; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
getBrandList() { |
||||
|
var data = { |
||||
|
page: 1, |
||||
|
page_size: this.value.count |
||||
|
}; |
||||
|
if (this.value.sources == 'diy') { |
||||
|
data.page_size = 0; |
||||
|
data.article_id_arr = this.value.articleIds.toString(); |
||||
|
} |
||||
|
|
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/article/page', |
||||
|
data: data, |
||||
|
success: res => { |
||||
|
if (res.code == 0 && res.data) { |
||||
|
let data = res.data; |
||||
|
this.list = data.list; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
toDetail(item) { |
||||
|
this.$util.redirectTo('/pages_tool/article/detail', { |
||||
|
article_id: item.article_id |
||||
|
}); |
||||
|
}, |
||||
|
imgError(index) { |
||||
|
if (this.list[index]) this.list[index].cover_img = this.$util.getDefaultImage().article; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.article-wrap { |
||||
|
.list-wrap { |
||||
|
&.style-1 { |
||||
|
.item { |
||||
|
display: flex; |
||||
|
padding: 20rpx; |
||||
|
margin: 24rpx 0; |
||||
|
|
||||
|
.article-img { |
||||
|
margin-right: 20rpx; |
||||
|
width: 160rpx; |
||||
|
height: 160rpx; |
||||
|
overflow: hidden; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.info-wrap { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: space-between; |
||||
|
.title { |
||||
|
font-weight: bold; |
||||
|
margin-bottom: 10rpx; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
display: -webkit-box; |
||||
|
-webkit-line-clamp: 2; |
||||
|
-webkit-box-orient: vertical; |
||||
|
font-size: 30rpx; |
||||
|
line-height: 1.5; |
||||
|
} |
||||
|
.abstract { |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
display: -webkit-box; |
||||
|
-webkit-line-clamp: 2; |
||||
|
-webkit-box-orient: vertical; |
||||
|
font-size: $font-size-tag; |
||||
|
} |
||||
|
.read-wrap { |
||||
|
display: flex; |
||||
|
color: #999ca7; |
||||
|
justify-content: flex-start; |
||||
|
align-items: center; |
||||
|
margin-top: 10rpx; |
||||
|
line-height: 1; |
||||
|
text { |
||||
|
font-size: $font-size-tag; |
||||
|
} |
||||
|
.iconfont { |
||||
|
font-size: 36rpx; |
||||
|
vertical-align: bottom; |
||||
|
margin-right: 10rpx; |
||||
|
} |
||||
|
.category-icon { |
||||
|
width: 8rpx; |
||||
|
height: 8rpx; |
||||
|
border-radius: 50%; |
||||
|
background: $base-color; |
||||
|
margin-right: 10rpx; |
||||
|
} |
||||
|
.date { |
||||
|
margin-left: 20rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,310 @@ |
|||||
|
<template> |
||||
|
<view v-if="tabBarList"> |
||||
|
<view class="tab-bar" :style="{ backgroundColor: tabBarList.backgroundColor }"> |
||||
|
<view class="tabbar-border"></view> |
||||
|
<view class="item" v-for="(item, index) in tabBarList.list" :key="index" @click="redirectTo(item.link)"> |
||||
|
<view class="bd"> |
||||
|
<block v-if="item.link.wap_url == '/pages/goods/cart'"> |
||||
|
<view class="icon" v-if="tabBarList.type == 1 || tabBarList.type == 2" |
||||
|
:animation="cartAnimation"> |
||||
|
<block v-if="verify(item.link)"> |
||||
|
<image v-if="item.selected_icon_type == 'img'" |
||||
|
:src="$util.img(item.selectedIconPath)" /> |
||||
|
<diy-icon v-if="item.selected_icon_type == 'icon'" :icon="item.selectedIconPath" |
||||
|
:value="item.selected_style ? item.selected_style : null"></diy-icon> |
||||
|
</block> |
||||
|
<block v-else> |
||||
|
<image v-if="item.icon_type == 'img'" :src="$util.img(item.iconPath)" /> |
||||
|
<diy-icon v-if="item.icon_type == 'icon'" :icon="item.iconPath" |
||||
|
:value="item.style ? item.style : null"></diy-icon> |
||||
|
</block> |
||||
|
<view class="cartNumberBtn font-size-activity-tag" :class="{ |
||||
|
max: item.link.wap_url == '/pages/goods/cart' && cartNumber > 99 |
||||
|
}" :style="{ background: 'var(--price-color)' }" |
||||
|
v-if="item.link.wap_url == '/pages/goods/cart' && cartNumber > 0"> |
||||
|
{{ cartNumber > 99 ? '99+' : cartNumber }} |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> |
||||
|
<block v-else> |
||||
|
<view class="icon" v-if="tabBarList.type == 1 || tabBarList.type == 2"> |
||||
|
<block v-if="verify(item.link)"> |
||||
|
<image v-if="item.selected_icon_type == 'img'" |
||||
|
:src="$util.img(item.selectedIconPath)" /> |
||||
|
<diy-icon v-if="item.selected_icon_type == 'icon'" :icon="item.selectedIconPath" |
||||
|
:value="item.selected_style ? item.selected_style : null"></diy-icon> |
||||
|
</block> |
||||
|
<block v-else> |
||||
|
<image v-if="item.icon_type == 'img'" :src="$util.img(item.iconPath)" /> |
||||
|
<diy-icon v-if="item.icon_type == 'icon'" :icon="item.iconPath" |
||||
|
:value="item.style ? item.style : null"></diy-icon> |
||||
|
</block> |
||||
|
</view> |
||||
|
</block> |
||||
|
<view class="label" v-if=" |
||||
|
(tabBarList.type == 1 || tabBarList.type == 3) && |
||||
|
tabBarList.theme == 'diy' |
||||
|
" :style="{ |
||||
|
color: verify(item.link) |
||||
|
? tabBarList.textHoverColor |
||||
|
: tabBarList.textColor |
||||
|
}"> |
||||
|
{{ item.text }} |
||||
|
</view> |
||||
|
<view class="label" v-if=" |
||||
|
(tabBarList.type == 1 || tabBarList.type == 3) && |
||||
|
tabBarList.theme == 'default' |
||||
|
" :style="{ color: verify(item.link) ? 'var(--base-color)' : '#999' }"> |
||||
|
{{ item.text }} |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!-- 解决fixed定位后底部导航栏塌陷问题 --> |
||||
|
<view class="tab-bar-placeholder"></view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'diy-bottom-nav', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
}, |
||||
|
name: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
currentRoute: '', //当前页面路径 |
||||
|
jumpFlag: true, //是否可以跳转,防止重复点击 |
||||
|
cartAnimation: {} |
||||
|
}; |
||||
|
}, |
||||
|
mounted() { |
||||
|
let currentPage = getCurrentPages()[getCurrentPages().length - 1]; |
||||
|
this.currentRoute = currentPage.route; |
||||
|
this.$store.dispatch('getCartNumber'); |
||||
|
}, |
||||
|
computed: { |
||||
|
cartNumber() { |
||||
|
return this.$store.state.cartNumber; |
||||
|
}, |
||||
|
cartChange() { |
||||
|
return this.$store.state.cartChange; |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
cartChange: function(nval, oval) { |
||||
|
if (nval > oval) { |
||||
|
let animation = uni.createAnimation({ |
||||
|
duration: 200, |
||||
|
timingFunction: 'ease' |
||||
|
}); |
||||
|
animation.scale(1.2).step(); |
||||
|
this.cartAnimation = animation.export(); |
||||
|
setTimeout(() => { |
||||
|
animation.scale(1).step(); |
||||
|
this.cartAnimation = animation.export(); |
||||
|
}, 300); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
redirectTo(link) { |
||||
|
console.log(link.wap_url); |
||||
|
// 判断登录 未登录时点击购物车和个人中心跳转登录页 |
||||
|
if (!uni.getStorageSync('token')) { |
||||
|
// ||link.wap_url =='/page_video/video/index' |
||||
|
if ((link.wap_url == '/pages/goods/cart') || link.wap_url == '/pages/member/index') { |
||||
|
this.$util.redirectTo('/pages_tool/login/login'); |
||||
|
} else { |
||||
|
uni.switchTab({ |
||||
|
url: link.wap_url |
||||
|
}); |
||||
|
} |
||||
|
} else { |
||||
|
this.$emit('callback'); |
||||
|
this.$util.diyRedirectTo(link); |
||||
|
} |
||||
|
}, |
||||
|
verify(link) { |
||||
|
if (link == null || link == '' || !link.wap_url) return false; |
||||
|
if (this.name) { |
||||
|
var url = this.currentRoute + '?name=' + this.name; |
||||
|
} else { |
||||
|
var url = this.currentRoute; |
||||
|
} |
||||
|
|
||||
|
// 首页特殊处理 |
||||
|
if (link.wap_url == '/pages/index/index' && this.name == 'DIY_VIEW_INDEX') { |
||||
|
return true; |
||||
|
} else if (link.wap_url.indexOf(url) != -1) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.placeholder { |
||||
|
height: 112rpx; |
||||
|
|
||||
|
&.bluge { |
||||
|
height: 180rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.safe-area { |
||||
|
padding-bottom: 0; |
||||
|
padding-bottom: constant(safe-area-inset-bottom); |
||||
|
padding-bottom: env(safe-area-inset-bottom); |
||||
|
} |
||||
|
|
||||
|
.tab-bar { |
||||
|
background-color: #fff; |
||||
|
box-sizing: border-box; |
||||
|
position: fixed; |
||||
|
left: 0; |
||||
|
bottom: 0; |
||||
|
width: 100%; |
||||
|
z-index: 9999999; |
||||
|
display: flex; |
||||
|
border-top: 2rpx solid #f5f5f5; |
||||
|
padding-bottom: 0; |
||||
|
padding-bottom: constant(safe-area-inset-bottom); |
||||
|
padding-bottom: env(safe-area-inset-bottom); |
||||
|
|
||||
|
.tabbar-border { |
||||
|
background-color: rgba(255, 255, 255, 0.329412); |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
width: 100%; |
||||
|
height: 2rpx; |
||||
|
-webkit-transform: scaleY(0.5); |
||||
|
transform: scaleY(0.5); |
||||
|
} |
||||
|
|
||||
|
.item { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
-webkit-box-orient: vertical; |
||||
|
-webkit-box-direction: normal; |
||||
|
flex: 1; |
||||
|
flex-direction: column; |
||||
|
padding-bottom: 10rpx; |
||||
|
box-sizing: border-box; |
||||
|
|
||||
|
.bd { |
||||
|
position: relative; |
||||
|
height: 100rpx; |
||||
|
flex-direction: column; |
||||
|
text-align: center; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
|
||||
|
.icon { |
||||
|
position: relative; |
||||
|
display: inline-block; |
||||
|
margin-top: 10rpx; |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
font-size: 40rpx; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
>view { |
||||
|
height: inherit; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.bar-icon { |
||||
|
font-size: 42rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.label { |
||||
|
position: relative; |
||||
|
text-align: center; |
||||
|
font-size: 24rpx; |
||||
|
line-height: 1; |
||||
|
margin-top: 12rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.bulge { |
||||
|
.bd { |
||||
|
position: relative; |
||||
|
height: 100rpx; |
||||
|
flex-direction: column; |
||||
|
text-align: center; |
||||
|
|
||||
|
.icon { |
||||
|
margin-top: -60rpx; |
||||
|
margin-bottom: 4rpx; |
||||
|
border-radius: 50%; |
||||
|
width: 100rpx; |
||||
|
height: 102rpx; |
||||
|
padding: 10rpx; |
||||
|
border-top: 2rpx solid #f5f5f5; |
||||
|
background-color: #fff; |
||||
|
box-sizing: border-box; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
border-radius: 50%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.label { |
||||
|
position: relative; |
||||
|
text-align: center; |
||||
|
font-size: 24rpx; |
||||
|
line-height: 1.6; |
||||
|
height: 40rpx; |
||||
|
line-height: 40rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.cartNumberBtn { |
||||
|
position: absolute; |
||||
|
top: -8rpx; |
||||
|
right: -18rpx; |
||||
|
width: 24rpx; |
||||
|
height: 24rpx !important; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
color: #fff; |
||||
|
padding: 6rpx; |
||||
|
border-radius: 50%; |
||||
|
z-index: 99; |
||||
|
|
||||
|
&.max { |
||||
|
width: 40rpx; |
||||
|
border-radius: 24rpx; |
||||
|
right: -28rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.tab-bar-placeholder { |
||||
|
padding-bottom: calc(constant(safe-area-inset-bottom) + 112rpx); |
||||
|
padding-bottom: calc(env(safe-area-inset-bottom) + 112rpx); |
||||
|
} |
||||
|
</style> |
||||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,30 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<!-- 扩展组件 --> |
||||
|
|
||||
|
<!-- 扩展标题 --> |
||||
|
<template v-if="value.componentName == 'TextExtend'"> |
||||
|
<diy-text-extend :value="value"></diy-text-extend> |
||||
|
</template> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 自定义扩展组件 |
||||
|
export default { |
||||
|
name: 'diy-comp-extend', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return {}; |
||||
|
}, |
||||
|
computed: {}, |
||||
|
created() {}, |
||||
|
methods: {} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
File diff suppressed because it is too large
@ -0,0 +1,102 @@ |
|||||
|
<template> |
||||
|
<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"> |
||||
|
<block v-for="(item, index) in value.list" :key="index"> |
||||
|
<view class="button-box" @click="$util.diyRedirectTo(item.link)"> |
||||
|
<image :src="$util.img(item.imageUrl)" mode="aspectFit" v-if="!item.iconType || item.iconType == 'img'"></image> |
||||
|
<diy-icon v-else-if="item.iconType && item.iconType == 'icon'" :icon="item.icon" :value="item.style ? item.style : null"></diy-icon> |
||||
|
</view> |
||||
|
</block> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 获取系统状态栏的高度 |
||||
|
let systemInfo = uni.getSystemInfoSync(); |
||||
|
export default { |
||||
|
name: 'diy-float-btn', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
navHeight: 0, |
||||
|
statusBarHeight: systemInfo.statusBarHeight |
||||
|
}; |
||||
|
}, |
||||
|
created() {}, |
||||
|
components: {}, |
||||
|
methods: {}, |
||||
|
computed:{ |
||||
|
style(){ |
||||
|
let style = {}, height = 54; |
||||
|
// #ifdef MP |
||||
|
height = systemInfo.platform == 'ios' ? 54 : 58; |
||||
|
// #endif |
||||
|
switch (this.value.bottomPosition) { |
||||
|
case 1: |
||||
|
style.top = (this.navHeight + this.statusBarHeight + parseInt(value.btnBottom)) * 2 + 'rpx !important' |
||||
|
break; |
||||
|
case 2: |
||||
|
style.top = (this.navHeight + this.statusBarHeight + parseInt(value.btnBottom)) * 2 + 'rpx !important' |
||||
|
break; |
||||
|
case 3: |
||||
|
style.bottom = (100 + parseInt(value.btnBottom)) * 2 + 'rpx !important' |
||||
|
break; |
||||
|
case 4: |
||||
|
style.bottom = (100 + parseInt(value.btnBottom)) * 2 + 'rpx !important' |
||||
|
break; |
||||
|
} |
||||
|
return this.$util.objToStyle(style); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.float-btn { |
||||
|
position: fixed; |
||||
|
bottom: 20%; |
||||
|
right: 40rpx; |
||||
|
z-index: 999; |
||||
|
&.right_top { |
||||
|
top: 100rpx; |
||||
|
right: 30rpx; |
||||
|
} |
||||
|
&.left_top { |
||||
|
top: 100rpx; |
||||
|
left: 30rpx; |
||||
|
} |
||||
|
&.right_bottom { |
||||
|
bottom: 200rpx; |
||||
|
right: 30rpx; |
||||
|
padding-bottom: constant(safe-area-inset-bottom); /*兼容 IOS<11.2*/ |
||||
|
padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/ |
||||
|
} |
||||
|
&.left_bottom { |
||||
|
bottom: 200rpx; |
||||
|
left: 30rpx; |
||||
|
padding-bottom: constant(safe-area-inset-bottom); /*兼容 IOS<11.2*/ |
||||
|
padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/ |
||||
|
} |
||||
|
.button-box { |
||||
|
margin-bottom: 20rpx; |
||||
|
width: 80rpx; |
||||
|
height: 80rpx; |
||||
|
font-size: 80rpx; |
||||
|
&:last-child { |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,127 @@ |
|||||
|
<template> |
||||
|
<view :class="['brand-wrap', value.ornament.type]" :style="warpCss" v-if="list.length > 0"> |
||||
|
<view :class="[value.style]"> |
||||
|
<view class="title-wrap" v-show="value.title" :style="{ color: value.textColor, fontWeight: value.fontWeight ? 'bold' : '' }">{{ value.title }}</view> |
||||
|
<view class="ul-wrap"> |
||||
|
<uni-grid :column="4" :showBorder="!1"> |
||||
|
<uni-grid-item v-for="(item, index) in list" :key="index" index="index"> |
||||
|
<image class="brand-pic" :src="$util.img(item.image_url)" mode="aspectFit" @click="toDetail(item)" @error="imgError(index)" :style="itemCss"></image> |
||||
|
</uni-grid-item> |
||||
|
</uni-grid> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 商品品牌 |
||||
|
import uniGrid from '@/components/uni-grid/uni-grid.vue'; |
||||
|
import uniGridItem from '@/components/uni-grid-item/uni-grid-item.vue'; |
||||
|
export default { |
||||
|
name: 'diy-goods-brand', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
components: { |
||||
|
uniGrid, |
||||
|
uniGridItem |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
list: [] |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.getBrandList(); |
||||
|
}, |
||||
|
computed: { |
||||
|
warpCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
if (this.value.componentAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
if (this.value.ornament.type == 'shadow') { |
||||
|
obj += 'box-shadow:' + '0 0 10rpx ' + this.value.ornament.color; |
||||
|
} |
||||
|
if (this.value.ornament.type == 'stroke') { |
||||
|
obj += 'border:' + '2rpx solid ' + this.value.ornament.color; |
||||
|
} |
||||
|
return obj; |
||||
|
}, |
||||
|
// 子项样式 |
||||
|
itemCss() { |
||||
|
var obj = ''; |
||||
|
if (this.value.elementAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
return obj; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
getBrandList() { |
||||
|
var data = { |
||||
|
page: 1, |
||||
|
page_size: this.value.count |
||||
|
}; |
||||
|
if (this.value.sources == 'diy') { |
||||
|
data.page_size = 0; |
||||
|
data.brand_id_arr = this.value.brandIds.toString(); |
||||
|
} |
||||
|
|
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/goodsbrand/page', |
||||
|
data: data, |
||||
|
success: res => { |
||||
|
if (res.code == 0 && res.data) { |
||||
|
let data = res.data; |
||||
|
this.list = data.list; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
toDetail(item) { |
||||
|
this.$util.redirectTo('/page_goods/goodsList/goodsList', { |
||||
|
brand_id: item.brand_id |
||||
|
}); |
||||
|
}, |
||||
|
imgError(index) { |
||||
|
if (this.list[index]) this.list[index].image_url = this.$util.getDefaultImage().goods; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.brand-wrap { |
||||
|
&.shadow { |
||||
|
margin-left: 8rpx; |
||||
|
margin-right: 8rpx; |
||||
|
margin-top: 8rpx; |
||||
|
margin-bottom: 8rpx; |
||||
|
} |
||||
|
.style-1 { |
||||
|
.title-wrap { |
||||
|
text-align: center; |
||||
|
padding: 20rpx 0 10rpx; |
||||
|
} |
||||
|
.ul-wrap { |
||||
|
padding: 20rpx; |
||||
|
.brand-pic { |
||||
|
width: 90%; |
||||
|
} |
||||
|
.uni-grid-item{ |
||||
|
width: calc(100% / 4) !important; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
File diff suppressed because it is too large
@ -0,0 +1,563 @@ |
|||||
|
<template> |
||||
|
<view v-if="list.length" :class="['goods-list', goodsValue.style]" :style="goodsListWarpCss"> |
||||
|
<view class="top-wrap"> |
||||
|
<text :class="['js-icon', goodsValue.topStyle.icon.value]" :style="{ |
||||
|
backgroundColor: goodsValue.topStyle.icon.bgColor, |
||||
|
color: goodsValue.topStyle.icon.color |
||||
|
}"></text> |
||||
|
<text class="title" :style="{ color: goodsValue.topStyle.color }"> |
||||
|
{{ goodsValue.topStyle.title }} |
||||
|
</text> |
||||
|
<text class="line" :style="{ color: goodsValue.topStyle.subColor }"></text> |
||||
|
<text class="sub" :style="{ color: goodsValue.topStyle.subColor }"> |
||||
|
{{ goodsValue.topStyle.subTitle }} |
||||
|
</text> |
||||
|
</view> |
||||
|
<swiper :autoplay="false" class="swiper" :style="{ height: swiperHeight }"> |
||||
|
<swiper-item v-for="(item, index) in page" :key="index" |
||||
|
:class="['swiper-item', [list[index].length / 3] >= 1 && 'flex-between']"> |
||||
|
<view class="goods-item" v-for="(dataItem, dataIndex) in list[index]" :key="dataIndex" @click="toDetail(dataItem)" |
||||
|
:class="[goodsValue.ornament.type]" :style="goodsItemCss"> |
||||
|
<image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" |
||||
|
:src="$util.img(dataItem.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(dataIndex)" |
||||
|
:lazy-load="true"></image> |
||||
|
<view :class="[ |
||||
|
'info-wrap', |
||||
|
{ 'multi-content': value.nameLineMode == 'multiple' } |
||||
|
]" v-if=" |
||||
|
goodsValue.goodsNameStyle.control || |
||||
|
goodsValue.priceStyle.mainControl || |
||||
|
goodsValue.priceStyle.lineControl |
||||
|
"> |
||||
|
<view v-if="goodsValue.goodsNameStyle.control" class="goods-name" :style="{ |
||||
|
color: |
||||
|
goodsValue.theme == 'diy' |
||||
|
? goodsValue.goodsNameStyle.color |
||||
|
: '', |
||||
|
fontWeight: goodsValue.goodsNameStyle.fontWeight ? 'bold' : '' |
||||
|
}" :class="[ |
||||
|
{ 'using-hidden': goodsValue.nameLineMode == 'single' }, |
||||
|
{ 'multi-hidden': goodsValue.nameLineMode == 'multiple' } |
||||
|
]"> |
||||
|
{{ dataItem.goods_name }} |
||||
|
</view> |
||||
|
<view class="pro-info"> |
||||
|
<view class="discount-price"> |
||||
|
<!-- <view class="price-wrap" v-if="goodsValue.priceStyle.mainControl"> |
||||
|
<text class="unit price-style small" :style="{ |
||||
|
color: |
||||
|
goodsValue.theme == 'diy' |
||||
|
? goodsValue.priceStyle.mainColor + '!important' |
||||
|
: '' |
||||
|
}"> |
||||
|
¥ |
||||
|
</text> |
||||
|
<text class="price price-style large" :style="{ |
||||
|
color: |
||||
|
goodsValue.theme == 'diy' |
||||
|
? goodsValue.priceStyle.mainColor + '!important' |
||||
|
: '' |
||||
|
}"> |
||||
|
{{ showPrice(dataItem).split('.')[0] }} |
||||
|
</text> |
||||
|
<text class="unit price-style small" :style="{ |
||||
|
color: |
||||
|
goodsValue.theme == 'diy' |
||||
|
? goodsValue.priceStyle.mainColor + '!important' |
||||
|
: '' |
||||
|
}"> |
||||
|
{{ '.' + showPrice(dataItem).split('.')[1] }} |
||||
|
</text> |
||||
|
</view> --> |
||||
|
<view v-if="goodsValue.priceStyle.mainControl" style="color: #f33b50;"> |
||||
|
<goodsPrice :goodsSkuDetail="dataItem"></goodsPrice> |
||||
|
</view> |
||||
|
<!-- <view |
||||
|
v-if="goodsValue.priceStyle.lineControl" |
||||
|
class="delete-price price-font" |
||||
|
:style="{ |
||||
|
color: |
||||
|
goodsValue.theme == 'diy' |
||||
|
? goodsValue.priceStyle.lineColor |
||||
|
: '' |
||||
|
}" |
||||
|
> |
||||
|
¥{{ |
||||
|
dataItem.market_price > 0 |
||||
|
? dataItem.market_price |
||||
|
: dataItem.price |
||||
|
}} |
||||
|
</view> --> |
||||
|
<view v-if="goodsValue.priceStyle.lineControl" style="color: #f33b50;"> |
||||
|
<goodsPrice :goodsSkuDetail="dataItem"></goodsPrice> |
||||
|
</view> |
||||
|
|
||||
|
<view class="sale" v-if="goodsValue.saleStyle.control" :style="{ |
||||
|
color: |
||||
|
goodsValue.theme == 'diy' |
||||
|
? goodsValue.saleStyle.color |
||||
|
: '' |
||||
|
}"> |
||||
|
售{{ dataItem.sale_num |
||||
|
}}{{ dataItem.unit ? dataItem.unit : '件' }} |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</swiper-item> |
||||
|
</swiper> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import goodsPrice from "@/components/goodsPrice.vue" |
||||
|
export default { |
||||
|
name: 'diy-goods-recommend', |
||||
|
components: { |
||||
|
goodsPrice |
||||
|
}, |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
list: [], |
||||
|
goodsValue: {}, |
||||
|
page: 1 |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.goodsValue = this.value; |
||||
|
this.getGoodsList(); |
||||
|
}, |
||||
|
computed: { |
||||
|
goodsListWarpCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.goodsValue.componentBgColor + ';'; |
||||
|
if (this.goodsValue.componentAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.goodsValue.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.goodsValue.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += |
||||
|
'border-bottom-left-radius:' + this.goodsValue.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
obj += |
||||
|
'border-bottom-right-radius:' + this.goodsValue.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
if (this.goodsValue.bgUrl) { |
||||
|
obj += `background-image: url('${this.$util.img(this.goodsValue.bgUrl)}');`; |
||||
|
} |
||||
|
return obj; |
||||
|
}, |
||||
|
// 商品项样式 |
||||
|
goodsItemCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.elementBgColor + ';'; |
||||
|
if (this.goodsValue.elementAngle == 'round') { |
||||
|
obj += |
||||
|
'border-top-left-radius:' + this.goodsValue.topElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += |
||||
|
'border-top-right-radius:' + |
||||
|
this.goodsValue.topElementAroundRadius * 2 + |
||||
|
'rpx;'; |
||||
|
obj += |
||||
|
'border-bottom-left-radius:' + |
||||
|
this.goodsValue.bottomElementAroundRadius * 2 + |
||||
|
'rpx;'; |
||||
|
obj += |
||||
|
'border-bottom-right-radius:' + |
||||
|
this.goodsValue.bottomElementAroundRadius * 2 + |
||||
|
'rpx;'; |
||||
|
} |
||||
|
if (this.goodsValue.ornament.type == 'shadow') { |
||||
|
obj += 'box-shadow:' + '0 0 10rpx ' + this.goodsValue.ornament.color + ';'; |
||||
|
} |
||||
|
if (this.goodsValue.ornament.type == 'stroke') { |
||||
|
obj += 'border:' + '2rpx solid ' + this.goodsValue.ornament.color + ';'; |
||||
|
} |
||||
|
const screenWidth = |
||||
|
uni.getSystemInfoSync().safeArea.width || uni.getSystemInfoSync().screenWidth; |
||||
|
var width = ''; |
||||
|
if (this.goodsValue.style != 'style-2') { |
||||
|
width = |
||||
|
[ |
||||
|
screenWidth - |
||||
|
this.rpxUpPx(20) * 2 - |
||||
|
this.rpxUpPx(200) * 3 - |
||||
|
this.rpxUpPx(this.value.margin.both * 2) * 2 |
||||
|
] / 6; |
||||
|
} else { |
||||
|
width = |
||||
|
[ |
||||
|
screenWidth - |
||||
|
this.rpxUpPx(20) * 2 - |
||||
|
this.rpxUpPx(20) * 2 - |
||||
|
this.rpxUpPx(200) * 3 - |
||||
|
this.rpxUpPx(this.value.margin.both * 2) * 2 |
||||
|
] / 6; |
||||
|
} |
||||
|
obj += 'margin-left:' + width + 'px;'; |
||||
|
obj += 'margin-right:' + width + 'px;'; |
||||
|
return obj; |
||||
|
}, |
||||
|
swiperHeight() { |
||||
|
if (this.goodsValue.style != 'style-2') { |
||||
|
if (this.value.nameLineMode == 'multiple') { |
||||
|
return '348rpx'; |
||||
|
} |
||||
|
return '312rpx'; |
||||
|
} else { |
||||
|
if (this.value.nameLineMode == 'multiple') { |
||||
|
return '360rpx'; |
||||
|
} |
||||
|
return '320rpx'; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
rpxUpPx(res) { |
||||
|
const screenWidth = |
||||
|
uni.getSystemInfoSync().safeArea.width || uni.getSystemInfoSync().screenWidth; |
||||
|
var data = (screenWidth * parseInt(res)) / 750; |
||||
|
return Math.floor(data); |
||||
|
}, |
||||
|
getGoodsList() { |
||||
|
var data = { |
||||
|
page: 1, |
||||
|
page_size: this.goodsValue.count, |
||||
|
cate_name: 6 |
||||
|
}; |
||||
|
if (this.goodsValue.sources == 'category') { |
||||
|
data.category_id = this.goodsValue.categoryId; |
||||
|
data.category_level = 1; |
||||
|
} else if (this.goodsValue.sources == 'diy') { |
||||
|
data.page_size = 0; |
||||
|
data.goods_id_arr = this.goodsValue.goodsId.toString(); |
||||
|
} |
||||
|
data.order = this.goodsValue.sortWay; |
||||
|
|
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/goodssku/pagecomponents', |
||||
|
data: data, |
||||
|
success: res => { |
||||
|
if (res.code == 0 && res.data) { |
||||
|
let data = res.data; |
||||
|
this.list = data.list; |
||||
|
|
||||
|
// 切屏滚动,每页显示固定数量 |
||||
|
let size = 3; |
||||
|
let temp = []; |
||||
|
this.page = Math.ceil(this.list.length / size); |
||||
|
for (var i = 0; i < this.page; i++) { |
||||
|
temp[i] = []; |
||||
|
for (var j = i * size; j < this.list.length; j++) { |
||||
|
if (temp[i].length == size) break; |
||||
|
temp[i].push(this.list[j]); |
||||
|
} |
||||
|
} |
||||
|
this.list = temp; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
toDetail(item) { |
||||
|
this.$util.redirectTo('/page_goods/detail/detail', { |
||||
|
goods_id: item.goods_id |
||||
|
}); |
||||
|
}, |
||||
|
imgError(index) { |
||||
|
if (this.list[index]) this.list[index].goods_image = this.$util.getDefaultImage().goods; |
||||
|
}, |
||||
|
showPrice(data) { |
||||
|
let price = data.discount_price; |
||||
|
if (data.member_price && parseFloat(data.member_price) < parseFloat(price)) |
||||
|
price = data.member_price; |
||||
|
return price; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.goods-list { |
||||
|
.goods-item { |
||||
|
line-height: 1; |
||||
|
|
||||
|
.sale { |
||||
|
line-height: 1; |
||||
|
color: $color-tip; |
||||
|
font-size: $font-size-activity-tag; |
||||
|
} |
||||
|
|
||||
|
.info-wrap { |
||||
|
.goods-name { |
||||
|
margin-bottom: 10rpx; |
||||
|
line-height: 1.3; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 商品列表横向滚动样式 |
||||
|
.goods-list.style-1 { |
||||
|
width: 100%; |
||||
|
white-space: nowrap; |
||||
|
background-repeat: round; |
||||
|
|
||||
|
.top-wrap { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding: 20rpx 0; |
||||
|
|
||||
|
.js-icon { |
||||
|
border-radius: 50%; |
||||
|
font-size: 40rpx; |
||||
|
margin-right: 10rpx; |
||||
|
width: 70rpx; |
||||
|
height: 70rpx; |
||||
|
text-align: center; |
||||
|
line-height: 70rpx; |
||||
|
} |
||||
|
|
||||
|
.line { |
||||
|
height: 28rpx; |
||||
|
margin: 0 10rpx; |
||||
|
border: 2rpx solid; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
font-weight: bold; |
||||
|
font-size: $font-size-toolbar; |
||||
|
} |
||||
|
|
||||
|
.sub { |
||||
|
font-size: $font-size-tag; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.flex-between { |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.swiper { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
margin: 0 20rpx; |
||||
|
|
||||
|
.swiper-item { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.goods-item { |
||||
|
overflow: hidden; |
||||
|
width: 200rpx; |
||||
|
display: inline-block; |
||||
|
box-sizing: border-box; |
||||
|
|
||||
|
&:nth-child(3n + 3) { |
||||
|
width: 198rpx; |
||||
|
} |
||||
|
|
||||
|
&.shadow { |
||||
|
margin-top: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.goods-img { |
||||
|
width: 100%; |
||||
|
height: 196rpx; |
||||
|
} |
||||
|
|
||||
|
.info-wrap { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
padding: 10rpx; |
||||
|
|
||||
|
&.multi-content { |
||||
|
height: 130rpx; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.goods-name { |
||||
|
font-size: $font-size-sub; |
||||
|
|
||||
|
&.using-hidden { |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
&.multi-hidden { |
||||
|
white-space: break-spaces; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.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 { |
||||
|
line-height: 1; |
||||
|
white-space: nowrap; |
||||
|
|
||||
|
.unit { |
||||
|
font-size: $font-size-tag; |
||||
|
color: $base-color; |
||||
|
} |
||||
|
|
||||
|
.price { |
||||
|
font-size: $font-size-toolbar; |
||||
|
} |
||||
|
|
||||
|
text { |
||||
|
font-weight: bold; |
||||
|
color: $base-color; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.delete-price { |
||||
|
margin-left: 10rpx; |
||||
|
text-decoration: line-through; |
||||
|
flex: 1; |
||||
|
line-height: 28rpx; |
||||
|
color: $color-tip; |
||||
|
font-size: $font-size-activity-tag; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 商品列表横向滚动样式 |
||||
|
.goods-list.style-2 { |
||||
|
width: 100%; |
||||
|
white-space: nowrap; |
||||
|
background-repeat: round; |
||||
|
padding-bottom: 20rpx; |
||||
|
|
||||
|
.top-wrap { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding: 20rpx; |
||||
|
|
||||
|
.js-icon { |
||||
|
border-radius: 50%; |
||||
|
font-size: 40rpx; |
||||
|
margin-right: 20rpx; |
||||
|
width: 70rpx; |
||||
|
height: 70rpx; |
||||
|
text-align: center; |
||||
|
line-height: 70rpx; |
||||
|
} |
||||
|
|
||||
|
.line { |
||||
|
height: 28rpx; |
||||
|
margin: 0 10rpx; |
||||
|
border: 2rpx solid; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
font-weight: bold; |
||||
|
font-size: $font-size-toolbar; |
||||
|
} |
||||
|
|
||||
|
.sub { |
||||
|
font-size: $font-size-tag; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.swiper { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
margin: 0 20rpx; |
||||
|
padding: 20rpx; |
||||
|
border-radius: 20rpx; |
||||
|
background-color: #fff; |
||||
|
} |
||||
|
|
||||
|
.goods-item { |
||||
|
overflow: hidden; |
||||
|
width: 200rpx; |
||||
|
display: inline-block; |
||||
|
box-sizing: border-box; |
||||
|
|
||||
|
&.shadow { |
||||
|
margin-top: 8rpx; |
||||
|
width: 200rpx; |
||||
|
} |
||||
|
|
||||
|
.goods-img { |
||||
|
width: 100%; |
||||
|
height: 200rpx; |
||||
|
} |
||||
|
|
||||
|
.info-wrap { |
||||
|
padding: 10rpx; |
||||
|
|
||||
|
.goods-name { |
||||
|
line-height: 1; |
||||
|
|
||||
|
&.using-hidden { |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
&.multi-hidden { |
||||
|
line-height: 1.3; |
||||
|
height: 68rpx; |
||||
|
white-space: break-spaces; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.pro-info { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: space-between; |
||||
|
|
||||
|
.discount-price { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
|
||||
|
.price-wrap { |
||||
|
line-height: 1.3; |
||||
|
|
||||
|
.unit { |
||||
|
font-size: $font-size-tag; |
||||
|
color: $base-color; |
||||
|
} |
||||
|
|
||||
|
text { |
||||
|
font-weight: bold; |
||||
|
color: $base-color; |
||||
|
|
||||
|
&:last-of-type { |
||||
|
font-size: 32rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.delete-price { |
||||
|
margin-left: 10rpx; |
||||
|
text-decoration: line-through; |
||||
|
flex: 1; |
||||
|
line-height: 28rpx; |
||||
|
color: $color-tip; |
||||
|
font-size: $font-size-activity-tag; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,313 @@ |
|||||
|
<template> |
||||
|
<div class="graphic_BOX"> |
||||
|
<view :style="componentStyle"> |
||||
|
<scroll-view :scroll-x="value.showStyle == 'singleSlide'" :class="['graphic-nav', value.showStyle]"> |
||||
|
<!-- #ifdef MP --> |
||||
|
<view class="uni-scroll-view-content"> |
||||
|
<!-- #endif --> |
||||
|
|
||||
|
<view class="graphic-nav-item" v-for="(item, index) in value.list" :key="index" |
||||
|
:style="{ width: 100 / value.rowCount + '%' }" @click="redirectTo(item.link)"> |
||||
|
<view class="graphic-img" v-show="value.mode != 'text'" :style="{ |
||||
|
fontSize: value.imageSize * 2 + 'rpx', |
||||
|
width: value.imageSize * 2 + 'rpx', |
||||
|
height: value.imageSize * 2 + 'rpx' |
||||
|
}"> |
||||
|
<image v-if="item.iconType == 'img'" :src=" |
||||
|
$util.img(item.imageUrl) || |
||||
|
$util.img('public/uniapp/default_img/goods.png') |
||||
|
" mode="aspectFill" :style="{ |
||||
|
maxWidth: value.imageSize * 2 + 'rpx', |
||||
|
maxHeight: value.imageSize * 2 + 'rpx', |
||||
|
borderRadius: value.aroundRadius * 2 + 'rpx' |
||||
|
}"></image> |
||||
|
<diy-icon v-if="item.iconType == 'icon'" :icon="item.icon" |
||||
|
:value="item.style ? item.style : null" :style="{ |
||||
|
maxWidth: value.imageSize * 2 + 'rpx', |
||||
|
maxHeight: value.imageSize * 2 + 'rpx', |
||||
|
width: '100%', |
||||
|
height: '100%' |
||||
|
}"></diy-icon> |
||||
|
<text :class="['tag', { alone: value.mode == 'text' }]" v-if="item.label.control" :style="{ |
||||
|
color: item.label.textColor, |
||||
|
backgroundImage: |
||||
|
'linear-gradient(' + |
||||
|
item.label.bgColorStart + |
||||
|
',' + |
||||
|
item.label.bgColorEnd + |
||||
|
')' |
||||
|
}"> |
||||
|
{{ item.label.text }} |
||||
|
</text> |
||||
|
</view> |
||||
|
<text v-show="value.mode != 'img'" class="graphic-text" :style="{ |
||||
|
fontSize: value.font.size * 2 + 'rpx', |
||||
|
fontWeight: value.font.weight, |
||||
|
color: value.font.color |
||||
|
}"> |
||||
|
{{ item.title }} |
||||
|
</text> |
||||
|
</view> |
||||
|
|
||||
|
<!-- #ifdef MP --> |
||||
|
</view> |
||||
|
<!-- #endif --> |
||||
|
</scroll-view> |
||||
|
</view> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'diy-graphic-nav', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
pageWidth: '', |
||||
|
indicatorDots: false, |
||||
|
swiperCurrent: 0 |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
// console.log('----------------------------------------') |
||||
|
}, |
||||
|
computed: { |
||||
|
componentStyle() { |
||||
|
var css = ''; |
||||
|
css += 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
if (this.value.componentAngle == 'round') { |
||||
|
css += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
css += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
css += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
css += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
css += |
||||
|
'box-shadow:' + |
||||
|
(this.value.ornament.type == 'shadow' ? |
||||
|
'0 0 10rpx ' + this.value.ornament.color : |
||||
|
'') + |
||||
|
';'; |
||||
|
css += |
||||
|
'border:' + |
||||
|
(this.value.ornament.type == 'stroke' ? |
||||
|
'2rpx solid ' + this.value.ornament.color : |
||||
|
'') + |
||||
|
';'; |
||||
|
return css; |
||||
|
}, |
||||
|
// 滑块容器的高度 |
||||
|
swiperHeight() { |
||||
|
var css = ''; |
||||
|
var height = 88 * this.value.pageCount; // 88 = 文字的高度 + 图片的高度 |
||||
|
|
||||
|
if (this.value.mode == 'img') height -= 21 * this.value.pageCount; // 21 = 文字的高度 |
||||
|
if (this.value.mode == 'text') height -= 50 * this.value.pageCount; // 21 = 文字的高度 |
||||
|
css += 'height:' + height * 2 + 'rpx'; |
||||
|
return css; |
||||
|
}, |
||||
|
// 是否显示轮播点 |
||||
|
isIndicatorDots() { |
||||
|
var bool = true; |
||||
|
bool = |
||||
|
this.value.carousel.type == 'hide' || |
||||
|
Math.ceil(this.value.list.length / (this.value.pageCount * this.value.rowCount)) == |
||||
|
1 ? |
||||
|
false : |
||||
|
true; |
||||
|
|
||||
|
return bool; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
redirectTo(link) { |
||||
|
console.log(link); |
||||
|
if (![ |
||||
|
'/pages_tool/quality_test/quality_test', |
||||
|
"/pages_tool/article/list", |
||||
|
"/pages_tool/goods/coupon", |
||||
|
"/page_goods/goodsList/goodsList" |
||||
|
].includes(link.wap_url)) { |
||||
|
if (!uni.getStorageSync('token')) { |
||||
|
this.$util.showToast({ |
||||
|
title: '您尚未登录,请先进行登录', |
||||
|
icon: 'none', |
||||
|
}); |
||||
|
setTimeout(() => { |
||||
|
this.$util.redirectTo('/pages_tool/login/login'); |
||||
|
}, 1000) |
||||
|
|
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
this.$util.diyRedirectTo(link); |
||||
|
}, |
||||
|
swiperChange(e) { |
||||
|
this.swiperCurrent = e.detail.current; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.graphic_BOX { |
||||
|
|
||||
|
|
||||
|
/* 固定显示 */ |
||||
|
.graphic-nav.fixed { |
||||
|
/deep/ .uni-scroll-view-content { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* #ifdef MP-ALIPAY*/ |
||||
|
.fixed { |
||||
|
position: relative; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
} |
||||
|
|
||||
|
/* #endif */ |
||||
|
|
||||
|
/* 单行滑动 */ |
||||
|
.graphic-nav.singleSlide { |
||||
|
/deep/ .uni-scroll-view-content { |
||||
|
display: flex; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.graphic-nav.pageSlide { |
||||
|
/deep/.uni-swiper-dots-horizontal { |
||||
|
bottom: 0rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.graphic-nav.pageSlide.straightLine { |
||||
|
/deep/.uni-swiper-dot { |
||||
|
width: 30rpx; |
||||
|
border-radius: 0; |
||||
|
height: 8rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.graphic-nav.pageSlide.circle { |
||||
|
/deep/.uni-swiper-dot { |
||||
|
width: 14rpx; |
||||
|
height: 14rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
|
<style lang="scss"> |
||||
|
.graphic-nav { |
||||
|
padding: 16rpx; |
||||
|
box-sizing: border-box; |
||||
|
// border-radius: 0rpx 0rpx 0rpx 0rpx; |
||||
|
// box-shadow: 0 0 4rpx rgba(100, 100, 100, 0.3); |
||||
|
|
||||
|
|
||||
|
&.singleSlide { |
||||
|
.graphic-nav-item { |
||||
|
flex-shrink: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.pageSlide { |
||||
|
position: relative; |
||||
|
|
||||
|
.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 { |
||||
|
padding-top: 12rpx; |
||||
|
line-height: 1.5; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden; |
||||
|
width: 100%; |
||||
|
text-align: center; |
||||
|
|
||||
|
&.alone { |
||||
|
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: -36rpx; |
||||
|
color: #fff; |
||||
|
border-radius: 24rpx; |
||||
|
border-bottom-left-radius: 0; |
||||
|
transform: scale(0.8); |
||||
|
padding: 8rpx 16rpx; |
||||
|
line-height: 1; |
||||
|
font-size: 24rpx; |
||||
|
} |
||||
|
|
||||
|
.icon { |
||||
|
font-size: 50rpx; |
||||
|
color: $color-sub; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.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: rgba(0, 0, 0, 1); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.straightLine { |
||||
|
.swiper-dot { |
||||
|
width: 30rpx; |
||||
|
border-radius: 0; |
||||
|
height: 8rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.circle { |
||||
|
.swiper-dot { |
||||
|
width: 15rpx; |
||||
|
border-radius: 50%; |
||||
|
height: 15rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,262 @@ |
|||||
|
<template> |
||||
|
<view class="diy-group" v-if="showFlag"> |
||||
|
<view v-for="(item, index) in diyGlobalData.value" :key="index" :style="item.pageStyle"> |
||||
|
<template v-if="item.componentName == 'Text'"> |
||||
|
<!-- 文本 --> |
||||
|
<diy-text :value="item"></diy-text> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'TextNav'"> |
||||
|
<!-- 文本导航 --> |
||||
|
<diy-text-nav :value="item"></diy-text-nav> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'Notice'"> |
||||
|
<!-- 公告 --> |
||||
|
<diy-notice :value="item"></diy-notice> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'GraphicNav'"> |
||||
|
<!-- 图文导航 --> |
||||
|
<diy-graphic-nav :value="item"></diy-graphic-nav> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'ImageAds'"> |
||||
|
<!-- 图片广告 --> |
||||
|
<view :class="!showStore || !addonIsExist.store ? 'noStore-bg' : ''"> |
||||
|
<diy-img-ads :value="item"></diy-img-ads> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'Search'"> |
||||
|
<!-- 搜索 --> |
||||
|
<view class="box" :class="!showStore || !addonIsExist.store ? 'noStore-bg' : ''"> |
||||
|
<diy-search :value="item"></diy-search> |
||||
|
</view> |
||||
|
<!-- <view :class="!showStore || !addonIsExist.store ? 'noStore-bg' : 'isStore-top'"> |
||||
|
<diy-search :value="item"></diy-search> |
||||
|
</view> --> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'RichText'"> |
||||
|
<!-- 富文本 --> |
||||
|
<u-parse :content="item.html"></u-parse> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'HorzLine'"> |
||||
|
<!-- 辅助线 --> |
||||
|
<diy-horz-line :value="item"></diy-horz-line> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'HorzBlank'"> |
||||
|
<!-- 辅助空白 --> |
||||
|
<diy-horz-blank :value="item"></diy-horz-blank> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'Coupon' && addonIsExist.coupon"> |
||||
|
<!-- 优惠券 --> |
||||
|
<diy-coupon :value="item"></diy-coupon> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'GoodsList'"> |
||||
|
<!-- 商品列表 --> |
||||
|
<diy-goods-list :value="item"></diy-goods-list> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'ManyGoodsList'"> |
||||
|
<!-- 多商品组 --> |
||||
|
<diy-many-goods-list ref="ManyGoodsList" :value="item" |
||||
|
:manyGoodsList='manyGoodsListData'></diy-many-goods-list> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'RubikCube'"> |
||||
|
<!-- 魔方、橱窗 --> |
||||
|
<diy-rubik-cube :value="item"></diy-rubik-cube> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'Video'"> |
||||
|
<!-- 视频 --> |
||||
|
<diy-video :value="item" ref="diyVideo"></diy-video> |
||||
|
</template> |
||||
|
|
||||
|
<view class="diy-goods-level-wrap" v-if="item.componentName == 'GoodsCategory'"> |
||||
|
<!-- 商品分类 使用view替代template目的是限制商品分类在自定义首页的高度--> |
||||
|
<!-- <diy-category :value="item"></diy-category> --> |
||||
|
</view> |
||||
|
|
||||
|
<template v-if="item.componentName == 'FloatBtn'"> |
||||
|
<!-- 浮动按钮 --> |
||||
|
<!-- <diy-float-btn :value="item"></diy-float-btn> --> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'GoodsRecommend'"> |
||||
|
<!-- 商品推荐 --> |
||||
|
<diy-goods-recommend :value="item"></diy-goods-recommend> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'GoodsBrand'"> |
||||
|
<!-- 商品品牌 --> |
||||
|
<diy-goods-brand :value="item"></diy-goods-brand> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'Article'"> |
||||
|
<!-- 文章 --> |
||||
|
<diy-article :value="item"></diy-article> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'MemberInfo'"> |
||||
|
<!-- 自定义会员中心——会员信息 --> |
||||
|
<diy-member-info ref="diyMemberIndex" :value="item" :token="token"></diy-member-info> |
||||
|
</template> |
||||
|
|
||||
|
<template v-if="item.componentName == 'MemberMyOrder'"> |
||||
|
<!-- 自定义会员中心——我的订单 --> |
||||
|
<diy-member-my-order ref="diyMemberMyOrder" :value="item" :token="token"></diy-member-my-order> |
||||
|
</template> |
||||
|
|
||||
|
<!-- 自定义扩展组件 --> |
||||
|
<template v-if="diyGlobalData.compExtend.indexOf(item.componentName) != -1"> |
||||
|
<!-- <diy-comp-extend :value="item"></diy-comp-extend> --> |
||||
|
</template> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
components: {}, |
||||
|
props: { |
||||
|
|
||||
|
diyData: { |
||||
|
type: Object |
||||
|
}, |
||||
|
storeId: { |
||||
|
type: [String, Number] |
||||
|
}, |
||||
|
token: { |
||||
|
type: String |
||||
|
}, |
||||
|
height: { |
||||
|
type: String, |
||||
|
default () { |
||||
|
return '100vh'; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
data() { |
||||
|
return { |
||||
|
showStore: false, |
||||
|
diyGlobalData: null, |
||||
|
showFlag: true, |
||||
|
manyGoodsListData: [], |
||||
|
}; |
||||
|
}, |
||||
|
watch: { |
||||
|
diyData: { |
||||
|
deep: true, |
||||
|
handler() { |
||||
|
this.showFlag = false |
||||
|
this.$nextTick(() => { |
||||
|
this.showFlag = true |
||||
|
this.diyGlobalData = JSON.parse(JSON.stringify(this.diyData)); |
||||
|
this.setPagestyle(); |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
this.diyGlobalData = JSON.parse(JSON.stringify(this.diyData)); |
||||
|
this.setPagestyle(); |
||||
|
}, |
||||
|
computed: { |
||||
|
bgColor() { |
||||
|
let str = ''; |
||||
|
if (this.diyData && this.diyData.global) { |
||||
|
str = this.diyData.global.bgColor; |
||||
|
} |
||||
|
return str; |
||||
|
}, |
||||
|
bgUrl() { |
||||
|
let str = ''; |
||||
|
if (this.diyData && this.diyData.global) { |
||||
|
str = this.diyData.global.bgUrl; |
||||
|
} |
||||
|
return str; |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
if (this.diyData != undefined) { |
||||
|
this.dealData(); |
||||
|
} |
||||
|
// this.getHomeIndexList() |
||||
|
}, |
||||
|
methods: { |
||||
|
setPagestyle() { |
||||
|
this.diyGlobalData.value.forEach((item, index) => { |
||||
|
item.pageStyle = ''; |
||||
|
item.pageStyle += 'background-color:' + item.pageBgColor + ';'; |
||||
|
if (item.margin) { |
||||
|
item.pageStyle += 'padding-top:' + item.margin.top * 2 + 'rpx' + ';'; |
||||
|
item.pageStyle += 'padding-bottom:' + item.margin.bottom * 2 + 'rpx' + ';'; |
||||
|
item.pageStyle += 'padding-right:' + item.margin.both * 2 + 'rpx' + ';'; |
||||
|
item.pageStyle += 'padding-left:' + item.margin.both * 2 + 'rpx' + ';'; |
||||
|
} |
||||
|
if (item.componentName == 'Search') { |
||||
|
item.pageStyle += |
||||
|
'position: sticky;top:0;padding-top: var(--status-bar-height); background: #f7f7f7;z-index: 999;' |
||||
|
// background: linear-gradient(#ceebfa, #ceebfa, #f7f7f7);' |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
// 刷新数据 |
||||
|
refresh(data) { |
||||
|
this.diyGlobalData = {}; // 必须先清空自定义组件集合,然后异步刷新 |
||||
|
setTimeout(() => { |
||||
|
this.diyGlobalData = data; |
||||
|
this.setPagestyle(); |
||||
|
}, 1); |
||||
|
}, |
||||
|
dealData() { |
||||
|
if (Array.isArray(this.diyData.value)) { |
||||
|
for (var i = 0; i < this.diyData.value.length; i++) { |
||||
|
if (this.diyData.value[i].componentName == 'StoreShow') { |
||||
|
this.showStore = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
getHomeIndexList() { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/goodssku/homeIndexList', |
||||
|
success: res => { |
||||
|
this.manyGoodsListData = res.data |
||||
|
console.log(this.manyGoodsListData); |
||||
|
}, |
||||
|
fail: err => { |
||||
|
|
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.diy-group { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
:has(.box) { |
||||
|
|
||||
|
z-index: 999 !important; |
||||
|
} |
||||
|
|
||||
|
// .diy-goods-level-wrap { |
||||
|
// position: relative; |
||||
|
// height: 60vh; |
||||
|
// } |
||||
|
</style> |
||||
@ -0,0 +1,416 @@ |
|||||
|
<template> |
||||
|
<view class="diy-groupbuy" v-if="list.length" :class="[value.template, value.style]" :style="warpCss"> |
||||
|
<template v-if="value.template == 'row1-of1'"> |
||||
|
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss"> |
||||
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> |
||||
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image,{size: 'mid'})" mode="widthFix" @error="imageError(index)"></image> |
||||
|
</view> |
||||
|
<view class="content" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control"> |
||||
|
<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 class="discount-price" v-if="value.priceStyle.mainControl"> |
||||
|
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor +'!important' : '' }">¥</text> |
||||
|
<text class="price price-style large" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor +'!important' : '' }">{{ item.groupbuy_price.split(".")[0] }}</text> |
||||
|
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor +'!important' : '' }">{{ "."+item.groupbuy_price.split(".")[1] }}</text> |
||||
|
</view> |
||||
|
<button |
||||
|
v-if="value.btnStyle.control" |
||||
|
: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' |
||||
|
}" |
||||
|
> |
||||
|
{{ value.btnStyle.text }} |
||||
|
</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
<template v-if="value.template == 'horizontal-slide'"> |
||||
|
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false"> |
||||
|
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss"> |
||||
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> |
||||
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image,{size: 'mid'})" mode="widthFix" @error="imageError(index)"></image> |
||||
|
<image class="bg" v-if="value.saleStyle.control" :src="$util.img('public/uniapp/groupbuy/bg.png')" mode="widthFix"></image> |
||||
|
<view class="num" v-if="value.saleStyle.control" :style="{ color: value.theme == 'diy' ? value.saleStyle.color : '' }">已团{{ item.sell_num }}件</view> |
||||
|
</view> |
||||
|
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl"> |
||||
|
<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 class="discount-price" v-if="value.priceStyle.mainControl"> |
||||
|
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor +'!important': '' }">¥</text> |
||||
|
<text class="price price-style large" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor +'!important' : '' }">{{ item.groupbuy_price.split(".")[0] }}</text> |
||||
|
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor +'!important' : '' }">{{ "."+item.groupbuy_price.split(".")[1] }}</text> |
||||
|
</view> |
||||
|
<view class="original-price price-font" v-if="value.priceStyle.lineControl" :style="{ color: value.theme == 'diy' ? value.priceStyle.lineColor : '' }"> |
||||
|
¥{{ item.price }} |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
|
||||
|
<swiper v-if="value.slideMode == 'slide'" :autoplay="false" class="swiper" :style="{ height: swiperHeight }"> |
||||
|
<swiper-item v-for="(pageItem,pageIndex) in page" :key="pageIndex" :class="['swiper-item', [list[pageIndex].length / 3] >= 1 && 'flex-between']"> |
||||
|
<view class="item" v-for="(item, dataIndex) in list[pageIndex]" :key="dataIndex" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss"> |
||||
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> |
||||
|
<image |
||||
|
:style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" |
||||
|
:src="$util.img(item.goods_image,{size: 'mid'})" |
||||
|
mode="widthFix" |
||||
|
@error="imageError(dataIndex)" |
||||
|
></image> |
||||
|
<image class="bg" v-if="value.saleStyle.control" :src="$util.img('public/uniapp/groupbuy/bg.png')" mode="widthFix"></image> |
||||
|
<view class="num" v-if="value.saleStyle.control" :style="{ color: value.theme == 'diy' ? value.saleStyle.color : '' }">已团{{ item.sell_num }}件</view> |
||||
|
</view> |
||||
|
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl"> |
||||
|
<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 class="discount-price" v-if="value.priceStyle.mainControl"> |
||||
|
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor +'!important' : '' }">¥</text> |
||||
|
<text class="price price-style large" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor +'!important' : '' }">{{ item.groupbuy_price.split(".")[1] }}</text> |
||||
|
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor +'!important' : '' }">{{ "."+item.groupbuy_price.split(".")[1] }}</text> |
||||
|
</view> |
||||
|
<view class="original-price price-font" v-if="value.priceStyle.lineControl" :style="{ color: value.theme == 'diy' ? value.priceStyle.lineColor : '' }"> |
||||
|
¥{{ item.price }} |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</swiper-item> |
||||
|
</swiper> |
||||
|
</template> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'diy-groupbuy', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
list: [], |
||||
|
page: 1 |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.getData(); |
||||
|
}, |
||||
|
computed: { |
||||
|
warpCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
if (this.value.componentAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
return obj; |
||||
|
}, |
||||
|
// 商品项样式 |
||||
|
goodsItemCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.elementBgColor + ';'; |
||||
|
if (this.value.elementAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
if (this.value.ornament.type == 'shadow') { |
||||
|
obj += 'box-shadow:' + '0 0 10rpx ' + this.value.ornament.color + ';'; |
||||
|
} |
||||
|
if (this.value.ornament.type == 'stroke') { |
||||
|
obj += 'border:' + '2rpx solid ' + this.value.ornament.color + ';'; |
||||
|
} |
||||
|
const screenWidth = uni.getSystemInfoSync().safeArea.width || uni.getSystemInfoSync().screenWidth; |
||||
|
if(this.value.template == 'horizontal-slide'){ |
||||
|
var width = ""; |
||||
|
if(this.value.slideMode == 'scroll' && this.value.goodsMarginType=='diy') |
||||
|
width = this.rpxUpPx(this.value.goodsMarginNum*2); |
||||
|
else |
||||
|
width = [screenWidth - (this.rpxUpPx(20)*2) - (this.rpxUpPx(200)*3) - (this.rpxUpPx(this.value.margin.both*2)*2)]/6; |
||||
|
obj += 'margin-left:' + width + "px;"; |
||||
|
obj += 'margin-right:' + width + "px;"; |
||||
|
} |
||||
|
return obj; |
||||
|
}, |
||||
|
swiperHeight() { |
||||
|
if (this.value.nameLineMode == 'multiple') |
||||
|
return this.value.ornament.type == 'shadow' ? '404rpx': '392rpx'; |
||||
|
return this.value.ornament.type == 'shadow' ? '376rpx': '368rpx'; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
rpxUpPx(res){ |
||||
|
const screenWidth = uni.getSystemInfoSync().safeArea.width || uni.getSystemInfoSync().screenWidth; |
||||
|
var data = screenWidth * parseInt(res) / 750; |
||||
|
return Math.floor(data); |
||||
|
}, |
||||
|
getData() { |
||||
|
var data = { |
||||
|
page: 1, |
||||
|
page_size: this.value.count |
||||
|
}; |
||||
|
if (this.value.sources == 'diy') { |
||||
|
data.page_size = 0; |
||||
|
data.goods_id_arr = this.value.goodsId.toString(); |
||||
|
} |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/groupbuy/api/goods/page', |
||||
|
data: data, |
||||
|
success: res => { |
||||
|
if (res.code == 0) { |
||||
|
this.list = res.data.list; |
||||
|
|
||||
|
// 切屏滚动,每页显示固定数量 |
||||
|
if (this.value.template == 'horizontal-slide' && this.value.slideMode == 'slide') { |
||||
|
let size = 3; |
||||
|
let temp = []; |
||||
|
this.page = Math.ceil(this.list.length / size); |
||||
|
for (var i = 0; i < this.page; i++) { |
||||
|
temp[i] = []; |
||||
|
for (var j = i * size; j < this.list.length; j++) { |
||||
|
if (temp[i].length == size) break; |
||||
|
temp[i].push(this.list[j]); |
||||
|
} |
||||
|
} |
||||
|
this.list = temp; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
toDetail(e) { |
||||
|
this.$util.redirectTo('/pages_promotion/groupbuy/detail', { |
||||
|
groupbuy_id: e.groupbuy_id |
||||
|
}); |
||||
|
}, |
||||
|
imageError(index) { |
||||
|
this.list[index].goods_image = this.$util.getDefaultImage().goods; |
||||
|
this.$forceUpdate(); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
/deep/.uni-scroll-view ::-webkit-scrollbar { |
||||
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */ |
||||
|
display: none; |
||||
|
width: 0; |
||||
|
height: 0; |
||||
|
color: transparent; |
||||
|
background: transparent; |
||||
|
} |
||||
|
|
||||
|
/deep/::-webkit-scrollbar { |
||||
|
display: none; |
||||
|
width: 0; |
||||
|
height: 0; |
||||
|
color: transparent; |
||||
|
background: transparent; |
||||
|
} |
||||
|
|
||||
|
scroll-view ::-webkit-scrollbar { |
||||
|
width: 0; |
||||
|
height: 0; |
||||
|
background-color: transparent; |
||||
|
touch-action: none; |
||||
|
} |
||||
|
|
||||
|
.diy-groupbuy { |
||||
|
&.row1-of1 { |
||||
|
.item { |
||||
|
display: flex; |
||||
|
margin-bottom: 20rpx; |
||||
|
padding: 16rpx; |
||||
|
&.shadow { |
||||
|
margin: 8rpx 8rpx 20rpx 8rpx; |
||||
|
} |
||||
|
&:last-child { |
||||
|
margin-bottom: 0; |
||||
|
padding-bottom: 20rpx; |
||||
|
} |
||||
|
.img-wrap { |
||||
|
width: 200rpx; |
||||
|
height: 200rpx; |
||||
|
> image { |
||||
|
width: 200rpx; |
||||
|
} |
||||
|
} |
||||
|
.goods-name{ |
||||
|
margin-top: 6rpx; |
||||
|
line-height: 1.5; |
||||
|
} |
||||
|
.content { |
||||
|
flex: 1; |
||||
|
margin-left: 20rpx; |
||||
|
position: relative; |
||||
|
.discount-price { |
||||
|
white-space: nowrap; |
||||
|
font-weight: bold; |
||||
|
position: absolute; |
||||
|
bottom: 20rpx; |
||||
|
left: 0; |
||||
|
display: flex; |
||||
|
align-items: baseline; |
||||
|
line-height: 1; |
||||
|
.unit { |
||||
|
font-size: $font-size-tag; |
||||
|
margin-right: 4rpx; |
||||
|
color: $base-color; |
||||
|
} |
||||
|
.price { |
||||
|
font-size: $font-size-toolbar; |
||||
|
color: $base-color; |
||||
|
} |
||||
|
} |
||||
|
button { |
||||
|
position: absolute; |
||||
|
bottom: 10rpx; |
||||
|
right: 20rpx; |
||||
|
margin: 0; |
||||
|
padding: 0 20rpx; |
||||
|
background-color: $base-color; |
||||
|
color: #fff; |
||||
|
min-width: 112rpx; |
||||
|
height: 52rpx; |
||||
|
line-height: 52rpx; |
||||
|
font-size: $font-size-tag; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.horizontal-slide { |
||||
|
.scroll { |
||||
|
width: calc(100% - 40rpx); |
||||
|
padding: 20rpx; |
||||
|
line-height: 1; |
||||
|
white-space: nowrap; |
||||
|
.item.shadow { |
||||
|
margin-bottom: 8rpx; |
||||
|
} |
||||
|
} |
||||
|
.flex-between { |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
.item { |
||||
|
display: inline-block; |
||||
|
width: 200rpx; |
||||
|
overflow: hidden; |
||||
|
box-sizing: border-box; |
||||
|
&:nth-child(3n+3){ |
||||
|
width: 198rpx; |
||||
|
} |
||||
|
&.shadow { |
||||
|
margin-top: 8rpx; |
||||
|
} |
||||
|
.img-wrap { |
||||
|
width: 200rpx; |
||||
|
height: 200rpx; |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
margin: 0 auto; |
||||
|
> image { |
||||
|
width: 200rpx; |
||||
|
} |
||||
|
.bg { |
||||
|
position: absolute; |
||||
|
width: 100%; |
||||
|
height: 60rpx; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
z-index: 2; |
||||
|
} |
||||
|
.num { |
||||
|
width: 180rpx; |
||||
|
position: absolute; |
||||
|
bottom: 10rpx; |
||||
|
padding-left: 20rpx; |
||||
|
font-size: 20rpx; |
||||
|
line-height: 1; |
||||
|
color: #ffffff; |
||||
|
z-index: 3; |
||||
|
} |
||||
|
} |
||||
|
.content { |
||||
|
padding: 10rpx; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: space-between; |
||||
|
&.multi-content{ |
||||
|
height: 158rpx; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
.goods-name { |
||||
|
line-height: 1.3; |
||||
|
&.using-hidden{ |
||||
|
display: block; |
||||
|
} |
||||
|
&.multi-hidden { |
||||
|
white-space: break-spaces; |
||||
|
} |
||||
|
} |
||||
|
.discount-price { |
||||
|
white-space: nowrap; |
||||
|
margin-top: auto; |
||||
|
font-weight: bold; |
||||
|
line-height: 1; |
||||
|
.unit { |
||||
|
font-size: $font-size-tag; |
||||
|
margin-right: 4rpx; |
||||
|
color: $base-color; |
||||
|
} |
||||
|
.price { |
||||
|
font-size: $font-size-toolbar; |
||||
|
color: $base-color; |
||||
|
} |
||||
|
} |
||||
|
.original-price { |
||||
|
font-size: $font-size-tag; |
||||
|
color: $color-tip; |
||||
|
line-height: 1; |
||||
|
text-decoration: line-through; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.swiper { |
||||
|
width: 100%; |
||||
|
white-space: nowrap; |
||||
|
padding: 20rpx; |
||||
|
box-sizing: border-box; |
||||
|
.swiper-item{ |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
.item { |
||||
|
width: 200rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,36 @@ |
|||||
|
<template> |
||||
|
<view :style="horzBlankGaugeWrap"></view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 辅助空白 |
||||
|
export default { |
||||
|
name: 'diy-horz-blank', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return {}; |
||||
|
}, |
||||
|
computed: { |
||||
|
horzBlankGaugeWrap: function() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
if (this.value.componentAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
obj += 'height:' + this.value.height * 2 + 'rpx'; |
||||
|
return obj; |
||||
|
} |
||||
|
}, |
||||
|
created() {}, |
||||
|
methods: {} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
@ -0,0 +1,21 @@ |
|||||
|
<template> |
||||
|
<view :style="{ borderTop: '2rpx ' + value.borderStyle + ' ' + value.color }"></view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 辅助线 |
||||
|
export default { |
||||
|
name: 'diy-horz-line', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return {}; |
||||
|
}, |
||||
|
methods: {} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
@ -0,0 +1,84 @@ |
|||||
|
<template> |
||||
|
<view class="diy-icon" :style="iconBgStyle"> |
||||
|
<text class="js-icon" :class="iconClass" :style="iconStyle"></text> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'diy-icon', |
||||
|
props: { |
||||
|
icon: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
value: { |
||||
|
type: Object, |
||||
|
default: function () { |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
iconClass(){ |
||||
|
var _class = ' ' + this.icon; |
||||
|
if (this.value && this.value.iconColor.length > 1) _class += ' gradient'; |
||||
|
return _class; |
||||
|
}, |
||||
|
iconBgStyle(){ |
||||
|
if (!this.value) return {}; |
||||
|
|
||||
|
var style = { |
||||
|
'border-radius': this.value.bgRadius + '%', |
||||
|
'background': '' |
||||
|
}; |
||||
|
|
||||
|
if (this.value.iconBgImg) style['background'] += 'url('+ this.$util.img(this.value.iconBgImg) +') no-repeat bottom / contain' |
||||
|
if (this.value.iconBgColor.length) { |
||||
|
if (style.background) style.background += ','; |
||||
|
if (this.value.iconBgColor.length == 1) { |
||||
|
style.background += this.value.iconBgColor[0]; |
||||
|
} else { |
||||
|
style['background'] += 'linear-gradient('+ this.value.iconBgColorDeg +'deg, '+ this.value.iconBgColor.join(',') +')'; |
||||
|
} |
||||
|
} |
||||
|
return this.$util.objToStyle(style); |
||||
|
}, |
||||
|
iconStyle(){ |
||||
|
if (!this.value) return {}; |
||||
|
|
||||
|
var style = { |
||||
|
'font-size': this.value.fontSize + '%' |
||||
|
} |
||||
|
if (this.value.iconColor.length == 1) { |
||||
|
style.color = this.value.iconColor[0]; |
||||
|
} else { |
||||
|
style['background'] = 'linear-gradient('+ this.value.iconColorDeg +'deg, '+ this.value.iconColor.join(',') +')'; |
||||
|
} |
||||
|
return this.$util.objToStyle(style); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.diy-icon { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
font-size: 100%; |
||||
|
color: #000; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
|
||||
|
.js-icon { |
||||
|
font-size: 50%; |
||||
|
line-height:1; |
||||
|
padding: 1rpx; |
||||
|
&.gradient { |
||||
|
-webkit-background-clip:text!important; |
||||
|
-webkit-text-fill-color:transparent; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,356 @@ |
|||||
|
<template> |
||||
|
<view class="single-graph"> |
||||
|
<view :style="imgAdsMarginWarp" class="swiper-box"> |
||||
|
<!-- <block v-if="imgAdsValue.list.length == 1"> |
||||
|
<view class="simple-graph-wrap" :style="imgAdsSwiper" @click="goAdsItem(imgAdsValue.list[0])"> |
||||
|
<image :style="{ height: imgAdsValue.list[0].imgHeight }" |
||||
|
:src="$util.img(imgAdsValue.list[0].imageUrl)" mode="widthFix"></image> |
||||
|
|
||||
|
<view v-if="imgAdsValue.list[0].heatMapData"> |
||||
|
<view class="heat-map" v-for="(mapItem, mapIndex) in imgAdsValue.list[0].heatMapData" |
||||
|
:key="mapIndex" :style="{ |
||||
|
width: mapItem.width + '%', |
||||
|
height: mapItem.height + '%', |
||||
|
left: mapItem.left + '%', |
||||
|
top: mapItem.top + '%' |
||||
|
}" @click.stop="$util.diyRedirectTo(mapItem.link)"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> v-else --> |
||||
|
<swiper class="swiper" :style="{ height: swiperHeight }" :class="{ |
||||
|
'swiper-left': imgAdsValue.indicatorLocation == 'left', |
||||
|
'swiper-right': imgAdsValue.indicatorLocation == 'right', |
||||
|
'ns-indicator-dots': imgAdsValue.carouselStyle == 'line' |
||||
|
}" circular="true" :indicator-dots="isDots" indicator-color="rgba(130, 130, 130, .5)" |
||||
|
:indicator-active-color="imgAdsValue.indicatorColor" @change="swiperChange"> |
||||
|
<swiper-item class="swiper-item" :style="imgAdsSwiper" v-for="(item, index) in imgAdsValue.list" :key="index" |
||||
|
v-if="item.imageUrl" @click="goAdsItem(item)"> |
||||
|
|
||||
|
<view class="item" style="display: flex;"> |
||||
|
<image :style="{ with: item.imgWidth + 'rpx', height: item.imgHeight + 'rpx' }" :src="$util.img(item.imageUrl)" |
||||
|
mode="scaleToFill"></image> |
||||
|
<!-- <img :src="$util.img(item.imageUrl)" alt="" /> --> |
||||
|
<!-- 热区功能 --> |
||||
|
<view v-if="item.heatMapData"> |
||||
|
<view class="heat-map" v-for="(mapItem, mapIndex) in item.heatMapData" :key="mapIndex" :style="{ |
||||
|
width: mapItem.width + '%', |
||||
|
height: mapItem.height + '%', |
||||
|
left: mapItem.left + '%', |
||||
|
top: mapItem.top + '%' |
||||
|
}" @click.stop="$util.diyRedirectTo(mapItem.link)"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</swiper-item> |
||||
|
</swiper> |
||||
|
<!-- #ifdef MP-WEIXIN || MP-ALIPAY --> |
||||
|
<view v-if="imgAdsValue.list.length > 1" :class="[ |
||||
|
'swiper-dot-box', |
||||
|
{ straightLine: imgAdsValue.carouselStyle == 'line' }, |
||||
|
{ 'swiper-left': imgAdsValue.indicatorLocation == 'left' }, |
||||
|
{ 'swiper-right': imgAdsValue.indicatorLocation == 'right' } |
||||
|
]"> |
||||
|
<view v-for="(numItem, numIndex) in imgAdsValue.list.length" :key="numIndex" |
||||
|
:class="['swiper-dot', { active: numIndex == swiperIndex }]" |
||||
|
:style="[numIndex == swiperIndex && { backgroundColor: imgAdsValue.indicatorColor }]"></view> |
||||
|
</view> |
||||
|
<!-- #endif --> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'diy-img-ads', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
isDots: true, |
||||
|
swiperHeight: 0, |
||||
|
imgAdsValue: null, // 深拷贝一遍数据,防止动态计算图片展示尺寸的时候,影响到父级的数据,导致二次渲染的时候,数据错误 |
||||
|
swiperIndex: 0 |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.calcSingleRow(); |
||||
|
}, |
||||
|
computed: { |
||||
|
imgAdsMarginWarp: function () { |
||||
|
var obj = ''; |
||||
|
obj = 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
return obj; |
||||
|
}, |
||||
|
imgAdsSwiper: function () { |
||||
|
var obj = ''; |
||||
|
if (this.value.componentAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
return obj; |
||||
|
}, |
||||
|
singleGraphBg: function () { |
||||
|
var imgArr = []; |
||||
|
for (let i = 0; i < this.imgAdsValue.list.length; i++) { |
||||
|
let item = this.imgAdsValue.list[i]; |
||||
|
imgArr[i] = parseFloat(item.imgHeight); |
||||
|
} |
||||
|
imgArr.sort(function (a, b) { |
||||
|
return b - a; |
||||
|
}); |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.imgAdsValue.backgroundColor + ';'; |
||||
|
obj += 'height:' + imgArr[0] * (this.imgAdsValue.backgroundHeight / 100) * 2 + 'rpx;'; |
||||
|
return obj; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
swiperChange(e) { |
||||
|
this.swiperIndex = e.detail.current; |
||||
|
}, |
||||
|
goAdsItem(item) { |
||||
|
console.log(item); |
||||
|
if (item.adv_id > 0) { |
||||
|
this.advpoint(item.adv_id) |
||||
|
} |
||||
|
|
||||
|
this.$util.diyRedirectTo(item.link) |
||||
|
}, |
||||
|
advpoint(adv_id) { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/adv/advpoint', |
||||
|
data: { |
||||
|
adv_id, |
||||
|
}, |
||||
|
success: res => { |
||||
|
|
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
calcSingleRow() { |
||||
|
let maxHeight = 0; |
||||
|
|
||||
|
// 深拷贝一层数据,防止数据更改越权 |
||||
|
this.imgAdsValue = JSON.parse(JSON.stringify(this.value)); |
||||
|
this.imgAdsValue.list.forEach((item, index) => { |
||||
|
uni.getSystemInfo({ |
||||
|
success: res => { |
||||
|
|
||||
|
// // #ifdef MP-ALIPAY |
||||
|
// let numH = item.imgHeight.slice(0, -3) |
||||
|
// var ratio = numH / item.imgWidth; |
||||
|
// item.imgWidth = res.windowWidth; |
||||
|
// item.imgWidth -= this.value.margin.both * 2; |
||||
|
// item.imgHeight = item.imgWidth * ratio + "rpx"; |
||||
|
// // #endif |
||||
|
// // #ifndef MP-ALIPAY |
||||
|
// var ratio = item.imgHeight / item.imgWidth; |
||||
|
// item.imgWidth = res.windowWidth; |
||||
|
// item.imgWidth -= this.value.margin.both * 2; |
||||
|
// item.imgHeight = item.imgWidth * ratio; |
||||
|
// // #endif |
||||
|
|
||||
|
|
||||
|
// // 固定 750 * 350 |
||||
|
item.imgWidth = 750 - this.value.margin.both * 2 |
||||
|
item.imgHeight = 350 * (item.imgWidth / 750) |
||||
|
this.swiperHeight = item.imgHeight + 'rpx'; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// 获取最大高度 |
||||
|
if (maxHeight == 0 || maxHeight < item.imgHeight) { |
||||
|
maxHeight = item.imgHeight; |
||||
|
} |
||||
|
}); |
||||
|
// this.imgAdsValue.list.forEach((item, index) => { |
||||
|
// item.imgHeight = maxHeight * 2 + 'rpx'; |
||||
|
// this.swiperHeight = maxHeight * 2 + 'rpx'; |
||||
|
// }); |
||||
|
this.imgAdsValue.indicatorColor = this.imgAdsValue.indicatorColor || '#fff'; |
||||
|
|
||||
|
// 是否显示指示器 |
||||
|
if (this.imgAdsValue.list.length <= 1) { |
||||
|
this.isDots = false; |
||||
|
} |
||||
|
|
||||
|
// #ifdef MP-WEIXIN || MP-ALIPAY |
||||
|
this.isDots = false; |
||||
|
// #endif |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.single-graph { |
||||
|
width: 100%; |
||||
|
line-height: 0; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.simple-graph-wrap { |
||||
|
line-height: 0; |
||||
|
overflow: hidden; |
||||
|
position: relative; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.heat-map { |
||||
|
position: absolute; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.item.active text { |
||||
|
background: rgba(0, 0, 0, 0.3); |
||||
|
position: absolute; |
||||
|
bottom: 0; |
||||
|
color: #ffffff; |
||||
|
font-size: $font-size-tag; |
||||
|
width: 100%; |
||||
|
left: 0; |
||||
|
line-height: 40rpx; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden; |
||||
|
padding: 0 10rpx; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.swiper-box { |
||||
|
position: relative; |
||||
|
width: 100%; |
||||
|
overflow: hidden; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.swiper { |
||||
|
margin: 0 auto; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.swiper-item { |
||||
|
width: 100%; |
||||
|
height: auto !important; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
flex-direction: column; |
||||
|
position: relative; |
||||
|
|
||||
|
.item { |
||||
|
width: 100%; |
||||
|
height: auto; |
||||
|
text-align: center; |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
max-width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.heat-map { |
||||
|
position: absolute; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.swiper-dot-box { |
||||
|
position: absolute; |
||||
|
bottom: 20rpx; |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
padding: 0 40rpx 8rpx; |
||||
|
box-sizing: border-box; |
||||
|
|
||||
|
&.swiper-left { |
||||
|
justify-content: flex-start; |
||||
|
} |
||||
|
|
||||
|
&.swiper-right { |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
|
||||
|
.swiper-dot { |
||||
|
background-color: #b2b2b2; |
||||
|
width: 15rpx; |
||||
|
border-radius: 50%; |
||||
|
height: 15rpx; |
||||
|
margin: 8rpx; |
||||
|
|
||||
|
&.active { |
||||
|
background-color: rgba(0, 0, 0, 1); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.straightLine { |
||||
|
.swiper-dot { |
||||
|
width: 18rpx; |
||||
|
height: 6rpx; |
||||
|
border-radius: 4rpx; |
||||
|
|
||||
|
&.active { |
||||
|
width: 36rpx; |
||||
|
background-color: rgba(0, 0, 0, 1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */ |
||||
|
/deep/.uni-scroll-view::-webkit-scrollbar { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
.swiper /deep/ .uni-swiper-dots-horizontal { |
||||
|
bottom: 25rpx; |
||||
|
} |
||||
|
|
||||
|
.swiper-left /deep/ .uni-swiper-dots-horizontal { |
||||
|
left: 40rpx; |
||||
|
transform: translate(0); |
||||
|
} |
||||
|
|
||||
|
.swiper-right /deep/ .uni-swiper-dots-horizontal { |
||||
|
right: 40rpx; |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
transform: translate(0); |
||||
|
} |
||||
|
|
||||
|
.carousel-angle /deep/ .uni-swiper-dots-horizontal .uni-swiper-dot { |
||||
|
width: 24rpx; |
||||
|
border-radius: 0; |
||||
|
height: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.swiper /deep/ .swiper-item .item uni-image>div { |
||||
|
background-size: cover !important; |
||||
|
} |
||||
|
|
||||
|
.swiper.ns-indicator-dots /deep/ .uni-swiper-dot { |
||||
|
width: 18rpx; |
||||
|
height: 6rpx; |
||||
|
border-radius: 4rpx; |
||||
|
} |
||||
|
|
||||
|
.swiper.ns-indicator-dots /deep/ .uni-swiper-dot-active { |
||||
|
width: 36rpx; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,692 @@ |
|||||
|
<template> |
||||
|
<scroll-view scroll-y="true" :style="{ height: scrollHeight }" @scroll="scroll" :scroll-top="scrollTop" @scrolltolower="scrolltolower"> |
||||
|
<view class="bg" :style="warpCss"> |
||||
|
<view class="nav_top_category"> |
||||
|
<scroll-view class="diyIndex widthAuto" @click="changePageIndex(0)"> |
||||
|
<view |
||||
|
class="item text-fiexd" |
||||
|
:class="{ fill: value.styleType == 'fill' }" |
||||
|
:style="{ background: pageIndex == 0 && value.styleType == 'fill' ? value.selectColor : '' }" |
||||
|
> |
||||
|
<view |
||||
|
class="text-con" |
||||
|
:class="pageIndex == 0 ? 'active' : ''" |
||||
|
:style="{ |
||||
|
color: index == pageIndex ? '' : value.noColor |
||||
|
}" |
||||
|
v-if="value.styleType == 'fill'" |
||||
|
> |
||||
|
{{ cateList[0].short_name ? cateList[0].short_name : cateList[0].category_name }} |
||||
|
</view> |
||||
|
<view |
||||
|
class="text-con" |
||||
|
:class="pageIndex == 0 ? 'active' : ''" |
||||
|
:style="{ |
||||
|
color: pageIndex == 0 ? value.selectColor : value.noColor |
||||
|
}" |
||||
|
v-else |
||||
|
> |
||||
|
{{ cateList[0].short_name ? cateList[0].short_name : cateList[0].category_name }} |
||||
|
</view> |
||||
|
<view |
||||
|
class="color-base-bg line" |
||||
|
v-if="pageIndex == 0 && value.styleType != 'fill'" |
||||
|
:style="{ background: value.selectColor ? value.selectColor + '!important' : 'rgba(0,0,0,0)' + '!important' }" |
||||
|
></view> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
|
||||
|
<scroll-view |
||||
|
v-if="value" |
||||
|
scroll-with-animation |
||||
|
class="diyIndex" |
||||
|
scroll-x="true" |
||||
|
:scroll-into-view="'a' + pageIndex" |
||||
|
:style="{ background: value.backgroundColor ? value.backgroundColor : '', width: 'calc(100% - 102rpx)' }" |
||||
|
> |
||||
|
<view |
||||
|
class="item" |
||||
|
:id="'a' + index" |
||||
|
v-for="(item, index) in cateList" |
||||
|
:key="index" |
||||
|
@click="changePageIndex(index)" |
||||
|
:class="{ fill: value.styleType == 'fill' }" |
||||
|
:style="{ background: index == pageIndex && value.styleType == 'fill' ? value.selectColor : '' }" |
||||
|
v-if="index > 0" |
||||
|
> |
||||
|
<view |
||||
|
class="text-con" |
||||
|
:class="index == pageIndex ? 'active' : ''" |
||||
|
:style="{ |
||||
|
color: index == pageIndex ? '' : value.noColor |
||||
|
}" |
||||
|
v-if="value.styleType == 'fill'" |
||||
|
> |
||||
|
{{ item.short_name ? item.short_name : item.category_name }} |
||||
|
</view> |
||||
|
<view |
||||
|
class="text-con" |
||||
|
:class="index == pageIndex ? 'active' : ''" |
||||
|
:style="{ |
||||
|
color: index == pageIndex ? value.selectColor : value.noColor |
||||
|
}" |
||||
|
v-else |
||||
|
> |
||||
|
{{ item.short_name ? item.short_name : item.category_name }} |
||||
|
</view> |
||||
|
<view |
||||
|
class="color-base-bg line" |
||||
|
v-if="index == pageIndex && value.styleType != 'fill'" |
||||
|
:style="{ background: value.selectColor ? value.selectColor + '!important' : 'rgba(0,0,0,0)' + '!important' }" |
||||
|
></view> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="index-page-content" :style="{ height: scrollTopHeight }"> |
||||
|
<block v-if="pageIndex == 0"><slot></slot></block> |
||||
|
<block v-else> |
||||
|
<view class="index-category-box"> |
||||
|
<!-- 二级分类 --> |
||||
|
<view class="twoCategorylist" v-if="twoCategorylist != 'undefined' && twoCategorylist && twoCategorylist.length > 0"> |
||||
|
<view class="twoCategory min" v-if="twoCategorylist.length <= 5"> |
||||
|
<view class="twoCategory-page"> |
||||
|
<view class="swiper-item" v-for="(item, index) in twoCategorylist" :key="index" @click="toCateGoodsList(item.category_id_2, 2)"> |
||||
|
<view class="item-box"> |
||||
|
<image :src="$util.img(item.image)" v-if="item.image" mode="aspectFill"></image> |
||||
|
<image :src="$util.getDefaultImage().goods" v-else mode="aspectFill"></image> |
||||
|
<view>{{ item.category_name }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="twoCategory base" v-if="twoCategorylist.length > 5 && twoCategorylist.length <= 10"> |
||||
|
<view class="twoCategory-page"> |
||||
|
<view class="swiper-item" v-for="(item, index) in twoCategorylist" :key="index" @click="toCateGoodsList(item.category_id_2, 2)"> |
||||
|
<view class="item-box"> |
||||
|
<image :src="$util.img(item.image)" v-if="item.image" mode="aspectFill"></image> |
||||
|
<image :src="$util.getDefaultImage().goods" v-else mode="aspectFill"></image> |
||||
|
<view>{{ item.category_name }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<swiper class="twoCategory big" :duration="500" v-if="twoCategorylist.length > 10" @change="swiperTocategoryChange"> |
||||
|
<swiper-item class="twoCategory-page" v-for="page in maxPage" :key="page"> |
||||
|
<view |
||||
|
class="swiper-item" |
||||
|
v-for="(item, index) in twoCategorylist" |
||||
|
:key="index" |
||||
|
v-if="index >= (page - 1) * 10 && index < page * 10" |
||||
|
@click="toCateGoodsList(item.category_id_2, 2)" |
||||
|
> |
||||
|
<view class="item-box"> |
||||
|
<image :src="item.image" mode="aspectFill"></image> |
||||
|
<view>{{ item.category_name }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</swiper-item> |
||||
|
</swiper> |
||||
|
<view class="dot-box"> |
||||
|
<view |
||||
|
class="dot-item" |
||||
|
v-for="page in maxPage" |
||||
|
v-if="maxPage > 1" |
||||
|
:key="page" |
||||
|
:class="twoCategorylistId == page - 1 ? 'active color-base-bg' : ''" |
||||
|
></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!-- 分类广告 --> |
||||
|
<image class="category_adv ns-margin" v-if="cateList[pageIndex].image_adv" :src="$util.img(cateList[pageIndex].image_adv)" mode="widthFix"></image> |
||||
|
|
||||
|
<view class="category-goods" v-show="!isloading"> |
||||
|
<view class="goods-list double-column" v-if="goodsList[pageIndex].list.length"> |
||||
|
<view class="goods-item" v-for="(item, index) in goodsList[pageIndex].list" :key="index" @click="toDetail(item)"> |
||||
|
<view class="goods-img"> |
||||
|
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"></image> |
||||
|
<view class="color-base-bg goods-tag" v-if="value.goodsTag == 'default' && goodsTag(item) != ''">{{ goodsTag(item) }}</view> |
||||
|
<view class="goods-tag-img" v-if="value.goodsTag == 'diy'"><image :src="$util.img(value.tagImg.imageUrl)" mode=""></image></view> |
||||
|
</view> |
||||
|
<view class="info-wrap"> |
||||
|
<view class="name-wrap"> |
||||
|
<view class="goods-name">{{ item.goods_name }}</view> |
||||
|
</view> |
||||
|
<view class="pro-info"> |
||||
|
<view class="delete-price font-size-activity-tag color-tip"> |
||||
|
<text class="unit">{{ $lang('common.currencySymbol') }}</text> |
||||
|
{{ item.market_price > 0 ? item.market_price : item.price }} |
||||
|
</view> |
||||
|
<view class="sale font-size-activity-tag color-tip">已售{{ item.sale_num }}{{ item.unit ? item.unit : '件' }}</view> |
||||
|
</view> |
||||
|
<view class="lineheight-clear"> |
||||
|
<view class="discount-price"> |
||||
|
<text class="unit color-base-text font-size-tag">{{ $lang('common.currencySymbol') }}</text> |
||||
|
<text class="price color-base-text font-size-toolbar">{{ showPrice(item) }}</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"></image> |
||||
|
</view> |
||||
|
<view class="member-price-tag" v-else-if="item.promotion_type == 1"> |
||||
|
<image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<ns-empty v-else-if="!isloading" :isIndex="false" text="该分类下暂无商品"></ns-empty> |
||||
|
</view> |
||||
|
<view class="loading" v-show="isloading"><ns-loading ref="loading"></ns-loading></view> |
||||
|
</view> |
||||
|
</block> |
||||
|
</view> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import nsLoading from '@/components/ns-loading/ns-loading.vue'; |
||||
|
export default { |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
}, |
||||
|
scrollHeight: { |
||||
|
type: String |
||||
|
}, |
||||
|
scrollTopHeight: { |
||||
|
type: String |
||||
|
}, |
||||
|
bgUrl: { |
||||
|
type: String |
||||
|
} |
||||
|
}, |
||||
|
components: { |
||||
|
nsLoading |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
pageIndex: 0, //当前选中分类id |
||||
|
cateList: [ |
||||
|
{ |
||||
|
//header分类 |
||||
|
category_name: '首页' |
||||
|
} |
||||
|
], |
||||
|
twoCategorylist: [], //二级分类 |
||||
|
twoCategorylistId: 0, //二级分类所在的swiper |
||||
|
goodsList: {}, |
||||
|
scrollTop: 0, |
||||
|
scrollTopCopy: 0, |
||||
|
isloading: true |
||||
|
}; |
||||
|
}, |
||||
|
computed: { |
||||
|
warpCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
obj += this.bgUrl ? 'background:' + 'url(' + this.$util.img(this.bgUrl) + ') no-repeat 0 0/100%' : ''; |
||||
|
return obj; |
||||
|
}, |
||||
|
maxPage() { |
||||
|
let num = 0; |
||||
|
if (this.twoCategorylist && this.twoCategorylist.length) { |
||||
|
num = Math.ceil(this.twoCategorylist.length / 10); |
||||
|
} |
||||
|
return num; |
||||
|
}, |
||||
|
type() { |
||||
|
if (this.value) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
type(newVal, oldVal) { |
||||
|
if (newVal) { |
||||
|
this.getCategoryList(); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.getCategoryList(); |
||||
|
}, |
||||
|
methods: { |
||||
|
initPageIndex() { |
||||
|
this.pageIndex = 0; |
||||
|
}, |
||||
|
//请求分类列表 |
||||
|
getCategoryList() { |
||||
|
let url = '/api/goodscategory/tree'; |
||||
|
let data = { |
||||
|
level: 3, |
||||
|
template: 2 |
||||
|
}; |
||||
|
this.$api.sendRequest({ |
||||
|
url: url, |
||||
|
data: data, |
||||
|
success: res => { |
||||
|
if (res.code >= 0) { |
||||
|
let arr = []; |
||||
|
let obj = { |
||||
|
list: [], |
||||
|
isAll: false |
||||
|
}; |
||||
|
obj.category_name = this.value.title ? this.value.title : '首页'; |
||||
|
arr.push(obj); |
||||
|
this.cateList = arr.concat(res.data); |
||||
|
Object.keys(this.cateList).forEach((key, index) => { |
||||
|
this.goodsList[key] = { |
||||
|
page: 1, |
||||
|
list: [], |
||||
|
isAll: false |
||||
|
}; |
||||
|
}); |
||||
|
this.twoCategorylist = this.cateList[this.pageIndex].child_list; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
//修改当前页面id |
||||
|
changePageIndex(e) { |
||||
|
this.isloading = true; |
||||
|
this.pageIndex = e; |
||||
|
if (e == 0) return; |
||||
|
this.twoCategorylist = this.cateList[this.pageIndex].child_list; |
||||
|
this.twoCategorylist = this.cateList[this.pageIndex].child_list; |
||||
|
if (this.cateList[this.pageIndex].child_list) { |
||||
|
this.twoCategorylist = this.cateList[this.pageIndex].child_list; |
||||
|
this.twoCategorylist.forEach(v => { |
||||
|
if (v.image) { |
||||
|
v.image = this.$util.img(v.image); |
||||
|
} else { |
||||
|
v.image = this.$util.getDefaultImage().goods; |
||||
|
} |
||||
|
}); |
||||
|
} else { |
||||
|
this.twoCategorylist = false; |
||||
|
} |
||||
|
let id = e; |
||||
|
if (this.goodsList[id] && this.goodsList[id].length) return; |
||||
|
this.scrollTop = this.scrollTopCopy; |
||||
|
this.$nextTick(function() { |
||||
|
this.scrollTop = 0; |
||||
|
}); |
||||
|
this.getGoodsList(); |
||||
|
}, |
||||
|
|
||||
|
//swiper 监听变化 |
||||
|
swiperChange(e) { |
||||
|
this.changePageIndex(e.detail.current); |
||||
|
}, |
||||
|
|
||||
|
//监听二级分类 页面切换 |
||||
|
swiperTocategoryChange(e) { |
||||
|
this.twoCategorylistId = e.detail.current; |
||||
|
}, |
||||
|
|
||||
|
toDetail(item) { |
||||
|
this.$util.redirectTo('/page_goods/detail/detail', { |
||||
|
goods_id: item.goods_id |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
scroll(e) { |
||||
|
this.scrollTopCopy = e.detail.scrollTop; |
||||
|
}, |
||||
|
|
||||
|
getGoodsList() { |
||||
|
let id = this.pageIndex; |
||||
|
var data = { |
||||
|
page: this.goodsList[id].page, |
||||
|
page_size: 10 |
||||
|
}; |
||||
|
data.category_id = this.cateList[this.pageIndex].category_id_1; |
||||
|
data.category_level = 1; |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/goodssku/page', |
||||
|
data: data, |
||||
|
success: res => { |
||||
|
this.isloading = false; |
||||
|
if (res.code == 0 && res.data) { |
||||
|
this.goodsList[id].list = this.goodsList[id].list.concat(res.data.list); |
||||
|
if (this.goodsList[id].list.length == res.data.count) { |
||||
|
this.goodsList[id].isAll = true; |
||||
|
} |
||||
|
this.goodsList[id].page += 1; |
||||
|
} |
||||
|
this.$forceUpdate(); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
//滚动到底部 |
||||
|
scrolltolower() { |
||||
|
let id = this.pageIndex; |
||||
|
if (this.goodsList[id].isAll) return; |
||||
|
this.isloading = true; |
||||
|
this.getGoodsList(); |
||||
|
}, |
||||
|
toCateGoodsList(e, f) { |
||||
|
this.$util.redirectTo('/page_goods/goodsList/goodsList', { category_id: e, category_level: f }); |
||||
|
}, |
||||
|
goodsImg(imgStr) { |
||||
|
let imgs = imgStr.split(','); |
||||
|
return imgs[0] ? this.$util.img(imgs[0], { size: 'mid' }) : this.$util.getDefaultImage().goods; |
||||
|
}, |
||||
|
imgError(index) { |
||||
|
this.goodsList[index].goods_image = this.$util.getDefaultImage().goods; |
||||
|
}, |
||||
|
showPrice(data) { |
||||
|
let price = data.discount_price; |
||||
|
if (data.member_price && parseFloat(data.member_price) < parseFloat(price)) price = data.member_price; |
||||
|
return price; |
||||
|
}, |
||||
|
goodsTag(data) { |
||||
|
return data.label_name || ''; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.bg { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
padding: 0 30rpx; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
.nav_top_category { |
||||
|
display: flex; |
||||
|
.text-fiexd { |
||||
|
.text-con { |
||||
|
line-height: 60rpx; |
||||
|
// &.active{ |
||||
|
// line-height: 1.8; |
||||
|
// } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.diyIndex { |
||||
|
width: 100%; |
||||
|
height: 100rpx; |
||||
|
white-space: nowrap; |
||||
|
padding: 20rpx 0 0; |
||||
|
box-sizing: border-box; |
||||
|
&.widthAuto { |
||||
|
width: auto; |
||||
|
} |
||||
|
.item { |
||||
|
padding: 0 20rpx; |
||||
|
display: inline-block; |
||||
|
line-height: 80rpx; |
||||
|
font-size: $font-size-base; |
||||
|
text-align: center; |
||||
|
.text-con { |
||||
|
height: 60rpx; |
||||
|
line-height: 60rpx; |
||||
|
} |
||||
|
.text-con.active { |
||||
|
font-size: $font-size-toolbar; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
.line { |
||||
|
width: 100%; |
||||
|
height: 5rpx; |
||||
|
border-radius: 5rpx; |
||||
|
} |
||||
|
&.fill { |
||||
|
border-radius: 50rpx; |
||||
|
.text-con.active { |
||||
|
font-size: $font-size-base; |
||||
|
font-weight: 600; |
||||
|
color: #fff; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.index-page-box { |
||||
|
width: 100%; |
||||
|
height: calc(100vh - 288rpx); |
||||
|
} |
||||
|
.index-page-content { |
||||
|
width: 100%; |
||||
|
// height: calc(100vh - 144px); |
||||
|
} |
||||
|
|
||||
|
.index-category-box.active { |
||||
|
padding-bottom: 160rpx; |
||||
|
padding-bottom: calc(160rpx + constant(safe-area-inset-bottom)); |
||||
|
padding-bottom: calc(160rpx + env(safe-area-inset-bottom)); |
||||
|
} |
||||
|
.index-category-box { |
||||
|
width: 100%; |
||||
|
padding-bottom: 110rpx; |
||||
|
padding-bottom: calc(110rpx + constant(safe-area-inset-bottom)); |
||||
|
padding-bottom: calc(110rpx + env(safe-area-inset-bottom)); |
||||
|
.twoCategorylist { |
||||
|
position: relative; |
||||
|
} |
||||
|
.twoCategory.min { |
||||
|
height: 160rpx; |
||||
|
} |
||||
|
.twoCategory.big { |
||||
|
height: 340rpx; |
||||
|
} |
||||
|
.twoCategory { |
||||
|
width: 100%; |
||||
|
background: #ffffff; |
||||
|
border-radius: 15rpx; |
||||
|
overflow: hidden; |
||||
|
margin-top: 20rpx; |
||||
|
.twoCategory-page { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
padding: 20rpx; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
.swiper-item { |
||||
|
width: 120rpx; |
||||
|
height: 120rpx; |
||||
|
display: inline-block; |
||||
|
margin-right: calc((100% - 120rpx * 5) / 4); |
||||
|
overflow: hidden; |
||||
|
.item-box { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
flex-direction: column; |
||||
|
image { |
||||
|
width: 88rpx; |
||||
|
height: 88rpx; |
||||
|
} |
||||
|
view { |
||||
|
width: 100%; |
||||
|
font-size: 22rpx; |
||||
|
line-height: 1; |
||||
|
margin-top: 10rpx; |
||||
|
display: -webkit-box; |
||||
|
-webkit-box-orient: vertical; |
||||
|
-webkit-line-clamp: 1; |
||||
|
overflow: hidden; |
||||
|
text-align: center; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.swiper-item:nth-child(5n) { |
||||
|
margin-right: 0; |
||||
|
} |
||||
|
.swiper-item:nth-child(10n + 6) { |
||||
|
margin-top: 15rpx; |
||||
|
} |
||||
|
} |
||||
|
.dot-box { |
||||
|
width: calc(100% - 40rpx); |
||||
|
height: 50rpx; |
||||
|
position: absolute; |
||||
|
bottom: 0rpx; |
||||
|
left: 20rpx; |
||||
|
background: rgba($color: #000000, $alpha: 0); |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
.dot-item { |
||||
|
width: 12rpx; |
||||
|
height: 12rpx; |
||||
|
background: #cccccc; |
||||
|
border-radius: 6rpx; |
||||
|
margin-right: 10rpx; |
||||
|
} |
||||
|
.dot-item.active { |
||||
|
width: 24rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.category_adv { |
||||
|
width: calc(100%); |
||||
|
margin-bottom: 0; |
||||
|
border-radius: 15rpx; |
||||
|
} |
||||
|
|
||||
|
.category-goods { |
||||
|
width: 100%; |
||||
|
} |
||||
|
} |
||||
|
.loading { |
||||
|
width: 100%; |
||||
|
height: 50rpx; |
||||
|
} |
||||
|
|
||||
|
/deep/.uni-scroll-view::-webkit-scrollbar { |
||||
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */ |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
.goods-list.double-column { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
margin-top: $margin-updown; |
||||
|
|
||||
|
.goods-item { |
||||
|
flex: 1; |
||||
|
position: relative; |
||||
|
background-color: #fff; |
||||
|
flex-basis: 48%; |
||||
|
max-width: calc((100% - 30rpx) / 2); |
||||
|
margin-right: $margin-both; |
||||
|
margin-bottom: $margin-updown; |
||||
|
border-radius: $border-radius; |
||||
|
|
||||
|
&:nth-child(2n) { |
||||
|
margin-right: 0; |
||||
|
} |
||||
|
|
||||
|
.goods-img { |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
padding-top: 100%; |
||||
|
border-top-left-radius: $border-radius; |
||||
|
border-top-right-radius: $border-radius; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
left: 0; |
||||
|
transform: translateY(-50%); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.goods-tag { |
||||
|
color: #fff; |
||||
|
line-height: 1; |
||||
|
padding: 8rpx 16rpx; |
||||
|
position: absolute; |
||||
|
border-bottom-right-radius: $border-radius; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
font-size: $font-size-goods-tag; |
||||
|
} |
||||
|
|
||||
|
.goods-tag-img { |
||||
|
position: absolute; |
||||
|
border-top-left-radius: $border-radius; |
||||
|
width: 80rpx; |
||||
|
height: 80rpx; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
z-index: 5; |
||||
|
overflow: hidden; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.info-wrap { |
||||
|
padding: 0 26rpx 26rpx 26rpx; |
||||
|
} |
||||
|
|
||||
|
.goods-name { |
||||
|
font-size: $font-size-base; |
||||
|
line-height: 1.3; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
display: -webkit-box; |
||||
|
-webkit-line-clamp: 2; |
||||
|
-webkit-box-orient: vertical; |
||||
|
margin-top: 20rpx; |
||||
|
height: 68rpx; |
||||
|
} |
||||
|
|
||||
|
.discount-price { |
||||
|
display: inline-block; |
||||
|
font-weight: bold; |
||||
|
line-height: 1; |
||||
|
margin-top: 16rpx; |
||||
|
|
||||
|
.unit { |
||||
|
margin-right: 6rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.pro-info { |
||||
|
display: flex; |
||||
|
margin-top: 16rpx; |
||||
|
|
||||
|
.delete-price { |
||||
|
text-decoration: line-through; |
||||
|
flex: 1; |
||||
|
|
||||
|
.unit { |
||||
|
margin-right: 6rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
& > view { |
||||
|
line-height: 1; |
||||
|
|
||||
|
&:nth-child(2) { |
||||
|
text-align: right; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.member-price-tag { |
||||
|
display: inline-block; |
||||
|
width: 60rpx; |
||||
|
line-height: 1; |
||||
|
margin-left: 6rpx; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,249 @@ |
|||||
|
<template> |
||||
|
<view class="many-goods-list"> |
||||
|
<u-tabs class="utabs" @change="tabsChange" keyName="title" :list="value.list" :current="cateIndex" |
||||
|
lineColor="var(--base-color)" :activeStyle="{ |
||||
|
color: '#303133', |
||||
|
fontWeight: 'bold', |
||||
|
transform: 'scale(1.15)' |
||||
|
}" :inactiveStyle="{ |
||||
|
color: '#999', |
||||
|
transform: 'scale(1)' |
||||
|
}"></u-tabs> |
||||
|
|
||||
|
<!-- <div style="height: 24rpx;"></div> --> |
||||
|
|
||||
|
<!-- <scroll-view scroll-x="true" :scroll-into-view="'a' + cateIndex"> |
||||
|
<view |
||||
|
v-for="(item, index) in value.list" |
||||
|
class="scroll-item" |
||||
|
:class="{ active: index == cateIndex }" |
||||
|
:id="'a' + index" |
||||
|
:key="index" |
||||
|
@click="changeCateIndex(item, index)" |
||||
|
> |
||||
|
<view class="item-wrap"> |
||||
|
<view class="split-line" v-if="index > 0"></view> |
||||
|
<view class="cate"> |
||||
|
<view class="name">{{ item.title }}</view> |
||||
|
<view class="desc" :class="{ 'color-base-bg': index == cateIndex && item.desc }">{{ item.desc }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
--> |
||||
|
<diy-goods-list v-show="cateIndex==0" :value.sync="goodsValue0" ref="diyGoodsList0"> |
||||
|
</diy-goods-list> |
||||
|
<!-- <diy-goods-list v-if="cateIndex==0" :value.sync="goodsValue0" ref="diyGoodsList0"> |
||||
|
</diy-goods-list> --> |
||||
|
|
||||
|
<diy-goods-list v-show="cateIndex==1" :value.sync="goodsValue1" ref="diyGoodsList1"> |
||||
|
</diy-goods-list> |
||||
|
<diy-goods-list v-show="cateIndex==2" :value.sync="goodsValue2" ref="diyGoodsList2"> |
||||
|
</diy-goods-list> |
||||
|
<diy-goods-list v-show="cateIndex==3" :value.sync="goodsValue3" ref="diyGoodsList3"> |
||||
|
</diy-goods-list> |
||||
|
<diy-goods-list v-show="cateIndex==4" :value.sync="goodsValue4" ref="diyGoodsList4"> |
||||
|
</diy-goods-list> |
||||
|
<diy-goods-list v-show="cateIndex==5" :value.sync="goodsValue5" ref="diyGoodsList5"> |
||||
|
</diy-goods-list> |
||||
|
|
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'diy-many-goods-list', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
cateIndex: 0, // 当前选中的分类id |
||||
|
goodsValue0: null, // 商品列表数据 |
||||
|
goodsValue1: null, |
||||
|
goodsValue2: null, |
||||
|
goodsValue3: null, |
||||
|
goodsValue4: null, |
||||
|
goodsValue5: null, |
||||
|
|
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.goodsValue0 = this.value.list[0] |
||||
|
this.goodsValue1 = this.value.list[1] |
||||
|
this.goodsValue2 = this.value.list[2] |
||||
|
this.goodsValue3 = this.value.list[3] |
||||
|
this.goodsValue4 = this.value.list[4] |
||||
|
this.goodsValue5 = this.value.list[5] |
||||
|
console.log(this.value, '组件的总数据'); |
||||
|
this.changeCateIndex(this.value.list[0], 0, true); |
||||
|
// this.changeCateIndex(this.value.list[0], 0); |
||||
|
}, |
||||
|
mounted() { |
||||
|
// this.$nextTick(_ => { |
||||
|
// this.changeCateIndex(this.value.list[0], 0, true); |
||||
|
// }) |
||||
|
}, |
||||
|
methods: { |
||||
|
|
||||
|
tabsChange(e) { |
||||
|
this.changeCateIndex(e, e.index, true); |
||||
|
}, |
||||
|
|
||||
|
changeCateIndex(item, index, isFirst) { |
||||
|
|
||||
|
console.log(this.cateIndex, '之前的tab'); |
||||
|
this.cateIndex = Number(item.newCategoryId) - 1; |
||||
|
console.log(this.cateIndex, '之后的tab'); |
||||
|
this.goodsValue = {} |
||||
|
this["goodsValue" + index] = { |
||||
|
sources: item.sources, |
||||
|
categoryId: item.categoryId, |
||||
|
categoryName: item.categoryName, |
||||
|
newCategoryId: item.newCategoryId, |
||||
|
newCategoryName: item.newCategoryName, |
||||
|
goodsId: item.goodsId, |
||||
|
componentBgColor: this.value.componentBgColor, |
||||
|
componentAngle: this.value.componentAngle, |
||||
|
topAroundRadius: this.value.topAroundRadius, |
||||
|
bottomAroundRadius: this.value.bottomAroundRadius, |
||||
|
elementBgColor: this.value.elementBgColor, |
||||
|
elementAngle: this.value.elementAngle, |
||||
|
topElementAroundRadius: this.value.topElementAroundRadius, |
||||
|
bottomElementAroundRadius: this.value.bottomElementAroundRadius, |
||||
|
count: this.value.count, |
||||
|
nameLineMode: this.value.nameLineMode, |
||||
|
template: this.value.template, |
||||
|
style: this.value.style, |
||||
|
ornament: this.value.ornament, |
||||
|
sortWay: this.value.sortWay, |
||||
|
saleStyle: this.value.saleStyle, |
||||
|
tag: this.value.tag, |
||||
|
btnStyle: this.value.btnStyle, |
||||
|
goodsNameStyle: this.value.goodsNameStyle, |
||||
|
theme: this.value.theme, |
||||
|
priceStyle: this.value.priceStyle, |
||||
|
slideMode: this.value.slideMode, |
||||
|
imgAroundRadius: this.value.imgAroundRadius, |
||||
|
cartEvent: this.value.cartEvent, |
||||
|
cateName: this.cateIndex + 1, |
||||
|
tabsTitle: item.title, |
||||
|
pageStyle: this.value.pageStyle |
||||
|
}; |
||||
|
console.log("goodsValue" + index, '切换之后的数据'); |
||||
|
console.log(this["goodsValue" + index], '切换之后的数据源头'); |
||||
|
|
||||
|
// this.goodsValue0 = { |
||||
|
// sources: item.sources, |
||||
|
// categoryId: item.categoryId, |
||||
|
// categoryName: item.categoryName, |
||||
|
// newCategoryId: item.newCategoryId, |
||||
|
// newCategoryName: item.newCategoryName, |
||||
|
// goodsId: item.goodsId, |
||||
|
// componentBgColor: this.value.componentBgColor, |
||||
|
// componentAngle: this.value.componentAngle, |
||||
|
// topAroundRadius: this.value.topAroundRadius, |
||||
|
// bottomAroundRadius: this.value.bottomAroundRadius, |
||||
|
// elementBgColor: this.value.elementBgColor, |
||||
|
// elementAngle: this.value.elementAngle, |
||||
|
// topElementAroundRadius: this.value.topElementAroundRadius, |
||||
|
// bottomElementAroundRadius: this.value.bottomElementAroundRadius, |
||||
|
// count: this.value.count, |
||||
|
// nameLineMode: this.value.nameLineMode, |
||||
|
// template: this.value.template, |
||||
|
// style: this.value.style, |
||||
|
// ornament: this.value.ornament, |
||||
|
// sortWay: this.value.sortWay, |
||||
|
// saleStyle: this.value.saleStyle, |
||||
|
// tag: this.value.tag, |
||||
|
// btnStyle: this.value.btnStyle, |
||||
|
// goodsNameStyle: this.value.goodsNameStyle, |
||||
|
// theme: this.value.theme, |
||||
|
// priceStyle: this.value.priceStyle, |
||||
|
// slideMode: this.value.slideMode, |
||||
|
// imgAroundRadius: this.value.imgAroundRadius, |
||||
|
// cartEvent: this.value.cartEvent, |
||||
|
// cateName: this.cateIndex + 1, |
||||
|
// tabsTitle: item.title, |
||||
|
// pageStyle: this.value.pageStyle |
||||
|
// }; |
||||
|
// 如果是第一次加载,不需要执行下面代码 |
||||
|
// #ifdef APP |
||||
|
if (isFirst) return; |
||||
|
// #endif |
||||
|
// // #ifndef APP |
||||
|
// if (this["goodsValue" + index].goodsId > 20) { |
||||
|
// if (isFirst) return; |
||||
|
// } |
||||
|
// // #endif |
||||
|
|
||||
|
|
||||
|
|
||||
|
this.$refs["diyGoodsList" + index].goodsValue = this["goodsValue" + index]; |
||||
|
this.$refs["diyGoodsList" + index].list = []; |
||||
|
this.$refs["diyGoodsList" + index].getGoodsList(); |
||||
|
this.$refs["diyGoodsList" + index].page = 1; |
||||
|
this.$refs["diyGoodsList" + index].nodata = false; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
scroll-view { |
||||
|
width: 100%; |
||||
|
white-space: nowrap; |
||||
|
box-sizing: border-box; |
||||
|
padding: 40rpx 20rpx; |
||||
|
|
||||
|
.scroll-item { |
||||
|
display: inline-block; |
||||
|
text-align: center; |
||||
|
vertical-align: top; |
||||
|
|
||||
|
.item-wrap { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.split-line { |
||||
|
display: inline-block; |
||||
|
width: 1rpx; |
||||
|
height: 30rpx; |
||||
|
// background-color: #e5e5e5; |
||||
|
margin: 0 20rpx; |
||||
|
} |
||||
|
|
||||
|
&.active { |
||||
|
.name { |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.desc { |
||||
|
color: #ffffff; |
||||
|
border-radius: 20rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.name { |
||||
|
font-size: 32rpx; |
||||
|
color: $color-title; |
||||
|
line-height: 1; |
||||
|
} |
||||
|
|
||||
|
.desc { |
||||
|
font-size: $font-size-tag; |
||||
|
color: $color-tip; |
||||
|
height: 36rpx; |
||||
|
line-height: 36rpx; |
||||
|
margin-top: 10rpx; |
||||
|
min-width: 120rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
File diff suppressed because it is too large
@ -0,0 +1,340 @@ |
|||||
|
<template> |
||||
|
<view class="common-wrap" :style="warpCss"> |
||||
|
<view class="order-wrap"> |
||||
|
<view class="status-wrap"> |
||||
|
<view class="item-wrap" @click="redirect('/pages/order/list?status=waitpay')"> |
||||
|
<view class="icon-block"> |
||||
|
<template v-if="value.style == 3"> |
||||
|
<image |
||||
|
:src="$util.img('public/uniapp/member/order/wait_pay.png')" |
||||
|
mode="widthFix" |
||||
|
></image> |
||||
|
<view |
||||
|
class="icon-shade" |
||||
|
:style=" |
||||
|
'-webkit-mask-image: url(' + |
||||
|
$util.img('public/uniapp/member/order/wait_pay_shade.png') + |
||||
|
')' |
||||
|
" |
||||
|
></view> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<diy-icon |
||||
|
:icon="value.icon.waitPay.icon" |
||||
|
v-if="value.icon.waitPay" |
||||
|
:value="value.icon.waitPay.style ? value.icon.waitPay.style : null" |
||||
|
></diy-icon> |
||||
|
</template> |
||||
|
<text |
||||
|
v-if="orderNum.waitpay > 0" |
||||
|
class="order-num color-base-bg price-font" |
||||
|
> |
||||
|
{{ orderNum.waitpay > 99 ? '99+' : orderNum.waitpay }} |
||||
|
</text> |
||||
|
</view> |
||||
|
<view class="title">待付款</view> |
||||
|
</view> |
||||
|
<view class="item-wrap" @click="redirect('/pages/order/list?status=waitsend')"> |
||||
|
<view class="icon-block"> |
||||
|
<template v-if="value.style == 3"> |
||||
|
<image |
||||
|
:src="$util.img('public/uniapp/member/order/wait_send.png')" |
||||
|
mode="widthFix" |
||||
|
></image> |
||||
|
<view |
||||
|
class="icon-shade" |
||||
|
:style=" |
||||
|
'-webkit-mask-image: url(' + |
||||
|
$util.img( |
||||
|
'public/uniapp/member/order/wait_send_shade.png' |
||||
|
) + |
||||
|
')' |
||||
|
" |
||||
|
></view> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<diy-icon |
||||
|
:icon="value.icon.waitSend.icon" |
||||
|
v-if="value.icon.waitSend" |
||||
|
:value=" |
||||
|
value.icon.waitSend.style ? value.icon.waitSend.style : null |
||||
|
" |
||||
|
></diy-icon> |
||||
|
</template> |
||||
|
<text |
||||
|
v-if="orderNum.waitsend > 0" |
||||
|
class="order-num color-base-bg price-font" |
||||
|
> |
||||
|
{{ orderNum.waitsend > 99 ? '99+' : orderNum.waitsend }} |
||||
|
</text> |
||||
|
</view> |
||||
|
<view class="title">待发货</view> |
||||
|
</view> |
||||
|
<view class="item-wrap" @click="redirect('/pages/order/list?status=waitconfirm')"> |
||||
|
<view class="icon-block"> |
||||
|
<template v-if="value.style == 3"> |
||||
|
<image |
||||
|
:src="$util.img('public/uniapp/member/order/wait_confirm.png')" |
||||
|
mode="widthFix" |
||||
|
></image> |
||||
|
<view |
||||
|
class="icon-shade" |
||||
|
:style=" |
||||
|
'-webkit-mask-image: url(' + |
||||
|
$util.img( |
||||
|
'public/uniapp/member/order/wait_confirm_shade.png' |
||||
|
) + |
||||
|
')' |
||||
|
" |
||||
|
></view> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<diy-icon |
||||
|
:icon="value.icon.waitConfirm.icon" |
||||
|
v-if="value.icon.waitConfirm" |
||||
|
:value=" |
||||
|
value.icon.waitConfirm.style |
||||
|
? value.icon.waitConfirm.style |
||||
|
: null |
||||
|
" |
||||
|
></diy-icon> |
||||
|
</template> |
||||
|
<text |
||||
|
v-if="orderNum.waitconfirm > 0" |
||||
|
class="order-num color-base-bg price-font" |
||||
|
> |
||||
|
{{ orderNum.waitconfirm > 99 ? '99+' : orderNum.waitconfirm }} |
||||
|
</text> |
||||
|
</view> |
||||
|
<view class="title">待收货</view> |
||||
|
</view> |
||||
|
<view class="item-wrap" @click="redirect('/pages/order/list?status=waitrate')"> |
||||
|
<view class="icon-block"> |
||||
|
<template v-if="value.style == 3"> |
||||
|
<image |
||||
|
:src="$util.img('public/uniapp/member/order/wait_rate.png')" |
||||
|
mode="widthFix" |
||||
|
></image> |
||||
|
<view |
||||
|
class="icon-shade" |
||||
|
:style=" |
||||
|
'-webkit-mask-image: url(' + |
||||
|
$util.img( |
||||
|
'public/uniapp/member/order/wait_rate_shade.png' |
||||
|
) + |
||||
|
')' |
||||
|
" |
||||
|
></view> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<diy-icon |
||||
|
:icon="value.icon.waitRate.icon" |
||||
|
v-if="value.icon.waitRate" |
||||
|
:value=" |
||||
|
value.icon.waitRate.style ? value.icon.waitRate.style : null |
||||
|
" |
||||
|
></diy-icon> |
||||
|
</template> |
||||
|
<text |
||||
|
v-if="orderNum.waitrate > 0" |
||||
|
class="order-num color-base-bg price-font" |
||||
|
> |
||||
|
{{ orderNum.waitrate > 99 ? '99+' : orderNum.waitrate }} |
||||
|
</text> |
||||
|
</view> |
||||
|
<view class="title">待评价</view> |
||||
|
</view> |
||||
|
<view class="item-wrap" @click="redirect('/pages_tool/order/activist')"> |
||||
|
<view class="icon-block"> |
||||
|
<template v-if="value.style == 3"> |
||||
|
<image |
||||
|
:src="$util.img('public/uniapp/member/order/refunding.png')" |
||||
|
mode="widthFix" |
||||
|
></image> |
||||
|
<view |
||||
|
class="icon-shade" |
||||
|
:style=" |
||||
|
'-webkit-mask-image: url(' + |
||||
|
$util.img( |
||||
|
'public/uniapp/member/order/refunding_shade.png' |
||||
|
) + |
||||
|
')' |
||||
|
" |
||||
|
></view> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<diy-icon |
||||
|
:icon="value.icon.refunding.icon" |
||||
|
v-if="value.icon.refunding" |
||||
|
:value=" |
||||
|
value.icon.refunding.style ? value.icon.refunding.style : null |
||||
|
" |
||||
|
></diy-icon> |
||||
|
</template> |
||||
|
<text |
||||
|
v-if="orderNum.refunding > 0" |
||||
|
class="order-num color-base-bg price-font" |
||||
|
> |
||||
|
{{ orderNum.refunding > 99 ? '99+' : orderNum.refunding }} |
||||
|
</text> |
||||
|
</view> |
||||
|
<view class="title">售后/退款</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<ns-login ref="login"></ns-login> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 自定义会员中心——我的订单 |
||||
|
export default { |
||||
|
name: 'diy-member-my-order', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
}, |
||||
|
token: { |
||||
|
type: String |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
orderNum: { |
||||
|
waitpay: 0, |
||||
|
waitsend: 0, |
||||
|
waitconfirm: 0, |
||||
|
waitrate: 0, |
||||
|
refunding: 0 |
||||
|
} |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.getOrderNum(); |
||||
|
}, |
||||
|
mounted() { |
||||
|
uni.$on('changeStore', data => { |
||||
|
if (data) { |
||||
|
this.getOrderNum(); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
watch: { |
||||
|
token(nVal, oVal) { |
||||
|
this.getOrderNum(); |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
warpCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
if (this.value.componentAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
return obj; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
/** |
||||
|
* 获取订单数量 |
||||
|
*/ |
||||
|
getOrderNum() { |
||||
|
if (!uni.getStorageSync('token')) return; |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/order/num', |
||||
|
data: { |
||||
|
order_status: 'waitpay,waitsend,waitconfirm,waitrate,refunding' |
||||
|
}, |
||||
|
success: res => { |
||||
|
if (res.code == 0) { |
||||
|
this.orderNum = res.data; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
/** |
||||
|
* 跳转 |
||||
|
* @param {Object} url |
||||
|
*/ |
||||
|
redirect(url) { |
||||
|
if (!uni.getStorageSync('token')) { |
||||
|
this.$refs.login.open(url); |
||||
|
} else { |
||||
|
this.$util.redirectTo(url); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.common-wrap { |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
.order-wrap { |
||||
|
.status-wrap { |
||||
|
display: flex; |
||||
|
padding: 30rpx 0; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
color: #333; |
||||
|
} |
||||
|
.item-wrap { |
||||
|
flex: 1; |
||||
|
text-align: center; |
||||
|
.icon-block { |
||||
|
width: 60rpx; |
||||
|
height: 60rpx; |
||||
|
font-size: 60rpx; |
||||
|
margin: 4rpx auto; |
||||
|
position: relative; |
||||
|
|
||||
|
& > image { |
||||
|
position: absolute; |
||||
|
top: 5%; |
||||
|
right: 5%; |
||||
|
width: 90%; |
||||
|
height: 90%; |
||||
|
z-index: 5; |
||||
|
} |
||||
|
.icon-shade { |
||||
|
width: 90%; |
||||
|
height: 90%; |
||||
|
position: absolute; |
||||
|
z-index: 4; |
||||
|
top: 5%; |
||||
|
right: 5%; |
||||
|
background: $base-color; |
||||
|
-webkit-mask: no-repeat center / contain; |
||||
|
} |
||||
|
} |
||||
|
.order-num { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
transform: translate(50%, -50%); |
||||
|
display: inline-block; |
||||
|
box-sizing: border-box; |
||||
|
color: #ffffff; |
||||
|
line-height: 1.2; |
||||
|
text-align: center; |
||||
|
font-size: 24rpx; |
||||
|
padding: 0 6rpx; |
||||
|
min-width: 30rpx; |
||||
|
border-radius: 16rpx; |
||||
|
height: 30rpx; |
||||
|
text-align: center; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
.title { |
||||
|
font-size: 26rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,184 @@ |
|||||
|
<template> |
||||
|
<view class="diy-notice"> |
||||
|
<view :class="['notice', value.contentStyle]" :style="noticeWrapCss"> |
||||
|
<image v-if="value.iconType == 'img'" class="notice-img" :src="$util.img(value.imageUrl)" mode="aspectFit"></image> |
||||
|
<diy-icon |
||||
|
v-if="value.iconType == 'icon'" |
||||
|
:icon="value.icon" |
||||
|
:value="value.style ? value.style : 'null'" |
||||
|
:style="{ maxWidth: 30 * 2 + 'rpx', maxHeight: 30 * 2 + 'rpx', width: '100%', height: '100%' }" |
||||
|
></diy-icon> |
||||
|
<view class="notice-xian"></view> |
||||
|
<view class="main-wrap"> |
||||
|
<text v-if="value.contentStyle == 'style-2'" class="iconfont icon-gonggao" :style="{ color: value.textColor }"></text> |
||||
|
<view class="uni-swiper-msg"> |
||||
|
<!-- 横向滚动:horizontal --> |
||||
|
<template v-if="value.scrollWay == 'horizontal'"> |
||||
|
<swiper :vertical="false" :duration="0" autoplay="true" circular="true"> |
||||
|
<swiper-item v-for="(item, index) in list" :key="index" @touchmove.stop> |
||||
|
<text @click="toLink(item)" class="beyond-hiding animate" :style="{ color: value.textColor }">{{ item.title }}</text> |
||||
|
</swiper-item> |
||||
|
</swiper> |
||||
|
</template> |
||||
|
|
||||
|
<!-- 上下滚动:upDown --> |
||||
|
<template v-if="value.scrollWay == 'upDown'"> |
||||
|
<swiper :vertical="true" :duration="500" autoplay="true" circular="true"> |
||||
|
<swiper-item v-for="(item, index) in list" :key="index"> |
||||
|
<text @click="toLink(item)" class="beyond-hiding" :style="{ color: value.textColor }">{{ item.title }}</text> |
||||
|
</swiper-item> |
||||
|
</swiper> |
||||
|
</template> |
||||
|
</view> |
||||
|
<text v-if="value.contentStyle == 'style-2'" class="iconfont icon-right arrows" @click="toLink"></text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
<script> |
||||
|
// 公告 |
||||
|
export default { |
||||
|
name: 'diy-notice', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
list: [] |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
// 数据源:公告系统 |
||||
|
if (this.value.sources == 'default') this.getData(); |
||||
|
else this.list = this.value.list; |
||||
|
}, |
||||
|
computed: { |
||||
|
noticeWrapCss: function() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
if (this.value.componentAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
return obj; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
getData() { |
||||
|
var data = {}; |
||||
|
data.id_arr = this.value.noticeIds.toString(); |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/notice/lists', |
||||
|
data: data, |
||||
|
success: res => { |
||||
|
console.log(res.data,'data'); |
||||
|
if (res.code == 0 && res.data) { |
||||
|
|
||||
|
this.list = res.data; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
toLink(item) { |
||||
|
if (this.value.sources == 'initial') this.$util.redirectTo('/pages_tool/notice/detail', { notice_id: item.id }); |
||||
|
else if (!item) this.$util.redirectTo('/pages_tool/notice/list'); |
||||
|
else this.$util.diyRedirectTo(item.link); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.notice { |
||||
|
height: 80rpx; |
||||
|
position: relative; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
overflow: hidden; |
||||
|
padding: 20rpx; |
||||
|
font-size: 70rpx; |
||||
|
box-sizing: border-box; |
||||
|
|
||||
|
.notice-img { |
||||
|
width: 212rpx; |
||||
|
height: 40rpx; |
||||
|
} |
||||
|
|
||||
|
.notice-xian { |
||||
|
width: 1rpx; |
||||
|
height: 26rpx; |
||||
|
background-color: #e4e4e4; |
||||
|
margin: 0 22rpx; |
||||
|
} |
||||
|
&.style-2 { |
||||
|
.main-wrap { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
.uni-swiper-msg { |
||||
|
width: 400rpx; |
||||
|
margin: 0 10rpx; |
||||
|
} |
||||
|
.arrows { |
||||
|
color: #999; |
||||
|
font-size: $font-size-sub; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.main-wrap { |
||||
|
display: inline-block; |
||||
|
width: calc(100% - 115rpx); |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
swiper { |
||||
|
height: 50rpx; |
||||
|
} |
||||
|
|
||||
|
.beyond-hiding { |
||||
|
display: inline-block; |
||||
|
width: 100%; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.animate { |
||||
|
width: auto; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
padding-left: 40rpx; |
||||
|
font-size: $font-size-base; |
||||
|
color: #000; |
||||
|
display: inline-block; |
||||
|
white-space: nowrap; |
||||
|
animation: 5s wordsLoop linear infinite normal; |
||||
|
} |
||||
|
|
||||
|
@keyframes wordsLoop { |
||||
|
0% { |
||||
|
transform: translateX(400rpx); |
||||
|
-webkit-transform: translateX(400rpx); |
||||
|
} |
||||
|
|
||||
|
100% { |
||||
|
transform: translateX(-100%); |
||||
|
-webkit-transform: translateX(-100%); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@-webkit-keyframes wordsLoop { |
||||
|
0% { |
||||
|
transform: translateX(400rpx); |
||||
|
-webkit-transform: translateX(400rpx); |
||||
|
} |
||||
|
|
||||
|
100% { |
||||
|
transform: translateX(-100%); |
||||
|
-webkit-transform: translateX(-100%); |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,536 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<!-- 自定义 --> |
||||
|
<view v-if="value.mode == 'custom-rubik-cube'"> |
||||
|
<view style="position: relative;"><rich-text :nodes="customHtml"></rich-text></view> |
||||
|
</view> |
||||
|
<view v-else :class="['rubik-cube', value.mode]" :style="rubikCubeWrapCss"> |
||||
|
<!-- 1左2右 --> |
||||
|
<template v-if="value.mode == 'row1-lt-of2-rt'"> |
||||
|
<view class="template-left"> |
||||
|
<view :class="['item', value.mode]" @click="$util.diyRedirectTo(value.list[0].link)" |
||||
|
:style="{ padding: value.imageGap + 'rpx', height: list[0].imgHeight * 2 + 'rpx' }"> |
||||
|
<image :src="$util.img(value.list[0].imageUrl)" mode="aspectFill" :style="list[0].pageItemStyle"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="template-right"> |
||||
|
<template v-for="(item, index) in list"> |
||||
|
<template v-if="index > 0"> |
||||
|
<view :key="index" :class="['item', value.mode]" @click="$util.diyRedirectTo(item.link)" |
||||
|
:style="{ padding: value.imageGap + 'rpx', height: item.imgHeight }"> |
||||
|
<image :src="$util.img(item.imageUrl)" mode="aspectFill" :style="item.pageItemStyle"></image> |
||||
|
</view> |
||||
|
</template> |
||||
|
</template> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<!-- 1左3右 --> |
||||
|
<template v-else-if="value.mode == 'row1-lt-of1-tp-of2-bm'"> |
||||
|
<view class="template-left" :style="{ paddingRight: value.imageGap + 'rpx' }"> |
||||
|
<view :class="['item', value.mode]" :style="{ height: list[0].imgHeight + 'rpx' }" |
||||
|
@click="$util.diyRedirectTo(value.list[0].link)"> |
||||
|
<image :src="$util.img(value.list[0].imageUrl)" mode="aspectFill" :style="list[0].pageItemStyle"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="template-right" :style="{ paddingLeft: value.imageGap + 'rpx' }"> |
||||
|
<view :class="['item', value.mode]" |
||||
|
:style="{ height: list[1].imgHeight + 'rpx', paddingBottom: value.imageGap + 'rpx' }" |
||||
|
@click="$util.diyRedirectTo(value.list[1].link)"> |
||||
|
<image :src="$util.img(value.list[1].imageUrl)" mode="aspectFill" :style="list[1].pageItemStyle"></image> |
||||
|
</view> |
||||
|
<view class="template-bottom" :style="{ paddingTop: value.imageGap + 'rpx' }"> |
||||
|
<template v-for="(item, index) in list"> |
||||
|
<template v-if="index > 1"> |
||||
|
<view :key="index" :class="['item', value.mode]" @click="$util.diyRedirectTo(item.link)" :style="{ |
||||
|
height: item.imgHeight + 'rpx', |
||||
|
paddingLeft: index == 3 ? value.imageGap * 2 + 'rpx' : 0 |
||||
|
}"> |
||||
|
<image :src="$util.img(item.imageUrl)" mode="aspectFill" :style="item.pageItemStyle"></image> |
||||
|
</view> |
||||
|
</template> |
||||
|
</template> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<template v-else> |
||||
|
<view :class="['item', value.mode]" v-for="(item, index) in list" :key="index" |
||||
|
@click="$util.diyRedirectTo(item.link)" |
||||
|
:style="{ padding: value.imageGap + 'rpx', height: item.imgHeight * 2 + 'rpx' }"> |
||||
|
<image :src="$util.img(item.imageUrl)" mode="aspectFill" :style="item.pageItemStyle"></image> |
||||
|
</view> |
||||
|
</template> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 魔方、橱窗 |
||||
|
// import htmlParser from '@/common/js/html-parser'; |
||||
|
export default { |
||||
|
name: 'diy-rubik-cube', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
customHtml: '' |
||||
|
}; |
||||
|
}, |
||||
|
created() { |
||||
|
this.init() |
||||
|
}, |
||||
|
computed: { |
||||
|
list() { |
||||
|
var arr = JSON.parse(JSON.stringify(this.value.list)); |
||||
|
arr.forEach((item, index) => { |
||||
|
item.pageItemStyle = this.countBorderRadius(this.value.mode, index); |
||||
|
}); |
||||
|
return arr; |
||||
|
}, |
||||
|
rubikCubeWrapCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
if (this.value.componentAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
return obj; |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
value() { |
||||
|
this.init(); |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
init() { |
||||
|
if (this.value.mode == 'custom-rubik-cube') { |
||||
|
this.value.diyHtml = this.value.diyHtml.replace(/"/g, '"'); |
||||
|
// this.customHtml = htmlParser(this.value.diyHtml); |
||||
|
} else { |
||||
|
var singleRow = { |
||||
|
'row1-of2': { |
||||
|
ratio: 2, |
||||
|
width: '50%' |
||||
|
}, |
||||
|
'row1-of3': { |
||||
|
ratio: 3, |
||||
|
width: '33.33%' |
||||
|
}, |
||||
|
'row1-of4': { |
||||
|
ratio: 4, |
||||
|
width: '25%' |
||||
|
} |
||||
|
}; |
||||
|
if (singleRow[this.value.mode]) { |
||||
|
this.calcSingleRow(singleRow[this.value.mode]); |
||||
|
} else if (this.value.mode == 'row2-lt-of2-rt') { |
||||
|
this.calcFourSquare(); |
||||
|
} else if (this.value.mode == 'row1-lt-of2-rt') { |
||||
|
this.calcRowOneLeftOfTwoRight(); |
||||
|
} else if (this.value.mode == 'row1-tp-of2-bm') { |
||||
|
this.calcRowOneTopOfTwoBottom(); |
||||
|
} else if (this.value.mode == 'row1-lt-of1-tp-of2-bm') { |
||||
|
this.calcRowOneLeftOfOneTopOfTwoBottom(); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* 魔方:单行多个,平分宽度 |
||||
|
* 公式: |
||||
|
* 宽度:屏幕宽度/2,示例:375/2=187.5 |
||||
|
* 比例:原图高/原图宽,示例:322/690=0.46 |
||||
|
* 高度:宽度*比例,示例:187.5*0.46=86.25 |
||||
|
*/ |
||||
|
calcSingleRow(params) { |
||||
|
let maxHeight = 0; |
||||
|
this.list.forEach((item, index) => { |
||||
|
uni.getSystemInfo({ |
||||
|
success: res => { |
||||
|
var ratio = item.imgHeight / item.imgWidth; |
||||
|
item.imgWidth = 375 / params.ratio; |
||||
|
item.imgWidth -= this.value.margin.both * 2; |
||||
|
item.imgHeight = item.imgWidth * ratio; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// 获取最大高度 |
||||
|
if (maxHeight == 0 || maxHeight < item.imgHeight) maxHeight = item.imgHeight; |
||||
|
}); |
||||
|
this.list.forEach((item, index) => { |
||||
|
item.imgWidth = params.width; |
||||
|
item.imgHeight = maxHeight; |
||||
|
}); |
||||
|
}, |
||||
|
/** |
||||
|
* 魔方:四方型,各占50% |
||||
|
*/ |
||||
|
calcFourSquare() { |
||||
|
let maxHeightFirst = 0; |
||||
|
let maxHeightTwo = 0; |
||||
|
this.list.forEach((item, index) => { |
||||
|
uni.getSystemInfo({ |
||||
|
success: res => { |
||||
|
var ratio = item.imgHeight / item.imgWidth; |
||||
|
item.imgWidth = 375 / 2; |
||||
|
item.imgWidth -= this.value.margin.both * 2; |
||||
|
item.imgHeight = item.imgWidth * ratio; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// 获取每行最大高度 |
||||
|
if (index <= 1) { |
||||
|
if (maxHeightFirst == 0 || maxHeightFirst < item.imgHeight) { |
||||
|
maxHeightFirst = item.imgHeight; |
||||
|
} |
||||
|
} else if (index > 1) { |
||||
|
if (maxHeightTwo == 0 || maxHeightTwo < item.imgHeight) { |
||||
|
maxHeightTwo = item.imgHeight; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
this.list.forEach((item, index) => { |
||||
|
item.imgWidth = '50%'; |
||||
|
if (index <= 1) { |
||||
|
item.imgHeight = maxHeightFirst; |
||||
|
} else if (index > 1) { |
||||
|
item.imgHeight = maxHeightTwo; |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
/** |
||||
|
* 魔方:1左2右 |
||||
|
*/ |
||||
|
calcRowOneLeftOfTwoRight() { |
||||
|
let rightHeight = 0; // 右侧两图平分高度 |
||||
|
let divide = 'left'; // 划分规则,left:左,right:右 |
||||
|
if (this.list[1].imgWidth === this.list[2].imgWidth) divide = 'right'; |
||||
|
this.list.forEach((item, index) => { |
||||
|
uni.getSystemInfo({ |
||||
|
success: res => { |
||||
|
if (index == 0) { |
||||
|
var ratio = item.imgHeight / item.imgWidth; // 获取左图的尺寸比例 |
||||
|
item.imgWidth = 375 / 2;// 因为这里使用px进行计算;最后结果会转换为rpx来适应屏幕的变化 |
||||
|
item.imgWidth -= (this.value.margin.both * 2 + this.value.imageGap / 2); |
||||
|
item.imgHeight = item.imgWidth * ratio; |
||||
|
rightHeight = item.imgHeight / 2 - this.value.imageGap / 2; |
||||
|
} else { |
||||
|
item.imgWidth = this.list[0].imgWidth; |
||||
|
item.imgHeight = rightHeight * 2; |
||||
|
item.imgHeight += 'rpx'; |
||||
|
// if (divide == 'left') { |
||||
|
// item.imgWidth = this.list[0].imgWidth; |
||||
|
// item.imgHeight = rightHeight / 100; |
||||
|
// } else { |
||||
|
// var ratio = item.imgHeight / item.imgWidth; // 获取右图的尺寸比例 |
||||
|
// if (isNaN(ratio)) ratio = 0; |
||||
|
// item.imgWidth = res.windowWidth * ratio; |
||||
|
// item.imgHeight = item.imgHeight * ratio; |
||||
|
// if (this.list[1].imgHeight) this.list[0].imgHeight = this.list[1].imgHeight * 2; |
||||
|
// } |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
// this.list.forEach((item, index) => { |
||||
|
// if (index == 0) item.imgHeight += this.value.imageGap; |
||||
|
// item.imgHeight += 'px'; |
||||
|
// }); |
||||
|
}, |
||||
|
/** |
||||
|
* 魔方:1上2下 |
||||
|
*/ |
||||
|
calcRowOneTopOfTwoBottom() { |
||||
|
var maxHeight = 0; |
||||
|
this.list.forEach((item, index) => { |
||||
|
uni.getSystemInfo({ |
||||
|
success: res => { |
||||
|
var ratio = item.imgHeight / item.imgWidth; // 获取左图的尺寸比例 |
||||
|
if (index == 0) item.imgWidth = 375; |
||||
|
else if (index > 0) item.imgWidth = 375 / 2; |
||||
|
|
||||
|
item.imgWidth -= this.value.margin.both * 2; |
||||
|
|
||||
|
item.imgHeight = item.imgWidth * ratio; |
||||
|
|
||||
|
// 获取最大高度 |
||||
|
if (index > 0 && (maxHeight == 0 || maxHeight < item.imgHeight)) maxHeight = item.imgHeight; |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
this.list.forEach((item, index) => { |
||||
|
if (index == 0) item.imgWidth -= this.value.margin.both * 2; // 减去左右边距 |
||||
|
if (index > 0) item.imgWidth -= this.value.margin.both * 2; // 减去左右边距 |
||||
|
item.imgWidth += item.imgWidth * 2 + 'rpx'; |
||||
|
if (index > 0) item.imgHeight = maxHeight; |
||||
|
// else item.imgHeight += 'px'; |
||||
|
}); |
||||
|
}, |
||||
|
/** |
||||
|
* 魔方:1左3右 |
||||
|
*/ |
||||
|
calcRowOneLeftOfOneTopOfTwoBottom() { |
||||
|
this.list.forEach((item, index) => { |
||||
|
uni.getSystemInfo({ |
||||
|
success: res => { |
||||
|
// 左图 |
||||
|
if (index == 0) { |
||||
|
var ratio = item.imgHeight / item.imgWidth; |
||||
|
item.imgWidth = 375 / 2; |
||||
|
item.imgWidth -= this.value.margin.both * 2; |
||||
|
item.imgHeight = item.imgWidth * ratio; |
||||
|
} else if (index == 1) { |
||||
|
item.imgWidth = 375 / 2; |
||||
|
item.imgWidth -= this.value.margin.both * 2; |
||||
|
item.imgHeight = this.list[0].imgHeight / 2; |
||||
|
} else if (index > 1) { |
||||
|
item.imgWidth = this.list[0].imgWidth / 2; |
||||
|
item.imgHeight = this.list[0].imgHeight / 2; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
this.list.forEach((item, index) => { |
||||
|
if (index == 0) { |
||||
|
item.imgHeight += this.value.imageGap; |
||||
|
item.imgHeight *= 2; |
||||
|
} else { |
||||
|
item.imgHeight *= 2; |
||||
|
} |
||||
|
if (index > 1) { |
||||
|
item.imgWidth -= this.value.imageGap / 2; |
||||
|
item.imgWidth -= this.value.margin.both; // 减去左右边距 |
||||
|
item.imgWidth = item.imgWidth * 2 + 'rpx'; |
||||
|
} else { |
||||
|
item.imgWidth -= this.value.margin.both * 2; // 减去左右边距 |
||||
|
item.imgWidth = item.imgWidth * 2 + 'rpx'; |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
countBorderRadius(type, index) { |
||||
|
var obj = ''; |
||||
|
if (this.value.elementAngle == 'right') { |
||||
|
return obj; |
||||
|
} |
||||
|
var defaultData = { |
||||
|
'row1-lt-of2-rt': [ |
||||
|
['border-top-right-radius', 'border-bottom-right-radius'], |
||||
|
['border-top-left-radius', 'border-bottom-left-radius', 'border-bottom-right-radius'], |
||||
|
['border-top-left-radius', 'border-bottom-left-radius', 'border-top-right-radius'] |
||||
|
], |
||||
|
'row1-lt-of1-tp-of2-bm': [ |
||||
|
['border-top-right-radius', 'border-bottom-right-radius'], |
||||
|
['border-top-left-radius', 'border-bottom-left-radius', 'border-bottom-right-radius'], |
||||
|
['border-radius'], |
||||
|
['border-top-left-radius', 'border-bottom-left-radius', 'border-top-right-radius'] |
||||
|
], |
||||
|
'row1-tp-of2-bm': [ |
||||
|
['border-bottom-left-radius', 'border-bottom-right-radius'], |
||||
|
['border-top-left-radius', 'border-bottom-right-radius', 'border-top-right-radius'], |
||||
|
['border-top-left-radius', 'border-bottom-left-radius', 'border-top-right-radius'] |
||||
|
], |
||||
|
'row2-lt-of2-rt': [ |
||||
|
['border-top-right-radius', 'border-bottom-left-radius', 'border-bottom-right-radius'], |
||||
|
['border-top-left-radius', 'border-bottom-right-radius', 'border-bottom-left-radius'], |
||||
|
['border-top-left-radius', 'border-bottom-right-radius', 'border-top-right-radius'], |
||||
|
['border-top-left-radius', 'border-bottom-left-radius', 'border-top-right-radius'] |
||||
|
], |
||||
|
'row1-of4': [ |
||||
|
['border-top-right-radius', 'border-bottom-right-radius'], |
||||
|
['border-radius'], |
||||
|
['border-radius'], |
||||
|
['border-top-left-radius', 'border-bottom-left-radius'] |
||||
|
], |
||||
|
'row1-of3': [['border-top-right-radius', 'border-bottom-right-radius'], ['border-radius'], ['border-top-left-radius', 'border-bottom-left-radius']], |
||||
|
'row1-of2': [['border-top-right-radius', 'border-bottom-right-radius'], ['border-top-left-radius', 'border-bottom-left-radius']] |
||||
|
}; |
||||
|
|
||||
|
defaultData[type][index].forEach((item, index) => { |
||||
|
// obj += item + ':' + this.value.aroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-left-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;'; |
||||
|
}); |
||||
|
return obj; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
.rubik-cube { |
||||
|
overflow: hidden; |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item { |
||||
|
text-align: center; |
||||
|
line-height: 0; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item image { |
||||
|
width: 100%; |
||||
|
max-width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
// 一行两个 |
||||
|
.rubik-cube .item.row1-of2 { |
||||
|
width: 50% !important; |
||||
|
box-sizing: border-box; |
||||
|
padding-top: 0 !important; |
||||
|
padding-bottom: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row1-of2:nth-child(1) { |
||||
|
padding-left: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row1-of2:nth-child(2) { |
||||
|
padding-right: 0 !important; |
||||
|
} |
||||
|
|
||||
|
// 一行三个 |
||||
|
.rubik-cube .item.row1-of3 { |
||||
|
width: 33.33%; |
||||
|
box-sizing: border-box; |
||||
|
padding-top: 0 !important; |
||||
|
padding-bottom: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row1-of3:nth-child(1) { |
||||
|
padding-left: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row1-of3:nth-child(3) { |
||||
|
padding-right: 0 !important; |
||||
|
} |
||||
|
|
||||
|
// 一行四个 |
||||
|
.rubik-cube .item.row1-of4 { |
||||
|
width: 25%; |
||||
|
box-sizing: border-box; |
||||
|
padding-top: 0 !important; |
||||
|
padding-bottom: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row1-of4:nth-child(1) { |
||||
|
padding-left: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row1-of4:nth-child(4) { |
||||
|
padding-right: 0 !important; |
||||
|
} |
||||
|
|
||||
|
// 两左两右 |
||||
|
.rubik-cube .item.row2-lt-of2-rt { |
||||
|
width: 50%; |
||||
|
display: inline-block; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row2-lt-of2-rt:nth-child(1) { |
||||
|
padding-left: 0 !important; |
||||
|
padding-top: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row2-lt-of2-rt:nth-child(2) { |
||||
|
padding-right: 0 !important; |
||||
|
padding-top: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row2-lt-of2-rt:nth-child(3) { |
||||
|
padding-left: 0 !important; |
||||
|
padding-bottom: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row2-lt-of2-rt:nth-child(4) { |
||||
|
padding-right: 0 !important; |
||||
|
padding-bottom: 0 !important; |
||||
|
} |
||||
|
|
||||
|
// 一左两右 |
||||
|
.rubik-cube .template-left, |
||||
|
.rubik-cube .template-right { |
||||
|
width: 50%; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .template-left .item.row1-lt-of2-rt:nth-child(1) { |
||||
|
width: auto; |
||||
|
padding-top: 0 !important; |
||||
|
padding-left: 0 !important; |
||||
|
padding-bottom: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .template-right .item.row1-lt-of2-rt:nth-child(1) { |
||||
|
padding-top: 0 !important; |
||||
|
padding-right: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .template-right .item.row1-lt-of2-rt:nth-child(2) { |
||||
|
padding-right: 0 !important; |
||||
|
padding-bottom: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube.row1-lt-of2-rt .template-right { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// 一上两下 |
||||
|
.rubik-cube .item.row1-tp-of2-bm:nth-child(1) { |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
padding-top: 0 !important; |
||||
|
padding-left: 0 !important; |
||||
|
padding-right: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row1-tp-of2-bm:nth-child(2) { |
||||
|
width: 50%; |
||||
|
box-sizing: border-box; |
||||
|
padding-left: 0 !important; |
||||
|
padding-bottom: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .item.row1-tp-of2-bm:nth-child(3) { |
||||
|
width: 50%; |
||||
|
box-sizing: border-box; |
||||
|
padding-right: 0 !important; |
||||
|
padding-bottom: 0 !important; |
||||
|
} |
||||
|
|
||||
|
// 一左三右 |
||||
|
.rubik-cube .template-left .item.row1-lt-of1-tp-of2-bm { |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .template-bottom { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.rubik-cube .template-bottom .item.row1-lt-of1-tp-of2-bm { |
||||
|
width: 50%; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,250 @@ |
|||||
|
<template> |
||||
|
<div class="navbar" :style="{ backgroundColor: navbarBgColor }"> |
||||
|
<!-- <u-navbar title=" " :autoBack="false" leftIconSize="0" :bgColor="navbarBgColor" > --> |
||||
|
|
||||
|
<!-- <view class="search-box" :style="searchWrapCss" slot="left" style="width: calc(100% );"> |
||||
|
<view class="img" v-if="value.searchStyle == 2 && value.iconType == 'img'"> |
||||
|
<image :src="$util.img(value.imageUrl)" mode="aspectFill"></image> |
||||
|
</view> |
||||
|
<diy-icon class="icon" v-if="value.searchStyle == 2 && value.iconType == 'icon'" :icon="value.icon" |
||||
|
:value="value.style ? value.style : 'null'" |
||||
|
:style="{ maxWidth: 30 * 2 + 'rpx', maxHeight: 30 * 2 + 'rpx' }"></diy-icon> |
||||
|
<view class="search-content" :style="inputStyle" style="border: 1px var(--base-color) solid;" |
||||
|
@click="search()"> |
||||
|
<input type="text" class="uni-input ns-font-size-base" maxlength="50" :placeholder="value.title" |
||||
|
v-model="searchText" @confirm="search()" :placeholderStyle="placeholderStyle" /> |
||||
|
<text class="iconfont icon-sousuo3" @click="search()" |
||||
|
:style="{ color: value.textColor ? value.textColor : 'rgba(0,0,0,0)' }"></text> |
||||
|
<div class="text"> |
||||
|
<div class="line"></div> |
||||
|
<div>搜索</div> |
||||
|
</div> |
||||
|
</view> |
||||
|
|
||||
|
<image :src="$util.img('/upload/weapp/user/ld.png')" @click="toNews" class="news"></image> |
||||
|
</view> --> |
||||
|
|
||||
|
<view class="search-box" :style="searchWrapCss" slot="center" style="width:calc(100%-56rpx);"> |
||||
|
<view class="img" v-if="value.searchStyle == 2 && value.iconType == 'img'"> |
||||
|
<image :src="$util.img(value.imageUrl)" mode="aspectFill"></image> |
||||
|
</view> |
||||
|
<diy-icon class="icon" v-if="value.searchStyle == 2 && value.iconType == 'icon'" :icon="value.icon" |
||||
|
:value="value.style ? value.style : 'null'" |
||||
|
:style="{ maxWidth: 30 * 2 + 'rpx', maxHeight: 30 * 2 + 'rpx' }"></diy-icon> |
||||
|
|
||||
|
<view class="search-content" :style="inputStyle" style="border: 1px var(--base-color) solid;" @click="search()"> |
||||
|
<input type="text" class="uni-input ns-font-size-base" maxlength="50" :placeholder="value.title" |
||||
|
v-model="searchText" @confirm="search()" :placeholderStyle="placeholderStyle" /> |
||||
|
<text class="iconfont icon-sousuo3" |
||||
|
:style="{ color: value.textColor ? value.textColor : 'rgba(0,0,0,0)' }"></text> |
||||
|
<div class="text"> |
||||
|
<div class="line"></div> |
||||
|
<div>搜索</div> |
||||
|
</div> |
||||
|
</view> |
||||
|
<view class=""> |
||||
|
<image :src="$util.img('/upload/weapp/user/ld.png')" @click="toNews" class="news"></image> |
||||
|
<u-badge type="error" max="99" :value="read_no_num" :absolute="true" :offset="[0, 0]"> </u-badge> |
||||
|
</view> |
||||
|
|
||||
|
|
||||
|
|
||||
|
</view> |
||||
|
</div> |
||||
|
<!-- #ifndef H5 --> |
||||
|
<!-- <div style="height: 80rpx;"></div> --> |
||||
|
<!-- #endif --> |
||||
|
<!-- #ifdef H5 --> |
||||
|
<!-- <div style="height: 60rpx;"></div> --> |
||||
|
<!-- #endif --> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 搜索 |
||||
|
export default { |
||||
|
name: 'diy-search', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object, |
||||
|
default: () => { |
||||
|
return {}; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
'$store.state.navbarBgColor': { |
||||
|
handler: function (newVal, oldVal) { |
||||
|
// this.navbarBgColor = newVal; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
searchText: '', |
||||
|
navbarBgColor: 'transparent', |
||||
|
read_no_num: "", |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
computed: { |
||||
|
searchWrapCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
if (this.value.borderType == 2) { |
||||
|
obj += 'border-radius:' + '100rpx;'; |
||||
|
} |
||||
|
obj += 'text-align:' + this.value.textAlign + ';'; |
||||
|
return obj; |
||||
|
}, |
||||
|
inputStyle() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.elementBgColor + ';'; |
||||
|
if (this.value.borderType == 2) { |
||||
|
obj += 'border-radius:' + '40rpx;'; |
||||
|
} else { |
||||
|
obj += 'border-radius:' + '16rpx;'; |
||||
|
} |
||||
|
return obj; |
||||
|
}, |
||||
|
placeholderStyle() { |
||||
|
var obj = ''; |
||||
|
if (this.value.textColor) { |
||||
|
obj += 'color:' + this.value.textColor; |
||||
|
} else { |
||||
|
obj += 'color: rgba(0,0,0,0)'; |
||||
|
} |
||||
|
return obj; |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
created() { |
||||
|
if (uni.getStorageSync('token')) { |
||||
|
this.getMessageNum() |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
methods: { |
||||
|
search() { |
||||
|
this.$util.redirectTo('/pages_tool/goods/search'); |
||||
|
}, |
||||
|
toNews() { |
||||
|
uni.navigateTo({ |
||||
|
url: '/pages_tool/news/news' |
||||
|
}); |
||||
|
}, |
||||
|
getMessageNum() { |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/notice/messageNum', |
||||
|
success: res => { |
||||
|
this.read_no_num = res.data.read_no_num; |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.navbar { |
||||
|
// position: fixed; |
||||
|
// z-index: 9999; |
||||
|
width: 100%; |
||||
|
height: 90rpx; |
||||
|
// position: sticky; |
||||
|
// top: 0; |
||||
|
// padding: 32rpx 0rpx 0rpx 32rpx; |
||||
|
// padding-top: calc(var(--status-bar-height) + 40rpx); |
||||
|
// top:0; |
||||
|
// left: 0; |
||||
|
background: transparent; |
||||
|
|
||||
|
// position: sticky;top: 0; background: #f7f7f7; |
||||
|
} |
||||
|
|
||||
|
.news { |
||||
|
width: 48rpx; |
||||
|
height: 48rpx; |
||||
|
margin: 16rpx; |
||||
|
} |
||||
|
|
||||
|
/deep/ .uni-input-placeholder { |
||||
|
overflow: initial; |
||||
|
} |
||||
|
|
||||
|
.search-box { |
||||
|
position: relative; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
background: transparent; |
||||
|
/* #ifndef H5 */ |
||||
|
// padding-top: 50rpx; |
||||
|
/* #endif */ |
||||
|
|
||||
|
.img { |
||||
|
width: 170rpx; |
||||
|
height: 60rpx; |
||||
|
margin-right: 20rpx; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.icon { |
||||
|
width: 170rpx; |
||||
|
height: 60rpx; |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.search-content { |
||||
|
flex: 1; |
||||
|
position: relative; |
||||
|
|
||||
|
.text { |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
right: 30rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
transform: translateY(-50%); |
||||
|
font-size: 28rpx; |
||||
|
z-index: 10; |
||||
|
color: $base-color; |
||||
|
|
||||
|
.line { |
||||
|
width: 1px; |
||||
|
height: 36rpx; |
||||
|
background: linear-gradient(180deg, |
||||
|
rgba(33, 187, 243, 0) 0%, |
||||
|
$base-color 50%, |
||||
|
rgba(33, 187, 243, 0) 100%); |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.search-content input { |
||||
|
box-sizing: border-box; |
||||
|
display: block; |
||||
|
height: 68rpx; |
||||
|
width: 100%; |
||||
|
padding: 0 20rpx 0 64rpx; |
||||
|
color: #333333; |
||||
|
} |
||||
|
|
||||
|
.search-content .iconfont { |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
left: -5rpx; |
||||
|
transform: translateY(-50%); |
||||
|
font-size: 36rpx; |
||||
|
z-index: 10; |
||||
|
width: 80rpx; |
||||
|
font-weight: bold; |
||||
|
text-align: center; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,24 @@ |
|||||
|
<template> |
||||
|
<view><text style="font-weight: bold;font-size: 20px;color: #0cc361;">我是扩展标题组件</text></view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 扩展标题组件 |
||||
|
export default { |
||||
|
name: 'diy-text-extend', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return {}; |
||||
|
}, |
||||
|
computed: {}, |
||||
|
created() { |
||||
|
}, |
||||
|
methods: {} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
@ -0,0 +1,116 @@ |
|||||
|
<template> |
||||
|
<view :style="{ fontSize: value.fontSize * 2 + 'rpx' }"> |
||||
|
<view |
||||
|
v-if="value.arrangement == 'vertical'" |
||||
|
class="diy-text-nav" |
||||
|
:style="{ |
||||
|
fontSize: value.fontSize * 2 + 'rpx', |
||||
|
background: value.backgroundColor, |
||||
|
textAlign: value.textAlign |
||||
|
}" |
||||
|
@click="redirectTo(value.list[0].link)" |
||||
|
> |
||||
|
<view |
||||
|
class="single" |
||||
|
:style="{ |
||||
|
fontSize: value.fontSize * 2 + 'rpx', |
||||
|
color: value.textColor ? value.textColor : 'rgba(0,0,0,0)' |
||||
|
}" |
||||
|
> |
||||
|
{{ value.list[0].text }} |
||||
|
<text class="subhead">{{ value.list[0].secondText }}</text> |
||||
|
<!-- <text :style="{ fontSize: value.fontSize * 2 + 'rpx'}" class="iconfont icon-right font-size-goods-tag"></text> --> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view v-else class="diy-text-nav" :style="{ background: value.backgroundColor }"> |
||||
|
<scroll-view scroll-x> |
||||
|
<view |
||||
|
v-for="(item, index) in value.list" |
||||
|
:key="index" |
||||
|
class="item" |
||||
|
@click="redirectTo(item.link)" |
||||
|
:style="{ |
||||
|
textAlign: value.textAlign, |
||||
|
fontSize: value.fontSize * 2 + 'rpx', |
||||
|
color: value.textColor ? value.textColor : 'rgba(0,0,0,0)' |
||||
|
}" |
||||
|
> |
||||
|
{{ item.text }} |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 文本导航 |
||||
|
export default { |
||||
|
name: 'diy-text-nav', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return {}; |
||||
|
}, |
||||
|
methods: { |
||||
|
redirectTo(link) { |
||||
|
this.$util.diyRedirectTo(link); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.control-text-navigation i { |
||||
|
float: right; |
||||
|
margin: 6rpx 20rpx 0 0; |
||||
|
} |
||||
|
|
||||
|
.diy-text-nav { |
||||
|
padding: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.diy-text-nav scroll-view { |
||||
|
width: 100%; |
||||
|
flex-direction: row; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.diy-text-nav scroll-view .item { |
||||
|
display: inline-block; |
||||
|
margin-left: 16rpx; |
||||
|
position: relative; |
||||
|
min-width: 25%; |
||||
|
text-overflow: ellipsis; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.diy-text-nav .single { |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.diy-text-nav .single .subhead { |
||||
|
font-size: 24rpx; |
||||
|
color: #777; |
||||
|
margin-left: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.diy-text-nav .iconfont { |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
transform: translateY(-50%); |
||||
|
right: 0; |
||||
|
} |
||||
|
</style> |
||||
|
<style scoped lang="scss"> |
||||
|
.uni-view { |
||||
|
font-size: 0; |
||||
|
} |
||||
|
.diy-text-nav { |
||||
|
/deep/.uni-scroll-view::-webkit-scrollbar { |
||||
|
display: none; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,980 @@ |
|||||
|
<template> |
||||
|
<view class="diy-text" @click="$util.diyRedirectTo(value.link)" :style="warpCss"> |
||||
|
<view :class="value.style == 'style-8' ? 'title2' : 'title'" :style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor }"> |
||||
|
<block v-if="value.style == 'style-1'" style="height: 40rpx; line-height: 40rpx;"> |
||||
|
<view class="text-left" :style="{ color: value.textColor}"><text>───</text></view> |
||||
|
<text>{{ value.text }}</text> |
||||
|
<view class="text-right" :style="{ color: value.textColor}"><text>───</text></view> |
||||
|
</block> |
||||
|
<block v-else-if="value.style == 'style-2'"> |
||||
|
<view class="style2"> |
||||
|
<text :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx' }">{{ value.text }}</text> |
||||
|
<view class="xian" :style="{ background: value.textColor }"> |
||||
|
<view class="line-triangle" :style="{ borderColor: value.textColor }"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> |
||||
|
<block v-else-if="value.style == 'style-3'"> |
||||
|
<view class="style3"> |
||||
|
<text :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx' }">{{ value.text }}</text> |
||||
|
<view class="inner-line" :style="{ background: value.textColor }"><view class="line-short" :style="{ background: value.textColor }"></view></view> |
||||
|
</view> |
||||
|
</block> |
||||
|
<block v-else-if="value.style == 'style-4'"> |
||||
|
<view class="style4"> |
||||
|
<text :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx' }">{{ value.text }}</text> |
||||
|
<view class="line-box"> |
||||
|
<view class="line-left" :style="{ background: value.textColor }"></view> |
||||
|
<view class="line-center" :style="{ borderColor: value.textColor }"></view> |
||||
|
<view class="line-right" :style="{ background: value.textColor }"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> |
||||
|
<block v-else-if="value.style == 'style-5'"> |
||||
|
<view class="style5"> |
||||
|
<view class="style5-box" :style="{ color: value.textColor }"> |
||||
|
<text class="style5-title" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx' }">{{ value.text }}</text> |
||||
|
<view class="line-left" :style="{ background: value.textColor }"></view> |
||||
|
<view class="line-right" :style="{ background: value.textColor }"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> |
||||
|
<block v-else-if="value.style == 'style-6'"> |
||||
|
<view class="style6"> |
||||
|
<view class="style6-box" :style="{ color: value.textColor }"> |
||||
|
<text class="style6-title" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx' }">{{ value.text }}</text> |
||||
|
<view class="style6-wrap" :style="{ color: value.textColor }"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> |
||||
|
<block v-else-if="value.style == 'style-7'"> |
||||
|
<view class="style7"> |
||||
|
<view class="style7-box" :style="{ color: value.textColor }"> |
||||
|
<text class="style7-title" :style="{ background: value.textColor, fontSize: value.fontSize * 2 + 'rpx' }">{{ value.text }}</text> |
||||
|
<view class="style7-wrap" :style="{ color: value.textColor }"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> |
||||
|
<block v-else-if="value.style == 'style-8'"> |
||||
|
<view class="style8"> |
||||
|
<view class="style8-box" :style="{ color: value.textColor }"> |
||||
|
<text class="style8-title" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx' }">{{ value.text }}</text> |
||||
|
<view class="style8-wrap" :style="{ background: value.textColor, height: value.fontSize * 2 + 'rpx' }"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> |
||||
|
<block v-else-if="value.style == 'style-9'"> |
||||
|
<view class="style9"> |
||||
|
<view class="style9-box"> |
||||
|
<view class="style9-center"> |
||||
|
<view class="left-img"><image :src="$util.img('public/uniapp/diy/style9-1.png')"></image></view> |
||||
|
<text |
||||
|
class="style9-title" |
||||
|
:style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor, fontWeight: value.fontWeight }" |
||||
|
> |
||||
|
{{ value.text }} |
||||
|
</text> |
||||
|
<view class="right-img"><image :src="$util.img('public/uniapp/diy/style9-2.png')"></image></view> |
||||
|
<view |
||||
|
class="style9-more" |
||||
|
v-if="value.more.isShow" |
||||
|
:style="{ color: value.more.color }" |
||||
|
@click.stop="$util.diyRedirectTo(value.more.link)" |
||||
|
> |
||||
|
{{ value.more.text }} |
||||
|
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<text class="sub-title" :style="{ color: value.subTitle.color }">{{ value.subTitle.text }}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> |
||||
|
<block v-else-if="value.style == 'style-10'"> |
||||
|
<view class="style10"> |
||||
|
<view class="style10-box"> |
||||
|
<view class="style10-center"> |
||||
|
<view class="left-img"><image :src="$util.img('public/uniapp/diy/style10-1.png')"></image></view> |
||||
|
|
||||
|
<text |
||||
|
class="style10-title" |
||||
|
v-if="$util.img('public/uniapp/diy/style10-3.png')" |
||||
|
:style="{ |
||||
|
backgroundImage: 'url(' + $util.img('public/uniapp/diy/style10-3.png') + ')', |
||||
|
backgroundSize: 100 + '%', |
||||
|
backgroundPositionY: 93 + '%', |
||||
|
backgroundRepeat: 'no-repeat', |
||||
|
fontSize: value.fontSize * 2 + 'rpx', |
||||
|
color: value.textColor, |
||||
|
fontWeight: value.fontWeight |
||||
|
}" |
||||
|
> |
||||
|
{{ value.text }} |
||||
|
</text> |
||||
|
<view class="right-img"><image :src="$util.img('public/uniapp/diy/style10-2.png')"></image></view> |
||||
|
<view class="style10-more" v-if="value.more.isShow" :style="{ color: value.more.color }" @click.stop="$util.diyRedirectTo(value.more.link)"> |
||||
|
{{ value.more.text }} |
||||
|
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<text class="sub-title" :style="{ color: value.subTitle.color }">{{ value.subTitle.text }}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> |
||||
|
<block v-else-if="value.style == 'style-11'"> |
||||
|
<view class="style11" :style="{ backgroundColor: value.backgroundColor }"> |
||||
|
<view class="style11-box"> |
||||
|
<view class="style11-conter"> |
||||
|
<view class="style11-conter-box"> |
||||
|
<view class="left"> |
||||
|
<view |
||||
|
class="style11-title" |
||||
|
:style="{ |
||||
|
fontSize: value.fontSize * 2 + 'rpx', |
||||
|
color: value.textColor, |
||||
|
fontWeight: value.fontWeight |
||||
|
}" |
||||
|
> |
||||
|
{{ value.text }} |
||||
|
</view> |
||||
|
<view class="style11-sub" :style="{ color: value.subTitle.color }">{{ value.subTitle.text }}</view> |
||||
|
</view> |
||||
|
<view class="style11-more" v-if="value.more.isShow" :style="{ color: value.more.color }" @click.stop="$util.diyRedirectTo(value.more.link)"> |
||||
|
{{ value.more.text }} |
||||
|
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view> |
||||
|
</view> |
||||
|
|
||||
|
<image class="center-img" :src="$util.img('public/uniapp/diy/style11-1.png')" mode="widthFix"></image> |
||||
|
|
||||
|
<image class="right-img" :src="$util.img('public/uniapp/diy/style11-2.png')" mode="widthFix"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> |
||||
|
<view class="style12" v-if="value.style == 'style-12'"> |
||||
|
<view |
||||
|
class="style12-title" |
||||
|
:style="{ |
||||
|
fontSize: value.fontSize * 2 + 'rpx', |
||||
|
color: value.textColor, |
||||
|
fontWeight: value.fontWeight |
||||
|
}" |
||||
|
> |
||||
|
{{ value.text }} |
||||
|
</view> |
||||
|
<text class="style12-sub-title" :style="{ color: value.subTitle.color }">{{ value.subTitle.text }}</text> |
||||
|
<view class="style12-more" v-if="value.more.isShow" :style="{ color: value.more.color }" @click.stop="$util.diyRedirectTo(value.more.link)"> |
||||
|
<text>{{ value.more.text }}</text> |
||||
|
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="style13" v-else-if="value.style == 'style-13'"> |
||||
|
<image class="left-img" :src="$util.img('public/uniapp/diy/style13-1.png')" mode="widthFix"></image> |
||||
|
<view |
||||
|
class="style13-title" |
||||
|
:style="{ |
||||
|
fontSize: value.fontSize * 2 + 'rpx', |
||||
|
color: value.textColor, |
||||
|
fontWeight: value.fontWeight |
||||
|
}" |
||||
|
> |
||||
|
{{ value.text }} |
||||
|
</view> |
||||
|
<image class="right-img" :src="$util.img('public/uniapp/diy/style13-1.png')" mode="widthFix"></image> |
||||
|
</view> |
||||
|
<view class="style14" v-else-if="value.style == 'style-14'"> |
||||
|
<view class="title-wrap"> |
||||
|
<view class="text"> |
||||
|
<text :style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor, fontWeight: value.fontWeight }"> |
||||
|
{{ value.text }} |
||||
|
</text> |
||||
|
<text class="zone" :style="{ fontSize: value.fontSize * 2 + 'rpx', fontWeight: value.fontWeight }">专区</text> |
||||
|
</view> |
||||
|
<text class="iconfont icon-danxuan-xuanzhong" :style="{ color: value.textColor, fontWeight: value.fontWeight }"></text> |
||||
|
<text class="iconfont icon-danxuan-xuanzhong" :style="{ color: value.textColor, fontWeight: value.fontWeight }"></text> |
||||
|
<text class="iconfont icon-danxuan-xuanzhong" :style="{ color: value.textColor, fontWeight: value.fontWeight }"></text> |
||||
|
<view |
||||
|
class="sub-title" |
||||
|
v-show="value.subTitle.text" |
||||
|
:style="{ fontSize: value.subTitle.fontSize * 2 + 'rpx', color: value.subTitle.color }" |
||||
|
> |
||||
|
{{ value.subTitle.text }} |
||||
|
</view> |
||||
|
</view> |
||||
|
<view v-show="value.more.isShow == 1" class="more" :style="{ color: value.more.color }"> |
||||
|
<text>{{ value.more.text }}</text> |
||||
|
<text class="iconfont icon-right"></text> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 图十五 --> |
||||
|
<view class="style15" v-else-if="value.style == 'style-15'"> |
||||
|
<view class="title-wrap"> |
||||
|
<view class="ornament" style="margin-right: 40rpx;"> |
||||
|
<text class="line" :style="{ color: value.textColor, fontWeight: value.fontWeight }"></text> |
||||
|
<text class="line" :style="{ color: value.textColor, fontWeight: value.fontWeight }"></text> |
||||
|
<text class="my"> |
||||
|
<text class="yuan" :style="{ backgroundColor: value.textColor, fontWeight: value.fontWeight }"></text> |
||||
|
<text class="vertical" :style="{ color: value.textColor, fontWeight: value.fontWeight }"></text> |
||||
|
</text> |
||||
|
</view> |
||||
|
<text :style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor, fontWeight: value.fontWeight }"> |
||||
|
{{ value.text }} |
||||
|
</text> |
||||
|
<view class="ornament" style="margin-left: 40rpx;"> |
||||
|
<text class="line" :style="{ color: value.textColor, fontWeight: value.fontWeight }"></text> |
||||
|
<text class="line" :style="{ color: value.textColor, fontWeight: value.fontWeight }"></text> |
||||
|
<text class="my"> |
||||
|
<text class="yuan" :style="{ backgroundColor: value.textColor, fontWeight: value.fontWeight }"></text> |
||||
|
<text class="vertical" :style="{ color: value.textColor, fontWeight: value.fontWeight }"></text> |
||||
|
</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view |
||||
|
class="sub-title" |
||||
|
v-show="value.subTitle.text" |
||||
|
:style="{ fontSize: value.subTitle.fontSize * 2 + 'rpx', color: value.subTitle.color }" |
||||
|
> |
||||
|
{{ value.subTitle.text }} |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 图十六 --> |
||||
|
<view class="style16" v-if="value.style == 'style-16'"> |
||||
|
<view |
||||
|
class="style16-title" |
||||
|
:style="{ |
||||
|
fontSize: value.fontSize * 2 + 'rpx', |
||||
|
color: value.textColor, |
||||
|
fontWeight: value.fontWeight |
||||
|
}" |
||||
|
> |
||||
|
{{ value.text }} |
||||
|
</view> |
||||
|
<view class="style16-sub-title" v-show="value.subTitle.text" :style="{ color: value.subTitle.color, backgroundColor: value.subTitle.bgColor }"> |
||||
|
<text :class="['js-icon', value.subTitle.icon]" :style="{ backgroundColor: value.subTitle.bgColor }"></text> |
||||
|
<text :style="{ fontWeight: value.subTitle.fontWeight }">{{ value.subTitle.text }}</text> |
||||
|
</view> |
||||
|
<view class="style16-more" v-if="value.more.isShow" :style="{ color: value.more.color }" @click.stop="$util.diyRedirectTo(value.more.link)"> |
||||
|
<text>{{ value.more.text }}</text> |
||||
|
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 标题 |
||||
|
export default { |
||||
|
name: 'diy-text', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return {}; |
||||
|
}, |
||||
|
created() {}, |
||||
|
computed: { |
||||
|
warpCss() { |
||||
|
var obj = ''; |
||||
|
obj += 'background-color:' + this.value.componentBgColor + ';'; |
||||
|
if (this.value.componentAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
return obj; |
||||
|
} |
||||
|
}, |
||||
|
methods: {} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.diy-text { |
||||
|
padding: 0; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.diy-text .title { |
||||
|
margin: 0; |
||||
|
color: #333; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.diy-text .title2 { |
||||
|
margin: 0; |
||||
|
color: #333; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.diy-text .title > text { |
||||
|
padding: 0 15rpx; |
||||
|
} |
||||
|
|
||||
|
.left { |
||||
|
transform: translateY(0%); |
||||
|
width: 30rpx; |
||||
|
height: 24rpx; |
||||
|
} |
||||
|
|
||||
|
.right { |
||||
|
transform: translateY(0%); |
||||
|
width: 30rpx; |
||||
|
height: 24rpx; |
||||
|
} |
||||
|
|
||||
|
.style2 { |
||||
|
width: 100%; |
||||
|
text-align: center; |
||||
|
|
||||
|
.xian { |
||||
|
width: 100%; |
||||
|
height: 2rpx; |
||||
|
vertical-align: top; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.line-triangle { |
||||
|
background: transparent !important; |
||||
|
position: absolute; |
||||
|
border: 12rpx solid #000; |
||||
|
border-top-color: transparent !important; |
||||
|
border-left-color: transparent !important; |
||||
|
left: 50%; |
||||
|
bottom: -10rpx; |
||||
|
margin-left: -12rpx; |
||||
|
transform: rotate(45deg); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style3 { |
||||
|
width: 100%; |
||||
|
text-align: center; |
||||
|
|
||||
|
.inner-line { |
||||
|
width: 100%; |
||||
|
height: 2rpx; |
||||
|
vertical-align: top; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.line-short { |
||||
|
width: 324rpx; |
||||
|
height: 6rpx; |
||||
|
position: absolute; |
||||
|
bottom: 0; |
||||
|
left: 50%; |
||||
|
margin-left: -162rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style4 { |
||||
|
text-align: center; |
||||
|
width: 100%; |
||||
|
|
||||
|
.line-box { |
||||
|
height: 5rpx; |
||||
|
position: relative; |
||||
|
text-align: center; |
||||
|
margin-top: 5rpx; |
||||
|
width: 100%; |
||||
|
|
||||
|
.line-left { |
||||
|
display: inline-block; |
||||
|
position: absolute; |
||||
|
top: 8rpx; |
||||
|
left: 0; |
||||
|
bottom: 0; |
||||
|
width: calc((100% - 44rpx) / 2); |
||||
|
height: 2rpx; |
||||
|
} |
||||
|
|
||||
|
.line-center { |
||||
|
width: 12rpx; |
||||
|
height: 12rpx; |
||||
|
border: 2rpx solid; |
||||
|
display: inline-block; |
||||
|
-webkit-transform: rotate(45deg); |
||||
|
transform: rotate(45deg); |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 50%; |
||||
|
bottom: 0; |
||||
|
margin-left: -6rpx; |
||||
|
} |
||||
|
|
||||
|
.line-right { |
||||
|
display: inline-block; |
||||
|
position: absolute; |
||||
|
top: 8rpx; |
||||
|
bottom: 0; |
||||
|
right: 0; |
||||
|
width: calc((100% - 44rpx) / 2); |
||||
|
height: 2rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style5 { |
||||
|
text-align: center; |
||||
|
position: relative; |
||||
|
|
||||
|
.style5-box { |
||||
|
display: inline-block; |
||||
|
padding: 10rpx !important; |
||||
|
border: 1rpx solid; |
||||
|
position: relative; |
||||
|
|
||||
|
.style5-title { |
||||
|
display: inline-block; |
||||
|
padding: 10rpx 30rpx; |
||||
|
border: 1rpx solid; |
||||
|
line-height: 1; |
||||
|
} |
||||
|
|
||||
|
.line-left { |
||||
|
height: 10rpx; |
||||
|
position: absolute; |
||||
|
width: 80rpx; |
||||
|
top: 50%; |
||||
|
margin-top: -4rpx; |
||||
|
left: 0; |
||||
|
margin-left: -60rpx; |
||||
|
} |
||||
|
|
||||
|
.line-right { |
||||
|
height: 10rpx; |
||||
|
position: absolute; |
||||
|
width: 80rpx; |
||||
|
top: 50%; |
||||
|
margin-top: -4rpx; |
||||
|
right: 0; |
||||
|
margin-right: -60rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style6 { |
||||
|
text-align: center; |
||||
|
position: relative; |
||||
|
|
||||
|
.style6-box { |
||||
|
display: inline-block; |
||||
|
position: relative; |
||||
|
|
||||
|
.style6-title { |
||||
|
display: inline-block; |
||||
|
padding: 6rpx 50rpx; |
||||
|
border: 1rpx solid; |
||||
|
position: relative; |
||||
|
z-index: 2; |
||||
|
padding-bottom: 6rpx; |
||||
|
background: rgb(255, 255, 255); |
||||
|
line-height: 1.5; |
||||
|
} |
||||
|
|
||||
|
.style6-wrap { |
||||
|
position: absolute; |
||||
|
display: inline-block; |
||||
|
width: 100%; |
||||
|
top: 10rpx; |
||||
|
right: 4rpx; |
||||
|
bottom: -10rpx; |
||||
|
left: 10rpx; |
||||
|
border: 1rpx solid; |
||||
|
z-index: 0; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style7 { |
||||
|
text-align: center; |
||||
|
position: relative; |
||||
|
|
||||
|
.style7-box { |
||||
|
display: inline-block; |
||||
|
position: relative; |
||||
|
|
||||
|
.style7-title { |
||||
|
display: inline-block; |
||||
|
padding: 0rpx 50rpx; |
||||
|
position: relative; |
||||
|
z-index: 2; |
||||
|
padding-bottom: 6rpx; |
||||
|
color: rgb(255, 255, 255); |
||||
|
line-height: 1.5; |
||||
|
} |
||||
|
|
||||
|
.style7-wrap { |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
position: absolute; |
||||
|
top: 10rpx; |
||||
|
right: 4rpx; |
||||
|
bottom: -10rpx; |
||||
|
left: 10rpx; |
||||
|
border: 1rpx solid; |
||||
|
z-index: 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style8 { |
||||
|
position: relative; |
||||
|
text-align: left; |
||||
|
|
||||
|
.style8-box { |
||||
|
text-align: left !important; |
||||
|
.style8-title{ |
||||
|
margin-left: 20rpx; |
||||
|
} |
||||
|
.style8-wrap { |
||||
|
height: 100%; |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
transform: translateY(-50%); |
||||
|
left: 0; |
||||
|
width: 4rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style9 { |
||||
|
width: 100%; |
||||
|
|
||||
|
.style9-box { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
|
||||
|
.style9-center { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
width: calc(100% - 264rpx); |
||||
|
position: relative; |
||||
|
|
||||
|
text { |
||||
|
max-width: 100%; |
||||
|
overflow: hidden; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
} |
||||
|
|
||||
|
.left-img { |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
text-align: center; |
||||
|
flex-shrink: 0; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.right-img { |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
text-align: center; |
||||
|
flex-shrink: 0; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style9-more { |
||||
|
display: flex; |
||||
|
position: absolute; |
||||
|
right: -140rpx; |
||||
|
/* #ifdef MP-WEIXIN */ |
||||
|
right: -120rpx; |
||||
|
/* #endif */ |
||||
|
top: 14rpx; |
||||
|
line-height: 1; |
||||
|
align-items: center; |
||||
|
|
||||
|
.iconfont { |
||||
|
line-height: 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.sub-title { |
||||
|
line-height: 1; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style10 { |
||||
|
width: 100%; |
||||
|
|
||||
|
.style10-box { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
|
||||
|
.style10-center { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
width: calc(100% - 264rpx); |
||||
|
position: relative; |
||||
|
|
||||
|
text { |
||||
|
max-width: 100%; |
||||
|
overflow: hidden; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
padding-bottom: 8rpx; |
||||
|
z-index: 99; |
||||
|
} |
||||
|
|
||||
|
.left-img { |
||||
|
padding-bottom: 13rpx; |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
text-align: center; |
||||
|
flex-shrink: 0; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.center-img { |
||||
|
width: 198rpx; |
||||
|
height: 18rpx; |
||||
|
text-align: center; |
||||
|
flex-shrink: 0; |
||||
|
position: absolute; |
||||
|
bottom: 26rpx; |
||||
|
z-index: 5; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.right-img { |
||||
|
padding-bottom: 13rpx; |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
text-align: center; |
||||
|
flex-shrink: 0; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style10-more { |
||||
|
display: flex; |
||||
|
position: absolute; |
||||
|
right: -140rpx; |
||||
|
/* #ifdef MP-WEIXIN */ |
||||
|
right: -120rpx; |
||||
|
/* #endif */ |
||||
|
top: 14rpx; |
||||
|
line-height: 1; |
||||
|
align-items: center; |
||||
|
|
||||
|
.iconfont { |
||||
|
line-height: 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.sub-title { |
||||
|
line-height: 1; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style11 { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
|
||||
|
.style11-box { |
||||
|
width: 100%; |
||||
|
margin: 10rpx 0; |
||||
|
|
||||
|
.style11-conter { |
||||
|
.style11-conter-box { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
position: relative; |
||||
|
|
||||
|
.left { |
||||
|
display: flex; |
||||
|
width: 70%; |
||||
|
flex-direction: column; |
||||
|
justify-content: space-between; |
||||
|
height: 100%; |
||||
|
margin: 15rpx 0; |
||||
|
padding-left: 34rpx; |
||||
|
z-index: 9; |
||||
|
|
||||
|
.style11-title { |
||||
|
width: 100%; |
||||
|
overflow: hidden; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
} |
||||
|
|
||||
|
.style11-sub { |
||||
|
letter-spacing: 14rpx; |
||||
|
width: 100%; |
||||
|
overflow: hidden; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style11-more { |
||||
|
display: flex; |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.center-img { |
||||
|
width: 61rpx; |
||||
|
position: absolute; |
||||
|
bottom: -26rpx; |
||||
|
left: 16rpx; |
||||
|
z-index: 0; |
||||
|
} |
||||
|
|
||||
|
.right-img { |
||||
|
width: 35rpx; |
||||
|
position: absolute; |
||||
|
top: -14rpx; |
||||
|
left: 172rpx; |
||||
|
z-index: 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style12 { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
padding: 20rpx; |
||||
|
|
||||
|
.style12-title { |
||||
|
text-align: left; |
||||
|
max-width: 200rpx; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.style12-sub-title { |
||||
|
text-align: left; |
||||
|
max-width: 300rpx; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.style12-more { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
margin-left: auto; |
||||
|
|
||||
|
text { |
||||
|
padding: 0; |
||||
|
max-width: 160rpx; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.style13 { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
|
||||
|
.style13-title { |
||||
|
max-width: 420rpx; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden; |
||||
|
margin: 0 10rpx; |
||||
|
} |
||||
|
|
||||
|
image { |
||||
|
height: 50rpx; |
||||
|
width: 76rpx; |
||||
|
} |
||||
|
|
||||
|
.right-img { |
||||
|
transform: rotateY(180deg); |
||||
|
} |
||||
|
} |
||||
|
.style14 { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
text-align: initial; |
||||
|
align-items: center; |
||||
|
flex: 1; |
||||
|
padding: 0 20rpx; |
||||
|
text { |
||||
|
padding: 0 !important; |
||||
|
} |
||||
|
.title-wrap { |
||||
|
.text { |
||||
|
display: inline-block; |
||||
|
} |
||||
|
.iconfont { |
||||
|
font-size: 24rpx; |
||||
|
&:nth-of-type(1) { |
||||
|
margin-left: 20rpx; |
||||
|
} |
||||
|
&:nth-of-type(2) { |
||||
|
opacity: 0.6; |
||||
|
} |
||||
|
&:nth-of-type(3) { |
||||
|
opacity: 0.4; |
||||
|
} |
||||
|
} |
||||
|
.sub-title { |
||||
|
opacity: 0.6; |
||||
|
} |
||||
|
.more { |
||||
|
text:first-child { |
||||
|
font-size: 28rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.style15 { |
||||
|
flex: 1; |
||||
|
text { |
||||
|
padding: 0 !important; |
||||
|
line-height: 1; |
||||
|
} |
||||
|
.title-wrap { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
} |
||||
|
.ornament { |
||||
|
display: flex; |
||||
|
align-items: flex-end; |
||||
|
.line { |
||||
|
border-left: 8rpx solid; |
||||
|
transform: rotate(40deg); |
||||
|
border-radius: 40rpx; |
||||
|
height: 28rpx; |
||||
|
display: block; |
||||
|
margin-right: 12rpx; |
||||
|
&:nth-of-type(2) { |
||||
|
height: 40rpx; |
||||
|
margin-right: 10rpx; |
||||
|
position: relative; |
||||
|
top: 4rpx; |
||||
|
} |
||||
|
} |
||||
|
.my { |
||||
|
transform: rotate(40deg); |
||||
|
line-height: 0; |
||||
|
position: relative; |
||||
|
top: 4rpx; |
||||
|
.yuan { |
||||
|
font-size: 100rpx; |
||||
|
border-radius: 50%; |
||||
|
width: 8rpx; |
||||
|
height: 8rpx; |
||||
|
display: block; |
||||
|
} |
||||
|
.vertical { |
||||
|
border-left: 8rpx solid; |
||||
|
height: 20rpx; |
||||
|
margin-top: 4rpx; |
||||
|
display: inline-block; |
||||
|
border-radius: 40rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.sub-title { |
||||
|
opacity: 0.6; |
||||
|
text-align: center; |
||||
|
} |
||||
|
} |
||||
|
.style16 { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
padding: 20rpx; |
||||
|
.style16-more { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
margin-left: auto; |
||||
|
& > text { |
||||
|
max-width: 200rpx; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
} |
||||
|
.style16-title { |
||||
|
text-align: left; |
||||
|
max-width: 200rpx; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
.style16-sub-title { |
||||
|
margin-left: 20rpx; |
||||
|
text-align: left; |
||||
|
max-width: 300rpx; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
overflow: hidden; |
||||
|
border-radius: 34rpx; |
||||
|
background-image: radial-gradient(transparent 60%, #fff); |
||||
|
height: 50rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding: 0 20rpx; |
||||
|
position: relative; |
||||
|
&> .js-icon { |
||||
|
padding: 8rpx; |
||||
|
background-image: radial-gradient(transparent 30%, #fff); |
||||
|
border-radius: 50%; |
||||
|
margin-left: -20rpx; |
||||
|
margin-right: 6rpx; |
||||
|
font-size: 28rpx; |
||||
|
line-height: 1; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,108 @@ |
|||||
|
<template> |
||||
|
<view class="" :style="boxStyle"> |
||||
|
<view class="goods-video" v-show="switchMedia == 'video'"> |
||||
|
<video :id="videoId" :src="$util.img(value.videoUrl)" :poster="$util.img(value.imageUrl)" |
||||
|
:style="videoWarpCss + boxStyle" objectFit="contain" :controls="true" :show-fullscreen-btn="true" |
||||
|
:auto-pause-if-navigate="false" :auto-pause-if-open-native="false" :show-mute-btn="true" :autoplay="autoplay" |
||||
|
@pause="pauseVideo()"></video> |
||||
|
</view> |
||||
|
<view style="position: relative;" v-show="switchMedia == 'img'" @click="changeType()"> |
||||
|
<img class="play_icon" :src="$util.img('upload/weapp/user/play_icon.png')" alt=""> |
||||
|
<image class="goods-img" :style="videoWarpCss + boxStyle" :src="$util.img(value.imageUrl)" mode="scaleToFill" |
||||
|
style="width: 100%;"> |
||||
|
</image> |
||||
|
</view> |
||||
|
|
||||
|
|
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 视频 |
||||
|
export default { |
||||
|
name: 'diy-video', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
videoId: 'video' + this._uid, |
||||
|
switchMedia: "img", |
||||
|
autoplay: false, |
||||
|
videoKey: 1, |
||||
|
boxStyle: {}, |
||||
|
videoContext: null |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
created() { |
||||
|
uni.$on('videoStop', () => { |
||||
|
this.pauseVideo() |
||||
|
}) |
||||
|
// uni.$on('videoStart', () => { |
||||
|
// this.changeType() |
||||
|
// }) |
||||
|
this.videoContext = uni.createVideoContext(this.videoId) |
||||
|
}, |
||||
|
computed: { |
||||
|
videoWarpCss: function () { |
||||
|
var obj = ''; |
||||
|
if (this.value.componentAngle == 'round') { |
||||
|
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; |
||||
|
} |
||||
|
this.calcStyle() |
||||
|
return obj; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
calcStyle() { |
||||
|
// uni.getSystemInfo({ |
||||
|
// success: res => { |
||||
|
// const { screenWidth, screenHeight, ratio } = res |
||||
|
// } |
||||
|
// }); |
||||
|
this.$nextTick(() => { |
||||
|
this.boxStyle = `width: 100%; height: ${this.value.imgHeight / (this.value.imgWidth / 690)}rpx;` |
||||
|
// this.boxStyle = { |
||||
|
// width: '100%', |
||||
|
// height: this.value.imgHeight / (this.value.imgWidth / 690) + 'rpx' |
||||
|
// } |
||||
|
}) |
||||
|
}, |
||||
|
changeType() { |
||||
|
this.switchMedia = "video"; |
||||
|
this.autoplay = true; |
||||
|
this.videoContext.play(); |
||||
|
}, |
||||
|
pauseVideo() { |
||||
|
this.switchMedia = "img"; |
||||
|
this.autoplay = false; |
||||
|
|
||||
|
this.videoContext.pause(); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
video { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.play_icon { |
||||
|
width: 80rpx; |
||||
|
height: 80rpx; |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
margin: auto; |
||||
|
z-index: 10; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,127 @@ |
|||||
|
<template> |
||||
|
<!-- IP选择器 --> |
||||
|
<view class=""> |
||||
|
<picker mode='selector' @change="selectIP" @cancel="selectIPStatus = false; IPclickNum = 0" :value="selectIPindex" |
||||
|
:range="IPArray" range-key="title"> |
||||
|
<view class="uni-input" style="text-align: center;color: #fff;background-color: #000;" v-if="selectIPStatus"> |
||||
|
<text>当前服务器:</text> |
||||
|
<text>{{ IPArray[selectIPindex].title }}</text> |
||||
|
</view> |
||||
|
</picker> |
||||
|
|
||||
|
<!-- 自定义IP弹出框 --> |
||||
|
<uniPopup ref="changeIPRef"> |
||||
|
<view class="" |
||||
|
style="width: 80vw;height: 30vh;background-color: #FFFFFF;border-radius: 20rpx;padding: 30rpx;text-align: center;"> |
||||
|
<view style="width: 100%;font-size: 40rpx;border-bottom: 1rpx solid #e3e3e3;margin-bottom: 20rpx;">自定义服务器</view> |
||||
|
<view class=""> |
||||
|
<textarea v-model="ipConfigChange" style="border: 1rpx solid #e3e3e3;padding: 20rpx;" :maxlength="80" focus |
||||
|
auto-height placeholder-style="color:#ffee89" placeholder="注意使用英文标点符号与大小写" /> |
||||
|
<text style="color: #dadada;font-size: 20rpx;">参考案例:<text |
||||
|
style="color: #ef6d53;">https://www.baidu.com/</text></text> |
||||
|
<button type="primary" style="position: absolute;bottom: 0;width: 90%;margin-bottom: 20rpx;" |
||||
|
@tap="comfirmSelectIP(selectIPindex, ipConfigChange)">确定</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</uniPopup> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import uniPopup from "./uni-popup/uni-popup" |
||||
|
export default { |
||||
|
name: "egg", |
||||
|
components: { |
||||
|
uniPopup |
||||
|
}, |
||||
|
props: { |
||||
|
// 时间范围限制(单位毫秒:1s=1000ms) |
||||
|
IPArray: { |
||||
|
type: Array |
||||
|
}, |
||||
|
defaultIP: { |
||||
|
type: String, |
||||
|
}, |
||||
|
time: { |
||||
|
type: Number, |
||||
|
default: 1200 |
||||
|
}, |
||||
|
// 触发条件 |
||||
|
clickNum: { |
||||
|
type: Number, |
||||
|
default: 8 |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
ipConfigChange: "", // 自定义IP |
||||
|
selectIPStatus: false, |
||||
|
selectIPindex: 0, |
||||
|
IPclickNum: 0, |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 打开IP选择器 使用方法 this.$refs.switchIp.openSelectIP() |
||||
|
openSelectIP() { |
||||
|
this.IPclickNum++ |
||||
|
let countNum = this.clickNum // 点击触发次数配置 |
||||
|
// if (this.IPclickNum > (countNum - countNum / 2) && this.IPclickNum < countNum) { |
||||
|
// uni.showToast({ |
||||
|
// title: '距离打开隐藏关卡,还差' + (countNum - this.IPclickNum) + '步', |
||||
|
// icon: "none", |
||||
|
// duration: 800 |
||||
|
// }); |
||||
|
// } |
||||
|
if (this.IPclickNum >= countNum) { |
||||
|
this.IPclickNum = 0 |
||||
|
// 查找当前IP配置 |
||||
|
this.IPArray.find((item, index) => { |
||||
|
if (item.ipConfig == this.defaultIP) { |
||||
|
this.selectIPindex = index |
||||
|
} |
||||
|
}) |
||||
|
uni.showToast({ |
||||
|
title: '您当前正在使用IP:' + this.defaultIP, |
||||
|
icon: "none", |
||||
|
duration: 3000 |
||||
|
}); |
||||
|
this.selectIPStatus = true // 显示IP配置 |
||||
|
} |
||||
|
// 时间限制 |
||||
|
setTimeout(() => { |
||||
|
this.IPclickNum = 0 |
||||
|
}, this.time) |
||||
|
}, |
||||
|
// 选择指定IP |
||||
|
selectIP(event) { |
||||
|
// 设置选中下标 |
||||
|
this.selectIPindex = event.detail.value |
||||
|
// 选择自定义IP |
||||
|
if (event.detail.value === 2) { |
||||
|
// 为自定义IP赋默认值,方便快速修改 |
||||
|
this.ipConfigChange = this.IPArray[event.detail.value].ipConfig |
||||
|
// 打开自定义IP弹出框 |
||||
|
this.$refs.changeIPRef.open() |
||||
|
} |
||||
|
this.comfirmSelectIP(event.detail.value) |
||||
|
}, |
||||
|
// 自定义IP确定更改 |
||||
|
comfirmSelectIP(index, value) { |
||||
|
// 自定义IP配置 |
||||
|
if (value && index === 2) { |
||||
|
this.IPArray[index].ipConfig = value |
||||
|
this.$refs.changeIPRef.close() |
||||
|
} |
||||
|
// 公用设置 |
||||
|
this.selectIPStatus = false |
||||
|
// 修改IP配置 |
||||
|
this.$emit("change", this.IPArray[index]) |
||||
|
uni.showToast({ |
||||
|
title: '请注意!正在使用' + JSON.stringify(this.IPArray[index]), |
||||
|
icon: "none", |
||||
|
duration: 3000 |
||||
|
}); |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
File diff suppressed because it is too large
@ -0,0 +1,39 @@ |
|||||
|
<template> |
||||
|
<text v-if="userInfo.show_price && token"> |
||||
|
<text class="price-symbol price-font">¥</text> |
||||
|
<template v-if="goodsSkuDetail.discount_price > 0"> |
||||
|
<text class="price price-font">{{ goodsSkuDetail.discount_price }}</text> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<template v-if="goodsSkuDetail.member_price > 0"> |
||||
|
<text class="price price-font">{{ goodsSkuDetail.member_price }}</text> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<text class="price price-font">{{ goodsSkuDetail.price}}</text> |
||||
|
</template> |
||||
|
|
||||
|
</template> |
||||
|
</text> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { mapGetters } from 'vuex'; |
||||
|
export default { |
||||
|
props: { |
||||
|
goodsSkuDetail: { |
||||
|
type: Object |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
token: uni.getStorageSync('token') |
||||
|
}; |
||||
|
}, |
||||
|
computed: { |
||||
|
...mapGetters(['userInfo']) |
||||
|
}, |
||||
|
// inject: ['showDiscount'] |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped></style> |
||||
@ -0,0 +1,992 @@ |
|||||
|
<template> |
||||
|
<!-- 一行一个 --> |
||||
|
<div class="seckill-item"> |
||||
|
<div class="cover" @click="click"> |
||||
|
<view class="cover1"><img :src="item[coverName]" /></view> |
||||
|
<!-- <view class="cover1"> |
||||
|
<image :src="$util.img(item[coverName])" alt="" /> |
||||
|
</view> --> |
||||
|
<!-- <image :src="$util.img(item.goods_image)" mode="aspectFill"></image> --> |
||||
|
<!-- <view class="time">销量:{{ item.sale_num }}</view> --> |
||||
|
<!-- <div class="time">23:23:46</div> --> |
||||
|
</div> |
||||
|
<div class="right"> |
||||
|
<div class="title" @click="click">{{ item.goods_name }}</div> |
||||
|
<div class="labels-1" @click="click"> |
||||
|
<div class="label-item">产地:{{ item.address }}</div> |
||||
|
<div class="label-item">规格:{{ item.spec_name||'-' }}</div> |
||||
|
<div class="label-item" v-if=" item.execu_content">执行标准:{{ item.execu_content.title ||'-'}}</div> |
||||
|
<div class="label-item">生产企业:{{ item.business }}</div> |
||||
|
</div> |
||||
|
<div class="bottom" v-if="userInfo.show_price && token"> |
||||
|
<div class="price" @click="click"> |
||||
|
¥ |
||||
|
<text class="price1"> |
||||
|
{{ |
||||
|
parseFloat(showPrice(item)) |
||||
|
.toFixed(2) |
||||
|
.split('.')[0] |
||||
|
}} |
||||
|
</text> |
||||
|
. |
||||
|
<text> |
||||
|
{{ |
||||
|
parseFloat(showPrice(item)) |
||||
|
.toFixed(2) |
||||
|
.split('.')[1] |
||||
|
}} |
||||
|
</text> |
||||
|
/{{ item.unit ? item.unit : '件' }} |
||||
|
</div> |
||||
|
<div style="display: flex;align-items: ceter;margin-top: 20rpx;" v-if="item.stock"> |
||||
|
<view slot="minus" class="minus" @click.stop="numChange(item, 'minus')"> |
||||
|
<u-icon name="minus-circle-fill" size="20" color="var(--base-color)"></u-icon> |
||||
|
</view> |
||||
|
<view class="df aic jcsa" style="margin:0 24rpx;" @click="focus(item)"> |
||||
|
{{ item.cart_num || 0 }} |
||||
|
</view> |
||||
|
<view slot="plus" class="minus" @click.stop="numChange(item, 'add')"> |
||||
|
<u-icon name="plus-circle-fill" size="20" color="var(--base-color)"></u-icon> |
||||
|
</view> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<div style="display: flex;align-items: ceter;margin-top: 20rpx;" v-else>库存不足</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<uni-popup ref="skuPopup" type="bottom" class="sku-layer" v-if="goods_Item_Detail"> |
||||
|
<view class="sku-info"> |
||||
|
<view class="header"> |
||||
|
<view class="img-wrap" @click="previewMedia()"> |
||||
|
<image :src="$util.img(goods_Item_Detail.sku_image, { size: 'mid' })" mode="aspectFit" /> |
||||
|
</view> |
||||
|
|
||||
|
<view class="main"> |
||||
|
<view class="goods_name">{{ goods_Item_Detail.goods_name }}</view> |
||||
|
<view class="price-wrap"> |
||||
|
<text class="unit price-style small">¥</text> |
||||
|
|
||||
|
<block> |
||||
|
<text class="price price-style large"> |
||||
|
{{ |
||||
|
parseFloat(showPrice(goods_Item_Detail)) |
||||
|
.toFixed(2) |
||||
|
.split('.')[0] |
||||
|
}} |
||||
|
</text> |
||||
|
|
||||
|
<text class="unit price-style small"> |
||||
|
.{{ |
||||
|
parseFloat(showPrice(goods_Item_Detail)) |
||||
|
.toFixed(2) |
||||
|
.split('.')[1] |
||||
|
}} |
||||
|
</text> |
||||
|
</block> |
||||
|
</view> |
||||
|
<view class="stock"> |
||||
|
<block v-if="goods_Item_Detail.stock_show"> |
||||
|
库存{{ goods_Item_Detail.stock }} |
||||
|
</block> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="sku-close iconfont icon-close" @click="closeSkuPopup()"></view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="body-item"> |
||||
|
<scroll-view scroll-y class="wrap"> |
||||
|
<view class="number-wrap"> |
||||
|
<view class="number-line"> |
||||
|
<text class="title font-size-base">购买数量</text> |
||||
|
<text class="limit-txt color-base-text" v-if="limitNumber > 0"> |
||||
|
(每人限购{{ limitNumber }}件) |
||||
|
</text> |
||||
|
<text v-if=" |
||||
|
goods_Item_Detail.maxBuy > 0 && goods_Item_Detail.minBuy > 1 |
||||
|
" class="limit-txt color-base-text"> |
||||
|
({{ goods_Item_Detail.minBuy }}件起售,限购{{ |
||||
|
goods_Item_Detail.maxBuy |
||||
|
}}件) |
||||
|
</text> |
||||
|
<text v-else-if="goods_Item_Detail.maxBuy > 0" class="limit-txt color-base-text"> |
||||
|
(限购{{ goods_Item_Detail.maxBuy }}件) |
||||
|
</text> |
||||
|
<text v-else-if="goods_Item_Detail.minBuy > 1" class="limit-txt color-base-text"> |
||||
|
({{ goods_Item_Detail.minBuy }}件起售) |
||||
|
</text> |
||||
|
<view class="number"> |
||||
|
<button type="default" class="decrease color-line-border" |
||||
|
:class="{ disabled: decreaseDisabled }" @click="changeNum('-')"> |
||||
|
- |
||||
|
</button> |
||||
|
<input id="tet" type="number" |
||||
|
class="uni-input color-line-border font-size-goods-tag" disabled="true" |
||||
|
v-model="number" placeholder="0" /> |
||||
|
|
||||
|
<button type="default" class="increase color-line-border" |
||||
|
:class="{ disabled: increaseDisabled }" @click="changeNum('+')"> |
||||
|
+ |
||||
|
</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
</view> |
||||
|
<u-number-keyboard mode="number" @change="change" :dotDisabled="true" |
||||
|
@backspace="backspace"></u-number-keyboard> |
||||
|
|
||||
|
<view class="footer"> |
||||
|
<button type="primary" v-if="goods_Item_Detail.stock" @click="confirm()"> |
||||
|
加入购物车 |
||||
|
</button> |
||||
|
|
||||
|
<button type="primary" v-else disabled="true">库存不足</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</uni-popup> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { mapGetters } from 'vuex'; |
||||
|
export default { |
||||
|
name: 'horizontalGoodsItem', |
||||
|
props: { |
||||
|
item: { |
||||
|
default: () => {} |
||||
|
}, |
||||
|
coverName: { |
||||
|
default: 'cover' |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
token: uni.getStorageSync('token'), |
||||
|
goodsSkuDetail: { |
||||
|
goods_id: 0, |
||||
|
goods_service: [] |
||||
|
}, |
||||
|
goods_name: '', |
||||
|
discount_price: '', |
||||
|
sku_id: '', |
||||
|
unit: '', |
||||
|
stock: Number, |
||||
|
goods_image: '', |
||||
|
number: 1, |
||||
|
limitNumber: 0, // 限购 |
||||
|
minNumber: 0, |
||||
|
goods_Item_Detail: {}, |
||||
|
loading: false, |
||||
|
keyboardShow: true |
||||
|
}; |
||||
|
}, |
||||
|
computed: { |
||||
|
...mapGetters(['userInfo']), |
||||
|
decreaseDisabled: function() { |
||||
|
let min = this.goods_Item_Detail.minBuy > 0 ? this.goods_Item_Detail.minBuy : 1; |
||||
|
return this.goods_Item_Detail.number <= min; |
||||
|
}, |
||||
|
increaseDisabled: function() { |
||||
|
let max = |
||||
|
this.goods_Item_Detail.maxBuy > 0 && |
||||
|
this.goods_Item_Detail.maxBuy < this.goods_Item_Detail.stock ? |
||||
|
this.goods_Item_Detail.maxBuy : |
||||
|
this.goods_Item_Detail.stock; |
||||
|
return this.goods_Item_Detail.number >= max; |
||||
|
}, |
||||
|
}, |
||||
|
methods: { |
||||
|
backspace() { |
||||
|
let str = String(this.number); |
||||
|
str = str.slice(0, -1); |
||||
|
this.number = str; |
||||
|
}, |
||||
|
change(e) { |
||||
|
if (!this.number) { |
||||
|
this.number = e; |
||||
|
} else { |
||||
|
this.number = this.number + String(e); |
||||
|
} |
||||
|
}, |
||||
|
click() { |
||||
|
this.$emit('click', this.item); |
||||
|
}, |
||||
|
inputBlur(event, item) { |
||||
|
const v = event.detail.value; |
||||
|
item.cart_num = 1; |
||||
|
const zero = /^(0{2,})|[^0-9]/g; |
||||
|
let final = 0; |
||||
|
if (!v) { |
||||
|
final = 0; |
||||
|
} else { |
||||
|
final = v.toString().replace(zero, v => { |
||||
|
return 0; |
||||
|
}); |
||||
|
|
||||
|
if (final.split('')[0] * 1 === 0) { |
||||
|
final = final.slice(1) - 0 || 0; |
||||
|
} |
||||
|
} |
||||
|
this.$nextTick(() => { |
||||
|
item.cart_num = final.toString() || 0; |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/cart/add', |
||||
|
data: { |
||||
|
num: v, |
||||
|
sku_id: item.sku_id, |
||||
|
is_all: 1 |
||||
|
}, |
||||
|
success: () => { |
||||
|
this.$store.dispatch('getCartNumber'); |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
}, |
||||
|
goodsTag(data) { |
||||
|
return data.label_name || ''; |
||||
|
}, |
||||
|
showPrice(data) { |
||||
|
let price = data.discount_price; |
||||
|
if (data.member_price && parseFloat(data.member_price) < parseFloat(price)) |
||||
|
price = data.member_price; |
||||
|
return price; |
||||
|
}, |
||||
|
focus(item) { |
||||
|
this.number = item.cart_num; |
||||
|
uni.hideKeyboard(); |
||||
|
this.getGoodsItem(item); |
||||
|
uni.removeStorageSync('buyer_message'); |
||||
|
}, |
||||
|
changeNum(tag) { |
||||
|
|
||||
|
if (this.goods_Item_Detail.max_buy) { |
||||
|
// is_limit 是否限购 limit_type限购类型 1单次 2长期 |
||||
|
if (this.goods_Item_Detail.is_limit && this.goods_Item_Detail.limit_type == 1) { |
||||
|
if (this.goods_Item_Detail.number >= this.goods_Item_Detail.max_buy && tag == "+") { |
||||
|
this.$util.showToast({ |
||||
|
title: `每人限购${this.goods_Item_Detail.max_buy}件` |
||||
|
}); |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} else if (this.goods_Item_Detail.is_limit && this.goods_Item_Detail.limit_type == 2) { |
||||
|
if (this.goods_Item_Detail.purchased_num >= this.goods_Item_Detail.max_buy) { |
||||
|
this.$util.showToast({ |
||||
|
// title: `每人长期限购${this.goods_Item_Detail.max_buy}件,您已购买${this.goods_Item_Detail.purchased_num}件` |
||||
|
title: `每人长期限购${this.goods_Item_Detail.max_buy}件` |
||||
|
}); |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
if (this.goods_Item_Detail.stock == 0) return; |
||||
|
var min = 1; |
||||
|
var stock = this.goods_Item_Detail.stock; |
||||
|
|
||||
|
if (this.maxBuy == 1) { |
||||
|
stock = 1; |
||||
|
} |
||||
|
|
||||
|
if (this.goods_Item_Detail.is_limit == 1 && this.maxBuy > 0 && this.maxBuy < stock) |
||||
|
stock = this.maxBuy; |
||||
|
|
||||
|
if ( |
||||
|
this.goods_Item_Detail.is_limit == 1 && |
||||
|
this.goods_Item_Detail.limit_type == 2 && |
||||
|
this.maxBuy > 0 && |
||||
|
this.goods_Item_Detail.purchased_num > 0 |
||||
|
) { |
||||
|
let maxBuy = this.maxBuy - this.goods_Item_Detail.purchased_num; |
||||
|
stock = |
||||
|
maxBuy < this.goods_Item_Detail.stock ? maxBuy : this.goods_Item_Detail.stock; |
||||
|
} |
||||
|
|
||||
|
if (this.minBuy > 1) { |
||||
|
min = this.minBuy; |
||||
|
} |
||||
|
|
||||
|
if (tag == '+') { |
||||
|
// 加 |
||||
|
if (this.number < stock) { |
||||
|
this.number++; |
||||
|
} else { |
||||
|
if (this.number >= this.goods_Item_Detail.stock) { |
||||
|
this.$util.showToast({ |
||||
|
title: '库存不足' |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (this.goods_Item_Detail.is_limit == 1 && this.maxBuy > 0) { |
||||
|
if (this.goods_Item_Detail.limit_type == 1) { |
||||
|
this.$util.showToast({ |
||||
|
title: '该商品每次最多购买' + this.maxBuy + this.goods_Item_Detail.unit |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (this.goods_Item_Detail.limit_type == 2) { |
||||
|
let message = |
||||
|
'该商品每人限购' + this.maxBuy + this.goods_Item_Detail.unit; |
||||
|
message += |
||||
|
this.goods_Item_Detail.purchased_num > 0 ? |
||||
|
',您已购买了' + |
||||
|
this.goods_Item_Detail.purchased_num + |
||||
|
this.goods_Item_Detail.unit : |
||||
|
''; |
||||
|
this.$util.showToast({ |
||||
|
title: message |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ( |
||||
|
this.type == 'seckill' && |
||||
|
this.goods_Item_Detail.seckill_id && |
||||
|
this.goods_Item_Detail.num > 0 |
||||
|
) { |
||||
|
this.$util.showToast({ |
||||
|
title: '该商品每人限购' + |
||||
|
this.goods_Item_Detail.num + |
||||
|
this.goods_Item_Detail.unit |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if ( |
||||
|
this.type == 'presale' && |
||||
|
this.goods_Item_Detail.presale_id && |
||||
|
this.goods_Item_Detail.presale_num > 0 |
||||
|
) { |
||||
|
this.$util.showToast({ |
||||
|
title: '该商品每人限购' + |
||||
|
this.goods_Item_Detail.presale_num + |
||||
|
this.goods_Item_Detail.unit |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
} else if (tag == '-') { |
||||
|
// 减 |
||||
|
if (this.number > min) { |
||||
|
this.number -= 1; |
||||
|
} else { |
||||
|
if (this.minBuy > 1) { |
||||
|
this.$util.showToast({ |
||||
|
title: '该商品' + this.minBuy + '件起售' |
||||
|
}); |
||||
|
} |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
if (this.number > this.limitNumber && this.limitNumber) { |
||||
|
this.number = this.limitNumber; |
||||
|
} |
||||
|
}, |
||||
|
//输入数量 |
||||
|
keyInput(flag, callback) { |
||||
|
setTimeout(() => { |
||||
|
var stock = this.goods_Item_Detail.stock; |
||||
|
|
||||
|
// 库存为0 |
||||
|
if (this.goods_Item_Detail.stock == 0) { |
||||
|
this.number = 0; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// 防止空 |
||||
|
if (flag && this.number.length == 0) this.number = 1; |
||||
|
|
||||
|
// 防止输入0和负数、非法输入 |
||||
|
if (flag && (this.number <= 0 || isNaN(this.number))) this.number = 1; |
||||
|
|
||||
|
if (this.number > stock) { |
||||
|
this.number = stock; |
||||
|
} |
||||
|
// 商品起售数 |
||||
|
if (this.minBuy > 1 && this.number < this.minBuy) { |
||||
|
this.number = this.minBuy; |
||||
|
} |
||||
|
|
||||
|
if (flag) this.number = parseInt(this.number); |
||||
|
if (callback) callback(); |
||||
|
}, 0); |
||||
|
}, |
||||
|
//提交 |
||||
|
confirm() { |
||||
|
// 删除待付款物流方式缓存 |
||||
|
uni.removeStorageSync('delivery'); |
||||
|
if (this.preview) { |
||||
|
this.$util.showToast({ |
||||
|
title: '预览商品无法购买' |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!uni.getStorageSync('token')) { |
||||
|
this.$refs.login.open(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
//纠正数量 |
||||
|
this.keyInput(true, () => { |
||||
|
if (this.goods_Item_Detail.stock == 0) { |
||||
|
this.$util.showToast({ |
||||
|
title: '商品已售罄' |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (this.number.length == 0 || this.number <= 0) { |
||||
|
this.$util.showToast({ |
||||
|
title: '购买数量不能小于等于0' |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (this.goods_Item_Detail.buy_num > this.goods_Item_Detail.stock) { |
||||
|
this.$util.showToast({ |
||||
|
title: '库存小于最低购买数量' |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (this.number > this.goods_Item_Detail.stock) { |
||||
|
this.$util.showToast({ |
||||
|
title: '库存不足' |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if ( |
||||
|
this.goods_Item_Detail.is_limit == 1 && |
||||
|
this.goods_Item_Detail.limit_type == 1 && |
||||
|
this.maxBuy > 0 && |
||||
|
this.number > this.maxBuy |
||||
|
) { |
||||
|
this.$util.showToast({ |
||||
|
title: '该商品每次最多购买' + this.maxBuy + this.goods_Item_Detail.unit |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if ( |
||||
|
this.goods_Item_Detail.is_limit == 1 && |
||||
|
this.goods_Item_Detail.limit_type == 2 && |
||||
|
this.maxBuy > 0 && |
||||
|
this.number + this.goods_Item_Detail.purchased_num > this.maxBuy |
||||
|
) { |
||||
|
let message = '该商品每人限购' + this.maxBuy + this.goods_Item_Detail.unit; |
||||
|
message += |
||||
|
this.goods_Item_Detail.purchased_num > 0 ? |
||||
|
',您已购买了' + |
||||
|
this.goods_Item_Detail.purchased_num + |
||||
|
this.goods_Item_Detail.unit : |
||||
|
''; |
||||
|
this.$util.showToast({ |
||||
|
title: message |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if ( |
||||
|
this.type == 'join_cart' && |
||||
|
this.goods_Item_Detail.is_limit == 1 && |
||||
|
this.maxBuy > 0 && |
||||
|
this.cartNumber + this.number > this.maxBuy |
||||
|
) { |
||||
|
this.$util.showToast({ |
||||
|
title: '该商品每人限购' + this.maxBuy + this.goods_Item_Detail.unit |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (this.goods_Item_Detail.max_buy) { |
||||
|
if (this.goods_Item_Detail.purchased_num >= this.goods_Item_Detail.max_buy) { |
||||
|
this.$util.showToast({ |
||||
|
title: `每人限购${this.goods_Item_Detail.max_buy}件,您已购买${this.goods_Item_Detail.purchased_num}件` |
||||
|
}); |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (this.goods_Item_Detail.max_buy) { |
||||
|
// is_limit 是否限购 limit_type限购类型 1单次 2长期 |
||||
|
if (this.goods_Item_Detail.is_limit && this.goods_Item_Detail.limit_type == 1) { |
||||
|
if (this.number > this.goods_Item_Detail.max_buy) { |
||||
|
this.$util.showToast({ |
||||
|
title: `每人限购${this.goods_Item_Detail.max_buy}件` |
||||
|
}); |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} else if (this.goods_Item_Detail.is_limit && this.goods_Item_Detail.limit_type == 2) { |
||||
|
if (this.goods_Item_Detail.purchased_num >= this.goods_Item_Detail.max_buy) { |
||||
|
this.$util.showToast({ |
||||
|
// title: `每人长期限购${this.goods_Item_Detail.max_buy}件,您已购买${this.goods_Item_Detail.purchased_num}件` |
||||
|
title: `每人长期限购${this.goods_Item_Detail.max_buy}件` |
||||
|
}); |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
if (this.btnSwitch) return; |
||||
|
this.btnSwitch = true; |
||||
|
|
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/cart/add', |
||||
|
data: { |
||||
|
sku_id: this.goods_Item_Detail.sku_id, |
||||
|
num: this.number, |
||||
|
is_all: 1 |
||||
|
}, |
||||
|
success: res => { |
||||
|
var data = res.data; |
||||
|
if (data > 0) { |
||||
|
this.$util.showToast({ |
||||
|
title: '加入购物车成功' |
||||
|
}); |
||||
|
this.cartNumber += this.number; |
||||
|
if (this.callback) this.callback(); |
||||
|
this.$store.dispatch('getCartNumber'); |
||||
|
} |
||||
|
|
||||
|
// uni.$emit('refresh', true); |
||||
|
|
||||
|
this.$refs.skuPopup.close(); |
||||
|
this.btnSwitch = false; |
||||
|
}, |
||||
|
fail: res => { |
||||
|
this.$refs.skuPopup.close(); |
||||
|
this.btnSwitch = false; |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
}, |
||||
|
getGoodsItem(item) { |
||||
|
this.loading = true; |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/goodssku/detail', |
||||
|
data: { |
||||
|
goods_id: item.goods_id |
||||
|
}, |
||||
|
success: res => { |
||||
|
this.goods_Item_Detail = res.data.goods_sku_detail; |
||||
|
this.goods_Item_Detail.goods_spec_format = JSON.parse( |
||||
|
res.data.goods_sku_detail.goods_spec_format |
||||
|
); |
||||
|
this.goods_Item_Detail.number = item.cart_num; |
||||
|
this.$refs.skuPopup.open(); |
||||
|
uni.$emit('cartBottomShow', false); |
||||
|
this.loading = false; |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
numChange(item, type) { |
||||
|
|
||||
|
if (item.max_buy) { |
||||
|
// is_limit 是否限购 limit_type限购类型 1单次 2长期 |
||||
|
if (item.is_limit && item.limit_type == 1) { |
||||
|
if (item.cart_num >= item.max_buy && type == "add") { |
||||
|
this.$util.showToast({ |
||||
|
title: `每人限购${item.max_buy}件` |
||||
|
}); |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} else if (item.is_limit && item.limit_type == 2) { |
||||
|
if (item.purchased_num >= item.max_buy) { |
||||
|
this.$util.showToast({ |
||||
|
// title: `每人长期限购${item.max_buy}件,您已购买${item.purchased_num}件` |
||||
|
title: `每人长期限购${item.max_buy}件` |
||||
|
}); |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (type == 'add') { |
||||
|
if (item.cart_num >= item.stock) { |
||||
|
this.$util.showToast({ |
||||
|
title: '库存不足' |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
item.cart_num = Number(item.cart_num); |
||||
|
let setp = 1; |
||||
|
item.cart_num ? item.cart_num : (item.cart_num = 0); |
||||
|
if (type == 'minus' && !item.cart_num) { |
||||
|
return; |
||||
|
} |
||||
|
if (!item.cart_num || item.is_multiple) { |
||||
|
setp = item.min_buy || 1; |
||||
|
} else { |
||||
|
if (type == 'add') { |
||||
|
setp = item.cart_num >= item.min_buy ? 1 : item.min_buy; |
||||
|
} else { |
||||
|
setp = item.cart_num == item.min_buy ? item.min_buy : 1; |
||||
|
} |
||||
|
} |
||||
|
type == 'add' ? (item.cart_num += setp) : (item.cart_num -= setp); |
||||
|
this.$forceUpdate(); |
||||
|
this.$api.sendRequest({ |
||||
|
url: '/api/cart/add', |
||||
|
data: { |
||||
|
num: item.cart_num, |
||||
|
sku_id: item.sku_id, |
||||
|
is_all: 1 |
||||
|
}, |
||||
|
success: ({ data }) => { |
||||
|
if (data > 0) { |
||||
|
this.$util.showToast({ |
||||
|
title: '加入购物车成功' |
||||
|
}); |
||||
|
this.$forceUpdate(); |
||||
|
this.cartNumber += this.number; |
||||
|
if (this.callback) this.callback(); |
||||
|
this.$store.dispatch('getCartNumber'); |
||||
|
// uni.$emit('refresh', true); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.seckill-item { |
||||
|
background-color: #fff; |
||||
|
margin-bottom: 30rpx; |
||||
|
padding: 24rpx; |
||||
|
display: flex; |
||||
|
line-height: 40rpx; |
||||
|
|
||||
|
border-radius: 16rpx; |
||||
|
|
||||
|
.labels-1 { |
||||
|
margin-top: 10rpx !important; |
||||
|
|
||||
|
.label-item { |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
display: -webkit-box; |
||||
|
-webkit-line-clamp: 1; |
||||
|
-webkit-box-orient: vertical; |
||||
|
font-size: 28rpx !important; |
||||
|
font-family: PingFangSC-Regular, PingFang SC; |
||||
|
font-weight: 400; |
||||
|
color: #999999 !important; |
||||
|
line-height: 40rpx !important; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.right { |
||||
|
padding-left: 20rpx; |
||||
|
flex: 1; |
||||
|
font-size: 24rpx; |
||||
|
font-family: PingFangSC-Regular, PingFang SC; |
||||
|
font-weight: 400; |
||||
|
color: #999999; |
||||
|
|
||||
|
.bottom { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
margin-top: 16rpx; |
||||
|
|
||||
|
.price { |
||||
|
// height: 104rpx; |
||||
|
font-size: 28rpx; |
||||
|
font-family: DINAlternate-Bold, DINAlternate; |
||||
|
font-weight: bold; |
||||
|
color: #f33b50; |
||||
|
|
||||
|
.price1 { |
||||
|
font-size: 40rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
font-size: 32rpx; |
||||
|
font-family: PingFangSC-Medium, PingFang SC; |
||||
|
font-weight: 500; |
||||
|
color: #333333; |
||||
|
margin-bottom: 16rpx; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
display: -webkit-box; |
||||
|
-webkit-line-clamp: 1; |
||||
|
-webkit-box-orient: vertical; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.cover1 { |
||||
|
width: 44vw; |
||||
|
height: 44vw; |
||||
|
border-radius: 16rpx; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
|
||||
|
img { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
border-radius: 16rpx; |
||||
|
object-fit: cover; |
||||
|
} |
||||
|
|
||||
|
.time { |
||||
|
width: 100%; |
||||
|
position: absolute; |
||||
|
text-align: center; |
||||
|
font-size: 30rpx; |
||||
|
font-family: PingFangSC-Regular, PingFang SC; |
||||
|
font-weight: 400; |
||||
|
color: #ffffff; |
||||
|
line-height: 44rpx; |
||||
|
background-color: rgba(0, 0, 0, 0.4); |
||||
|
bottom: 0; |
||||
|
border-radius: 0 0 8rpx 8rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.sku-layer { |
||||
|
|
||||
|
.sku-info { |
||||
|
max-height: 75vh; |
||||
|
height: 65vh; |
||||
|
position: relative; |
||||
|
|
||||
|
.header { |
||||
|
padding: 30rpx 30rpx 20rpx 210rpx; |
||||
|
position: relative; |
||||
|
border-bottom: 2rpx solid $color-line; |
||||
|
min-height: 170rpx; |
||||
|
|
||||
|
.img-wrap { |
||||
|
width: 160rpx; |
||||
|
height: 160rpx; |
||||
|
position: absolute; |
||||
|
left: 20rpx; |
||||
|
border-radius: $border-radius; |
||||
|
overflow: hidden; |
||||
|
padding: 2rpx; |
||||
|
background-color: #fff; |
||||
|
line-height: 208rpx; |
||||
|
|
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.main { |
||||
|
font-size: 24rpx; |
||||
|
line-height: 40rpx; |
||||
|
padding-right: 40rpx; |
||||
|
|
||||
|
.price-wrap { |
||||
|
font-weight: bold; |
||||
|
|
||||
|
.unit { |
||||
|
margin-right: 4rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.stock { |
||||
|
font-size: $font-size-tag; |
||||
|
color: $color-tip; |
||||
|
display: -webkit-box; |
||||
|
-webkit-line-clamp: 2; |
||||
|
-webkit-box-orient: vertical; |
||||
|
height: 70rpx; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.price { |
||||
|
word-wrap: break-word; |
||||
|
} |
||||
|
|
||||
|
.goods_name { |
||||
|
font-size: 30rpx; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
|
||||
|
.sku-name { |
||||
|
display: -webkit-box; |
||||
|
-webkit-line-clamp: 1; |
||||
|
-webkit-box-orient: vertical; |
||||
|
overflow: hidden; |
||||
|
height: 42rpx; |
||||
|
|
||||
|
.spec-value { |
||||
|
&::after { |
||||
|
content: '/'; |
||||
|
} |
||||
|
|
||||
|
&:last-child { |
||||
|
&::after { |
||||
|
content: ''; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.sku-close { |
||||
|
position: absolute; |
||||
|
top: 20rpx; |
||||
|
right: 40rpx; |
||||
|
width: 40rpx; |
||||
|
height: 80rpx; |
||||
|
font-size: 40rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.body-item { |
||||
|
padding: 0 30rpx; |
||||
|
height: 120rpx; |
||||
|
box-sizing: border-box; |
||||
|
overflow: scroll; |
||||
|
|
||||
|
.wrap { |
||||
|
height: 120rpx; |
||||
|
} |
||||
|
|
||||
|
.sku-list-wrap { |
||||
|
padding-bottom: 0rpx; |
||||
|
|
||||
|
.title { |
||||
|
padding: 20rpx 0; |
||||
|
display: block; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.items { |
||||
|
position: relative; |
||||
|
display: inline-block; |
||||
|
border: 2rpx solid $color-line; |
||||
|
padding: 4rpx 30rpx; |
||||
|
border-radius: 8rpx; |
||||
|
margin: 0 20rpx 20rpx 0; |
||||
|
background-color: #fff; |
||||
|
font-size: $font-size-tag; |
||||
|
|
||||
|
.disabled { |
||||
|
border: 2rpx dashed; |
||||
|
} |
||||
|
|
||||
|
image { |
||||
|
height: 44rpx; |
||||
|
width: 44rpx; |
||||
|
border-radius: $border-radius; |
||||
|
margin-right: 10rpx; |
||||
|
display: inline-block; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.number-wrap { |
||||
|
.number-line { |
||||
|
padding: 20rpx 0; |
||||
|
line-height: 72rpx; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
|
||||
|
.number { |
||||
|
display: flex; |
||||
|
height: 72rpx; |
||||
|
border-radius: 6rpx; |
||||
|
float: right; |
||||
|
|
||||
|
button { |
||||
|
display: inline-block; |
||||
|
line-height: 64rpx; |
||||
|
height: 68rpx; |
||||
|
width: 60rpx; |
||||
|
font-size: 48rpx; |
||||
|
box-sizing: content-box; |
||||
|
border: 2rpx solid $color-line; |
||||
|
padding: 0; |
||||
|
margin: 0; |
||||
|
border-radius: 0; |
||||
|
background-color: #fff !important; |
||||
|
|
||||
|
&.disabled { |
||||
|
background: #f7f7f7 !important; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
input { |
||||
|
display: inline-block; |
||||
|
line-height: 64rpx; |
||||
|
height: 68rpx; |
||||
|
width: 72rpx; |
||||
|
text-align: center; |
||||
|
font-weight: 700; |
||||
|
border: 2rpx solid; |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
vertical-align: top; |
||||
|
background-color: $color-bg !important; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.keyBoard { |
||||
|
padding: 0 30rpx; |
||||
|
} |
||||
|
|
||||
|
/deep/ .u-keyboard { |
||||
|
background-color: #fff; |
||||
|
|
||||
|
.u-keyboard__button-wrapper { |
||||
|
.u-keyboard__button-wrapper__button { |
||||
|
background-color: #eee; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.footer { |
||||
|
height: 100rpx; |
||||
|
width: 100%; |
||||
|
margin-top: 40rpx; |
||||
|
color: #fff; |
||||
|
z-index: 1; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: flex-start; |
||||
|
|
||||
|
button { |
||||
|
width: 100%; |
||||
|
height: 80rpx; |
||||
|
background-color: var(--goods-btn-color); |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,56 @@ |
|||||
|
<template> |
||||
|
<text>{{ temp }}</text> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import _time_ from './time.js'; |
||||
|
export default { |
||||
|
name: 'l-time', |
||||
|
props: { |
||||
|
//日期字符串 |
||||
|
text: { |
||||
|
type: [String, Number, Date], |
||||
|
default: '' |
||||
|
}, |
||||
|
//是否显示大于当前时间日期,默认false:大于显示刚刚 |
||||
|
maxDate: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
textVal: this.text |
||||
|
}; |
||||
|
}, |
||||
|
watch: { |
||||
|
text() { |
||||
|
this.textVal = this.text; |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
temp() { |
||||
|
return this.getText(); |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
getText() { |
||||
|
let self = this; |
||||
|
let timeVal = _time_.getFormatTime(self.textVal, self.maxDate); |
||||
|
if (timeVal && (timeVal.endsWith('刚刚') || timeVal.endsWith('分钟前'))) { |
||||
|
setTimeout(() => { |
||||
|
let temp = self.textVal; |
||||
|
self.textVal = ''; |
||||
|
self.textVal = temp; |
||||
|
}, 60000); |
||||
|
} |
||||
|
return this.textVal ? timeVal : ''; |
||||
|
}, |
||||
|
onClick() { |
||||
|
this.$emit('on-tap', this.textVal); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style></style> |
||||
@ -0,0 +1,161 @@ |
|||||
|
Function.prototype.asyAfter = function(afterfn) { |
||||
|
var _self = this; |
||||
|
return function() { |
||||
|
var ret = _self.apply(this, arguments); |
||||
|
if (ret === 'next') { |
||||
|
return afterfn.apply(this, arguments); |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Date.prototype.pattern = function(fmt) { |
||||
|
var o = { |
||||
|
"M+": this.getMonth() + 1, //月份
|
||||
|
"d+": this.getDate(), //日
|
||||
|
"h+": this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时
|
||||
|
"H+": this.getHours(), //小时
|
||||
|
"m+": this.getMinutes(), //分
|
||||
|
"s+": this.getSeconds(), //秒
|
||||
|
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
|
||||
|
"S": this.getMilliseconds() //毫秒
|
||||
|
}; |
||||
|
var week = { |
||||
|
"0": "\u65e5", |
||||
|
"1": "\u4e00", |
||||
|
"2": "\u4e8c", |
||||
|
"3": "\u4e09", |
||||
|
"4": "\u56db", |
||||
|
"5": "\u4e94", |
||||
|
"6": "\u516d" |
||||
|
}; |
||||
|
if (/(y+)/.test(fmt)) { |
||||
|
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); |
||||
|
} |
||||
|
if (/(E+)/.test(fmt)) { |
||||
|
fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "\u661f\u671f" : "\u5468") : |
||||
|
"") + |
||||
|
week[this.getDay() + ""]); |
||||
|
} |
||||
|
for (var k in o) { |
||||
|
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; |
||||
|
} |
||||
|
|
||||
|
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(); |
||||
|
} |
||||
|
|
||||
|
//获取当天0点0分0秒时间戳
|
||||
|
timeProto.getTodayUnix = function() { |
||||
|
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(); |
||||
|
date.setMonth(0); |
||||
|
date.setDate(1); |
||||
|
date.setHours(0); |
||||
|
date.setMinutes(0); |
||||
|
date.setSeconds(0); |
||||
|
date.setMilliseconds(0); |
||||
|
return date.getTime(); |
||||
|
} |
||||
|
|
||||
|
//获取当前时间标准年月日
|
||||
|
timeProto.getLastDate = function(constTime) { |
||||
|
if (!constTime) { |
||||
|
return; |
||||
|
} |
||||
|
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; |
||||
|
} |
||||
|
|
||||
|
const resDateStr = function(timer, constTime) { |
||||
|
let _just = function(timer) { |
||||
|
|
||||
|
if (timer <= 0 || Math.floor(timer / 60) <= 0) { |
||||
|
return "刚刚" |
||||
|
} else return 'next'; |
||||
|
} |
||||
|
|
||||
|
let _mm = function(timer) { |
||||
|
if (timer < 3600) { |
||||
|
return Math.floor(timer / 60) + "分钟前" |
||||
|
} else return 'next'; |
||||
|
} |
||||
|
let _hh = function(timer, constTime) { |
||||
|
let today = _time_.getTodayUnix(); |
||||
|
if (timer >= 3600 && (constTime - today >= 0)) { |
||||
|
//可切换显示模式
|
||||
|
// return "今天 " + new Date(constTime).pattern("HH:mm");
|
||||
|
return Math.floor(timer / 60 / 60) + "小时前"; |
||||
|
} else { |
||||
|
return 'next' |
||||
|
}; |
||||
|
} |
||||
|
let _dd = function(timer, constTime) { |
||||
|
let today = _time_.getTodayUnix(); |
||||
|
timer = (today - constTime) / 1000; |
||||
|
if (timer / 86400 <= 31) { |
||||
|
return Math.ceil(timer / 86400) + "天前" |
||||
|
} else return 'next'; |
||||
|
} |
||||
|
let _dlast = function(timer, constTime) { |
||||
|
return _time_.getLastDate(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) { |
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
switch (isType(constTime)) { |
||||
|
case 'Date': |
||||
|
constTime = constTime.getTime(); |
||||
|
break; |
||||
|
case 'String': |
||||
|
constTime = constTime.replace(reg, "/"); |
||||
|
default: |
||||
|
constTime = new Date(constTime).getTime(); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
let now = this.getUnix(); |
||||
|
let year = this.getYearUnix(); |
||||
|
let timer = (now - constTime) / 1000; |
||||
|
if (constTime > now && max) { |
||||
|
return this.getLastDate(constTime); |
||||
|
} |
||||
|
|
||||
|
let _t = this; |
||||
|
return resDateStr(timer, constTime); |
||||
|
} |
||||
|
|
||||
|
const _time_ = new Time(); |
||||
|
export default _time_; |
||||
@ -0,0 +1,336 @@ |
|||||
|
<template> |
||||
|
<view class="load-refresh"> |
||||
|
<!-- 刷新动画,可自定义,占高100rpx --> |
||||
|
<view class="animation" :style="{'--color': color}"> |
||||
|
<view v-if="!playState" class="remind"> |
||||
|
{{moving ? '↑ 松开释放' : '↓ 下拉刷新'}} |
||||
|
</view> |
||||
|
<view v-if="playState && refreshType === 'hollowDots'" class="refresh hollow-dots-spinner"> |
||||
|
<view class="dot"></view> |
||||
|
<view class="dot"></view> |
||||
|
<view class="dot"></view> |
||||
|
</view> |
||||
|
<view v-if="playState && refreshType === 'halfCircle'" class="refresh half-circle-spinner"> |
||||
|
<view class="circle circle-1"></view> |
||||
|
<view class="circle circle-2"></view> |
||||
|
</view> |
||||
|
<view v-if="playState && refreshType === 'swappingSquares'" class="refresh swapping-squares-spinner"> |
||||
|
<view class="square"></view> |
||||
|
<view class="square"></view> |
||||
|
<view class="square"></view> |
||||
|
<view class="square"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!-- 数据列表块 --> |
||||
|
<view |
||||
|
class="cover-container" |
||||
|
:style="[{ |
||||
|
background: backgroundCover, |
||||
|
transform: coverTransform, |
||||
|
transition: coverTransition |
||||
|
}]" |
||||
|
@touchstart="coverTouchstart" |
||||
|
@touchmove="coverTouchmove" |
||||
|
@touchend="coverTouchend"> |
||||
|
<scroll-view scroll-y class="list" :scroll-top="scrollTop" @scrolltolower="loadMore" :style="getHeight"> |
||||
|
<!-- 数据集插槽 --> |
||||
|
<slot name="content-list"></slot> |
||||
|
<!-- 上拉加载 --> |
||||
|
<view class="load-more">{{loadText}}</view> |
||||
|
</scroll-view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'loadRefresh', |
||||
|
props: { |
||||
|
isRefresh: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
refreshType: { |
||||
|
type: String, |
||||
|
default: 'hollowDots' |
||||
|
}, |
||||
|
fixedHeight: { |
||||
|
type: String, |
||||
|
default: '0' |
||||
|
}, |
||||
|
heightReduce: { |
||||
|
type: String, |
||||
|
default: '0' |
||||
|
}, |
||||
|
color: { |
||||
|
type: String, |
||||
|
default: '#04C4C4' |
||||
|
}, |
||||
|
backgroundCover: { |
||||
|
type: String, |
||||
|
default: 'white' |
||||
|
}, |
||||
|
currentPage: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
totalPages: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
startY: 0, |
||||
|
moveY: 0, |
||||
|
updating: false, // 数据更新状态(true: 更新中) |
||||
|
updateType: true, // 数据更新类型(true: 下拉刷新: false: 加载更多) |
||||
|
moving: false, |
||||
|
scrollTop: -1, |
||||
|
coverTransform: 'translateY(0px)', |
||||
|
coverTransition: '0s', |
||||
|
playState: false // 动画的状态 暂停 paused/开始 running |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
// 计算组件所占屏幕高度 |
||||
|
getHeight() { |
||||
|
// rpx = px / uni.getSystemInfoSync().windowWidth * 750 |
||||
|
if (Number(this.fixedHeight)) { |
||||
|
return `height: ${this.fixedHeight}rpx;` |
||||
|
} else { |
||||
|
let height = uni.getSystemInfoSync().windowHeight - uni.upx2px(0 + this.heightReduce) |
||||
|
return `height: ${height}px;` |
||||
|
} |
||||
|
}, |
||||
|
// 判断loadText,可以根据需求自定义 |
||||
|
loadText() { |
||||
|
const { currentPage, totalPages, updating, updateType } = this |
||||
|
if (!updateType && updating) { |
||||
|
return '加载中...' |
||||
|
} else if (currentPage < totalPages) { |
||||
|
return '上拉加载更多' |
||||
|
} else { |
||||
|
return '已经到底啦~' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 根据currentPage和totalPages的值来判断 是否触发@loadMore |
||||
|
loadMore() { |
||||
|
const { currentPage, totalPages } = this |
||||
|
if (!this.updating && currentPage < totalPages) { |
||||
|
this.updating = true |
||||
|
this.updateType = false |
||||
|
this.$emit('loadMore') |
||||
|
} |
||||
|
}, |
||||
|
// 回弹效果 |
||||
|
coverTouchstart(e) { |
||||
|
if (!this.isRefresh) { |
||||
|
return |
||||
|
} |
||||
|
this.coverTransition = 'transform .1s linear' |
||||
|
this.startY = e.touches[0].clientY |
||||
|
}, |
||||
|
coverTouchmove(e) { |
||||
|
if (!this.isRefresh || this.updating) { |
||||
|
return |
||||
|
} |
||||
|
this.moveY = e.touches[0].clientY |
||||
|
let moveDistance = this.moveY - this.startY |
||||
|
if (moveDistance <= 50) { |
||||
|
this.coverTransform = `translateY(${moveDistance}px)` |
||||
|
} |
||||
|
this.moving = moveDistance >= 50 |
||||
|
}, |
||||
|
coverTouchend() { |
||||
|
if (!this.isRefresh || this.updating) { |
||||
|
return |
||||
|
} |
||||
|
if (this.moving) { |
||||
|
this.runRefresh() |
||||
|
} else { |
||||
|
this.coverTransition = 'transform 0.3s cubic-bezier(.21,1.93,.53,.64)' |
||||
|
this.coverTransform = 'translateY(0px)' |
||||
|
} |
||||
|
}, |
||||
|
runRefresh() { |
||||
|
this.scrollTop = 0 |
||||
|
this.coverTransition = 'transform .1s linear' |
||||
|
this.coverTransform = 'translateY(50px)' |
||||
|
this.playState = true |
||||
|
this.updating = true |
||||
|
this.updateType = true |
||||
|
this.$emit('refresh') |
||||
|
}, |
||||
|
completed() { |
||||
|
if (this.updateType) { |
||||
|
// 下拉刷新 |
||||
|
this.moving = false |
||||
|
this.scrollTop = -1 |
||||
|
this.coverTransition = 'transform 0.3s cubic-bezier(.21,1.93,.53,.64)' |
||||
|
this.coverTransform = 'translateY(0px)' |
||||
|
setTimeout(() => { |
||||
|
this.playState = false |
||||
|
}, 300) |
||||
|
} |
||||
|
this.updating = false |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
$color: var(--color); |
||||
|
|
||||
|
.load-refresh{ |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
width: 100%; |
||||
|
.cover-container{ |
||||
|
width: 100%; |
||||
|
margin-top: -100rpx; |
||||
|
.list{ |
||||
|
width: 100%; |
||||
|
.load-more{ |
||||
|
font-size: 20rpx; |
||||
|
text-align: center; |
||||
|
color: #AAAAAA; |
||||
|
padding: 16rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* 动画 */ |
||||
|
.animation { |
||||
|
width: 100%; |
||||
|
height: 100rpx; |
||||
|
.remind { |
||||
|
width: 100%; |
||||
|
height: 100rpx; |
||||
|
text-align: center; |
||||
|
line-height: 100rpx; |
||||
|
} |
||||
|
.refresh { |
||||
|
width: 100%; |
||||
|
height: 100rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
box-sizing: border-box; |
||||
|
view { |
||||
|
// animation-play-state: $playState!important; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* HollowDots */ |
||||
|
.hollow-dots-spinner .dot { |
||||
|
width: 30rpx; |
||||
|
height: 30rpx; |
||||
|
margin: 0 calc(30rpx / 2); |
||||
|
border: calc(30rpx / 5) solid $color; |
||||
|
border-radius: 50%; |
||||
|
float: left; |
||||
|
transform: scale(0); |
||||
|
animation: hollowDots 1000ms ease infinite 0ms; |
||||
|
} |
||||
|
.hollow-dots-spinner .dot:nth-child(1) { |
||||
|
animation-delay: calc(300ms * 1); |
||||
|
} |
||||
|
.hollow-dots-spinner .dot:nth-child(2) { |
||||
|
animation-delay: calc(300ms * 2); |
||||
|
} |
||||
|
.hollow-dots-spinner .dot:nth-child(3) { |
||||
|
animation-delay: calc(300ms * 3); |
||||
|
} |
||||
|
@keyframes hollowDots { |
||||
|
50% { |
||||
|
transform: scale(1); |
||||
|
opacity: 1; |
||||
|
} |
||||
|
100% { |
||||
|
opacity: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* halfCircle */ |
||||
|
.half-circle-spinner .circle { |
||||
|
content: ""; |
||||
|
position: absolute; |
||||
|
width: 60rpx; |
||||
|
height: 60rpx; |
||||
|
border-radius: 100%; |
||||
|
border: calc(60rpx / 10) solid transparent; |
||||
|
} |
||||
|
|
||||
|
.half-circle-spinner .circle.circle-1 { |
||||
|
border-top-color: $color; |
||||
|
animation: halfCircle 1s infinite; |
||||
|
} |
||||
|
.half-circle-spinner .circle.circle-2 { |
||||
|
border-bottom-color: $color; |
||||
|
animation: halfCircle 1s infinite alternate; |
||||
|
} |
||||
|
@keyframes halfCircle { |
||||
|
0% { |
||||
|
transform: rotate(0deg); |
||||
|
} |
||||
|
100%{ |
||||
|
transform: rotate(360deg); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* swappingSquares */ |
||||
|
.swapping-squares-spinner { |
||||
|
position: relative; |
||||
|
} |
||||
|
.swapping-squares-spinner .square { |
||||
|
height: calc(65rpx * 0.25 / 1.3); |
||||
|
width: calc(65rpx * 0.25 / 1.3); |
||||
|
animation-duration: 1000ms; |
||||
|
border: calc(65rpx * 0.04 / 1.3) solid $color; |
||||
|
margin-right: auto; |
||||
|
margin-left: auto; |
||||
|
position: absolute; |
||||
|
animation-iteration-count: infinite; |
||||
|
} |
||||
|
.swapping-squares-spinner .square:nth-child(1) { |
||||
|
animation-name: swappingSquares-child-1; |
||||
|
animation-delay: 500ms; |
||||
|
} |
||||
|
.swapping-squares-spinner .square:nth-child(2) { |
||||
|
animation-name: swappingSquares-child-2; |
||||
|
animation-delay: 0ms; |
||||
|
} |
||||
|
.swapping-squares-spinner .square:nth-child(3) { |
||||
|
animation-name: swappingSquares-child-3; |
||||
|
animation-delay: 500ms; |
||||
|
} |
||||
|
.swapping-squares-spinner .square:nth-child(4) { |
||||
|
animation-name: swappingSquares-child-4; |
||||
|
animation-delay: 0ms; |
||||
|
} |
||||
|
@keyframes swappingSquares-child-1 { |
||||
|
50% { |
||||
|
transform: translate(150%,150%) scale(2,2); |
||||
|
} |
||||
|
} |
||||
|
@keyframes swappingSquares-child-2 { |
||||
|
50% { |
||||
|
transform: translate(-150%,150%) scale(2,2); |
||||
|
} |
||||
|
} |
||||
|
@keyframes swappingSquares-child-3 { |
||||
|
50% { |
||||
|
transform: translate(-150%,-150%) scale(2,2); |
||||
|
} |
||||
|
} |
||||
|
@keyframes swappingSquares-child-4 { |
||||
|
50% { |
||||
|
transform: translate(150%,-150%) scale(2,2); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,113 @@ |
|||||
|
<template> |
||||
|
<view class="loading-layer" v-if="isShow"> |
||||
|
<view class="loading-anim" v-if="themeStyle"> |
||||
|
<view class="box item"><view class="border out item" :style="{'border-left-color':themeStyle.main_color, 'border-top-color':themeStyle.main_color}"></view></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'loading-cover', |
||||
|
props: { |
||||
|
initShow: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
isShow: true |
||||
|
}; |
||||
|
}, |
||||
|
components: {}, |
||||
|
created() { |
||||
|
this.isShow = this.initShow; |
||||
|
}, |
||||
|
methods: { |
||||
|
show() { |
||||
|
this.isShow = true; |
||||
|
}, |
||||
|
hide() { |
||||
|
this.isShow = false; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
@keyframes spin { |
||||
|
from { |
||||
|
transform: rotate(0deg); |
||||
|
} |
||||
|
|
||||
|
to { |
||||
|
transform: rotate(360deg); |
||||
|
} |
||||
|
} |
||||
|
.loading-layer { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
z-index: 997; |
||||
|
background: #f8f8f8; |
||||
|
} |
||||
|
|
||||
|
.loading-anim { |
||||
|
position: absolute; |
||||
|
left: 50%; |
||||
|
top: 40%; |
||||
|
transform: translate(-50%, -50%); |
||||
|
} |
||||
|
|
||||
|
.loading-anim > .item { |
||||
|
position: relative; |
||||
|
width: 70rpx; |
||||
|
height: 70rpx; |
||||
|
perspective: 1600rpx; |
||||
|
transform-style: preserve-3d; |
||||
|
transition: all 0.2s ease-out; |
||||
|
} |
||||
|
|
||||
|
.loading-anim .border { |
||||
|
position: absolute; |
||||
|
border-radius: 50%; |
||||
|
border: 6rpx solid; |
||||
|
} |
||||
|
|
||||
|
.loading-anim .out { |
||||
|
top: 15%; |
||||
|
left: 15%; |
||||
|
width: 70%; |
||||
|
height: 70%; |
||||
|
border-left-color: #FF4646; |
||||
|
border-right-color: #C5C5C5 !important; |
||||
|
// border-right-color: rgba($color: #000000, $alpha: 0) !important; |
||||
|
border-top-color: #FF4646 ; |
||||
|
border-bottom-color: #C5C5C5 !important; |
||||
|
// border-bottom-color: rgba($color: #000000, $alpha: 0) !important; |
||||
|
animation: spin 0.6s linear normal infinite; |
||||
|
} |
||||
|
|
||||
|
.loading-anim .in { |
||||
|
top: 25%; |
||||
|
left: 25%; |
||||
|
width: 50%; |
||||
|
height: 50%; |
||||
|
border-top-color: transparent !important; |
||||
|
border-bottom-color: transparent !important; |
||||
|
animation: spin 0.8s linear infinite; |
||||
|
} |
||||
|
|
||||
|
.loading-anim .mid { |
||||
|
top: 40%; |
||||
|
left: 40%; |
||||
|
width: 20%; |
||||
|
height: 20%; |
||||
|
border-left-color: transparent; |
||||
|
border-right-color: transparent; |
||||
|
animation: spin 0.6s linear infinite; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,228 @@ |
|||||
|
<template> |
||||
|
<view v-html="videoHtml" id="dom-video" class="dom-video" :eventDrive="eventDrive" |
||||
|
:change:eventDrive="domVideo.eventHandle" :videoSrc="videoSrc" :change:videoSrc="domVideo.srcChange" |
||||
|
:videoProps="videoProps" :change:videoProps="domVideo.propsChange" :randomNum="randomNum" |
||||
|
:change:randomNum="domVideo.randomNumChange" /> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
src: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
autoplay: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
loop: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
controls: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
objectFit: { |
||||
|
type: String, |
||||
|
default: 'contain' |
||||
|
}, |
||||
|
muted: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
poster: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
// 数据状态 |
||||
|
data() { |
||||
|
return { |
||||
|
videoHtml: '', |
||||
|
videoSrc: '', |
||||
|
eventDrive: null, |
||||
|
videoProps: {}, |
||||
|
randomNum: Math.floor(Math.random() * 100000000 + 1) |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
// 监听视频资源文件更新 |
||||
|
src: { |
||||
|
handler(val) { |
||||
|
if (!val) return |
||||
|
this.initVideoHtml() |
||||
|
setTimeout(() => { |
||||
|
this.videoSrc = val |
||||
|
}, 0) |
||||
|
}, |
||||
|
immediate: true |
||||
|
}, |
||||
|
// 监听首次加载 |
||||
|
autoplay: { |
||||
|
handler(val) { |
||||
|
this.videoProps.autoplay = val |
||||
|
}, |
||||
|
immediate: true |
||||
|
}, |
||||
|
}, |
||||
|
// 生命周期 |
||||
|
mounted() { |
||||
|
this.initVideoHtml() |
||||
|
}, |
||||
|
beforeDestroy() { |
||||
|
this.videoHtml = '' |
||||
|
}, |
||||
|
|
||||
|
// 方法 |
||||
|
methods: { |
||||
|
// 将video的事件传递给父组件 |
||||
|
listener(data) { |
||||
|
console.log('向父组件传递事件 =>', data) |
||||
|
this.$emit('listener', data) |
||||
|
}, |
||||
|
// 初始化视频 |
||||
|
initVideoHtml() { |
||||
|
this.videoHtml = `<video |
||||
|
src="${this.src}" |
||||
|
id="dom-html-video_${this.randomNum}" |
||||
|
class="dom-html-video" |
||||
|
${this.autoplay ? 'autoplay' : ''} |
||||
|
${this.loop ? 'loop' : ''} |
||||
|
${this.controls ? 'controls' : ''} |
||||
|
${this.muted ? 'muted' : ''} |
||||
|
${this.poster ? 'poster="' + this.poster + '"' : ''} |
||||
|
preload="auto" |
||||
|
playsinline |
||||
|
webkit-playsinline |
||||
|
width="100%" |
||||
|
height="100%" |
||||
|
style="object-fit: ${this.objectFit};padding:0;" |
||||
|
> |
||||
|
<source src="${this.src}" type="video/mp4"> |
||||
|
<source src="${this.src}" type="video/ogg"> |
||||
|
<source src="${this.src}" type="video/webm"> |
||||
|
</video> |
||||
|
` |
||||
|
// console.log('视频html =>', this.videoHtml) |
||||
|
}, |
||||
|
resetEventDrive() { |
||||
|
this.eventDrive = null |
||||
|
}, |
||||
|
// 将service层的事件/数据 => 传递给renderjs层 |
||||
|
play() { |
||||
|
this.eventDrive = 'play' |
||||
|
}, |
||||
|
pause() { |
||||
|
this.eventDrive = 'pause' |
||||
|
}, |
||||
|
stop() { |
||||
|
this.eventDrive = 'stop' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<script module="domVideo" lang="renderjs"> |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
video: null, |
||||
|
num: '', |
||||
|
options: {}, |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.initVideoEvent() |
||||
|
}, |
||||
|
methods: { |
||||
|
initVideoEvent() { |
||||
|
setTimeout(() => { |
||||
|
let video = document.getElementById(`dom-html-video_${this.num}`) |
||||
|
this.video = video |
||||
|
// 监听视频事件 |
||||
|
video.addEventListener('play', () => { |
||||
|
this.$ownerInstance.callMethod('listener', { |
||||
|
name: 'play', |
||||
|
currentTime: 0, |
||||
|
duration: this.video.duration |
||||
|
}) |
||||
|
}) |
||||
|
video.addEventListener('pause', () => { |
||||
|
this.$ownerInstance.callMethod('listener', { |
||||
|
name: 'pause', |
||||
|
currentTime: this.video.currentTime, |
||||
|
duration: this.video.duration |
||||
|
}) |
||||
|
}) |
||||
|
video.addEventListener('ended', () => { |
||||
|
this.$ownerInstance.callMethod('listener', { |
||||
|
name: 'ended', |
||||
|
currentTime: this.video.currentTime, |
||||
|
duration: this.video.duration |
||||
|
}) |
||||
|
this.$ownerInstance.callMethod('resetEventDrive') |
||||
|
}) |
||||
|
|
||||
|
}, 100) |
||||
|
|
||||
|
}, |
||||
|
eventHandle(eventType) { |
||||
|
if (eventType) { |
||||
|
this.video = document.getElementById(`dom-html-video_${this.num}`) |
||||
|
if (!this.video) { |
||||
|
console.error(`Cannot find video element with id: dom-html-video_${this.num}`); |
||||
|
return; |
||||
|
} |
||||
|
if (eventType === 'play') { |
||||
|
this.video.play() |
||||
|
} else if (eventType === 'pause') { |
||||
|
this.video.pause() |
||||
|
} else if (eventType === 'stop') { |
||||
|
this.video.pause() |
||||
|
this.video.currentTime = 0; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
srcChange(val) { |
||||
|
// 实现视频的第一帧作为封面,避免视频展示黑屏 |
||||
|
// this.initVideoEvent() |
||||
|
setTimeout(() => { |
||||
|
let video = document.getElementById(`dom-html-video_${this.num}`) |
||||
|
|
||||
|
video.addEventListener('loadedmetadata', () => { |
||||
|
|
||||
|
console.log('this.options', this.options) |
||||
|
let { autoplay } = this.options |
||||
|
if (!autoplay) { |
||||
|
video.pause() |
||||
|
} else { |
||||
|
video.play() |
||||
|
} |
||||
|
}) |
||||
|
}, 100) |
||||
|
}, |
||||
|
propsChange(obj) { |
||||
|
this.options = obj |
||||
|
}, |
||||
|
randomNumChange(val) { |
||||
|
this.num = val |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.dom-video { |
||||
|
overflow: hidden; |
||||
|
height: 100%; |
||||
|
padding: 0; |
||||
|
|
||||
|
&-height { |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,326 @@ |
|||||
|
<template> |
||||
|
<swiper class="m-tiktok-video-swiper" circular @change="swiperChange" :current="current" :vertical="true" |
||||
|
duration="300"> |
||||
|
{{originList}} |
||||
|
<swiper-item v-for="(item, index) in displaySwiperList" :key="index"> |
||||
|
|
||||
|
<view class="swiper-item" @click="handleClick"> |
||||
|
|
||||
|
<ls-dom-video :ref="'DomVideo'+index" v-if="index === 0 || !isFirstLoad" :src="item.video" |
||||
|
:autoplay="true" :controls="false" @ended="endedVideo" @listener="listener"></ls-dom-video> |
||||
|
<!-- <video class="m-tiktok-video-player" :src="item.src" :id="`video__${index}`" :controls="controls" |
||||
|
:show-center-play-btn="controls" :object-fit="item.objectFit" :autoplay="false" :loop="loop" |
||||
|
:custom-cache="false" @ended="ended" @controlstoggle="controlstoggle" @play="onPlay" |
||||
|
@error="emits('error')" @loadedmetadata="loadVideoData($event, item)" |
||||
|
v-if="index === 0 || !isFirstLoad"></video> --> |
||||
|
<!-- <view class="m-tiktok-video-play-btn" v-if="!controls && displayIndex === index" @click="togglePlay"> |
||||
|
<text class="m-tiktok-video-iconfont video-icon" :class="{ active: !isPlaying }"></text> |
||||
|
</view> |
||||
|
<image v-if="item.poster && displayIndex != index" :src="item.poster" class="m-tiktok-video-poster" |
||||
|
mode="aspectFit"></image> |
||||
|
<slot :item="item"></slot> --> |
||||
|
</view> |
||||
|
</swiper-item> |
||||
|
</swiper> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
/** |
||||
|
* 视频列表 |
||||
|
*/ |
||||
|
videoList: { |
||||
|
type: Array, |
||||
|
default: () => [], |
||||
|
}, |
||||
|
/** |
||||
|
* 是否循环播放一个视频 |
||||
|
*/ |
||||
|
loop: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
/** |
||||
|
* 显示原生控制栏 |
||||
|
*/ |
||||
|
controls: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
/** |
||||
|
* 是否自动播放 |
||||
|
*/ |
||||
|
autoplay: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
/** |
||||
|
* 是否自动滚动播放 |
||||
|
*/ |
||||
|
autoChange: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
/** |
||||
|
* 滚动加载阈值(即播放到剩余多少个之后触发加载更多 |
||||
|
*/ |
||||
|
loadMoreOffsetCount: { |
||||
|
type: Number, |
||||
|
default: 2, |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 视频自动自适应平铺模式 |
||||
|
* 竖屏cover,横屏自适应 |
||||
|
*/ |
||||
|
autoObjectFit: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
originList: [], // 源数据 |
||||
|
displaySwiperList: [], // swiper需要的数据 |
||||
|
displayIndex: 0, // 用于显示swiper的真正的下标数值只有:0,1,2。 |
||||
|
originIndex: 0, // 记录源数据的下标 |
||||
|
current: 0, |
||||
|
oid: 0, |
||||
|
videoContexts: [], |
||||
|
isFirstLoad: true, |
||||
|
isPlaying: false, |
||||
|
|
||||
|
loadTimer: null, |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
videoList: { |
||||
|
handler(val) { |
||||
|
if (val.length) { |
||||
|
this.originList = val; |
||||
|
console.log(this.originList); |
||||
|
if (this.isFirstLoad || this.videoContexts.length) { |
||||
|
this.initSwiperData(this.originIndex) |
||||
|
this.initVideoContexts() |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
immediate: true, |
||||
|
deep: true |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
}, |
||||
|
mounted() { |
||||
|
console.log(this.videoList); |
||||
|
}, |
||||
|
methods: { |
||||
|
initVideoContexts() { |
||||
|
this.videoContexts = this.videoContexts.map((item, index) => { |
||||
|
return uni.createVideoContext(`video__${index}`, this); |
||||
|
}) |
||||
|
}, |
||||
|
onPlay(e) { |
||||
|
this.isPlaying = true; |
||||
|
this.initFirstLoad() |
||||
|
this.$emit('play', e) |
||||
|
|
||||
|
}, |
||||
|
handleClick(e) { |
||||
|
this.$emit("click", e); |
||||
|
}, |
||||
|
ended() { |
||||
|
if (this.autoChange) { |
||||
|
if (this.displayIndex < 2) { |
||||
|
this.current = this.displayIndex + 1 |
||||
|
} else { |
||||
|
this.current = 0 |
||||
|
} |
||||
|
} |
||||
|
this.$emit('ended') |
||||
|
}, |
||||
|
/** |
||||
|
* 初始一个显示的swiper数据 |
||||
|
* @originIndex 从源数据的哪个开始显示默认0,如从其他页面跳转进来,要显示第n个,这个参数就是他的下标 |
||||
|
*/ |
||||
|
initSwiperData(originIndex) { |
||||
|
const originListLength = this.originList.length; // 源数据长度 |
||||
|
const displayList = []; // 显示的swiper数据 |
||||
|
displayList[this.displayIndex] = this.originList[originIndex]; |
||||
|
displayList[this.displayIndex - 1 == -1 ? 2 : this.displayIndex - 1] = |
||||
|
this.originList[ |
||||
|
originIndex - 1 == -1 ? originListLength - 1 : originIndex - 1 |
||||
|
]; |
||||
|
displayList[this.displayIndex + 1 == 3 ? 0 : this.displayIndex + 1] = |
||||
|
this.originList[originIndex + 1 == originListLength ? 0 : originIndex + 1]; |
||||
|
this.displaySwiperList = displayList; |
||||
|
console.log('displaySwiperList', this.displaySwiperList); |
||||
|
if (this.oid >= this.originList.length) { |
||||
|
this.oid = 0; |
||||
|
} |
||||
|
if (this.oid < 0) { |
||||
|
this.oid = this.originList.length - 1; |
||||
|
} |
||||
|
|
||||
|
//暂停所有视频 |
||||
|
this.videoContexts.map((item) => item?.stop()); |
||||
|
setTimeout(() => { |
||||
|
if (this.autoplay) { |
||||
|
uni.createVideoContext(`video__${this.displayIndex}`, this).play(); |
||||
|
} |
||||
|
}, 500) |
||||
|
this.$emit('change', { |
||||
|
index: originIndex, |
||||
|
detail: this.originList[originIndex], |
||||
|
}) |
||||
|
// 赋值 |
||||
|
this.originIndex = originIndex; |
||||
|
// 加载更多 |
||||
|
var pCount = this.originList.length - this.loadMoreOffsetCount; |
||||
|
if (originIndex == pCount) { |
||||
|
this.$emit('loadMore') |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* swiper滑动时候 |
||||
|
*/ |
||||
|
swiperChange(event) { |
||||
|
const { current } = event.detail; |
||||
|
this.isFirstLoad = false |
||||
|
const originListLength = this.originList.length |
||||
|
// 向后滚动 |
||||
|
if (this.displayIndex - current == 2 || this.displayIndex - current == -1) { |
||||
|
this.originIndex = |
||||
|
this.originIndex + 1 == originListLength ? 0 : this.originIndex + 1; |
||||
|
this.displayIndex = |
||||
|
this.displayIndex + 1 == 3 ? 0 : this.displayIndex + 1; |
||||
|
this.oid = this.originIndex - 1; |
||||
|
this.initSwiperData(this.originIndex); |
||||
|
} |
||||
|
// 如果两者的差为-2或者1则是向前滑动 |
||||
|
else if ( |
||||
|
this.displayIndex - current == -2 || |
||||
|
this.displayIndex - current == 1 |
||||
|
) { |
||||
|
this.originIndex = |
||||
|
this.originIndex - 1 == -1 ? |
||||
|
originListLength - 1 : |
||||
|
this.originIndex - 1; |
||||
|
this.displayIndex = |
||||
|
this.displayIndex - 1 == -1 ? 2 : this.displayIndex - 1; |
||||
|
this.oid = this.originIndex + 1; |
||||
|
this.initSwiperData(this.originIndex); |
||||
|
} |
||||
|
}, |
||||
|
controlstoggle(e) { |
||||
|
this.$emit('controlstoggle', e) |
||||
|
}, |
||||
|
togglePlay() { |
||||
|
const video = uni.createVideoContext(`video__${this.displayIndex}`, this) |
||||
|
if (this.isPlay) { |
||||
|
video.pause() |
||||
|
this.isPlay = false |
||||
|
|
||||
|
} else { |
||||
|
video.play() |
||||
|
this.isPlay = true |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
playSeeked(value) { |
||||
|
const video = uni.createVideoContext(`video__${this.displayIndex}`, this) |
||||
|
video.seek(value) |
||||
|
}, |
||||
|
initFirstLoad() { |
||||
|
if (this.isFirstLoad) { |
||||
|
this.loadTimer = setTimeout(() => { |
||||
|
this.isFirstLoad = false |
||||
|
clearTimeout(this.loadTimer) |
||||
|
}, 5000) |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* 视频源数据加载时触发 |
||||
|
* @param $event |
||||
|
* @param item |
||||
|
*/ |
||||
|
loadVideoData($event, item) { |
||||
|
if (item.objectFit) { |
||||
|
return |
||||
|
} |
||||
|
if (!this.autoObjectFit) { |
||||
|
return |
||||
|
} |
||||
|
// 自动计算设置视频平铺模式 |
||||
|
if ($event.detail.width < $event.detail.height) { |
||||
|
item.objectFit = 'cover' |
||||
|
} else { |
||||
|
item.objectFit = 'contain' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
onUnload() { |
||||
|
clearTimeout(this.loadTimer) |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
// @font-face { |
||||
|
// font-family: "m-tiktok-play-icon"; |
||||
|
// src: url(data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAAJ0AA0AAAAABlgAAAIiAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGh4GYACCQhEICkhaCwoAATYCJAMQBCAFhQIHLxt4BcieBXbLR4jiyygbC491Mg0vz9JsPPz/ft/2ufeMmCQP9fXfRhxvMKHjkcSsTkqWplJJqpFFfn79mr4NG5fvwujI+EPeZCbudGJcy6oVklRVp8IAdgMJUqD853ceuhm3iSafWxNoC0bbskAmUGABTlrDAgwsC+xJ3/SJf3DecLgpCpyFgDcXlRJ8uiufSVcHBjENilBVIVGQKS50UZ6U1+ApeD7+6kcvRVcl2fZub1Q8/BfJG9VHbUp9J0UAYBWhomIRgUZWYFHOKkgp+FFsyVvmRkB0E4AooAg/DwF/49FSQIJeBMbBDIAEQIzfDW+OPVHX48vXUy26fUwfJnN0+tW5bLx3+dz5fHT61rQEIBDc77r579ZI8793IDWgftfb8/q83gC9Cggqvex6gvqcDoBMGojkOvpX4wgU9OtHC2DcOwgwoYpA6LWDQNHjDgJVr8cCpF7PBOgy4JUA3Xq9BYF+29EgMGAiLlSRfVgDlgyjlmQx7JSsRgVQYkeyy7RLstuoF7Lfid+qAWtxbiWmkbDEVgmyA2hRBHx6jOEomxtSuCEvAg5k/U4c0Bh2XJIYfiwLaz88BE9oYgkrKPS0dWGtk7/X7rqFOsU+TZzFM4k9Qx9jOkEXC3iErR+f0LhcASEUC9g0CtaGY3Jrsjf6zPrqiLsTyi1RpN9z3wPOMRaa6+jQAzbblCgVWLpySeZmOVzvLw8uOfSjoLSEEiV7Yg==) format("woff2"); |
||||
|
// font-weight: normal; |
||||
|
// font-style: normal; |
||||
|
// font-display: swap; |
||||
|
// } |
||||
|
|
||||
|
.m-tiktok-video-iconfont { |
||||
|
// font-family: m-tiktok-play-icon; |
||||
|
} |
||||
|
|
||||
|
.m-tiktok-video-swiper, |
||||
|
.m-tiktok-video-player { |
||||
|
width: 100%; |
||||
|
height: 100vh; |
||||
|
background-color: #000; |
||||
|
} |
||||
|
|
||||
|
.m-tiktok-video-swiper { |
||||
|
.swiper-item { |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.m-tiktok-video-poster { |
||||
|
background-color: #000; |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
} |
||||
|
|
||||
|
.m-tiktok-video-play-btn { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
z-index: 1; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
|
||||
|
.video-icon { |
||||
|
font-size: 50px; |
||||
|
display: block; |
||||
|
color: rgba(255, 255, 255, 0.8); |
||||
|
opacity: 0; |
||||
|
|
||||
|
&.active { |
||||
|
opacity: 1; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,55 @@ |
|||||
|
/* 下拉刷新区域 */ |
||||
|
.mescroll-downwarp { |
||||
|
position: absolute; |
||||
|
top: -100%; |
||||
|
left: 0; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
/* 下拉刷新--内容区,定位于区域底部 */ |
||||
|
.mescroll-downwarp .downwarp-content { |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
bottom: 0; |
||||
|
width: 100%; |
||||
|
min-height: 60rpx; |
||||
|
padding: 20rpx 0; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
/* 下拉刷新--提示文本 */ |
||||
|
.mescroll-downwarp .downwarp-tip { |
||||
|
display: inline-block; |
||||
|
font-size: 28rpx; |
||||
|
color: gray; |
||||
|
vertical-align: middle; |
||||
|
margin-left: 16rpx; |
||||
|
} |
||||
|
|
||||
|
/* 下拉刷新--旋转进度条 */ |
||||
|
.mescroll-downwarp .downwarp-progress { |
||||
|
display: inline-block; |
||||
|
width: 32rpx; |
||||
|
height: 32rpx; |
||||
|
border-radius: 50%; |
||||
|
border: 2rpx solid gray; |
||||
|
border-bottom-color: transparent; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
/* 旋转动画 */ |
||||
|
.mescroll-downwarp .mescroll-rotate { |
||||
|
animation: mescrollDownRotate 0.6s linear infinite; |
||||
|
} |
||||
|
|
||||
|
@keyframes mescrollDownRotate { |
||||
|
0% { |
||||
|
transform: rotate(0deg); |
||||
|
} |
||||
|
|
||||
|
100% { |
||||
|
transform: rotate(360deg); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
<!-- 下拉刷新区域 --> |
||||
|
<template> |
||||
|
<view v-if="mOption.use" class="mescroll-downwarp"> |
||||
|
<view class="downwarp-content"> |
||||
|
<view class="downwarp-progress" :class="{ 'mescroll-rotate': isDownLoading }" :style="{ transform: downRotate }"></view> |
||||
|
<view class="downwarp-tip">{{ downText }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
option: Object, // down的配置项 |
||||
|
type: Number, // 下拉状态(inOffset:1, outOffset:2, showLoading:3, endDownScroll:4) |
||||
|
rate: Number // 下拉比率 (inOffset: rate<1; outOffset: rate>=1) |
||||
|
}, |
||||
|
computed: { |
||||
|
// 支付宝小程序需写成计算属性,prop定义default仍报错 |
||||
|
mOption() { |
||||
|
return this.option || {}; |
||||
|
}, |
||||
|
// 是否在加载中 |
||||
|
isDownLoading() { |
||||
|
return this.type === 3; |
||||
|
}, |
||||
|
// 旋转的角度 |
||||
|
downRotate() { |
||||
|
return 'rotate(' + 360 * this.rate + 'deg)'; |
||||
|
}, |
||||
|
// 文本提示 |
||||
|
downText() { |
||||
|
switch (this.type) { |
||||
|
case 1: |
||||
|
return this.mOption.textInOffset; |
||||
|
case 2: |
||||
|
return this.mOption.textOutOffset; |
||||
|
case 3: |
||||
|
return this.mOption.textLoading; |
||||
|
case 4: |
||||
|
return this.mOption.textLoading; |
||||
|
default: |
||||
|
return this.mOption.textInOffset; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
@import './mescroll-down.css'; |
||||
|
</style> |
||||
@ -0,0 +1,90 @@ |
|||||
|
<!--空布局 |
||||
|
|
||||
|
可作为独立的组件, 不使用mescroll的页面也能单独引入, 以便APP全局统一管理: |
||||
|
import MescrollEmpty from '@/components/mescroll-uni/components/mescroll-empty.vue'; |
||||
|
<mescroll-empty v-if="isShowEmpty" :option="optEmpty" @emptyclick="emptyClick"></mescroll-empty> |
||||
|
|
||||
|
--> |
||||
|
<template> |
||||
|
<view class="mescroll-empty" :class="{ 'empty-fixed': option.fixed }" :style="{ 'z-index': option.zIndex, top: option.top }"> |
||||
|
<image v-if="icon" class="empty-icon" :src="icon" mode="widthFix" /> |
||||
|
<view v-if="tip" class="empty-tip">{{ tip }}</view> |
||||
|
<view v-if="option.btnText" class="empty-btn" @click="emptyClick">{{ option.btnText }}</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 引入全局配置 |
||||
|
import GlobalOption from './../mescroll-uni-option.js'; |
||||
|
export default { |
||||
|
props: { |
||||
|
// empty的配置项: 默认为GlobalOption.up.empty |
||||
|
option: { |
||||
|
type: Object, |
||||
|
default() { |
||||
|
return {}; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// 使用computed获取配置,用于支持option的动态配置 |
||||
|
computed: { |
||||
|
// 图标 |
||||
|
icon() { |
||||
|
return this.option.icon == null ? GlobalOption.up.empty.icon : this.option.icon; // 此处不使用短路求值, 用于支持传空串不显示图标 |
||||
|
}, |
||||
|
// 文本提示 |
||||
|
tip() { |
||||
|
return this.option.tip == null ? GlobalOption.up.empty.tip : this.option.tip; // 此处不使用短路求值, 用于支持传空串不显示文本提示 |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 点击按钮 |
||||
|
emptyClick() { |
||||
|
this.$emit('emptyclick'); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
/* 无任何数据的空布局 */ |
||||
|
.mescroll-empty { |
||||
|
box-sizing: border-box; |
||||
|
width: 100%; |
||||
|
padding: 100rpx 50rpx; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.mescroll-empty.empty-fixed { |
||||
|
z-index: 99; |
||||
|
position: absolute; /*transform会使fixed失效,最终会降级为absolute */ |
||||
|
top: 100rpx; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.mescroll-empty .empty-icon { |
||||
|
width: 280rpx; |
||||
|
height: 280rpx; |
||||
|
} |
||||
|
|
||||
|
.mescroll-empty .empty-tip { |
||||
|
margin-top: 20rpx; |
||||
|
font-size: $font-size-tag; |
||||
|
color: gray; |
||||
|
} |
||||
|
|
||||
|
.mescroll-empty .empty-btn { |
||||
|
display: inline-block; |
||||
|
margin-top: 40rpx; |
||||
|
min-width: 200rpx; |
||||
|
padding: 18rpx; |
||||
|
font-size: $font-size-base; |
||||
|
border: 1rpx solid #e04b28; |
||||
|
border-radius: 60rpx; |
||||
|
color: #e04b28; |
||||
|
} |
||||
|
|
||||
|
.mescroll-empty .empty-btn:active { |
||||
|
opacity: 0.75; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,81 @@ |
|||||
|
<!-- 回到顶部的按钮 --> |
||||
|
<template> |
||||
|
<image |
||||
|
v-if="mOption.src" |
||||
|
class="mescroll-totop" |
||||
|
:class="[value ? 'mescroll-totop-in' : 'mescroll-totop-out', { 'mescroll-safe-bottom': mOption.safearea }]" |
||||
|
:style="{ 'z-index': mOption.zIndex, left: left, right: right, bottom: addUnit(mOption.bottom), width: addUnit(mOption.width), 'border-radius': addUnit(mOption.radius) }" |
||||
|
:src="mOption.src" |
||||
|
mode="widthFix" |
||||
|
@click="toTopClick" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
// up.toTop的配置项 |
||||
|
option: Object, |
||||
|
// 是否显示 |
||||
|
value: false |
||||
|
}, |
||||
|
computed: { |
||||
|
// 支付宝小程序需写成计算属性,prop定义default仍报错 |
||||
|
mOption() { |
||||
|
return this.option || {}; |
||||
|
}, |
||||
|
// 优先显示左边 |
||||
|
left() { |
||||
|
return this.mOption.left ? this.addUnit(this.mOption.left) : 'auto'; |
||||
|
}, |
||||
|
// 右边距离 (优先显示左边) |
||||
|
right() { |
||||
|
return this.mOption.left ? 'auto' : this.addUnit(this.mOption.right); |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
addUnit(num) { |
||||
|
if (!num) return 0; |
||||
|
if (typeof num === 'number') return num + 'rpx'; |
||||
|
return num; |
||||
|
}, |
||||
|
toTopClick() { |
||||
|
this.$emit('input', false); // 使v-model生效 |
||||
|
this.$emit('click'); // 派发点击事件 |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
/* 回到顶部的按钮 */ |
||||
|
.mescroll-totop { |
||||
|
z-index: 99; |
||||
|
position: fixed !important; /* 加上important避免编译到H5,在多mescroll中定位失效 */ |
||||
|
right: 46rpx !important; |
||||
|
bottom: 272rpx !important; |
||||
|
width: 72rpx; |
||||
|
height: auto; |
||||
|
border-radius: 50%; |
||||
|
opacity: 0; |
||||
|
transition: opacity 0.5s; /* 过渡 */ |
||||
|
margin-bottom: var(--window-bottom); /* css变量 */ |
||||
|
} |
||||
|
|
||||
|
/* 适配 iPhoneX */ |
||||
|
.mescroll-safe-bottom { |
||||
|
margin-bottom: calc(var(--window-bottom) + constant(safe-area-inset-bottom)); /* window-bottom + 适配 iPhoneX */ |
||||
|
margin-bottom: calc(var(--window-bottom) + env(safe-area-inset-bottom)); |
||||
|
} |
||||
|
|
||||
|
/* 显示 -- 淡入 */ |
||||
|
.mescroll-totop-in { |
||||
|
opacity: 1; |
||||
|
} |
||||
|
|
||||
|
/* 隐藏 -- 淡出且不接收事件*/ |
||||
|
.mescroll-totop-out { |
||||
|
opacity: 0; |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,47 @@ |
|||||
|
/* 上拉加载区域 */ |
||||
|
.mescroll-upwarp { |
||||
|
min-height: 60rpx; |
||||
|
padding: 30rpx 0; |
||||
|
text-align: center; |
||||
|
clear: both; |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
/*提示文本 */ |
||||
|
.mescroll-upwarp .upwarp-tip, |
||||
|
.mescroll-upwarp .upwarp-nodata { |
||||
|
display: inline-block; |
||||
|
font-size: 28rpx; |
||||
|
color: #b1b1b1; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
.mescroll-upwarp .upwarp-tip { |
||||
|
margin-left: 16rpx; |
||||
|
} |
||||
|
|
||||
|
/*旋转进度条 */ |
||||
|
.mescroll-upwarp .upwarp-progress { |
||||
|
display: inline-block; |
||||
|
width: 32rpx; |
||||
|
height: 32rpx; |
||||
|
border-radius: 50%; |
||||
|
border: 2rpx solid #b1b1b1; |
||||
|
border-bottom-color: transparent; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
/* 旋转动画 */ |
||||
|
.mescroll-upwarp .mescroll-rotate { |
||||
|
animation: mescrollUpRotate 0.6s linear infinite; |
||||
|
} |
||||
|
|
||||
|
@keyframes mescrollUpRotate { |
||||
|
0% { |
||||
|
transform: rotate(0deg); |
||||
|
} |
||||
|
|
||||
|
100% { |
||||
|
transform: rotate(360deg); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
<!-- 上拉加载区域 --> |
||||
|
<template> |
||||
|
<view class="mescroll-upwarp"> |
||||
|
<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) --> |
||||
|
<view v-show="isUpLoading"> |
||||
|
<view class="upwarp-progress mescroll-rotate"></view> |
||||
|
<view class="upwarp-tip">{{ mOption.textLoading }}</view> |
||||
|
</view> |
||||
|
<!-- 无数据 --> |
||||
|
<view v-if="isUpNoMore" class="upwarp-nodata">{{ mOption.textNoMore }}</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
option: Object, // up的配置项 |
||||
|
type: Number // 上拉加载的状态:0(loading前),1(loading中),2(没有更多了) |
||||
|
}, |
||||
|
computed: { |
||||
|
// 支付宝小程序需写成计算属性,prop定义default仍报错 |
||||
|
mOption() { |
||||
|
return this.option || {}; |
||||
|
}, |
||||
|
// 加载中 |
||||
|
isUpLoading() { |
||||
|
return this.type === 1; |
||||
|
}, |
||||
|
// 没有更多了 |
||||
|
isUpNoMore() { |
||||
|
return this.type === 2; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
@import './mescroll-up.css'; |
||||
|
</style> |
||||
@ -0,0 +1,15 @@ |
|||||
|
page { |
||||
|
-webkit-overflow-scrolling: touch; |
||||
|
/* 使iOS滚动流畅 */ |
||||
|
} |
||||
|
|
||||
|
.mescroll-body { |
||||
|
position: relative; |
||||
|
/* 下拉刷新区域相对自身定位 */ |
||||
|
height: auto; |
||||
|
/* 不可固定高度,否则overflow: hidden, 可通过设置最小高度使列表不满屏仍可下拉*/ |
||||
|
overflow: hidden; |
||||
|
/* 遮住顶部下拉刷新区域 */ |
||||
|
box-sizing: border-box; |
||||
|
/* 避免设置padding出现双滚动条的问题 */ |
||||
|
} |
||||
@ -0,0 +1,298 @@ |
|||||
|
<template> |
||||
|
<view |
||||
|
class="mescroll-body" |
||||
|
:style="{ minHeight: minHeight, 'padding-top': padTop, 'padding-bottom': padBottom, 'padding-bottom': padBottomConstant, 'padding-bottom': padBottomEnv }" |
||||
|
@touchstart="touchstartEvent" |
||||
|
@touchmove="touchmoveEvent" |
||||
|
@touchend="touchendEvent" |
||||
|
@touchcancel="touchendEvent" |
||||
|
> |
||||
|
<view class="mescroll-body-content mescroll-touch" :style="{ transform: translateY, transition: transition }"> |
||||
|
<!-- 下拉加载区域 (支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-down组件实现)--> |
||||
|
<!-- <mescroll-down :option="mescroll.optDown" :type="downLoadType" :rate="downRate"></mescroll-down> --> |
||||
|
<view v-if="mescroll.optDown.use" class="mescroll-downwarp"> |
||||
|
<view class="downwarp-content"> |
||||
|
<view class="downwarp-progress" :class="{ 'mescroll-rotate': isDownLoading }" :style="{ transform: downRotate }"></view> |
||||
|
<view class="downwarp-tip">{{ downText }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 列表内容 --> |
||||
|
<slot></slot> |
||||
|
|
||||
|
<!-- 空布局 --> |
||||
|
<!-- <mescroll-empty v-if="isShowEmpty" :option="mescroll.optUp.empty" @emptyclick="emptyClick"></mescroll-empty> --> |
||||
|
|
||||
|
<!-- 上拉加载区域 (下拉刷新时不显示, 支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-up组件实现)--> |
||||
|
<!-- <mescroll-up v-if="mescroll.optUp.use && !isDownLoading" :option="mescroll.optUp" :type="upLoadType"></mescroll-up> --> |
||||
|
<view v-if="mescroll.optUp.use && !isDownLoading" class="mescroll-upwarp"> |
||||
|
<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) --> |
||||
|
<view v-show="upLoadType === 1"> |
||||
|
<view class="upwarp-progress mescroll-rotate"></view> |
||||
|
<view class="upwarp-tip">{{ mescroll.optUp.textLoading }}</view> |
||||
|
</view> |
||||
|
<!-- 无数据 --> |
||||
|
<view v-if="upLoadType === 2" class="upwarp-nodata">{{ mescroll.optUp.textNoMore }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 回到顶部按钮 (fixed元素需写在transform外面,防止降级为absolute)--> |
||||
|
<mescroll-top v-model="isShowToTop" :option="mescroll.optUp.toTop" @click="toTopClick" v-if="showTop"></mescroll-top> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// 引入mescroll-uni.js,处理核心逻辑 |
||||
|
import MeScroll from './mescroll-uni.js'; |
||||
|
// 引入全局配置 |
||||
|
import GlobalOption from './mescroll-uni-option.js'; |
||||
|
// 引入空布局组件 |
||||
|
// import MescrollEmpty from './components/mescroll-empty.vue'; |
||||
|
// 引入回到顶部组件 |
||||
|
import MescrollTop from './components/mescroll-top.vue'; |
||||
|
|
||||
|
export default { |
||||
|
components: { |
||||
|
// MescrollEmpty, |
||||
|
MescrollTop |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
mescroll: { optDown: {}, optUp: {} }, // mescroll实例 |
||||
|
downHight: 0, //下拉刷新: 容器高度 |
||||
|
downRate: 0, // 下拉比率(inOffset: rate<1; outOffset: rate>=1) |
||||
|
downLoadType: 4, // 下拉刷新状态 (inOffset:1, outOffset:2, showLoading:3, endDownScroll:4) |
||||
|
upLoadType: 0, // 上拉加载状态:0(loading前),1(loading中),2(没有更多了) |
||||
|
isShowEmpty: false, // 是否显示空布局 |
||||
|
isShowToTop: false, // 是否显示回到顶部按钮 |
||||
|
windowHeight: 0, // 可使用窗口的高度 |
||||
|
statusBarHeight: 0 // 状态栏高度 |
||||
|
}; |
||||
|
}, |
||||
|
props: { |
||||
|
down: Object, // 下拉刷新的参数配置 |
||||
|
up: Object, // 上拉加载的参数配置 |
||||
|
top: [String, Number], // 下拉布局往下的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight) |
||||
|
topbar: Boolean, // top的偏移量是否加上状态栏高度, 默认false (使用场景:取消原生导航栏时,配置此项可自动加上状态栏高度的偏移量) |
||||
|
bottom: [String, Number], // 上拉布局往上的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight) |
||||
|
safearea: Boolean, // bottom的偏移量是否加上底部安全区的距离, 默认false (需要适配iPhoneX时使用) |
||||
|
height: [String, Number], // 指定mescroll最小高度,默认windowHeight,使列表不满屏仍可下拉 |
||||
|
showTop: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
// mescroll最小高度,默认windowHeight,使列表不满屏仍可下拉 |
||||
|
minHeight() { |
||||
|
return this.toPx(this.height || '100%') + 'px'; |
||||
|
}, |
||||
|
// 下拉布局往下偏移的距离 (px) |
||||
|
numTop() { |
||||
|
return this.toPx(this.top) + (this.topbar ? this.statusBarHeight : 0); |
||||
|
}, |
||||
|
padTop() { |
||||
|
return this.numTop + 'px'; |
||||
|
}, |
||||
|
// 上拉布局往上偏移 (px) |
||||
|
numBottom() { |
||||
|
return this.toPx(this.bottom); |
||||
|
}, |
||||
|
padBottom() { |
||||
|
return this.numBottom + 'px'; |
||||
|
}, |
||||
|
padBottomConstant() { |
||||
|
return this.safearea ? 'calc(' + this.padBottom + ' + constant(safe-area-inset-bottom))' : this.padBottom; |
||||
|
}, |
||||
|
padBottomEnv() { |
||||
|
return this.safearea ? 'calc(' + this.padBottom + ' + env(safe-area-inset-bottom))' : this.padBottom; |
||||
|
}, |
||||
|
// 是否为重置下拉的状态 |
||||
|
isDownReset() { |
||||
|
return this.downLoadType === 3 || this.downLoadType === 4; |
||||
|
}, |
||||
|
// 过渡 |
||||
|
transition() { |
||||
|
return this.isDownReset ? 'transform 300ms' : ''; |
||||
|
}, |
||||
|
translateY() { |
||||
|
return this.downHight > 0 ? 'translateY(' + this.downHight + 'px)' : ''; // transform会使fixed失效,需注意把fixed元素写在mescroll之外 |
||||
|
}, |
||||
|
// 是否在加载中 |
||||
|
isDownLoading() { |
||||
|
return this.downLoadType === 3; |
||||
|
}, |
||||
|
// 旋转的角度 |
||||
|
downRotate() { |
||||
|
return 'rotate(' + 360 * this.downRate + 'deg)'; |
||||
|
}, |
||||
|
// 文本提示 |
||||
|
downText() { |
||||
|
switch (this.downLoadType) { |
||||
|
case 1: |
||||
|
return this.mescroll.optDown.textInOffset; |
||||
|
case 2: |
||||
|
return this.mescroll.optDown.textOutOffset; |
||||
|
case 3: |
||||
|
return this.mescroll.optDown.textLoading; |
||||
|
case 4: |
||||
|
return this.mescroll.optDown.textLoading; |
||||
|
default: |
||||
|
return this.mescroll.optDown.textInOffset; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
//number,rpx,upx,px,% --> px的数值 |
||||
|
toPx(num) { |
||||
|
if (typeof num === 'string') { |
||||
|
if (num.indexOf('px') !== -1) { |
||||
|
if (num.indexOf('rpx') !== -1) { |
||||
|
// "10rpx" |
||||
|
num = num.replace('rpx', ''); |
||||
|
} else if (num.indexOf('upx') !== -1) { |
||||
|
// "10upx" |
||||
|
num = num.replace('upx', ''); |
||||
|
} else { |
||||
|
// "10px" |
||||
|
return Number(num.replace('px', '')); |
||||
|
} |
||||
|
} else if (num.indexOf('%') !== -1) { |
||||
|
// 传百分比,则相对于windowHeight,传"10%"则等于windowHeight的10% |
||||
|
let rate = Number(num.replace('%', '')) / 100; |
||||
|
return this.windowHeight * rate; |
||||
|
} |
||||
|
} |
||||
|
return num ? uni.upx2px(Number(num)) : 0; |
||||
|
}, |
||||
|
//注册列表touchstart事件,用于下拉刷新 |
||||
|
touchstartEvent(e) { |
||||
|
this.mescroll.touchstartEvent(e); |
||||
|
}, |
||||
|
//注册列表touchmove事件,用于下拉刷新 |
||||
|
touchmoveEvent(e) { |
||||
|
this.mescroll.touchmoveEvent(e); |
||||
|
}, |
||||
|
//注册列表touchend事件,用于下拉刷新 |
||||
|
touchendEvent(e) { |
||||
|
this.mescroll.touchendEvent(e); |
||||
|
}, |
||||
|
// 点击空布局的按钮回调 |
||||
|
emptyClick() { |
||||
|
this.$emit('emptyclick', this.mescroll); |
||||
|
}, |
||||
|
// 点击回到顶部的按钮回调 |
||||
|
toTopClick() { |
||||
|
this.mescroll.scrollTo(0, this.mescroll.optUp.toTop.duration); // 执行回到顶部 |
||||
|
this.$emit('topclick', this.mescroll); // 派发点击回到顶部按钮的回调 |
||||
|
} |
||||
|
}, |
||||
|
// 使用created初始化mescroll对象; 如果用mounted部分css样式编译到H5会失效 |
||||
|
created() { |
||||
|
let vm = this; |
||||
|
|
||||
|
let diyOption = { |
||||
|
// 下拉刷新的配置 |
||||
|
down: { |
||||
|
inOffset(mescroll) { |
||||
|
vm.downLoadType = 1; // 下拉的距离进入offset范围内那一刻的回调 (自定义mescroll组件时,此行不可删) |
||||
|
}, |
||||
|
outOffset(mescroll) { |
||||
|
vm.downLoadType = 2; // 下拉的距离大于offset那一刻的回调 (自定义mescroll组件时,此行不可删) |
||||
|
}, |
||||
|
onMoving(mescroll, rate, downHight) { |
||||
|
// 下拉过程中的回调,滑动过程一直在执行; |
||||
|
vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删) |
||||
|
vm.downRate = rate; //下拉比率 (inOffset: rate<1; outOffset: rate>=1) |
||||
|
}, |
||||
|
showLoading(mescroll, downHight) { |
||||
|
vm.downLoadType = 3; // 显示下拉刷新进度的回调 (自定义mescroll组件时,此行不可删) |
||||
|
vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删) |
||||
|
}, |
||||
|
endDownScroll(mescroll) { |
||||
|
vm.downLoadType = 4; // 结束下拉 (自定义mescroll组件时,此行不可删) |
||||
|
vm.downHight = 0; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删) |
||||
|
}, |
||||
|
// 派发下拉刷新的回调 |
||||
|
callback: function(mescroll) { |
||||
|
vm.$emit('down', mescroll); |
||||
|
} |
||||
|
}, |
||||
|
// 上拉加载的配置 |
||||
|
up: { |
||||
|
// 显示加载中的回调 |
||||
|
showLoading() { |
||||
|
vm.upLoadType = 1; |
||||
|
}, |
||||
|
// 显示无更多数据的回调 |
||||
|
showNoMore() { |
||||
|
vm.upLoadType = 2; |
||||
|
}, |
||||
|
// 隐藏上拉加载的回调 |
||||
|
hideUpScroll() { |
||||
|
vm.upLoadType = 0; |
||||
|
}, |
||||
|
// 空布局 |
||||
|
empty: { |
||||
|
onShow(isShow) { |
||||
|
// 显示隐藏的回调 |
||||
|
vm.isShowEmpty = isShow; |
||||
|
} |
||||
|
}, |
||||
|
// 回到顶部 |
||||
|
toTop: { |
||||
|
onShow(isShow) { |
||||
|
// 显示隐藏的回调 |
||||
|
vm.isShowToTop = isShow; |
||||
|
} |
||||
|
}, |
||||
|
// 派发上拉加载的回调 |
||||
|
callback: function(mescroll) { |
||||
|
vm.$emit('up', mescroll); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
MeScroll.extend(diyOption, GlobalOption); // 混入全局的配置 |
||||
|
let myOption = JSON.parse( |
||||
|
JSON.stringify({ |
||||
|
down: vm.down, |
||||
|
up: vm.up |
||||
|
}) |
||||
|
); // 深拷贝,避免对props的影响 |
||||
|
MeScroll.extend(myOption, diyOption); // 混入具体界面的配置 |
||||
|
|
||||
|
// 初始化MeScroll对象 |
||||
|
vm.mescroll = new MeScroll(myOption, true); // 传入true,标记body为滚动区域 |
||||
|
// init回调mescroll对象 |
||||
|
vm.$emit('init', vm.mescroll); |
||||
|
|
||||
|
// 设置高度 |
||||
|
const sys = uni.getSystemInfoSync(); |
||||
|
if (sys.windowHeight) vm.windowHeight = sys.windowHeight; |
||||
|
if (sys.statusBarHeight) vm.statusBarHeight = sys.statusBarHeight; |
||||
|
// 使down的bottomOffset生效 |
||||
|
vm.mescroll.setBodyHeight(sys.windowHeight); |
||||
|
|
||||
|
// 因为使用的是page的scroll,这里需自定义scrollTo |
||||
|
vm.mescroll.resetScrollTo((y, t) => { |
||||
|
uni.pageScrollTo({ |
||||
|
scrollTop: y, |
||||
|
duration: t |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
// 具体的界面如果不配置up.toTop.safearea,则取本vue的safearea值 |
||||
|
if (vm.up && vm.up.toTop && vm.up.toTop.safearea != null) { |
||||
|
} else { |
||||
|
vm.mescroll.optUp.toTop.safearea = vm.safearea; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
@import './mescroll-body.css'; |
||||
|
@import './components/mescroll-down.css'; |
||||
|
@import './components/mescroll-up.css'; |
||||
|
</style> |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue