Compare commits
10 Commits
dev/2.0
...
b633125cc3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b633125cc3 | ||
|
|
f1c01833e4 | ||
|
|
5bd0881946 | ||
|
|
86e43e3e6c | ||
|
|
bf09d8ad26 | ||
| 03aa6e099f | |||
| 4585fb6c07 | |||
| 4aeb7d04c4 | |||
|
|
067bbf6e2d | ||
|
|
3cef4b9987 |
18
App.vue
18
App.vue
@@ -40,7 +40,7 @@
|
|||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
if (uni.getDeviceInfo().platform == 'ios') {
|
if (uni.getSystemInfoSync().platform == 'ios') {
|
||||||
uni.setStorageSync('initUrl', location.href);
|
uni.setStorageSync('initUrl', location.href);
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
@@ -98,11 +98,6 @@
|
|||||||
if (uni.getStorageSync('servicerConfig')) {
|
if (uni.getStorageSync('servicerConfig')) {
|
||||||
this.$store.commit('setServicerConfig', uni.getStorageSync('servicerConfig'));
|
this.$store.commit('setServicerConfig', uni.getStorageSync('servicerConfig'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 企业微信配置
|
|
||||||
if (uni.getStorageSync('wxworkConfig')) {
|
|
||||||
this.$store.commit('setWxworkConfig', uni.getStorageSync('wxworkConfig'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 版权信息
|
// 版权信息
|
||||||
if (uni.getStorageSync('copyright')) {
|
if (uni.getStorageSync('copyright')) {
|
||||||
@@ -151,6 +146,7 @@
|
|||||||
onShow: function(options) {
|
onShow: function(options) {
|
||||||
// #ifdef MP
|
// #ifdef MP
|
||||||
// 自动授权登录
|
// 自动授权登录
|
||||||
|
this.getAuthInfo();
|
||||||
if (this.$store.state.token) {
|
if (this.$store.state.token) {
|
||||||
this.$api.sendRequest({
|
this.$api.sendRequest({
|
||||||
url: '/api/member/info',
|
url: '/api/member/info',
|
||||||
@@ -160,8 +156,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else{
|
|
||||||
this.getAuthInfo();
|
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
@@ -178,7 +172,8 @@
|
|||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
if (this.$util.isWeiXin()) {
|
if (this.$util.isWeiXin()) {
|
||||||
this.$util.getUrlCode(urlParams => {
|
this.$util.getUrlCode(urlParams => {
|
||||||
if (urlParams.source_member) uni.setStorageSync('source_member', urlParams.source_member);
|
if (urlParams.source_member) uni.setStorageSync('source_member', urlParams
|
||||||
|
.source_member);
|
||||||
|
|
||||||
if (urlParams.code == undefined) {
|
if (urlParams.code == undefined) {
|
||||||
this.$api.sendRequest({
|
this.$api.sendRequest({
|
||||||
@@ -204,7 +199,8 @@
|
|||||||
let data = {};
|
let data = {};
|
||||||
if (res.data.openid) data.wx_openid = res.data.openid;
|
if (res.data.openid) data.wx_openid = res.data.openid;
|
||||||
if (res.data.unionid) data.wx_unionid = res.data.unionid;
|
if (res.data.unionid) data.wx_unionid = res.data.unionid;
|
||||||
if (res.data.userinfo) Object.assign(data, res.data.userinfo);
|
if (res.data.userinfo) Object.assign(data, res.data
|
||||||
|
.userinfo);
|
||||||
this.authLogin(data);
|
this.authLogin(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,7 +296,7 @@
|
|||||||
this.shareConfig();
|
this.shareConfig();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 代表在watch里声明了firstName这个方法之后立即先去执行handler方法
|
// 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
|
||||||
immediate: true
|
immediate: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,305 +1,234 @@
|
|||||||
.collectPopupWindow {
|
.collectPopupWindow {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 113rpx;
|
height: 113rpx;
|
||||||
width: 510rpx;
|
width: 510rpx;
|
||||||
margin-left: calc(100% - 530rpx);
|
margin-left: calc(100% - 530rpx);
|
||||||
|
|
||||||
image {
|
image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
text {
|
text {
|
||||||
color: #ff4544 !important;
|
color: #ff4544 !important;
|
||||||
font-size: 24rpx !important;
|
font-size: 24rpx !important;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 48rpx;
|
top: 48rpx;
|
||||||
right: 25rpx;
|
right: 25rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.zhezhao {
|
.zhezhao {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
image {
|
image {
|
||||||
max-width: 100% !important;
|
max-width: 100% !important;
|
||||||
max-height: 100% !important;
|
max-height: 100% !important;
|
||||||
}
|
}
|
||||||
.diy-wrap {
|
.diy-wrap {
|
||||||
/* #ifdef H5 */
|
/* #ifdef H5 */
|
||||||
height: calc(100vh - 88rpx);
|
height: calc(100vh - 88rpx);
|
||||||
/* #endif */
|
/* #endif */
|
||||||
/* #ifdef MP-WEIXIN */
|
/* #ifdef MP-WEIXIN */
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-img {
|
.page-img {
|
||||||
background-size: contain !important;
|
background-size: contain !important;
|
||||||
background-repeat: no-repeat !important;
|
background-repeat: no-repeat !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-header {
|
.page-header {
|
||||||
background-size: 100% !important;
|
background-size: 100% !important;
|
||||||
background-repeat: no-repeat !important;
|
background-repeat: no-repeat !important;
|
||||||
background-position: top center;
|
background-position: top center;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-index {
|
.bg-index {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background-size: 100% !important;
|
background-size: 100% !important;
|
||||||
background-repeat: no-repeat !important;
|
background-repeat: no-repeat !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wap-floating {
|
.wap-floating {
|
||||||
text {
|
text {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 60rpx;
|
font-size: 60rpx;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.wap-floating-collect .uni-popup__mask {
|
.wap-floating-collect .uni-popup__mask {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-box {
|
.popup-box {
|
||||||
width: 450rpx;
|
width: 450rpx;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.close_title {
|
.close_title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
height: 70rpx;
|
height: 70rpx;
|
||||||
line-height: 70rpx;
|
line-height: 70rpx;
|
||||||
font-size: $font-size-base;
|
font-size: $font-size-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close_content {
|
.close_content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-height: 500rpx;
|
max-height: 500rpx;
|
||||||
padding: $padding;
|
padding: $padding;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close_content_box {
|
.close_content_box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-height: 460rpx;
|
max-height: 460rpx;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.noStore-text {
|
.noStore-text {
|
||||||
color: #000000 !important;
|
color: #000000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.isStore-top {
|
.isStore-top {
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 10rpx;
|
||||||
}
|
}
|
||||||
.keep-on-record {
|
.keep-on-record {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding-bottom: 20rpx;
|
padding-bottom: 20rpx;
|
||||||
image {
|
image {
|
||||||
width: 150rpx;
|
width: 150rpx;
|
||||||
height: 60rpx;
|
height: 60rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.padding-bottom {
|
.padding-bottom {
|
||||||
padding-bottom: 40rpx !important;
|
padding-bottom: 40rpx !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choose-store {
|
.choose-store {
|
||||||
/deep/ .uni-popup__wrapper{
|
/deep/ .uni-popup__wrapper{
|
||||||
background: none!important;
|
background: none!important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.choose-store-popup {
|
.choose-store-popup {
|
||||||
padding: 30rpx;
|
padding: 30rpx;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
.head-wrap {
|
.head-wrap {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: $font-size-toolbar;
|
font-size: $font-size-toolbar;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
color: #202021;
|
color: #202021;
|
||||||
}
|
}
|
||||||
.position-wrap {
|
.position-wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
color: #202021;
|
color: #202021;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
.icon-dizhi {
|
.icon-dizhi {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: $font-size-tag;
|
font-size: $font-size-tag;
|
||||||
margin-right: 10rpx;
|
margin-right: 10rpx;
|
||||||
}
|
}
|
||||||
.address {
|
.address {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: $font-size-tag;
|
font-size: $font-size-tag;
|
||||||
margin-right: 10rpx;
|
margin-right: 10rpx;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
-o-text-overflow: ellipsis;
|
-o-text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
.reposition {
|
.reposition {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.iconfont {
|
.iconfont {
|
||||||
font-size: $font-size-base;
|
font-size: $font-size-base;
|
||||||
margin-right: 6rpx;
|
margin-right: 6rpx;
|
||||||
}
|
}
|
||||||
text {
|
text {
|
||||||
font-size: $font-size-tag;
|
font-size: $font-size-tag;
|
||||||
color: #fd463e;
|
color: #fd463e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store-wrap {
|
.store-wrap {
|
||||||
border: 1px solid $base-color;
|
border: 1px solid $base-color;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
padding: 20rpx 30rpx;
|
padding: 20rpx 30rpx;
|
||||||
margin-bottom: 30rpx;
|
margin-bottom: 30rpx;
|
||||||
.tag {
|
.tag {
|
||||||
background-color: #fee9ea;
|
background-color: #fee9ea;
|
||||||
color: #fd463e;
|
color: #fd463e;
|
||||||
font-size: $font-size-activity-tag;
|
font-size: $font-size-activity-tag;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-radius: 6rpx;
|
border-radius: 6rpx;
|
||||||
padding: 4rpx 12rpx;
|
padding: 4rpx 12rpx;
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
transform: scale(0.8);
|
transform: scale(0.8);
|
||||||
margin-left: -10rpx;
|
margin-left: -10rpx;
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
.store-name {
|
.store-name {
|
||||||
margin: 10rpx 0;
|
margin: 10rpx 0;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #202021;
|
color: #202021;
|
||||||
font-size: $font-size-toolbar;
|
font-size: $font-size-toolbar;
|
||||||
}
|
}
|
||||||
.store-close-desc{
|
.address {
|
||||||
color: red;
|
color: #5f6067;
|
||||||
font-size: $font-size-tag;
|
font-size: $font-size-tag;
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 10rpx;
|
||||||
}
|
}
|
||||||
.address {
|
.distance {
|
||||||
color: #5f6067;
|
display: flex;
|
||||||
font-size: $font-size-tag;
|
align-items: center;
|
||||||
margin-bottom: 10rpx;
|
color: #5f6067;
|
||||||
}
|
font-size: $font-size-tag;
|
||||||
.distance {
|
.iconfont {
|
||||||
display: flex;
|
font-size: $font-size-base;
|
||||||
align-items: center;
|
margin-right: 10rpx;
|
||||||
color: #5f6067;
|
}
|
||||||
font-size: $font-size-tag;
|
}
|
||||||
.iconfont {
|
}
|
||||||
font-size: $font-size-base;
|
|
||||||
margin-right: 10rpx;
|
button {
|
||||||
}
|
border-radius: 40rpx;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
.other-store {
|
||||||
button {
|
display: flex;
|
||||||
border-radius: 40rpx;
|
align-items: center;
|
||||||
}
|
color: #5e6066;
|
||||||
|
font-weight: bold;
|
||||||
.other-store {
|
justify-content: center;
|
||||||
display: flex;
|
margin-top: 20rpx;
|
||||||
align-items: center;
|
margin-bottom: 20rpx;
|
||||||
color: #5e6066;
|
.iconfont {
|
||||||
font-weight: bold;
|
margin-left: 10rpx;
|
||||||
justify-content: center;
|
font-size: $font-size-tag;
|
||||||
margin-top: 20rpx;
|
}
|
||||||
margin-bottom: 20rpx;
|
}
|
||||||
.iconfont {
|
}
|
||||||
margin-left: 10rpx;
|
.page-bottom {
|
||||||
font-size: $font-size-tag;
|
margin-top: 20rpx;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
.page-bottom {
|
|
||||||
margin-top: 20rpx;
|
|
||||||
}
|
|
||||||
.chain-stores{
|
|
||||||
.chain-store-popup{
|
|
||||||
background-color: #fff;
|
|
||||||
border-top-left-radius: 24rpx;
|
|
||||||
border-top-right-radius: 24rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
.title{
|
|
||||||
font-size: 36rpx;
|
|
||||||
line-height: 104rpx;
|
|
||||||
text-align: center;
|
|
||||||
color: #000;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.body{
|
|
||||||
padding: 20rpx 30rpx;
|
|
||||||
background-color: #F4F4F4;
|
|
||||||
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom)) !important;
|
|
||||||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom)) !important;
|
|
||||||
.center{
|
|
||||||
background-color: #fff;
|
|
||||||
box-shadow: 4rpx 4rpx 12rpx 4rpx rgba(0,0,0,0.02);
|
|
||||||
border-radius: 24rpx;
|
|
||||||
padding-top: 60rpx;
|
|
||||||
padding-bottom: 23rpx;
|
|
||||||
.image{
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.text-top{
|
|
||||||
margin-top: 44rpx;
|
|
||||||
font-size: 30rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #000;
|
|
||||||
line-height: 42rpx;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.text-bottom{
|
|
||||||
margin-top: 20rpx;
|
|
||||||
padding: 0 57rpx;
|
|
||||||
font-size: 24rpx;
|
|
||||||
line-height: 34rpx;
|
|
||||||
color: #999;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.footer{
|
|
||||||
display: flex;
|
|
||||||
margin-top: 20rpx;
|
|
||||||
padding: 0 24rpx;
|
|
||||||
button{
|
|
||||||
margin: 0 !important;
|
|
||||||
box-sizing: border-box;
|
|
||||||
height: 84rpx;
|
|
||||||
line-height: 84rpx;
|
|
||||||
border-radius: 62rpx;
|
|
||||||
font-size: 30rpx;
|
|
||||||
flex:1;
|
|
||||||
}
|
|
||||||
button.btn-right{
|
|
||||||
margin-left: 20rpx !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -1,434 +1,356 @@
|
|||||||
import Config from './config.js'
|
import http from './http.js'
|
||||||
import http from './http.js'
|
import store from '@/store/index.js'
|
||||||
import store from '@/store/index.js'
|
|
||||||
|
export default {
|
||||||
let currentConversationId = null;
|
/**
|
||||||
const CONVERSATION_KEY = 'ai_conversation_id';
|
* 发送消息到Dify API
|
||||||
|
* @param {string} message 用户消息内容
|
||||||
// 初始化时从本地读取会话ID
|
* @param {Object} options 配置选项
|
||||||
try {
|
* @returns {Promise}
|
||||||
const saved = uni.getStorageSync(CONVERSATION_KEY);
|
*/
|
||||||
if (saved) {
|
async sendMessage(message, options = {}) {
|
||||||
currentConversationId = saved;
|
try {
|
||||||
}
|
// 获取AI配置
|
||||||
} catch (e) {
|
const aiConfig = store.getters.globalAIAgentConfig
|
||||||
console.warn('读取会话ID失败:', e);
|
|
||||||
}
|
// 构建Dify API请求参数
|
||||||
|
const params = {
|
||||||
export default {
|
url: '/api/ai/chat', // 后端代理接口
|
||||||
/**
|
data: {
|
||||||
* 发送普通消息(blocking 模式)
|
message: message,
|
||||||
*/
|
conversation_id: options.conversationId || this.generateConversationId(),
|
||||||
async sendMessage(message, options = {}) {
|
user_id: store.state.memberInfo?.id || 'anonymous',
|
||||||
try {
|
stream: options.stream || false, // 是否流式响应
|
||||||
const aiConfig = store.getters.globalAIKefuConfig;
|
// Dify API参数
|
||||||
const params = {
|
inputs: {},
|
||||||
url: '/api/kefu/chat',
|
query: message,
|
||||||
data: {
|
response_mode: options.stream ? 'streaming' : 'blocking',
|
||||||
user_id: store.state.memberInfo?.id || 'anonymous',
|
user: store.state.memberInfo?.id || 'anonymous'
|
||||||
stream: false,
|
},
|
||||||
inputs: {},
|
header: {
|
||||||
query: message,
|
'Content-Type': 'application/json'
|
||||||
response_mode: 'blocking', // 强制 blocking
|
}
|
||||||
user: store.state.memberInfo?.id || 'anonymous',
|
}
|
||||||
conversation_id: this.getConversationId() || ''
|
|
||||||
},
|
// 如果有Dify配置,添加API密钥
|
||||||
header: {
|
if (aiConfig?.difyApiKey) {
|
||||||
'Content-Type': 'application/json'
|
params.header['Authorization'] = `Bearer ${aiConfig.difyApiKey}`
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
if (aiConfig?.difyBaseUrl) {
|
||||||
console.log('Sending blocking request to:', params.url);
|
params.header['X-Dify-Url'] = aiConfig.difyBaseUrl
|
||||||
console.log('Request data:', params.data);
|
}
|
||||||
|
|
||||||
const response = await http.sendRequest({
|
// 发送请求
|
||||||
...params,
|
const response = await http.sendRequest({
|
||||||
async: false
|
...params,
|
||||||
});
|
async: false // 使用Promise方式
|
||||||
|
})
|
||||||
const result = this.handleResponse(response);
|
|
||||||
if (result.conversationId) {
|
return this.handleResponse(response, options)
|
||||||
this.setConversationId(result.conversationId);
|
|
||||||
}
|
} catch (error) {
|
||||||
return result;
|
console.error('Dify API请求失败:', error)
|
||||||
} catch (error) {
|
throw new Error('AI服务暂时不可用,请稍后重试')
|
||||||
console.error('Dify API请求失败:', error);
|
}
|
||||||
throw new Error('AI服务暂时不可用,请稍后重试');
|
},
|
||||||
}
|
|
||||||
},
|
/**
|
||||||
|
* 流式消息处理
|
||||||
/**
|
* @param {string} message 用户消息
|
||||||
* 流式消息入口(自动适配平台)
|
* @param {Function} onChunk 流式数据回调
|
||||||
*/
|
* @param {Function} onComplete 完成回调
|
||||||
async sendStreamMessage(message, onChunk, onComplete) {
|
*/
|
||||||
// #ifdef MP-WEIXIN
|
async sendStreamMessage(message, onChunk, onComplete) {
|
||||||
// 微信小程序:降级为普通请求 + 前端打字模拟
|
try {
|
||||||
try {
|
const aiConfig = store.getters.globalAIAgentConfig
|
||||||
const result = await this.sendMessage(message);
|
|
||||||
const content = result.content || '';
|
// 检查配置
|
||||||
const conversationId = result.conversationId || '';
|
if (!aiConfig?.difyBaseUrl || !aiConfig?.difyApiKey) {
|
||||||
|
throw new Error('未配置Dify服务')
|
||||||
// 保存会话ID(确保连续对话)
|
}
|
||||||
if (conversationId) {
|
|
||||||
this.setConversationId(conversationId);
|
// 创建WebSocket连接或使用Server-Sent Events
|
||||||
}
|
if (aiConfig?.difyWsUrl) {
|
||||||
|
return this.connectWebSocket(message, onChunk, onComplete)
|
||||||
// 模拟打字效果
|
} else {
|
||||||
let index = 0;
|
// 使用HTTP流式请求
|
||||||
const chunkSize = 2; // 每次显示2个字符
|
return this.sendHttpStream(message, onChunk, onComplete)
|
||||||
return new Promise((resolve) => {
|
}
|
||||||
const timer = setInterval(() => {
|
|
||||||
if (index < content.length) {
|
} catch (error) {
|
||||||
const chunk = content.substring(index, index + chunkSize);
|
console.error('流式消息发送失败:', error)
|
||||||
index += chunkSize;
|
throw error
|
||||||
if (onChunk) onChunk(chunk);
|
}
|
||||||
} else {
|
},
|
||||||
clearInterval(timer);
|
|
||||||
if (onComplete) {
|
/**
|
||||||
onComplete({
|
* WebSocket连接
|
||||||
content: content,
|
*/
|
||||||
conversation_id: conversationId
|
connectWebSocket(message, onChunk, onComplete) {
|
||||||
});
|
return new Promise((resolve, reject) => {
|
||||||
}
|
const aiConfig = store.getters.globalAIAgentConfig
|
||||||
resolve({ content, conversation_id: conversationId });
|
const wsUrl = aiConfig.difyWsUrl
|
||||||
}
|
|
||||||
}, 80); // 打字速度:80ms/次
|
if (!wsUrl) {
|
||||||
});
|
reject(new Error('未配置WebSocket地址'))
|
||||||
} catch (error) {
|
return
|
||||||
console.error('小程序流式消息降级失败:', error);
|
}
|
||||||
if (onComplete) {
|
|
||||||
onComplete({ error: error.message || '发送失败' });
|
// #ifdef H5
|
||||||
}
|
const ws = new WebSocket(wsUrl)
|
||||||
throw error;
|
|
||||||
}
|
ws.onopen = () => {
|
||||||
// #endif
|
// 发送消息
|
||||||
|
ws.send(JSON.stringify({
|
||||||
// #ifdef H5
|
message: message,
|
||||||
// H5:使用真实流式(EventSource / Fetch)
|
user_id: store.state.memberInfo?.id || 'anonymous',
|
||||||
return this.sendHttpStream(message, onChunk, onComplete);
|
conversation_id: this.generateConversationId()
|
||||||
// #endif
|
}))
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
ws.onmessage = (event) => {
|
||||||
* HTTP 流式请求(仅 H5 使用)
|
try {
|
||||||
*/
|
const data = JSON.parse(event.data)
|
||||||
async sendHttpStream(message, onChunk, onComplete) {
|
if (data.type === 'chunk' && onChunk) {
|
||||||
// #ifdef H5
|
onChunk(data.content)
|
||||||
try {
|
} else if (data.type === 'complete' && onComplete) {
|
||||||
const url = Config.baseUrl + `/api/kefu/chat`;
|
onComplete(data.content)
|
||||||
const response = await fetch(url, {
|
ws.close()
|
||||||
method: 'POST',
|
resolve(data.content)
|
||||||
headers: {
|
}
|
||||||
'Content-Type': 'application/json',
|
} catch (e) {
|
||||||
'Accept': 'text/event-stream',
|
console.error('WebSocket消息解析失败:', e)
|
||||||
},
|
}
|
||||||
body: JSON.stringify({
|
}
|
||||||
uniacid: store.state.uniacid || '1',
|
|
||||||
inputs: {},
|
ws.onerror = (error) => {
|
||||||
query: message,
|
console.error('WebSocket连接错误:', error)
|
||||||
response_mode: 'streaming',
|
reject(error)
|
||||||
user_id: store.state.memberInfo?.id || 'anonymous',
|
}
|
||||||
conversation_id: this.getConversationId() || ''
|
|
||||||
})
|
ws.onclose = () => {
|
||||||
});
|
console.log('WebSocket连接关闭')
|
||||||
|
}
|
||||||
if (!response.ok) {
|
// #endif
|
||||||
throw new Error(`HTTP ${response.status}`);
|
|
||||||
}
|
// #ifdef MP-WEIXIN || APP-PLUS
|
||||||
if (!response.body) {
|
// 小程序和APP使用uni.connectSocket
|
||||||
throw new Error('响应体不可用');
|
uni.connectSocket({
|
||||||
}
|
url: wsUrl,
|
||||||
|
success: () => {
|
||||||
const reader = response.body.getReader();
|
uni.onSocketOpen(() => {
|
||||||
const decoder = new TextDecoder('utf-8');
|
uni.sendSocketMessage({
|
||||||
let buffer = '';
|
data: JSON.stringify({
|
||||||
let content = '';
|
message: message,
|
||||||
let conversationId = '';
|
user_id: store.state.memberInfo?.id || 'anonymous',
|
||||||
|
conversation_id: this.generateConversationId()
|
||||||
function processBuffer(buf, callback) {
|
})
|
||||||
const lines = buf.split('\n');
|
})
|
||||||
buf = lines.pop() || '';
|
})
|
||||||
for (const line of lines) {
|
|
||||||
const trimmed = line.trim();
|
uni.onSocketMessage((res) => {
|
||||||
if (trimmed.startsWith('data:')) {
|
try {
|
||||||
const jsonStr = trimmed.slice(5).trim();
|
const data = JSON.parse(res.data)
|
||||||
if (jsonStr) {
|
if (data.type === 'chunk' && onChunk) {
|
||||||
try {
|
onChunk(data.content)
|
||||||
const data = JSON.parse(jsonStr);
|
} else if (data.type === 'complete' && onComplete) {
|
||||||
if (data.event === 'message') {
|
onComplete(data.content)
|
||||||
const text = data.answer || data.text || '';
|
uni.closeSocket()
|
||||||
content += text;
|
resolve(data.content)
|
||||||
callback(text);
|
}
|
||||||
}
|
} catch (e) {
|
||||||
if (data.conversation_id) {
|
console.error('WebSocket消息解析失败:', e)
|
||||||
conversationId = data.conversation_id;
|
}
|
||||||
}
|
})
|
||||||
if (data.event === 'message_end') {
|
|
||||||
// 可选:提前完成
|
uni.onSocketError((error) => {
|
||||||
}
|
console.error('WebSocket连接错误:', error)
|
||||||
} catch (e) {
|
reject(error)
|
||||||
console.warn('解析流数据失败:', e);
|
})
|
||||||
}
|
},
|
||||||
}
|
fail: (error) => {
|
||||||
}
|
reject(error)
|
||||||
}
|
}
|
||||||
return buf;
|
})
|
||||||
}
|
// #endif
|
||||||
|
})
|
||||||
while (true) {
|
},
|
||||||
const { done, value } = await reader.read();
|
|
||||||
if (done) break;
|
/**
|
||||||
buffer += decoder.decode(value, { stream: true });
|
* HTTP流式请求
|
||||||
buffer = processBuffer(buffer, (chunk) => {
|
*/
|
||||||
if (onChunk) onChunk(chunk);
|
async sendHttpStream(message, onChunk, onComplete) {
|
||||||
});
|
const aiConfig = store.getters.globalAIAgentConfig
|
||||||
}
|
|
||||||
|
const params = {
|
||||||
if (onComplete) {
|
url: '/api/ai/chat-stream',
|
||||||
onComplete({
|
data: {
|
||||||
content,
|
message: message,
|
||||||
conversation_id: conversationId
|
conversation_id: this.generateConversationId(),
|
||||||
});
|
user_id: store.state.memberInfo?.id || 'anonymous',
|
||||||
}
|
stream: true
|
||||||
return { content, conversation_id: conversationId };
|
},
|
||||||
} catch (error) {
|
header: {
|
||||||
console.error('H5 流式请求失败:', error);
|
'Content-Type': 'application/json'
|
||||||
throw error;
|
}
|
||||||
}
|
}
|
||||||
// #endif
|
|
||||||
|
if (aiConfig?.difyApiKey) {
|
||||||
// #ifdef MP-WEIXIN
|
params.header['Authorization'] = `Bearer ${aiConfig.difyApiKey}`
|
||||||
// 理论上不会执行到这里,但防止 fallback
|
}
|
||||||
return this.sendStreamMessage(message, onChunk, onComplete);
|
|
||||||
// #endif
|
// 使用fetch API进行流式请求(H5环境)
|
||||||
},
|
// #ifdef H5
|
||||||
|
try {
|
||||||
/**
|
const response = await fetch(`${aiConfig.difyBaseUrl}/chat-messages`, {
|
||||||
* 处理API响应(统一格式)
|
method: 'POST',
|
||||||
*/
|
headers: {
|
||||||
handleResponse(response) {
|
'Content-Type': 'application/json',
|
||||||
if (response.code === 0 || response.success) {
|
'Authorization': `Bearer ${aiConfig.difyApiKey}`
|
||||||
return {
|
},
|
||||||
success: true,
|
body: JSON.stringify({
|
||||||
content: response.data?.answer || response.data?.content || response.data?.reply || response.data,
|
inputs: {},
|
||||||
conversationId: response.data?.conversation_id,
|
query: message,
|
||||||
messageId: response.data?.message_id
|
response_mode: 'streaming',
|
||||||
};
|
user: store.state.memberInfo?.id || 'anonymous'
|
||||||
} else {
|
})
|
||||||
throw new Error(response.message || 'AI服务返回错误');
|
})
|
||||||
}
|
|
||||||
},
|
const reader = response.body.getReader()
|
||||||
|
const decoder = new TextDecoder()
|
||||||
/**
|
let content = ''
|
||||||
* 获取当前会话ID
|
|
||||||
*/
|
while (true) {
|
||||||
getConversationId() {
|
const { done, value } = await reader.read()
|
||||||
return currentConversationId;
|
if (done) break
|
||||||
},
|
|
||||||
|
const chunk = decoder.decode(value)
|
||||||
/**
|
const lines = chunk.split('\n')
|
||||||
* 设置并持久化会话ID
|
|
||||||
*/
|
for (const line of lines) {
|
||||||
setConversationId(id) {
|
if (line.startsWith('data: ')) {
|
||||||
if (id && id !== currentConversationId) {
|
try {
|
||||||
currentConversationId = id;
|
const data = JSON.parse(line.slice(6))
|
||||||
try {
|
if (data.event === 'text_message' && data.text) {
|
||||||
uni.setStorageSync(CONVERSATION_KEY, id);
|
content += data.text
|
||||||
} catch (e) {
|
if (onChunk) onChunk(data.text)
|
||||||
console.error('保存会话ID失败:', e);
|
}
|
||||||
}
|
} catch (e) {
|
||||||
}
|
// 忽略解析错误
|
||||||
},
|
}
|
||||||
|
}
|
||||||
/**
|
}
|
||||||
* 清除会话ID
|
}
|
||||||
*/
|
|
||||||
clearConversationId() {
|
if (onComplete) onComplete(content)
|
||||||
currentConversationId = null;
|
return content
|
||||||
try {
|
|
||||||
uni.removeStorageSync(CONVERSATION_KEY);
|
} catch (error) {
|
||||||
} catch (e) {
|
console.error('HTTP流式请求失败:', error)
|
||||||
console.error('清除会话ID失败:', e);
|
throw error
|
||||||
}
|
}
|
||||||
},
|
// #endif
|
||||||
|
|
||||||
/**
|
// 非H5环境使用普通请求模拟流式效果
|
||||||
* 生成新会话(如需)
|
// #ifndef H5
|
||||||
*/
|
const response = await http.sendRequest({
|
||||||
async generateConversationId() {
|
...params,
|
||||||
const params = {
|
async: false
|
||||||
url: '/api/kefu/createConversation',
|
})
|
||||||
data: {
|
|
||||||
uniacid: store.state.uniacid,
|
// 模拟流式效果
|
||||||
user_id: store.state.memberInfo?.id || 'anonymous',
|
if (response.success && response.data) {
|
||||||
member_id: store.state.memberInfo?.id || '',
|
const content = response.data
|
||||||
},
|
const chunkSize = 3
|
||||||
header: {
|
let index = 0
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
const streamInterval = setInterval(() => {
|
||||||
};
|
if (index < content.length) {
|
||||||
const response = await http.sendRequest({
|
const chunk = content.substring(index, index + chunkSize)
|
||||||
...params,
|
index += chunkSize
|
||||||
async: false
|
if (onChunk) onChunk(chunk)
|
||||||
});
|
} else {
|
||||||
return this.handleResponse(response);
|
clearInterval(streamInterval)
|
||||||
},
|
if (onComplete) onComplete(content)
|
||||||
|
}
|
||||||
/**
|
}, 100)
|
||||||
* 获取服务状态
|
}
|
||||||
*/
|
// #endif
|
||||||
async getServiceStatus() {
|
},
|
||||||
try {
|
|
||||||
const response = await http.sendRequest({
|
/**
|
||||||
url: '/api/kefu/health',
|
* 处理API响应
|
||||||
async: false,
|
*/
|
||||||
data: {}
|
handleResponse(response, options) {
|
||||||
});
|
if (response.code === 0 || response.success) {
|
||||||
const available = [response?.data?.status, response?.data?.components?.ai_service_config?.status]
|
return {
|
||||||
.filter(item => item === 'healthy').length > 0;
|
success: true,
|
||||||
return {
|
content: response.data?.answer || response.data?.content || response.data,
|
||||||
available,
|
conversationId: response.data?.conversation_id,
|
||||||
reason: available ? '服务正常' : '服务异常'
|
messageId: response.data?.message_id
|
||||||
};
|
}
|
||||||
} catch (error) {
|
} else {
|
||||||
return {
|
throw new Error(response.message || 'AI服务返回错误')
|
||||||
available: false,
|
}
|
||||||
reason: '服务检查失败'
|
},
|
||||||
};
|
|
||||||
}
|
/**
|
||||||
},
|
* 生成会话ID
|
||||||
|
*/
|
||||||
/**
|
generateConversationId() {
|
||||||
* 清除会话历史(调用后端接口)
|
return 'conv_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
|
||||||
*/
|
},
|
||||||
async clearConversation(conversationId) {
|
|
||||||
try {
|
/**
|
||||||
const response = await http.sendRequest({
|
* 获取AI服务状态
|
||||||
url: '/api/kefu/clear-conversation',
|
*/
|
||||||
data: { conversation_id: conversationId },
|
async getServiceStatus() {
|
||||||
async: false
|
try {
|
||||||
});
|
const aiConfig = store.getters.globalAIAgentConfig
|
||||||
return response.success;
|
|
||||||
} catch (error) {
|
if (!aiConfig?.difyBaseUrl || !aiConfig?.difyApiKey) {
|
||||||
console.error('清除会话失败:', error);
|
return {
|
||||||
return false;
|
available: false,
|
||||||
}
|
reason: '未配置Dify服务'
|
||||||
},
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* 获取会话历史
|
// 简单的健康检查
|
||||||
*/
|
const response = await http.sendRequest({
|
||||||
async getConversationHistory(params = {}) {
|
url: '/api/ai/health',
|
||||||
try {
|
async: false
|
||||||
if (!params.conversation_id) {
|
})
|
||||||
throw new Error('会话ID(conversation_id)是必填参数');
|
|
||||||
}
|
return {
|
||||||
const requestData = {
|
available: response.success,
|
||||||
uniacid: params.uniacid || store.state.uniacid || '1',
|
reason: response.success ? '服务正常' : '服务异常'
|
||||||
conversation_id: params.conversation_id,
|
}
|
||||||
user_id: params.user_id || store.state.memberInfo?.id || 'anonymous',
|
|
||||||
limit: params.limit || 20,
|
} catch (error) {
|
||||||
offset: params.offset || 0,
|
return {
|
||||||
member_id: params.member_id || store.state.memberInfo?.id || '',
|
available: false,
|
||||||
token: params.token || ''
|
reason: '服务检查失败'
|
||||||
};
|
}
|
||||||
const response = await http.sendRequest({
|
}
|
||||||
url: '/api/kefu/getHistory',
|
},
|
||||||
data: requestData,
|
|
||||||
header: {
|
/**
|
||||||
'Content-Type': 'application/json'
|
* 清除会话历史
|
||||||
},
|
*/
|
||||||
async: false
|
async clearConversation(conversationId) {
|
||||||
});
|
try {
|
||||||
if (response.code === 0 || response.success) {
|
const response = await http.sendRequest({
|
||||||
return {
|
url: '/api/ai/clear-conversation',
|
||||||
success: true,
|
data: { conversation_id: conversationId },
|
||||||
data: response.data,
|
async: false
|
||||||
messages: response.data?.messages || [],
|
})
|
||||||
total: response.data?.total || 0,
|
|
||||||
page_info: response.data?.page_info || { limit: 20, offset: 0 }
|
return response.success
|
||||||
};
|
|
||||||
} else {
|
} catch (error) {
|
||||||
throw new Error(response.message || '获取会话历史失败');
|
console.error('清除会话失败:', error)
|
||||||
}
|
return false
|
||||||
} catch (error) {
|
}
|
||||||
console.error('获取会话历史失败:', error);
|
}
|
||||||
throw new Error(error.message || '获取会话历史时发生错误,请稍后重试');
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// ================================
|
|
||||||
// 以下方法仅用于 H5,小程序无效
|
|
||||||
// ================================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [H5 Only] EventSource 流式聊天(备用)
|
|
||||||
*/
|
|
||||||
chatWithEventSource(message, conversationId = '', onMessage, onComplete, onError) {
|
|
||||||
// #ifdef H5
|
|
||||||
if (window.currentEventSource) {
|
|
||||||
window.currentEventSource.close();
|
|
||||||
}
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
uniacid: store.state.uniacid || '1',
|
|
||||||
user_id: store.state.memberInfo?.id || '123456',
|
|
||||||
query: message,
|
|
||||||
conversation_id: conversationId || '',
|
|
||||||
stream: 'true'
|
|
||||||
});
|
|
||||||
const url = `${Config.baseUrl}/api/kefu/chat?${params.toString()}`;
|
|
||||||
try {
|
|
||||||
const eventSource = new EventSource(url);
|
|
||||||
window.currentEventSource = eventSource;
|
|
||||||
let aiMessage = '';
|
|
||||||
eventSource.onmessage = (event) => {
|
|
||||||
try {
|
|
||||||
const data = JSON.parse(event.data);
|
|
||||||
if (data.event === 'message') {
|
|
||||||
aiMessage += data.answer || '';
|
|
||||||
if (onMessage) onMessage(data.answer || '');
|
|
||||||
}
|
|
||||||
if (data.event === 'message_end') {
|
|
||||||
if (onComplete) onComplete({
|
|
||||||
conversation_id: data.conversation_id,
|
|
||||||
message: aiMessage
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('解析消息失败:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
eventSource.onerror = (error) => {
|
|
||||||
console.error('EventSource错误:', error);
|
|
||||||
if (onError) onError({ error: '连接失败' });
|
|
||||||
window.currentEventSource = null;
|
|
||||||
};
|
|
||||||
return eventSource;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('创建EventSource失败:', error);
|
|
||||||
if (onError) onError({ error: error.message });
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
console.warn('chatWithEventSource 不支持微信小程序');
|
|
||||||
return null;
|
|
||||||
// #endif
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [H5 Only] Fetch 流式聊天(备用)
|
|
||||||
*/
|
|
||||||
async chatWithFetchStream(message, conversationId = '', onMessage, onComplete, onError) {
|
|
||||||
// #ifdef H5
|
|
||||||
// 实际逻辑已在 sendHttpStream 中实现,此处可复用或留空
|
|
||||||
return this.sendHttpStream(message, onMessage, (res) => {
|
|
||||||
onComplete?.({ message: res.content, conversation_id: res.conversation_id });
|
|
||||||
});
|
|
||||||
// #endif
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
console.warn('chatWithFetchStream 不支持微信小程序');
|
|
||||||
return null;
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,100 +1,103 @@
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
authInfo: {}
|
authInfo: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
/**
|
||||||
* 获取用户登录凭证code
|
* 获取用户登录凭证code
|
||||||
*/
|
*/
|
||||||
getCode(callback) {
|
getCode(callback) {
|
||||||
// 微信小程序
|
// 微信小程序
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
uni.login({
|
uni.login({
|
||||||
provider: 'weixin',
|
provider: 'weixin',
|
||||||
timeout: 3000,
|
timeout: 3000,
|
||||||
success: res => {
|
success: res => {
|
||||||
if (res.code) {
|
if (res.code) {
|
||||||
this.$api.sendRequest({
|
this.$api.sendRequest({
|
||||||
url: '/weapp/api/weapp/authcodetoopenid',
|
url: '/weapp/api/weapp/authcodetoopenid',
|
||||||
data: {
|
data: {
|
||||||
code: res.code
|
code: res.code
|
||||||
},
|
},
|
||||||
success: res => {
|
success: res => {
|
||||||
if (res.code >= 0) {
|
if (res.code >= 0) {
|
||||||
if (res.data.openid) this.authInfo.weapp_openid = res.data.openid;
|
if (res.data.openid) this.authInfo.weapp_openid = res.data
|
||||||
if (res.data.unionid) this.authInfo.wx_unionid = res.data.unionid;
|
.openid;
|
||||||
typeof callback == 'function' && callback(this.authInfo);
|
if (res.data.unionid) this.authInfo.wx_unionid = res.data
|
||||||
} else {
|
.unionid;
|
||||||
this.$util.showToast({
|
typeof callback == 'function' && callback(this.authInfo);
|
||||||
title: res.message ? res.message : '小程序配置错误'
|
} else {
|
||||||
});
|
this.$util.showToast({
|
||||||
}
|
title: res.message ? res.message : '小程序配置错误'
|
||||||
}
|
});
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
fail: (res) => {
|
}
|
||||||
// #ifdef MP-WEIXIN
|
},
|
||||||
let scene = wx.getLaunchOptionsSync().scene;
|
fail: (res) => {
|
||||||
if ([1154, 1155].indexOf(scene) == -1) {
|
// #ifdef MP-WEIXIN
|
||||||
this.$util.showToast({
|
let scene = wx.getLaunchOptionsSync().scene;
|
||||||
title: res.errMsg
|
if ([1154, 1155].indexOf(scene) == -1) {
|
||||||
});
|
this.$util.showToast({
|
||||||
}
|
title: res.errMsg
|
||||||
// #endif
|
});
|
||||||
}
|
}
|
||||||
})
|
// #endif
|
||||||
// #endif
|
}
|
||||||
|
})
|
||||||
// #ifdef MP-ALIPAY
|
// #endif
|
||||||
uni.login({
|
|
||||||
timeout: 3000,
|
// #ifdef MP-ALIPAY
|
||||||
success: res => {
|
uni.login({
|
||||||
if (res.code) {
|
timeout: 3000,
|
||||||
this.$api.sendRequest({
|
success: res => {
|
||||||
url: '/aliapp/api/aliapp/authcodetouserid',
|
if (res.code) {
|
||||||
data: {
|
this.$api.sendRequest({
|
||||||
code: res.code
|
url: '/aliapp/api/aliapp/authcodetouserid',
|
||||||
},
|
data: {
|
||||||
success: res => {
|
code: res.code
|
||||||
if (res.code >= 0) {
|
},
|
||||||
if (res.data.user_id) this.authInfo.ali_openid = res.data.user_id;
|
success: res => {
|
||||||
typeof callback == 'function' && callback(this.authInfo);
|
if (res.code >= 0) {
|
||||||
} else {
|
if (res.data.user_id) this.authInfo.ali_openid = res.data
|
||||||
this.$util.showToast({
|
.user_id;
|
||||||
title: res.message ? res.message : '小程序配置错误'
|
typeof callback == 'function' && callback(this.authInfo);
|
||||||
});
|
} else {
|
||||||
}
|
this.$util.showToast({
|
||||||
}
|
title: res.message ? res.message : '小程序配置错误'
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
fail: (res) => {
|
})
|
||||||
this.$util.showToast({
|
}
|
||||||
title: res.errMsg
|
},
|
||||||
});
|
fail: (err) => {
|
||||||
}
|
this.$util.showToast({
|
||||||
})
|
title: res.errMsg
|
||||||
// #endif
|
});
|
||||||
|
}
|
||||||
// #ifdef H5
|
})
|
||||||
if (this.$util.isWeiXin()) {
|
// #endif
|
||||||
this.$api.sendRequest({
|
|
||||||
url: '/wechat/api/wechat/authcode',
|
// #ifdef H5
|
||||||
data: {
|
if (this.$util.isWeiXin()) {
|
||||||
redirect_url: location.href,
|
this.$api.sendRequest({
|
||||||
scopes: 'snsapi_userinfo'
|
url: '/wechat/api/wechat/authcode',
|
||||||
},
|
data: {
|
||||||
success: res => {
|
redirect_url: location.href,
|
||||||
if (res.code >= 0) {
|
scopes: 'snsapi_userinfo'
|
||||||
location.href = res.data;
|
},
|
||||||
}
|
success: res => {
|
||||||
}
|
if (res.code >= 0) {
|
||||||
});
|
location.href = res.data;
|
||||||
}
|
}
|
||||||
// #endif
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,511 +0,0 @@
|
|||||||
/**
|
|
||||||
* 客服统一处理服务
|
|
||||||
* 整合各种客服方式,提供统一的调用接口
|
|
||||||
*/
|
|
||||||
export class CustomerService {
|
|
||||||
constructor(vueInstance, externalConfig = null) {
|
|
||||||
this.vm = vueInstance;
|
|
||||||
this.externalConfig = externalConfig; // 外部传入的最新配置(优先级最高)
|
|
||||||
this.latestPlatformConfig = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 强制刷新配置(支持传入外部配置)
|
|
||||||
* @param {Object} externalConfig 外部最新配置
|
|
||||||
*/
|
|
||||||
refreshConfig(externalConfig = null) {
|
|
||||||
this.externalConfig = externalConfig || this.externalConfig;
|
|
||||||
this.latestPlatformConfig = null;
|
|
||||||
return this.getPlatformConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取平台配置
|
|
||||||
* @returns {Object} 平台对应的客服配置
|
|
||||||
*/
|
|
||||||
getPlatformConfig() {
|
|
||||||
if (this.latestPlatformConfig) {
|
|
||||||
return this.latestPlatformConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 优先级:外部传入的最新配置 > vuex配置 > 空对象
|
|
||||||
const servicerConfig = this.externalConfig || this.vm.$store.state.servicerConfig || {};
|
|
||||||
console.log(`【实时客服配置】`, servicerConfig);
|
|
||||||
|
|
||||||
let platformConfig = null;
|
|
||||||
// #ifdef H5
|
|
||||||
platformConfig = servicerConfig.h5 ? (typeof servicerConfig.h5 === 'object' ? servicerConfig.h5 : null) : null;
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
platformConfig = servicerConfig.weapp ? (typeof servicerConfig.weapp === 'object' ? servicerConfig.weapp : null) : null;
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef MP-ALIPAY
|
|
||||||
platformConfig = servicerConfig.aliapp ? (typeof servicerConfig.aliapp === 'object' ? servicerConfig.aliapp : null) : null;
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef PC
|
|
||||||
platformConfig = servicerConfig.pc ? (typeof servicerConfig.pc === 'object' ? servicerConfig.pc : null) : null;
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// 处理空数组情况(你的配置中pc/aliapp是空数组,转为null)
|
|
||||||
if (Array.isArray(platformConfig)) {
|
|
||||||
platformConfig = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.latestPlatformConfig = platformConfig;
|
|
||||||
return platformConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取企业微信配置
|
|
||||||
* @returns {Object} 企业微信配置
|
|
||||||
*/
|
|
||||||
getWxworkConfig() {
|
|
||||||
return this.vm.$store.state.wxworkConfig || {};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查客服配置是否可用
|
|
||||||
* @returns {boolean} 是否有可用配置
|
|
||||||
*/
|
|
||||||
isConfigAvailable() {
|
|
||||||
const config = this.getPlatformConfig();
|
|
||||||
return config && typeof config === 'object' && config.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证客服配置完整性
|
|
||||||
* @returns {Object} 验证结果
|
|
||||||
*/
|
|
||||||
validateConfig() {
|
|
||||||
const config = this.getPlatformConfig();
|
|
||||||
const wxworkConfig = this.getWxworkConfig();
|
|
||||||
|
|
||||||
const result = {
|
|
||||||
isValid: true,
|
|
||||||
errors: [],
|
|
||||||
warnings: []
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!config) {
|
|
||||||
result.isValid = false;
|
|
||||||
result.errors.push('客服配置不存在');
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.type === 'aikefu') {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.type) {
|
|
||||||
result.isValid = false;
|
|
||||||
result.errors.push('客服类型未配置');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.type === 'wxwork') {
|
|
||||||
if (!wxworkConfig) {
|
|
||||||
result.isValid = false;
|
|
||||||
result.errors.push('企业微信配置不存在');
|
|
||||||
} else {
|
|
||||||
if (!wxworkConfig.enable) {
|
|
||||||
result.warnings.push('企业微信功能未启用');
|
|
||||||
}
|
|
||||||
if (!wxworkConfig.contact_url) {
|
|
||||||
result.warnings.push('企业微信活码链接未配置,将使用原有客服方式');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 跳转到Dify客服页面
|
|
||||||
*/
|
|
||||||
openDifyService() {
|
|
||||||
try {
|
|
||||||
if (this.vm.setAiUnreadCount) {
|
|
||||||
this.vm.setAiUnreadCount(0);
|
|
||||||
}
|
|
||||||
// 强制跳转,忽略框架层的封装
|
|
||||||
uni.redirectTo({
|
|
||||||
url: '/pages_tool/ai-chat/index',
|
|
||||||
fail: (err) => {
|
|
||||||
// 兜底:使用window.location跳转(H5)
|
|
||||||
// #ifdef H5
|
|
||||||
window.location.href = '/pages_tool/ai-chat/index';
|
|
||||||
// #endif
|
|
||||||
console.error('跳转Dify客服失败:', err);
|
|
||||||
uni.showToast({
|
|
||||||
title: '跳转客服失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.error('跳转Dify客服异常:', e);
|
|
||||||
uni.showToast({
|
|
||||||
title: '跳转客服失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理客服点击事件
|
|
||||||
* @param {Object} options 选项参数
|
|
||||||
*/
|
|
||||||
handleCustomerClick(options = {}) {
|
|
||||||
const validation = this.validateConfig();
|
|
||||||
if (!validation.isValid) {
|
|
||||||
console.error('客服配置验证失败:', validation.errors);
|
|
||||||
this.showConfigErrorPopup(validation.errors);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validation.warnings.length > 0) {
|
|
||||||
console.warn('客服配置警告:', validation.warnings);
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = this.getPlatformConfig();
|
|
||||||
const { niushop = {}, sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options;
|
|
||||||
|
|
||||||
if (config.type === 'none') {
|
|
||||||
this.showNoServicePopup();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 核心分支:根据最新的type处理
|
|
||||||
switch (config.type) {
|
|
||||||
case 'aikefu':
|
|
||||||
this.openDifyService();
|
|
||||||
break;
|
|
||||||
case 'wxwork':
|
|
||||||
this.openWxworkService(false, config, options);
|
|
||||||
break;
|
|
||||||
case 'third':
|
|
||||||
this.openThirdService(config);
|
|
||||||
break;
|
|
||||||
case 'niushop':
|
|
||||||
this.openNiushopService(niushop);
|
|
||||||
break;
|
|
||||||
case 'weapp':
|
|
||||||
this.openWeappService(config, options);
|
|
||||||
break;
|
|
||||||
case 'aliapp':
|
|
||||||
this.openAliappService(config);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.makePhoneCall();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开企业微信客服
|
|
||||||
* @param {boolean} useOriginalService 是否使用原有客服方式
|
|
||||||
* @param {Object} servicerConfig 客服配置
|
|
||||||
* @param {Object} options 选项参数
|
|
||||||
*/
|
|
||||||
openWxworkService(useOriginalService = false, servicerConfig = null, options = {}) {
|
|
||||||
const config = servicerConfig || this.getPlatformConfig();
|
|
||||||
const wxworkConfig = this.getWxworkConfig();
|
|
||||||
const { sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options;
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
if (wxworkConfig?.enable && wxworkConfig?.contact_url && !useOriginalService) {
|
|
||||||
wx.navigateToMiniProgram({
|
|
||||||
appId: 'wxeb490c6f9b154ef9',
|
|
||||||
path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(wxworkConfig.contact_url)}`,
|
|
||||||
success: () => console.log('跳转企业微信成功'),
|
|
||||||
fail: (err) => {
|
|
||||||
console.error('跳转企业微信失败:', err);
|
|
||||||
this.fallbackToOriginalService();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
wx.openCustomerServiceChat({
|
|
||||||
extInfo: { url: config.wxwork_url },
|
|
||||||
corpId: config.corpid,
|
|
||||||
showMessageCard: true,
|
|
||||||
sendMessageTitle,
|
|
||||||
sendMessagePath,
|
|
||||||
sendMessageImg
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef H5
|
|
||||||
if (wxworkConfig?.enable && wxworkConfig?.contact_url) {
|
|
||||||
window.location.href = wxworkConfig.contact_url;
|
|
||||||
} else if (config.wxwork_url) {
|
|
||||||
location.href = config.wxwork_url;
|
|
||||||
} else {
|
|
||||||
this.fallbackToPhoneCall();
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开第三方客服
|
|
||||||
* @param {Object} config 客服配置
|
|
||||||
*/
|
|
||||||
openThirdService(config) {
|
|
||||||
if (config.third_url) {
|
|
||||||
window.location.href = config.third_url;
|
|
||||||
} else {
|
|
||||||
this.fallbackToPhoneCall();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开牛商客服
|
|
||||||
* @param {Object} niushop 牛商参数
|
|
||||||
*/
|
|
||||||
openNiushopService(niushop) {
|
|
||||||
if (Object.keys(niushop).length > 0) {
|
|
||||||
this.vm.$util.redirectTo('/pages_tool/chat/room', niushop);
|
|
||||||
} else {
|
|
||||||
this.makePhoneCall();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开微信小程序客服
|
|
||||||
* @param {Object} config 客服配置
|
|
||||||
* @param {Object} options 选项参数
|
|
||||||
*/
|
|
||||||
openWeappService(config, options = {}) {
|
|
||||||
if (!this.shouldUseCustomService(config)) {
|
|
||||||
console.log('使用官方微信小程序客服');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('使用自定义微信小程序客服');
|
|
||||||
this.handleCustomWeappService(config, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理自定义微信小程序客服
|
|
||||||
* @param {Object} config 客服配置
|
|
||||||
* @param {Object} options 选项参数
|
|
||||||
*/
|
|
||||||
handleCustomWeappService(config, options = {}) {
|
|
||||||
const { sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options;
|
|
||||||
|
|
||||||
if (config.customServiceUrl) {
|
|
||||||
let url = config.customServiceUrl;
|
|
||||||
const params = [];
|
|
||||||
if (sendMessageTitle) params.push(`title=${encodeURIComponent(sendMessageTitle)}`);
|
|
||||||
if (sendMessagePath) params.push(`path=${encodeURIComponent(sendMessagePath)}`);
|
|
||||||
if (sendMessageImg) params.push(`img=${encodeURIComponent(sendMessageImg)}`);
|
|
||||||
|
|
||||||
if (params.length > 0) {
|
|
||||||
url += (url.includes('?') ? '&' : '?') + params.join('&');
|
|
||||||
}
|
|
||||||
|
|
||||||
uni.navigateTo({
|
|
||||||
url: url,
|
|
||||||
fail: (err) => {
|
|
||||||
console.error('跳转自定义客服页面失败:', err);
|
|
||||||
this.tryThirdPartyService(config, options);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tryThirdPartyService(config, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 尝试使用第三方客服
|
|
||||||
* @param {Object} config 客服配置
|
|
||||||
* @param {Object} options 选项参数
|
|
||||||
*/
|
|
||||||
tryThirdPartyService(config, options = {}) {
|
|
||||||
if (config.thirdPartyServiceUrl) {
|
|
||||||
// #ifdef H5
|
|
||||||
window.open(config.thirdPartyServiceUrl, '_blank');
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
if (config.thirdPartyMiniAppId) {
|
|
||||||
wx.navigateToMiniProgram({
|
|
||||||
appId: config.thirdPartyMiniAppId,
|
|
||||||
path: config.thirdPartyMiniAppPath || '',
|
|
||||||
fail: (err) => {
|
|
||||||
console.error('跳转第三方小程序失败:', err);
|
|
||||||
this.fallbackToPhoneCall();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
uni.setClipboardData({
|
|
||||||
data: config.thirdPartyServiceUrl,
|
|
||||||
success: () => {
|
|
||||||
uni.showModal({
|
|
||||||
title: '客服链接已复制',
|
|
||||||
content: '客服链接已复制到剪贴板,请在浏览器中粘贴访问',
|
|
||||||
showCancel: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fallbackToPhoneCall();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 降级到电话客服
|
|
||||||
*/
|
|
||||||
fallbackToPhoneCall() {
|
|
||||||
uni.showModal({
|
|
||||||
title: '联系客服',
|
|
||||||
content: '在线客服暂时不可用,是否拨打电话联系客服?',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
this.makePhoneCall();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开支付宝小程序客服
|
|
||||||
* @param {Object} config 客服配置
|
|
||||||
*/
|
|
||||||
openAliappService(config) {
|
|
||||||
console.log('支付宝小程序客服', config);
|
|
||||||
switch (config.type) {
|
|
||||||
case 'aikefu':
|
|
||||||
this.openDifyService();
|
|
||||||
break;
|
|
||||||
case 'third':
|
|
||||||
this.openThirdService(config);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log('使用支付宝官方客服');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拨打电话
|
|
||||||
*/
|
|
||||||
makePhoneCall() {
|
|
||||||
this.vm.$api.sendRequest({
|
|
||||||
url: '/api/site/shopcontact',
|
|
||||||
success: res => {
|
|
||||||
if (res.code === 0 && res.data?.mobile) {
|
|
||||||
uni.makePhoneCall({
|
|
||||||
phoneNumber: res.data.mobile
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: '暂无客服电话',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fail: () => {
|
|
||||||
uni.showToast({
|
|
||||||
title: '获取客服电话失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示无客服弹窗
|
|
||||||
*/
|
|
||||||
showNoServicePopup() {
|
|
||||||
const siteInfo = this.vm.$store.state.siteInfo || {};
|
|
||||||
const message = siteInfo?.site_tel
|
|
||||||
? `请联系客服,客服电话是${siteInfo.site_tel}`
|
|
||||||
: '抱歉,商家暂无客服,请线下联系';
|
|
||||||
|
|
||||||
uni.showModal({
|
|
||||||
title: '联系客服',
|
|
||||||
content: message,
|
|
||||||
showCancel: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示配置错误弹窗
|
|
||||||
* @param {Array} errors 错误列表
|
|
||||||
*/
|
|
||||||
showConfigErrorPopup(errors) {
|
|
||||||
const message = errors.join('\n');
|
|
||||||
uni.showModal({
|
|
||||||
title: '配置错误',
|
|
||||||
content: `客服配置有误:\n${message}`,
|
|
||||||
showCancel: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 降级处理:使用原有客服方式
|
|
||||||
*/
|
|
||||||
fallbackToOriginalService() {
|
|
||||||
uni.showModal({
|
|
||||||
title: '提示',
|
|
||||||
content: '无法直接添加企业微信客服,是否使用其他方式联系客服?',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
this.openWxworkService(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取客服按钮配置
|
|
||||||
* @returns {Object} 按钮配置
|
|
||||||
*/
|
|
||||||
getButtonConfig() {
|
|
||||||
const config = this.getPlatformConfig();
|
|
||||||
if (!config) return { openType: '' };
|
|
||||||
|
|
||||||
let openType = '';
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
if (config.type === 'weapp') {
|
|
||||||
openType = config.useOfficial !== false ? 'contact' : '';
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef MP-ALIPAY
|
|
||||||
if (config.type === 'aliapp') openType = 'contact';
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
return { ...config, openType };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否应该使用自定义客服处理
|
|
||||||
* @param {Object} config 客服配置
|
|
||||||
* @returns {boolean} 是否使用自定义客服
|
|
||||||
*/
|
|
||||||
shouldUseCustomService(config) {
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
if (config?.type === 'weapp') {
|
|
||||||
return config.useOfficial === false;
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建客服服务实例
|
|
||||||
* @param {Object} vueInstance Vue实例
|
|
||||||
* @param {Object} externalConfig 外部最新配置
|
|
||||||
* @returns {CustomerService} 客服服务实例
|
|
||||||
*/
|
|
||||||
export function createCustomerService(vueInstance, externalConfig = null) {
|
|
||||||
return new CustomerService(vueInstance, externalConfig);
|
|
||||||
}
|
|
||||||
386
common/js/diy.js
386
common/js/diy.js
@@ -1,14 +1,7 @@
|
|||||||
import { QQMapWX } from 'common/js/map-wx-jssdk.js';
|
import WxMap from 'common/js/map-wx-jssdk.js';
|
||||||
import Config from '@/common/js/config.js';
|
import Config from '@/common/js/config.js';
|
||||||
|
|
||||||
let systemInfo = {};
|
let systemInfo = uni.getSystemInfoSync();
|
||||||
try {
|
|
||||||
// 合并设备信息和窗口信息
|
|
||||||
systemInfo = {...uni.getDeviceInfo(), ...uni.getWindowInfo()};
|
|
||||||
} catch (e) {
|
|
||||||
// 兼容旧版本
|
|
||||||
systemInfo = uni.getSystemInfoSync();
|
|
||||||
}
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -42,7 +35,6 @@ export default {
|
|||||||
latitude: null, // 纬度
|
latitude: null, // 纬度
|
||||||
longitude: null, // 经度
|
longitude: null, // 经度
|
||||||
currentPosition: '', // 当前位置
|
currentPosition: '', // 当前位置
|
||||||
currentStore: null,//当前门店
|
|
||||||
nearestStore: null, // 离自己最近的门店
|
nearestStore: null, // 离自己最近的门店
|
||||||
|
|
||||||
storeTimeOut: null, // 没有获取到定位,则获取默认门店
|
storeTimeOut: null, // 没有获取到定位,则获取默认门店
|
||||||
@@ -51,26 +43,19 @@ export default {
|
|||||||
diyRoute: '', // 页面路由
|
diyRoute: '', // 页面路由
|
||||||
openBottomNav: false,
|
openBottomNav: false,
|
||||||
isShowCopyRight: false,
|
isShowCopyRight: false,
|
||||||
option: null,
|
|
||||||
firstDiy: true,
|
|
||||||
|
|
||||||
//启动广告
|
//启动广告
|
||||||
adv: {},
|
adv:{},
|
||||||
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
onLoad(option) {
|
onLoad(option) {
|
||||||
this.option = option;
|
|
||||||
uni.hideTabBar();
|
uni.hideTabBar();
|
||||||
// 支付宝小程序传参处理
|
|
||||||
// #ifdef MP-ALIPAY
|
|
||||||
let aliapp_option = my.getLaunchOptionsSync();
|
|
||||||
aliapp_option.query && Object.assign(option, aliapp_option.query);
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// 处理分享人数据
|
if (option.source_member) uni.setStorageSync('source_member', option.source_member);
|
||||||
if (option.source_member) uni.setStorageSync('source_member', option.source_member);// 分享链接进入
|
|
||||||
if (option.scene) {// 小程序扫码进入
|
// 小程序扫码进入
|
||||||
|
if (option.scene) {
|
||||||
var sceneParams = decodeURIComponent(option.scene);
|
var sceneParams = decodeURIComponent(option.scene);
|
||||||
sceneParams = sceneParams.split('&');
|
sceneParams = sceneParams.split('&');
|
||||||
if (sceneParams.length) {
|
if (sceneParams.length) {
|
||||||
@@ -80,36 +65,64 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// H5地图选择位置回调
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
// H5地图选择位置回调数据
|
// H5地图选择位置回调数据
|
||||||
if (option.module && option.module == 'locationPicker') {
|
if (option.module && option.module == 'locationPicker') {
|
||||||
option.name = ''; // 自定义页面传参id和name,防止获取地址时变量混淆
|
option.name = ''; // 清空地址
|
||||||
this.locationModule = option.module;
|
this.locationModule = option.module;
|
||||||
this.latitude = option.latng.split(',')[0];
|
this.latitude = option.latng.split(',')[0];
|
||||||
this.longitude = option.latng.split(',')[1];
|
this.longitude = option.latng.split(',')[1];
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
//自定义页面的id和名称
|
|
||||||
this.id = option.id || 0;
|
this.id = option.id || 0;
|
||||||
this.name = option.name || '';
|
this.name = option.name || '';
|
||||||
|
|
||||||
//获取当前门店信息 必须是首页且不是手动切换操作
|
uni.removeStorageSync('manual_store_info'); // 清除手动切换门店缓存
|
||||||
let current_route = this.$util.getCurrentRoute();
|
uni.removeStorageSync('manual_change_store'); // 清楚手动切换门店标识
|
||||||
let manualChangeStore = uni.getStorageSync('manual_change_store'); // 手动切换门店
|
|
||||||
if (current_route.path.indexOf('/pages/index/index') > -1 && !manualChangeStore) {
|
// H5才会执行
|
||||||
this.getCurrentStore(option);
|
if (this.locationModule == 'locationPicker') {
|
||||||
|
|
||||||
|
// H5地图选址后的回调
|
||||||
|
this.getNearestStore();
|
||||||
|
this.getCurrentLocation();
|
||||||
|
|
||||||
|
} else if (this.mapConfig.wap_is_open == 1) {
|
||||||
|
|
||||||
|
// 每次都要定位,获取当前位置
|
||||||
|
/*this.$util.getLocation({
|
||||||
|
fail: (res) => {
|
||||||
|
// 拒绝定位,进入默认总店
|
||||||
|
this.enterDefaultStore();
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
|
||||||
|
// 如果3秒没有获取到定位,则获取默认门店,H5使用
|
||||||
|
// #ifdef H5
|
||||||
|
this.storeTimeOut = setTimeout(() => {
|
||||||
|
this.enterDefaultStore();
|
||||||
|
}, 1000 * 3);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 关闭定位
|
||||||
|
this.enterDefaultStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
async onShow() {
|
onShow() {
|
||||||
if (this.firstDiy) {
|
|
||||||
this.firstDiy = false;
|
this.init();
|
||||||
await this.getDiyMethod();
|
|
||||||
}
|
|
||||||
await this.onShowMethod();
|
|
||||||
},
|
},
|
||||||
onHide() {
|
onHide() {
|
||||||
|
if (this.storeTimeOut) {
|
||||||
|
clearTimeout(this.storeTimeOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转页面要关闭门店弹出框
|
||||||
|
this.closeChooseStorePopup();
|
||||||
|
|
||||||
// 清除限时秒杀定时器
|
// 清除限时秒杀定时器
|
||||||
this.$store.commit('setDiySeckillInterval', 0);
|
this.$store.commit('setDiySeckillInterval', 0);
|
||||||
},
|
},
|
||||||
@@ -136,7 +149,7 @@ export default {
|
|||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
backgroundUrl() {
|
backgroundUrl() {
|
||||||
var str = this.diyData.global?.bgUrl && this.diyData.global?.bgUrl != 'transparent' ? 'url(' + this.$util.img(this.diyData.global?.bgUrl) + ') ' : '';
|
var str = this.diyData.global.bgUrl && this.diyData.global.bgUrl != 'transparent' ? 'url(' + this.$util.img(this.diyData.global.bgUrl) + ') ' : '';
|
||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
textNavColor() {
|
textNavColor() {
|
||||||
@@ -174,34 +187,30 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
/* location: function (nVal) {
|
location: function (nVal) {
|
||||||
if (nVal && !this.latitude && !this.longitude) {
|
if (nVal) {
|
||||||
this.latitude = nVal.latitude;
|
this.latitude = nVal.latitude;
|
||||||
this.longitude = nVal.longitude;
|
this.longitude = nVal.longitude;
|
||||||
this.getStoreInfoByLocation();
|
this.getNearestStore();
|
||||||
|
this.getCurrentLocation();
|
||||||
}
|
}
|
||||||
}, */
|
|
||||||
initStatus: function (val) {
|
|
||||||
if (!this.option.store_id) this.getLocation();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getDiyMethod() {
|
play(){
|
||||||
await this.getDiyInfo();
|
console.log(123)
|
||||||
|
|
||||||
this.$store.commit('setDiySeckillInterval', 1);
|
|
||||||
this.$store.commit('setComponentRefresh');
|
|
||||||
},
|
},
|
||||||
async onShowMethod() {
|
async init() {
|
||||||
|
|
||||||
// 定位信息过期后,重新获取定位
|
// 定位信息过期后,重新获取定位
|
||||||
// if (this.mapConfig.wap_is_open == 1 && this.locationStorage && this.locationStorage.is_expired) {
|
if(this.mapConfig.wap_is_open == 1 && this.locationStorage && this.locationStorage.is_expired) {
|
||||||
// this.$util.getLocation({
|
this.$util.getLocation({
|
||||||
// fail: (res) => {
|
fail: (res) => {
|
||||||
// // 失败了不需要做任何处理,保持之前的门店选择即可
|
// 拒绝定位,进入默认总店
|
||||||
// }
|
this.enterDefaultStore();
|
||||||
// });
|
}
|
||||||
// }
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (this.storeToken) {
|
if (this.storeToken) {
|
||||||
//记录分享关系
|
//记录分享关系
|
||||||
@@ -216,15 +225,17 @@ export default {
|
|||||||
|
|
||||||
this.$store.commit('setDiySeckillInterval', 1);
|
this.$store.commit('setDiySeckillInterval', 1);
|
||||||
|
|
||||||
|
//小程序分享
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.$util.getMpShare().then(res => {
|
||||||
|
this.mpShareData = res;
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
|
||||||
let manualChangeStore = uni.getStorageSync('manual_change_store'); // 手动切换门店
|
let manualChangeStore = uni.getStorageSync('manual_change_store'); // 手动切换门店
|
||||||
if (manualChangeStore) {
|
if (manualChangeStore) {
|
||||||
uni.removeStorageSync('manual_change_store');
|
uni.removeStorageSync('manual_change_store');
|
||||||
let manualStoreInfo = uni.getStorageSync('manual_store_info'); // 手动选择门店
|
|
||||||
uni.removeStorageSync('manual_store_info');
|
|
||||||
if (manualStoreInfo) {
|
|
||||||
this.currentStore = manualStoreInfo;
|
|
||||||
}
|
|
||||||
this.closeGetLocationFailPopup();
|
|
||||||
// 滚动至顶部
|
// 滚动至顶部
|
||||||
uni.pageScrollTo({
|
uni.pageScrollTo({
|
||||||
duration: 200,
|
duration: 200,
|
||||||
@@ -256,14 +267,8 @@ export default {
|
|||||||
query.select('.page-header').boundingClientRect(data => {
|
query.select('.page-header').boundingClientRect(data => {
|
||||||
if (data && data.height) {
|
if (data && data.height) {
|
||||||
// 从状态栏高度开始算
|
// 从状态栏高度开始算
|
||||||
if (!this.diyData.global.topNavBg) {
|
this.paddingTop = data.height + 'px';
|
||||||
this.paddingTop = 0;
|
this.marginTop = -data.height + 'px';
|
||||||
this.marginTop = 0;
|
|
||||||
} else {
|
|
||||||
this.paddingTop = data.height + 'px';
|
|
||||||
this.marginTop = -data.height + 'px';
|
|
||||||
}
|
|
||||||
|
|
||||||
clearInterval(time);
|
clearInterval(time);
|
||||||
}
|
}
|
||||||
}).exec();
|
}).exec();
|
||||||
@@ -271,7 +276,7 @@ export default {
|
|||||||
}, 50);
|
}, 50);
|
||||||
// #endif
|
// #endif
|
||||||
},
|
},
|
||||||
async getDiyAdv() {
|
async getDiyAdv(){
|
||||||
//启动广告
|
//启动广告
|
||||||
let res = await this.$api.sendRequest({
|
let res = await this.$api.sendRequest({
|
||||||
url: '/api/diyview/getstartadv',
|
url: '/api/diyview/getstartadv',
|
||||||
@@ -280,13 +285,13 @@ export default {
|
|||||||
});
|
});
|
||||||
this.adv = res.value
|
this.adv = res.value
|
||||||
// 弹框形式,首次弹出 1,每次弹出 0
|
// 弹框形式,首次弹出 1,每次弹出 0
|
||||||
if (this.adv.advshow == 1) {
|
if(this.adv.advshow == 1){
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (res.value.advtype == 1) {
|
if (res.value.advtype == 1) {
|
||||||
var popwindow_count = uni.getStorageSync(this.id + this.name + '_popwindow_count');
|
var popwindow_count = uni.getStorageSync(this.id + this.name + '_popwindow_count');
|
||||||
if ((this.$refs.uniPopupWindow && popwindow_count == '') || (
|
if ((this.$refs.uniPopupWindow && popwindow_count == '') || (
|
||||||
this.$refs.uniPopupWindow && popwindow_count == 1)) {
|
this.$refs.uniPopupWindow && popwindow_count == 1)) {
|
||||||
|
|
||||||
this.$refs.uniPopupWindow.open();
|
this.$refs.uniPopupWindow.open();
|
||||||
uni.setStorageSync(this.id + this.name + '_popwindow_count', 1);
|
uni.setStorageSync(this.id + this.name + '_popwindow_count', 1);
|
||||||
}
|
}
|
||||||
@@ -296,7 +301,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
async getDiyInfo() {
|
async getDiyInfo() {
|
||||||
let res = await this.$api.sendRequest({
|
let res = await this.$api.sendRequest({
|
||||||
@@ -304,7 +309,7 @@ export default {
|
|||||||
data: {
|
data: {
|
||||||
id: this.id,
|
id: this.id,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
en_type: uni.getStorageSync("lang"),//获取语言底部
|
en_type:uni.getStorageSync("lang"),//获取语言底部
|
||||||
},
|
},
|
||||||
async: false
|
async: false
|
||||||
});
|
});
|
||||||
@@ -332,7 +337,7 @@ export default {
|
|||||||
this.$langConfig.title(this.diyData.global.title);
|
this.$langConfig.title(this.diyData.global.title);
|
||||||
this.mpCollect = this.diyData.global.mpCollect;
|
this.mpCollect = this.diyData.global.mpCollect;
|
||||||
this.setPublicShare();
|
this.setPublicShare();
|
||||||
if (this.diyData.global.popWindow && this.diyData.global.popWindow.imageUrl) {
|
/* if (this.diyData.global.popWindow && this.diyData.global.popWindow.imageUrl) {
|
||||||
// 弹框形式,首次弹出 1,每次弹出 0
|
// 弹框形式,首次弹出 1,每次弹出 0
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.diyData.global.popWindow.count == 1) {
|
if (this.diyData.global.popWindow.count == 1) {
|
||||||
@@ -347,7 +352,7 @@ export default {
|
|||||||
uni.setStorageSync(this.id + this.name + '_popwindow_count', 0);
|
uni.setStorageSync(this.id + this.name + '_popwindow_count', 0);
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// 修改diy数据结构排序
|
// 修改diy数据结构排序
|
||||||
let searchIndex = -1;
|
let searchIndex = -1;
|
||||||
@@ -370,15 +375,14 @@ export default {
|
|||||||
this.diyData.value.splice(topCategoryIndex, 1);
|
this.diyData.value.splice(topCategoryIndex, 1);
|
||||||
this.diyData.value.splice(0, 0, ...topCategoryData);
|
this.diyData.value.splice(0, 0, ...topCategoryData);
|
||||||
this.diyData.value.splice(1, 0, ...searchData);
|
this.diyData.value.splice(1, 0, ...searchData);
|
||||||
} else {
|
} else
|
||||||
this.diyData.value.splice(0, 0, ...searchData);
|
this.diyData.value.splice(0, 0, ...searchData);
|
||||||
}
|
|
||||||
} else if (searchIndex != -1 && topCategoryIndex == -1) {
|
} else if (searchIndex != -1 && topCategoryIndex == -1) {
|
||||||
let searchData = this.diyData.value.slice(searchIndex, searchIndex + 1);
|
let searchData = this.diyData.value.slice(searchIndex, searchIndex + 1);
|
||||||
this.diyData.value.splice(searchIndex, 1);
|
this.diyData.value.splice(searchIndex, 1);
|
||||||
this.diyData.value.splice(0, 0, ...searchData);
|
this.diyData.value.splice(0, 0, ...searchData);
|
||||||
}
|
}
|
||||||
this.topIndexValue = null;
|
|
||||||
for (var i = 0; i < this.diyData.value.length; i++) {
|
for (var i = 0; i < this.diyData.value.length; i++) {
|
||||||
// 分类导航组件
|
// 分类导航组件
|
||||||
if (this.diyData.value[i].componentName == 'TopCategory') {
|
if (this.diyData.value[i].componentName == 'TopCategory') {
|
||||||
@@ -398,6 +402,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// #ifdef MP
|
// #ifdef MP
|
||||||
//小程序收藏
|
//小程序收藏
|
||||||
if (!uni.getStorageSync('isCollect') && this.diyData.global.mpCollect) {
|
if (!uni.getStorageSync('isCollect') && this.diyData.global.mpCollect) {
|
||||||
@@ -411,45 +416,6 @@ export default {
|
|||||||
this.openBottomNav = this.diyData.global.openBottomNav;
|
this.openBottomNav = this.diyData.global.openBottomNav;
|
||||||
}
|
}
|
||||||
this.isShowCopyRight = true;
|
this.isShowCopyRight = true;
|
||||||
|
|
||||||
//小程序分享
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
let path = this.$util.getCurrentRoute().path;
|
|
||||||
if (path == '/pages/member/index') {
|
|
||||||
this.mpShareData = {};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let share_path = path;
|
|
||||||
if (this.$store.state.memberInfo && this.$store.state.memberInfo.member_id) {
|
|
||||||
share_path = this.$util.getCurrentShareRoute(this.$store.state.memberInfo.member_id).path
|
|
||||||
}
|
|
||||||
let appMessageData = {
|
|
||||||
title: this.diyData.global.weappShareTitle,
|
|
||||||
path: share_path,
|
|
||||||
imageUrl: this.$util.img(this.diyData.global.weappShareImage),
|
|
||||||
success: res => { },
|
|
||||||
fail: res => { }
|
|
||||||
}
|
|
||||||
let timeLineData = {
|
|
||||||
title: this.diyData.global.weappShareTitle,
|
|
||||||
query: share_path,
|
|
||||||
imageUrl: this.$util.img(this.diyData.global.weappShareImage),
|
|
||||||
}
|
|
||||||
|
|
||||||
this.mpShareData = {
|
|
||||||
appMessage: appMessageData,
|
|
||||||
timeLine: timeLineData
|
|
||||||
};
|
|
||||||
//console.log(this.mpShareData, 'this.mpShareData');
|
|
||||||
|
|
||||||
var store_info = this.$store.state.globalStoreInfo;
|
|
||||||
if (store_info) {
|
|
||||||
this.mpShareData.appMessage.path += (this.mpShareData.appMessage.path.indexOf('?') > -1 ? '&' : '?') + 'store_id=' + store_info.store_id;
|
|
||||||
this.mpShareData.timeLine.query += (this.mpShareData.timeLine.query.indexOf('?') > -1 ? '&' : '?') + 'store_id=' + store_info.store_id;
|
|
||||||
}
|
|
||||||
//朋友圈不需要页面路径,只要要后面的参数就行
|
|
||||||
this.mpShareData.timeLine.query = this.mpShareData.timeLine.query.split('?')[1] || '';
|
|
||||||
// #endif
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
closePopupWindow() {
|
closePopupWindow() {
|
||||||
@@ -464,131 +430,44 @@ export default {
|
|||||||
this.$util.diyRedirectTo(this.diyData.global.popWindow.link);
|
this.$util.diyRedirectTo(this.diyData.global.popWindow.link);
|
||||||
this.closePopupWindow();
|
this.closePopupWindow();
|
||||||
},
|
},
|
||||||
/******************************************** 获取门店相关 START ***************************************************/
|
|
||||||
/**
|
|
||||||
* 1、分享携带门店id
|
|
||||||
* 门店id正确 进入门店
|
|
||||||
* 门店id错误 通过定位获取门店
|
|
||||||
* 2、通过定位获取门店
|
|
||||||
* 开启获取定位
|
|
||||||
* 同意获取定位 获取最近门店 进入门店
|
|
||||||
* 拒绝获取定位
|
|
||||||
* 平台运营模式 进入默认门店
|
|
||||||
* 连锁门店模式 提示获取定位失败,手动选择门店或引导去开启定位
|
|
||||||
* 关闭获取定位
|
|
||||||
* 平台运营模式 进入默认门店
|
|
||||||
* 连锁门店模式 提示获取定位失败,手动选择门店
|
|
||||||
*/
|
|
||||||
getCurrentStore(option) {
|
|
||||||
if (option.store_id && !isNaN(parseInt(option.store_id))) {
|
|
||||||
this.getStoreInfoByShare(option.store_id);
|
|
||||||
} else {
|
|
||||||
this.getLocation();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getStoreInfoByShare(store_id) {
|
|
||||||
this.$api.sendRequest({
|
|
||||||
url: '/api/store/info',
|
|
||||||
data: { store_id },
|
|
||||||
success: res => {
|
|
||||||
if (res.code >= 0 && res.data) {
|
|
||||||
this.changeCurrentStore(res.data);
|
|
||||||
} else {
|
|
||||||
this.getLocation();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fail: res => {
|
|
||||||
this.getLocation();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getLocation() {
|
|
||||||
if (!this.latitude && !this.longitude && this.initStatus) {
|
|
||||||
if (this.mapConfig.wap_is_open == 1) {
|
|
||||||
this.$util.getLocation({
|
|
||||||
complete: (res) => {
|
|
||||||
if (res.latitude && res.longitude) {
|
|
||||||
this.closeGetLocationFailPopup();
|
|
||||||
this.latitude = res.latitude;
|
|
||||||
this.longitude = res.longitude;
|
|
||||||
this.getStoreInfoByLocation();
|
|
||||||
} else {
|
|
||||||
let is_h5 = false;
|
|
||||||
// #ifdef H5
|
|
||||||
is_h5 = true;
|
|
||||||
// #endif
|
|
||||||
if (is_h5) {
|
|
||||||
//H5同意了也会进入失败,所以直接进入默认门店
|
|
||||||
this.enterDefaultStore();
|
|
||||||
} else {
|
|
||||||
this.getLocationFail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// #ifdef H5
|
|
||||||
//H5有的机型可能根本不会触发getLocation的任何执行,包括success,fail,completele
|
|
||||||
//所以这里如果等待一定时间后还是没有获取到当前门店则进入默认门店
|
|
||||||
setTimeout(() => {
|
|
||||||
let current_route = this.$util.getCurrentRoute();
|
|
||||||
if (this.mapConfig.wap_is_open == 1 && !this.currentStore && current_route.path == '/pages/index/index') {
|
|
||||||
this.enterDefaultStore();
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
// #endif
|
|
||||||
} else {
|
|
||||||
this.getLocationFail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getStoreInfoByLocation() {
|
|
||||||
if (this.latitude && this.longitude) {
|
|
||||||
this.getNearestStore();
|
|
||||||
this.getCurrentLocation();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
changeCurrentStore(store_info) {
|
|
||||||
this.currentStore = store_info;
|
|
||||||
this.changeStore(store_info);
|
|
||||||
this.openChooseStorePopup();
|
|
||||||
},
|
|
||||||
getLocationFail() {
|
|
||||||
if (this.globalStoreConfig.store_business == 'shop') {
|
|
||||||
this.enterDefaultStore();
|
|
||||||
} else {
|
|
||||||
this.openGetLocationFailPopup();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
openGetLocationFailPopup() {
|
|
||||||
if (this.$refs.getLocationFailRef) this.$refs.getLocationFailRef.open();
|
|
||||||
},
|
|
||||||
closeGetLocationFailPopup() {
|
|
||||||
if (this.$refs.getLocationFailRef) this.$refs.getLocationFailRef.close();
|
|
||||||
},
|
|
||||||
openChooseStorePopup() {
|
openChooseStorePopup() {
|
||||||
let globalStoreInfo = this.globalStoreInfo;
|
|
||||||
if (this.globalStoreConfig && this.globalStoreConfig.confirm_popup_control == 1) {
|
if (this.globalStoreConfig && this.globalStoreConfig.confirm_popup_control == 1) {
|
||||||
this.currentStore.show_address = this.currentStore.full_address.replace(/,/g, ' ') + ' ' + this.currentStore.address;
|
let storeInfo = this.globalStoreInfo;
|
||||||
if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.open();
|
|
||||||
|
// 首次进入门店,没有门店信息 || 当前位置的门店和缓存门店不一致要弹框
|
||||||
|
if (!storeInfo || storeInfo && this.nearestStore && storeInfo.store_id != this.nearestStore.store_id) {
|
||||||
|
if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.open();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let manualStoreInfo = uni.getStorageSync('manual_store_info'); // 手动选择门店
|
||||||
|
if (manualStoreInfo) {
|
||||||
|
this.nearestStore = manualStoreInfo;
|
||||||
|
}
|
||||||
|
this.changeStore(this.nearestStore); // 切换门店数据
|
||||||
},
|
},
|
||||||
closeChooseStorePopup() {
|
closeChooseStorePopup() {
|
||||||
if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.close();
|
if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.close();
|
||||||
},
|
},
|
||||||
|
// 确认进入门店
|
||||||
|
enterStore() {
|
||||||
|
this.closeChooseStorePopup();
|
||||||
|
},
|
||||||
// 选择其他门店
|
// 选择其他门店
|
||||||
chooseOtherStore() {
|
chooseOtherStore() {
|
||||||
this.$util.redirectTo('/pages_tool/store/list');
|
this.$util.redirectTo('/pages_tool/store/list');
|
||||||
this.closeChooseStorePopup();
|
this.closeChooseStorePopup();
|
||||||
},
|
},
|
||||||
// 打开地图重新选择位置
|
// 打开地图重新选择位置
|
||||||
reGetLocation() {
|
reposition() {
|
||||||
// #ifdef MP
|
// #ifdef MP
|
||||||
uni.chooseLocation({
|
/*uni.chooseLocation({
|
||||||
success: res => {
|
success: res => {
|
||||||
this.latitude = res.latitude;
|
this.latitude = res.latitude;
|
||||||
this.longitude = res.longitude;
|
this.longitude = res.longitude;
|
||||||
this.currentPosition = res.name;
|
this.currentPosition = res.name;
|
||||||
this.getStoreInfoByLocation();
|
this.getNearestStore();
|
||||||
|
this.getCurrentLocation();
|
||||||
},
|
},
|
||||||
fail(res) {
|
fail(res) {
|
||||||
uni.getSetting({
|
uni.getSetting({
|
||||||
@@ -613,7 +492,8 @@ export default {
|
|||||||
this.latitude = res.latitude;
|
this.latitude = res.latitude;
|
||||||
this.longitude = res.longitude;
|
this.longitude = res.longitude;
|
||||||
this.currentPosition = res.name;
|
this.currentPosition = res.name;
|
||||||
this.getStoreInfoByLocation();
|
this.getNearestStore();
|
||||||
|
this.getCurrentLocation();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 1000);
|
}, 1000);
|
||||||
@@ -631,7 +511,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
@@ -652,7 +532,9 @@ export default {
|
|||||||
data: data,
|
data: data,
|
||||||
success: res => {
|
success: res => {
|
||||||
if (res.code == 0 && res.data) {
|
if (res.code == 0 && res.data) {
|
||||||
this.changeCurrentStore(res.data);
|
this.nearestStore = res.data;
|
||||||
|
this.nearestStore.show_address = this.nearestStore.full_address.replace(/,/g, ' ') + ' ' + this.nearestStore.address;
|
||||||
|
this.openChooseStorePopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -665,6 +547,7 @@ export default {
|
|||||||
data.latitude = this.latitude;
|
data.latitude = this.latitude;
|
||||||
data.longitude = this.longitude;
|
data.longitude = this.longitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$api.sendRequest({
|
this.$api.sendRequest({
|
||||||
url: '/api/store/getLocation',
|
url: '/api/store/getLocation',
|
||||||
data: data,
|
data: data,
|
||||||
@@ -680,42 +563,26 @@ export default {
|
|||||||
// 定位失败,进入默认门店
|
// 定位失败,进入默认门店
|
||||||
enterDefaultStore() {
|
enterDefaultStore() {
|
||||||
if (this.defaultStoreInfo) {
|
if (this.defaultStoreInfo) {
|
||||||
this.changeCurrentStore(this.defaultStoreInfo);
|
if (!this.nearestStore) {
|
||||||
|
this.nearestStore = this.defaultStoreInfo;
|
||||||
|
this.nearestStore.show_address = this.nearestStore.full_address.replace(/,/g, ' ') + ' ' + this.nearestStore.address;
|
||||||
|
}
|
||||||
|
if (this.currentPosition == '') this.currentPosition = '未获取到定位';
|
||||||
|
this.openChooseStorePopup();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//连锁门店未定位选择门店
|
|
||||||
chooseStore() {
|
|
||||||
this.$util.redirectTo('/pages_tool/store/list');
|
|
||||||
},
|
|
||||||
//打开手机设置重新定位
|
|
||||||
openSetting() {
|
|
||||||
uni.openSetting({
|
|
||||||
success: res => {
|
|
||||||
this.getLocation();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
/******************************************** 获取门店相关 END ***************************************************/
|
|
||||||
// 设置公众号分享
|
// 设置公众号分享
|
||||||
setPublicShare() {
|
setPublicShare() {
|
||||||
let shareUrl = this.$config.h5Domain + this.diyRoute;
|
let shareUrl = this.$config.h5Domain + this.diyRoute;
|
||||||
var store_info = this.$store.state.globalStoreInfo;
|
if (this.id) shareUrl += '?id=' + this.id;
|
||||||
//if (store_info) shareUrl += '?store_id=' + store_info.store_id;
|
else if (this.name) shareUrl += '?name=' + this.name;
|
||||||
if (shareUrl.indexOf('?') > 0) {
|
|
||||||
shareUrl += '&';
|
|
||||||
} else {
|
|
||||||
shareUrl += '?';
|
|
||||||
}
|
|
||||||
if (this.id) shareUrl += 'id=' + this.id;
|
|
||||||
else if (this.name) shareUrl += 'name=' + this.name;
|
|
||||||
// alert('diydiydiy')
|
|
||||||
this.$util.setPublicShare({
|
this.$util.setPublicShare({
|
||||||
title: this.diyData.global.wechatShareTitle || this.diyData.global.title,
|
title: this.diyData.global.title,
|
||||||
desc: this.diyData.global.wechatShareDesc,
|
desc: '',
|
||||||
link: shareUrl,
|
link: shareUrl,
|
||||||
imgUrl: this.diyData.global.wechatShareImage ? this.$util.img(this.diyData.global.wechatShareImage) : this.$util.img(this.siteInfo.logo_square)
|
imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : ''
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
onPageScroll(e) {
|
onPageScroll(e) {
|
||||||
this.scrollTop = e.scrollTop;
|
this.scrollTop = e.scrollTop;
|
||||||
@@ -730,7 +597,6 @@ export default {
|
|||||||
// 下拉刷新
|
// 下拉刷新
|
||||||
onPullDownRefresh() {
|
onPullDownRefresh() {
|
||||||
this.$store.commit('setComponentRefresh');
|
this.$store.commit('setComponentRefresh');
|
||||||
this.getDiyMethod();
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
uni.stopPullDownRefresh();
|
uni.stopPullDownRefresh();
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|||||||
@@ -1,190 +1,186 @@
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 页面样式,动态设置主色调
|
// 页面样式,动态设置主色调
|
||||||
themeColor: '' //''--base-color:#fa5d14;--base-help-color:#ff7e00;'
|
themeColor: '' //''--base-color:#fa5d14;--base-help-color:#ff7e00;'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {},
|
onLoad() {},
|
||||||
onShow() {
|
onShow() {
|
||||||
// 刷新多语言
|
// 刷新多语言
|
||||||
this.$langConfig.refresh();
|
this.$langConfig.refresh();
|
||||||
let time = setInterval(() => {
|
let time = setInterval(() => {
|
||||||
let theme = this.themeStyle;
|
let theme = this.themeStyle;
|
||||||
if (theme && theme.main_color) {
|
if (theme && theme.main_color) {
|
||||||
this.themeColorSet();
|
this.themeColorSet();
|
||||||
clearInterval(time);
|
clearInterval(time);
|
||||||
}
|
}
|
||||||
}, 50);
|
}, 50);
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
themeStyle() {
|
themeStyle() {
|
||||||
return this.$store.state.themeStyle;
|
return this.$store.state.themeStyle;
|
||||||
},
|
},
|
||||||
// 插件是否存在
|
// 插件是否存在
|
||||||
addonIsExist() {
|
addonIsExist() {
|
||||||
return this.$store.state.addonIsExist;
|
return this.$store.state.addonIsExist;
|
||||||
},
|
},
|
||||||
tabBarList() {
|
tabBarList() {
|
||||||
return this.$store.state.tabBarList;
|
return this.$store.state.tabBarList;
|
||||||
},
|
},
|
||||||
siteInfo() {
|
siteInfo() {
|
||||||
return this.$store.state.siteInfo;
|
return this.$store.state.siteInfo;
|
||||||
},
|
},
|
||||||
memberInfo() {
|
memberInfo() {
|
||||||
return this.$store.state.memberInfo;
|
return this.$store.state.memberInfo;
|
||||||
},
|
},
|
||||||
storeToken() {
|
storeToken() {
|
||||||
return this.$store.state.token;
|
return this.$store.state.token;
|
||||||
},
|
},
|
||||||
bottomNavHidden() {
|
bottomNavHidden() {
|
||||||
return this.$store.state.bottomNavHidden;
|
return this.$store.state.bottomNavHidden;
|
||||||
},
|
},
|
||||||
globalStoreConfig() {
|
globalStoreConfig() {
|
||||||
return this.$store.state.globalStoreConfig;
|
return this.$store.state.globalStoreConfig;
|
||||||
},
|
},
|
||||||
globalStoreInfo() {
|
globalStoreInfo() {
|
||||||
return this.$store.state.globalStoreInfo;
|
return this.$store.state.globalStoreInfo;
|
||||||
},
|
},
|
||||||
// 定位信息
|
// 定位信息
|
||||||
location() {
|
location() {
|
||||||
return this.$store.state.location;
|
return this.$store.state.location;
|
||||||
},
|
},
|
||||||
// 定位信息(缓存)
|
// 定位信息(缓存)
|
||||||
locationStorage() {
|
locationStorage() {
|
||||||
let data = uni.getStorageSync('location');
|
let data = uni.getStorageSync('location');
|
||||||
if (data) {
|
if (data) {
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
if (this.mapConfig.wap_valid_time > 0) {
|
if (this.mapConfig.wap_valid_time > 0) {
|
||||||
data.is_expired = (date.getTime() / 1000) > data.valid_time; // 是否过期
|
data.is_expired = (date.getTime() / 1000) > data.valid_time; // 是否过期
|
||||||
} else {
|
} else {
|
||||||
data.is_expired = false;
|
data.is_expired = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
// 默认总店(定位失败后使用)
|
// 默认总店(定位失败后使用)
|
||||||
defaultStoreInfo() {
|
defaultStoreInfo() {
|
||||||
return this.$store.state.defaultStoreInfo;
|
return this.$store.state.defaultStoreInfo;
|
||||||
},
|
},
|
||||||
// 组件刷新计数
|
// 组件刷新计数
|
||||||
componentRefresh() {
|
componentRefresh() {
|
||||||
return this.$store.state.componentRefresh;
|
return this.$store.state.componentRefresh;
|
||||||
},
|
},
|
||||||
// 客服配置
|
// 客服配置
|
||||||
servicerConfig() {
|
servicerConfig() {
|
||||||
return this.$store.state.servicerConfig;
|
return this.$store.state.servicerConfig;
|
||||||
},
|
},
|
||||||
// 企业微信配置
|
diySeckillInterval() {
|
||||||
wxworkConfig() {
|
return this.$store.state.diySeckillInterval;
|
||||||
return this.$store.state.wxworkConfig;
|
},
|
||||||
},
|
tabBarHeight() {
|
||||||
diySeckillInterval() {
|
return this.$store.state.tabBarHeight;
|
||||||
return this.$store.state.diySeckillInterval;
|
},
|
||||||
},
|
mapConfig() {
|
||||||
tabBarHeight() {
|
return this.$store.state.mapConfig;
|
||||||
return this.$store.state.tabBarHeight;
|
},
|
||||||
},
|
copyright() {
|
||||||
mapConfig() {
|
let copyright = this.$store.state.copyright;
|
||||||
return this.$store.state.mapConfig;
|
// 判断是否授权
|
||||||
},
|
if (copyright && !copyright.auth) {
|
||||||
copyright() {
|
copyright.logo = '';
|
||||||
let copyright = this.$store.state.copyright;
|
copyright.copyright_link = '';
|
||||||
// 判断是否授权
|
}
|
||||||
if (copyright && !copyright.auth) {
|
return copyright;
|
||||||
copyright.logo = '';
|
},
|
||||||
copyright.copyright_link = '';
|
cartList() {
|
||||||
}
|
return this.$store.state.cartList;
|
||||||
return copyright;
|
},
|
||||||
},
|
cartIds() {
|
||||||
cartList() {
|
return this.$store.state.cartIds;
|
||||||
return this.$store.state.cartList;
|
},
|
||||||
},
|
cartNumber() {
|
||||||
cartIds() {
|
return this.$store.state.cartNumber;
|
||||||
return this.$store.state.cartIds;
|
},
|
||||||
},
|
cartMoney() {
|
||||||
cartNumber() {
|
return this.$store.state.cartMoney;
|
||||||
return this.$store.state.cartNumber;
|
}
|
||||||
},
|
},
|
||||||
cartMoney() {
|
methods: {
|
||||||
return this.$store.state.cartMoney;
|
themeColorSet() {
|
||||||
}
|
let theme = this.themeStyle;
|
||||||
},
|
this.themeColor = `--base-color:${theme.main_color};--base-help-color:${theme.aux_color};`;
|
||||||
methods: {
|
if (this.tabBarHeight != '56px') this.themeColor += `--tab-bar-height:${this.tabBarHeight};`
|
||||||
themeColorSet() {
|
Object.keys(theme).forEach(key => {
|
||||||
let theme = this.themeStyle;
|
let data = theme[key];
|
||||||
this.themeColor = `--base-color:${theme.main_color};--base-help-color:${theme.aux_color};`;
|
if (typeof(data) == "object") {
|
||||||
if (this.tabBarHeight != '56px') this.themeColor += `--tab-bar-height:${this.tabBarHeight};`
|
Object.keys(data).forEach(k => {
|
||||||
Object.keys(theme).forEach(key => {
|
this.themeColor += '--' + k.replace(/_/g, "-") + ':' + data[k] + ';';
|
||||||
let data = theme[key];
|
});
|
||||||
if (typeof(data) == "object") {
|
} else if (typeof(key) == "string" && key) {
|
||||||
Object.keys(data).forEach(k => {
|
this.themeColor += '--' + key.replace(/_/g, "-") + ':' + data + ';';
|
||||||
this.themeColor += '--' + k.replace(/_/g, "-") + ':' + data[k] + ';';
|
}
|
||||||
});
|
});
|
||||||
} else if (typeof(key) == "string" && key) {
|
for (let i = 9; i >= 5; i--) {
|
||||||
this.themeColor += '--' + key.replace(/_/g, "-") + ':' + data + ';';
|
let color = this.$util.colourBlend(theme.main_color, '#ffffff', (i / 10));
|
||||||
}
|
this.themeColor += `--base-color-light-${i}:${color};`;
|
||||||
});
|
}
|
||||||
for (let i = 9; i >= 5; i--) {
|
},
|
||||||
let color = this.$util.colourBlend(theme.main_color, '#ffffff', (i / 10));
|
// 颜色变浅(>0)、变深函数(<0)
|
||||||
this.themeColor += `--base-color-light-${i}:${color};`;
|
lightenDarkenColor(color, amount) {
|
||||||
}
|
|
||||||
},
|
var usePound = false;
|
||||||
// 颜色变浅(>0)、变深函数(<0)
|
|
||||||
lightenDarkenColor(color, amount) {
|
if (color[0] == "#") {
|
||||||
|
color = color.slice(1);
|
||||||
var usePound = false;
|
usePound = true;
|
||||||
|
}
|
||||||
if (color[0] == "#") {
|
|
||||||
color = color.slice(1);
|
var num = parseInt(color, 16);
|
||||||
usePound = true;
|
|
||||||
}
|
var r = (num >> 16) + amount;
|
||||||
|
|
||||||
var num = parseInt(color, 16);
|
if (r > 255) r = 255;
|
||||||
|
else if (r < 0) r = 0;
|
||||||
var r = (num >> 16) + amount;
|
|
||||||
|
var b = ((num >> 8) & 0x00FF) + amount;
|
||||||
if (r > 255) r = 255;
|
|
||||||
else if (r < 0) r = 0;
|
if (b > 255) b = 255;
|
||||||
|
else if (b < 0) b = 0;
|
||||||
var b = ((num >> 8) & 0x00FF) + amount;
|
|
||||||
|
var g = (num & 0x0000FF) + amount;
|
||||||
if (b > 255) b = 255;
|
|
||||||
else if (b < 0) b = 0;
|
if (g > 255) g = 255;
|
||||||
|
else if (g < 0) g = 0;
|
||||||
var g = (num & 0x0000FF) + amount;
|
|
||||||
|
return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16);
|
||||||
if (g > 255) g = 255;
|
|
||||||
else if (g < 0) g = 0;
|
},
|
||||||
|
/**
|
||||||
return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16);
|
* 切换门店
|
||||||
|
* @param {Object} info 门店信息
|
||||||
},
|
* @param {Object} isJump 是否跳转到首页
|
||||||
/**
|
*/
|
||||||
* 切换门店
|
changeStore(info, isJump) {
|
||||||
* @param {Object} info 门店信息
|
if (info) {
|
||||||
* @param {Object} isJump 是否跳转到首页
|
this.$store.commit('setGlobalStoreInfo', info);
|
||||||
*/
|
}
|
||||||
changeStore(info, isJump) {
|
let route = this.$util.getCurrRoute();
|
||||||
if (info) {
|
if (isJump && route != 'pages/index/index') {
|
||||||
this.$store.commit('setGlobalStoreInfo', info);
|
uni.setStorageSync('manual_change_store', true); // 手动切换门店
|
||||||
}
|
this.$store.dispatch('getCartNumber'); //重新获取购物车数据
|
||||||
let route = this.$util.getCurrRoute();
|
this.$util.redirectTo('/pages/index/index');
|
||||||
if (isJump && route != 'pages/index/index') {
|
}
|
||||||
uni.setStorageSync('manual_change_store', true); // 手动切换门店
|
}
|
||||||
this.$store.dispatch('getCartNumber'); //重新获取购物车数据
|
},
|
||||||
this.$util.redirectTo('/pages/index/index');
|
filters: {
|
||||||
}
|
/**
|
||||||
}
|
* 金额格式化输出
|
||||||
},
|
* @param {Object} money
|
||||||
filters: {
|
*/
|
||||||
/**
|
moneyFormat(money) {
|
||||||
* 金额格式化输出
|
if (isNaN(parseFloat(money))) return money;
|
||||||
* @param {Object} money
|
return parseFloat(money).toFixed(2);
|
||||||
*/
|
}
|
||||||
moneyFormat(money) {
|
}
|
||||||
if (isNaN(parseFloat(money))) return money;
|
|
||||||
return parseFloat(money).toFixed(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,382 +1,371 @@
|
|||||||
// 商品详情业务
|
// 商品详情业务
|
||||||
import htmlParser from '@/common/js/html-parser';
|
import htmlParser from '@/common/js/html-parser';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
skuId: 0,
|
skuId: 0,
|
||||||
goodsId: 0,
|
goodsId: 0,
|
||||||
// 商品详情
|
// 商品详情
|
||||||
goodsSkuDetail: {
|
goodsSkuDetail: {
|
||||||
goods_id: 0,
|
goods_id: 0,
|
||||||
goods_service: []
|
goods_service: []
|
||||||
},
|
},
|
||||||
preview: 0, //是否开启预览,0:不开启,1:开启
|
preview: 0, //是否开启预览,0:不开启,1:开启
|
||||||
//评价
|
//评价
|
||||||
contactData: {
|
contactData: {
|
||||||
title: '',
|
title: '',
|
||||||
path: '',
|
path: '',
|
||||||
img: ''
|
img: ''
|
||||||
},
|
},
|
||||||
|
|
||||||
shareQuery: '', // 分享参数
|
shareQuery: '', // 分享参数
|
||||||
shareUrl: '', // 分享链接
|
shareUrl: '', // 分享链接
|
||||||
|
|
||||||
source_member: 0, //分享人的id
|
source_member: 0, //分享人的id
|
||||||
chatRoomParams: {}, // 联系客服参数
|
chatRoomParams: {}, // 联系客服参数
|
||||||
isIphoneX: false, //判断手机是否是iphoneX以上
|
isIphoneX: false, //判断手机是否是iphoneX以上
|
||||||
whetherCollection: 0,
|
whetherCollection: 0,
|
||||||
posterParams: {}, //海报所需参数
|
posterParams: {}, //海报所需参数
|
||||||
shareImg: '',
|
shareImg: '',
|
||||||
navbarData: {
|
navbarData: {
|
||||||
title: '',
|
title: '',
|
||||||
topNavColor: "#ffffff",
|
topNavColor: "#ffffff",
|
||||||
topNavBg: false,
|
topNavBg: false,
|
||||||
navBarSwitch: true, // 导航栏是否显示
|
navBarSwitch: true, // 导航栏是否显示
|
||||||
textNavColor: "#333333",
|
textNavColor: "#333333",
|
||||||
moreLink: {
|
moreLink: {
|
||||||
name: ""
|
name: ""
|
||||||
},
|
},
|
||||||
navStyle: 1,
|
navStyle: 1,
|
||||||
bgUrl: '',
|
bgUrl: '',
|
||||||
textImgPosLink: 'left'
|
textImgPosLink: 'left'
|
||||||
},
|
},
|
||||||
goodsFormVal: []
|
}
|
||||||
}
|
},
|
||||||
},
|
onLoad(data) {
|
||||||
onLoad(data) {
|
//刷新多语言
|
||||||
//刷新多语言
|
this.$langConfig.refresh();
|
||||||
this.$langConfig.refresh();
|
// #ifdef MP-ALIPAY
|
||||||
// #ifdef MP-ALIPAY
|
let options = my.getLaunchOptionsSync();
|
||||||
let options = my.getLaunchOptionsSync();
|
options.query && Object.assign(data, options.query);
|
||||||
options.query && Object.assign(data, options.query);
|
// #endif
|
||||||
// #endif
|
|
||||||
|
this.preview = data.preview || 0;
|
||||||
this.preview = data.preview || 0;
|
this.isIphoneX = this.$util.uniappIsIPhoneX();
|
||||||
this.isIphoneX = this.$util.uniappIsIPhoneX();
|
|
||||||
|
if (data.source_member) {
|
||||||
if (data.source_member) {
|
uni.setStorageSync('source_member', data.source_member);
|
||||||
uni.setStorageSync('source_member', data.source_member);
|
this.source_member = data.source_member;
|
||||||
this.source_member = data.source_member;
|
}
|
||||||
}
|
//记录分享关系
|
||||||
//记录分享关系
|
if (this.storeToken && uni.getStorageSync('source_member')) {
|
||||||
if (this.storeToken && uni.getStorageSync('source_member')) {
|
this.$util.onSourceMember(uni.getStorageSync('source_member'));
|
||||||
this.$util.onSourceMember(uni.getStorageSync('source_member'));
|
}
|
||||||
}
|
|
||||||
|
// 小程序扫码进入
|
||||||
// 小程序扫码进入
|
if (data.scene) {
|
||||||
if (data.scene) {
|
var sceneParams = decodeURIComponent(data.scene);
|
||||||
var sceneParams = decodeURIComponent(data.scene);
|
sceneParams = sceneParams.split('&');
|
||||||
sceneParams = sceneParams.split('&');
|
if (sceneParams.length) {
|
||||||
if (sceneParams.length) {
|
sceneParams.forEach(item => {
|
||||||
sceneParams.forEach(item => {
|
if (item.indexOf('m') != -1) uni.setStorageSync('source_member', item.split('-')[1]);
|
||||||
if (item.indexOf('m') != -1) uni.setStorageSync('source_member', item.split('-')[1]);
|
if (item.indexOf('is_test') != -1) uni.setStorageSync('is_test', 1);
|
||||||
if (item.indexOf('is_test') != -1) uni.setStorageSync('is_test', 1);
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
onShow() {
|
||||||
onShow() {
|
},
|
||||||
},
|
methods: {
|
||||||
methods: {
|
// 处理商品详情数据
|
||||||
detailChangeVal(data) {
|
handleGoodsSkuData() {
|
||||||
this.goodsFormVal = data;
|
// this.navbarData.title = this.goodsSkuDetail.goods_name.length > 9 ? this.goodsSkuDetail.goods_name.substr(0, 9) + "..." : this.goodsSkuDetail.goods_name;
|
||||||
},
|
//设置标题
|
||||||
// 处理商品详情数据
|
// this.$langConfig.title(this.navbarData.title);
|
||||||
handleGoodsSkuData() {
|
if (this.goodsSkuDetail.config) {
|
||||||
this.navbarData.title = this.goodsSkuDetail.goods_name.length > 9 ? this.goodsSkuDetail.goods_name.substr(0, 9) + "..." : this.goodsSkuDetail.goods_name;
|
this.navbarData.navBarSwitch = this.goodsSkuDetail.config.nav_bar_switch;
|
||||||
this.$langConfig.title(this.navbarData.title);
|
}
|
||||||
if (this.goodsSkuDetail.config) {
|
|
||||||
this.navbarData.navBarSwitch = this.goodsSkuDetail.config.nav_bar_switch;
|
this.whetherCollection = this.goodsSkuDetail.is_collect; // 用户关注商品状态
|
||||||
}
|
|
||||||
|
this.modifyGoodsInfo();
|
||||||
this.whetherCollection = this.goodsSkuDetail.is_collect; // 用户关注商品状态
|
|
||||||
|
// 初始化商品详情视图数据
|
||||||
this.modifyGoodsInfo();
|
if (this.$refs.goodsDetailView) this.$refs.goodsDetailView.init({
|
||||||
|
sku_id: this.skuId,
|
||||||
// 初始化商品详情视图数据
|
goods_id: this.goodsSkuDetail.goods_id,
|
||||||
if (this.$refs.goodsDetailView) this.$refs.goodsDetailView.init({
|
preview: this.preview,
|
||||||
sku_id: this.skuId,
|
source_member: this.source_member,
|
||||||
goods_id: this.goodsSkuDetail.goods_id,
|
posterParams: this.posterParams,
|
||||||
preview: this.preview,
|
posterApi: this.posterApi,
|
||||||
source_member: this.source_member,
|
shareUrl: this.shareUrl,
|
||||||
posterParams: this.posterParams,
|
goodsRoute: this.goodsRoute,
|
||||||
posterApi: this.posterApi,
|
isVirtual: this.goodsSkuDetail.is_virtual,
|
||||||
shareUrl: this.shareUrl,
|
deliveryType: this.goodsSkuDetail.express_type,
|
||||||
goodsRoute: this.goodsRoute,
|
whetherCollection: this.goodsSkuDetail.is_collect,
|
||||||
isVirtual: this.goodsSkuDetail.is_virtual,
|
evaluateConfig: this.goodsSkuDetail.evaluate_config,
|
||||||
deliveryType: this.goodsSkuDetail.express_type,
|
evaluateList: this.goodsSkuDetail.evaluate_list,
|
||||||
whetherCollection: this.goodsSkuDetail.is_collect,
|
evaluateCount: this.goodsSkuDetail.evaluate_count
|
||||||
evaluateConfig: this.goodsSkuDetail.evaluate_config,
|
});
|
||||||
evaluateList: this.goodsSkuDetail.evaluate_list,
|
|
||||||
evaluateCount: this.goodsSkuDetail.evaluate_count,
|
//媒体
|
||||||
goods_class : this.goodsSkuDetail.goods_class,
|
if (this.goodsSkuDetail.video_url) this.switchMedia = "video";
|
||||||
sale_store: this.goodsSkuDetail.sale_store
|
|
||||||
});
|
if (!Array.isArray(this.goodsSkuDetail.sku_images)) {
|
||||||
|
if (this.goodsSkuDetail.sku_images) this.goodsSkuDetail.sku_images = this.goodsSkuDetail.sku_images.split(",");
|
||||||
//媒体
|
else this.goodsSkuDetail.sku_images = [];
|
||||||
if (this.goodsSkuDetail.video_url) this.switchMedia = "video";
|
}
|
||||||
|
|
||||||
if (!Array.isArray(this.goodsSkuDetail.sku_images)) {
|
// 多规格时合并主图
|
||||||
if (this.goodsSkuDetail.sku_images) this.goodsSkuDetail.sku_images = this.goodsSkuDetail.sku_images.split(",");
|
if (this.goodsSkuDetail.goods_spec_format && this.goodsSkuDetail.goods_image) {
|
||||||
else this.goodsSkuDetail.sku_images = [];
|
|
||||||
}
|
if (!Array.isArray(this.goodsSkuDetail.goods_image)) this.goodsSkuDetail.goods_image = this.goodsSkuDetail.goods_image.split(",");
|
||||||
|
|
||||||
// 多规格时合并主图
|
this.goodsSkuDetail.sku_images = this.goodsSkuDetail.goods_image.concat(this.goodsSkuDetail.sku_images);
|
||||||
if (this.goodsSkuDetail.goods_spec_format && this.goodsSkuDetail.goods_image) {
|
}
|
||||||
|
|
||||||
if (!Array.isArray(this.goodsSkuDetail.goods_image)) this.goodsSkuDetail.goods_image = this.goodsSkuDetail.goods_image.split(",");
|
let maxHeight = '';
|
||||||
|
let systemInfo = uni.getSystemInfoSync();
|
||||||
this.goodsSkuDetail.sku_images = this.goodsSkuDetail.goods_image.concat(this.goodsSkuDetail.sku_images);
|
this.goodsSkuDetail.goods_image_list.forEach((item, index) => {
|
||||||
}
|
if (typeof item.pic_spec == "string")
|
||||||
|
item.pic_spec = item.pic_spec.split('*');
|
||||||
let maxHeight = '';
|
|
||||||
let systemInfo = uni.getSystemInfoSync();
|
let ratio = item.pic_spec[0] / systemInfo.windowWidth;
|
||||||
this.goodsSkuDetail.goods_image_list.forEach((item, index) => {
|
item.pic_spec[0] = item.pic_spec[0] / ratio;
|
||||||
if (typeof item.pic_spec == "string")
|
item.pic_spec[1] = item.pic_spec[1] / ratio;
|
||||||
item.pic_spec = item.pic_spec.split('*');
|
|
||||||
|
if (!maxHeight || maxHeight > item.pic_spec[1]) {
|
||||||
let ratio = item.pic_spec[0] / systemInfo.windowWidth;
|
maxHeight = item.pic_spec[1];
|
||||||
item.pic_spec[0] = item.pic_spec[0] / ratio;
|
}
|
||||||
item.pic_spec[1] = item.pic_spec[1] / ratio;
|
});
|
||||||
|
this.goodsSkuDetail.swiperHeight = maxHeight + 'px';
|
||||||
if (!maxHeight || maxHeight > item.pic_spec[1]) {
|
|
||||||
maxHeight = item.pic_spec[1];
|
this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件";
|
||||||
}
|
|
||||||
});
|
// 当前商品SKU规格
|
||||||
this.goodsSkuDetail.swiperHeight = maxHeight + 'px';
|
if (this.goodsSkuDetail.sku_spec_format) this.goodsSkuDetail.sku_spec_format = JSON.parse(this.goodsSkuDetail.sku_spec_format);
|
||||||
|
|
||||||
this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件";
|
// 商品属性
|
||||||
|
if (this.goodsSkuDetail.goods_attr_format) {
|
||||||
// 当前商品SKU规格
|
let goods_attr_format = JSON.parse(this.goodsSkuDetail.goods_attr_format);
|
||||||
if (this.goodsSkuDetail.sku_spec_format) this.goodsSkuDetail.sku_spec_format = JSON.parse(this.goodsSkuDetail.sku_spec_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) {
|
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) {
|
||||||
let goods_attr_format = JSON.parse(this.goodsSkuDetail.goods_attr_format);
|
this.goodsSkuDetail.goods_attr_format[i].attr_value_name += "、" + goods_attr_format[j].attr_value_name;
|
||||||
this.goodsSkuDetail.goods_attr_format = this.$util.unique(goods_attr_format, "attr_id");
|
}
|
||||||
for (var i = 0; i < this.goodsSkuDetail.goods_attr_format.length; i++) {
|
}
|
||||||
for (var j = 0; j < goods_attr_format.length; j++) {
|
}
|
||||||
if (this.goodsSkuDetail.goods_attr_format[i].attr_id == goods_attr_format[j].attr_id && this.goodsSkuDetail.goods_attr_format[i].attr_value_id != goods_attr_format[j].attr_value_id) {
|
}
|
||||||
this.goodsSkuDetail.goods_attr_format[i].attr_value_name += "、" + goods_attr_format[j].attr_value_name;
|
|
||||||
}
|
// 商品SKU格式
|
||||||
}
|
if (this.goodsSkuDetail.goods_spec_format) this.goodsSkuDetail.goods_spec_format = JSON.parse(this.goodsSkuDetail.goods_spec_format);
|
||||||
}
|
|
||||||
}
|
// 商品详情
|
||||||
|
if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = (this.goodsSkuDetail.goods_content);
|
||||||
// 商品SKU格式
|
console.log(this.goodsSkuDetail.goods_content)
|
||||||
if (this.goodsSkuDetail.goods_spec_format) this.goodsSkuDetail.goods_spec_format = JSON.parse(this.goodsSkuDetail.goods_spec_format);
|
// if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = htmlParser(this.goodsSkuDetail.goods_content);
|
||||||
|
|
||||||
// 商品详情
|
//商品服务
|
||||||
if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = (this.goodsSkuDetail.goods_content);
|
if (this.goodsSkuDetail.goods_service) {
|
||||||
console.log(this.goodsSkuDetail.goods_content)
|
for (let i in this.goodsSkuDetail.goods_service) {
|
||||||
// if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = htmlParser(this.goodsSkuDetail.goods_content);
|
this.goodsSkuDetail.goods_service[i]['icon'] = this.goodsSkuDetail.goods_service[i]['icon'] ? JSON.parse(this.goodsSkuDetail.goods_service[i]['icon']) : '';
|
||||||
|
}
|
||||||
//商品服务
|
}
|
||||||
if (this.goodsSkuDetail.goods_service) {
|
|
||||||
for (let i in this.goodsSkuDetail.goods_service) {
|
this.contactData = {
|
||||||
this.goodsSkuDetail.goods_service[i]['icon'] = this.goodsSkuDetail.goods_service[i]['icon'] ? JSON.parse(this.goodsSkuDetail.goods_service[i]['icon']) : '';
|
title: this.goodsSkuDetail.sku_name,
|
||||||
}
|
path: this.shareUrl,
|
||||||
}
|
img: this.$util.img(this.goodsSkuDetail.sku_image, {
|
||||||
|
size: 'big'
|
||||||
this.contactData = {
|
})
|
||||||
title: this.goodsSkuDetail.sku_name,
|
};
|
||||||
path: this.shareUrl,
|
if (this.$refs.goodsPromotion) this.$refs.goodsPromotion.refresh(this.goodsSkuDetail.goods_promotion);
|
||||||
img: this.$util.img(this.goodsSkuDetail.sku_image, {
|
|
||||||
size: 'big'
|
if (this.goodsRoute != '/pages/goods/detail') this.setPublicShare();
|
||||||
})
|
|
||||||
};
|
// this.getBarrageData();
|
||||||
if (this.$refs.goodsPromotion) this.$refs.goodsPromotion.refresh(this.goodsSkuDetail.goods_promotion);
|
if (this.addonIsExist.form) {
|
||||||
|
this.getGoodsForm();
|
||||||
this.setPublicShare();
|
}
|
||||||
// if (this.goodsRoute != '/pages/goods/detail') this.setPublicShare();
|
},
|
||||||
|
/**
|
||||||
this.getBarrageData();
|
* 刷新商品详情数据
|
||||||
if (this.addonIsExist.form) {
|
* @param {Object} data
|
||||||
this.getGoodsForm();
|
*/
|
||||||
}
|
refreshGoodsSkuDetail(data) {
|
||||||
},
|
this.goodsSkuDetail = Object.assign({}, this.goodsSkuDetail, data);
|
||||||
/**
|
if (this.$refs.goodsPromotion) this.$refs.goodsPromotion.refresh(this.goodsSkuDetail.goods_promotion);
|
||||||
* 刷新商品详情数据
|
if (this.$refs.goodsDetailView) {
|
||||||
* @param {Object} data
|
|
||||||
*/
|
// 初始化商品详情视图数据
|
||||||
refreshGoodsSkuDetail(data) {
|
this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件";
|
||||||
this.goodsSkuDetail = Object.assign({}, this.goodsSkuDetail, data);
|
|
||||||
if (this.$refs.goodsPromotion) this.$refs.goodsPromotion.refresh(this.goodsSkuDetail.goods_promotion);
|
// 解决轮播图数量不一致时,切换到第一个
|
||||||
if (this.$refs.goodsDetailView) {
|
if (this.swiperCurrent > this.goodsSkuDetail.sku_images.length) {
|
||||||
|
this.swiperAutoplay = true;
|
||||||
// 初始化商品详情视图数据
|
this.swiperCurrent = 1;
|
||||||
this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件";
|
setTimeout(() => {
|
||||||
|
this.swiperAutoplay = false;
|
||||||
// 解决轮播图数量不一致时,切换到第一个
|
}, 40);
|
||||||
if (this.swiperCurrent > this.goodsSkuDetail.sku_images.length) {
|
}
|
||||||
this.swiperAutoplay = true;
|
|
||||||
this.swiperCurrent = 1;
|
}
|
||||||
setTimeout(() => {
|
this.navbarData.title = this.goodsSkuDetail.goods_name.length > 9 ? this.goodsSkuDetail.goods_name.substr(0, 9) + "..." : this.goodsSkuDetail.goods_name;
|
||||||
this.swiperAutoplay = false;
|
this.$langConfig.title(this.navbarData.title);
|
||||||
}, 40);
|
|
||||||
}
|
if (this.goodsSkuDetail.membercard) {
|
||||||
|
this.membercard = this.goodsSkuDetail.membercard;
|
||||||
}
|
}
|
||||||
this.navbarData.title = this.goodsSkuDetail.goods_name.length > 9 ? this.goodsSkuDetail.goods_name.substr(0, 9) + "..." : this.goodsSkuDetail.goods_name;
|
},
|
||||||
this.$langConfig.title(this.navbarData.title);
|
goodsDetailViewInit() {
|
||||||
|
// 初始化商品详情视图数据
|
||||||
if (this.goodsSkuDetail.membercard) {
|
if (this.$refs.goodsDetailView) this.$refs.goodsDetailView.init({
|
||||||
this.membercard = this.goodsSkuDetail.membercard;
|
sku_id: this.skuId,
|
||||||
}
|
goods_id: this.goodsSkuDetail.goods_id,
|
||||||
},
|
preview: this.preview,
|
||||||
goodsDetailViewInit() {
|
source_member: this.source_member,
|
||||||
// 初始化商品详情视图数据
|
posterParams: this.posterParams,
|
||||||
if (this.$refs.goodsDetailView) this.$refs.goodsDetailView.init({
|
posterApi: this.posterApi,
|
||||||
sku_id: this.skuId,
|
shareUrl: this.shareUrl,
|
||||||
goods_id: this.goodsSkuDetail.goods_id,
|
goodsRoute: this.goodsRoute,
|
||||||
preview: this.preview,
|
isVirtual: this.goodsSkuDetail.is_virtual,
|
||||||
source_member: this.source_member,
|
deliveryType: this.goodsSkuDetail.express_type,
|
||||||
posterParams: this.posterParams,
|
whetherCollection: this.goodsSkuDetail.is_collect,
|
||||||
posterApi: this.posterApi,
|
evaluateConfig: this.goodsSkuDetail.evaluate_config,
|
||||||
shareUrl: this.shareUrl,
|
evaluateList: this.goodsSkuDetail.evaluate_list,
|
||||||
goodsRoute: this.goodsRoute,
|
evaluateCount: this.goodsSkuDetail.evaluate_count
|
||||||
isVirtual: this.goodsSkuDetail.is_virtual,
|
});
|
||||||
deliveryType: this.goodsSkuDetail.express_type,
|
},
|
||||||
whetherCollection: this.goodsSkuDetail.is_collect,
|
goHome() {
|
||||||
evaluateConfig: this.goodsSkuDetail.evaluate_config,
|
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
||||||
evaluateList: this.goodsSkuDetail.evaluate_list,
|
this.$util.redirectTo('/pages/index/index');
|
||||||
evaluateCount: this.goodsSkuDetail.evaluate_count
|
},
|
||||||
});
|
goCart() {
|
||||||
},
|
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
||||||
goHome() {
|
this.$util.redirectTo('/pages/goods/cart');
|
||||||
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
},
|
||||||
this.$util.redirectTo('/pages/index/index');
|
//-------------------------------------关注-------------------------------------
|
||||||
},
|
//更新商品信息
|
||||||
goCart() {
|
modifyGoodsInfo() {
|
||||||
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
||||||
this.$util.redirectTo('/pages/goods/cart');
|
//更新商品点击量
|
||||||
},
|
this.$api.sendRequest({
|
||||||
//-------------------------------------关注-------------------------------------
|
url: "/api/goods/modifyclicks",
|
||||||
//更新商品信息
|
data: {
|
||||||
modifyGoodsInfo() {
|
sku_id: this.skuId
|
||||||
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
},
|
||||||
//更新商品点击量
|
success: res => {
|
||||||
this.$api.sendRequest({
|
}
|
||||||
url: "/api/goods/modifyclicks",
|
});
|
||||||
data: {
|
|
||||||
sku_id: this.skuId
|
//添加足迹
|
||||||
},
|
this.$api.sendRequest({
|
||||||
success: res => {
|
url: "/api/goodsbrowse/add",
|
||||||
}
|
data: {
|
||||||
});
|
goods_id: this.goodsSkuDetail.goods_id,
|
||||||
|
sku_id: this.skuId
|
||||||
//添加足迹
|
},
|
||||||
this.$api.sendRequest({
|
success: res => {
|
||||||
url: "/api/goodsbrowse/add",
|
}
|
||||||
data: {
|
});
|
||||||
goods_id: this.goodsSkuDetail.goods_id,
|
},
|
||||||
sku_id: this.skuId
|
//-------------------------------------关注-------------------------------------
|
||||||
},
|
async editCollection() {
|
||||||
success: res => {
|
if (this.$refs.goodsDetailView) {
|
||||||
}
|
this.whetherCollection = await this.$refs.goodsDetailView.collection();
|
||||||
});
|
}
|
||||||
},
|
},
|
||||||
//-------------------------------------关注-------------------------------------
|
openSharePopup() {
|
||||||
async editCollection() {
|
if (this.$refs.goodsDetailView) {
|
||||||
if (this.$refs.goodsDetailView) {
|
this.$refs.goodsDetailView.openSharePopup();
|
||||||
this.whetherCollection = await this.$refs.goodsDetailView.collection();
|
}
|
||||||
}
|
},
|
||||||
},
|
//弹幕
|
||||||
openSharePopup() {
|
getBarrageData() {
|
||||||
if (this.$refs.goodsDetailView) {
|
this.$api.sendRequest({
|
||||||
this.$refs.goodsDetailView.openSharePopup();
|
url: '/api/goods/goodsbarrage',
|
||||||
}
|
data: {
|
||||||
},
|
goods_id: this.goodsSkuDetail.goods_id
|
||||||
//弹幕
|
},
|
||||||
getBarrageData() {
|
success: res => {
|
||||||
this.$api.sendRequest({
|
if (res.code == 0 && res.data) {
|
||||||
url: '/api/goods/goodsbarrage',
|
let barrageData = [];
|
||||||
data: {
|
for (let i in res.data.list) {
|
||||||
goods_id: this.goodsSkuDetail.goods_id
|
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)
|
||||||
success: res => {
|
barrageData.push({
|
||||||
if (res.code == 0 && res.data) {
|
img: res.data.list[i]['img'] ? res.data.list[i]['img'] : this.$util.getDefaultImage().head,
|
||||||
let barrageData = [];
|
title: title + '已下单'
|
||||||
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({
|
this.goodsSkuDetail.barrageData = barrageData;
|
||||||
img: res.data.list[i]['img'] ? res.data.list[i]['img'] : this.$util.getDefaultImage().head,
|
}
|
||||||
title: title + '已下单'
|
}
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
/**
|
||||||
this.goodsSkuDetail.barrageData = barrageData;
|
* 设置公众号分享
|
||||||
}
|
*/
|
||||||
}
|
setPublicShare() {
|
||||||
});
|
let shareUrl = this.$config.h5Domain + this.shareUrl;
|
||||||
},
|
if (this.memberInfo && this.memberInfo.member_id) shareUrl += '&source_member=' + this.memberInfo.member_id;
|
||||||
/**
|
|
||||||
* 设置公众号分享
|
this.$util.setPublicShare({
|
||||||
*/
|
title: this.goodsSkuDetail.goods_name,
|
||||||
setPublicShare() {
|
desc: '',
|
||||||
let shareUrl = this.$config.h5Domain + this.shareUrl;
|
link: shareUrl,
|
||||||
if (this.memberInfo && this.memberInfo.member_id) shareUrl += '&source_member=' + this.memberInfo.member_id;
|
imgUrl: typeof this.goodsSkuDetail.goods_image == 'object' ? this.goodsSkuDetail.goods_image[0] : this.goodsSkuDetail.goods_image.split(',')[0]
|
||||||
var store_info = this.$store.state.globalStoreInfo;
|
})
|
||||||
if (store_info) shareUrl+= '&store_id=' + store_info.store_id;
|
},
|
||||||
this.$util.setPublicShare({
|
/**
|
||||||
title: this.goodsSkuDetail.goods_name,
|
* 获取商品表单
|
||||||
desc: '',
|
*/
|
||||||
link: shareUrl,
|
getGoodsForm() {
|
||||||
imgUrl: typeof this.goodsSkuDetail.goods_image == 'object' ? this.goodsSkuDetail.goods_image[0] : this.goodsSkuDetail.goods_image.split(',')[0]
|
this.$api.sendRequest({
|
||||||
})
|
url: "/form/api/form/goodsform",
|
||||||
},
|
data: {
|
||||||
/**
|
goods_id: this.goodsSkuDetail.goods_id
|
||||||
* 获取商品表单
|
},
|
||||||
*/
|
success: res => {
|
||||||
getGoodsForm() {
|
if (res.code == 0 && res.data) this.$set(this.goodsSkuDetail, 'goods_form', res.data);
|
||||||
this.$api.sendRequest({
|
}
|
||||||
url: "/form/api/form/goodsform",
|
});
|
||||||
data: {
|
}
|
||||||
goods_id: this.goodsSkuDetail.goods_id
|
},
|
||||||
},
|
/**
|
||||||
success: res => {
|
* 自定义分享内容
|
||||||
if (res.code == 0 && res.data) this.$set(this.goodsSkuDetail, 'goods_form', res.data);
|
* @param {Object} res
|
||||||
}
|
*/
|
||||||
});
|
onShareAppMessage(res) {
|
||||||
}
|
var path = this.shareUrl;
|
||||||
},
|
if (this.memberInfo && this.memberInfo.member_id) path += '&source_member=' + this.memberInfo.member_id;
|
||||||
/**
|
return {
|
||||||
* 自定义分享内容
|
title: this.goodsSkuDetail.sku_name,
|
||||||
* @param {Object} res
|
imageUrl: this.shareImg ? this.$util.img(this.shareImg) : this.$util.img(this.goodsSkuDetail.sku_image, {
|
||||||
*/
|
size: 'big'
|
||||||
onShareAppMessage(res) {
|
}),
|
||||||
var path = this.shareUrl;
|
path: path,
|
||||||
var store_info = this.$store.state.globalStoreInfo;
|
success: res => {
|
||||||
if (store_info) path+= '&store_id=' + store_info.store_id;
|
},
|
||||||
if (this.memberInfo && this.memberInfo.member_id) path += '&source_member=' + this.memberInfo.member_id;
|
fail: res => {
|
||||||
return {
|
}
|
||||||
title: this.goodsSkuDetail.sku_name,
|
};
|
||||||
imageUrl: this.shareImg ? this.$util.img(this.shareImg) : this.$util.img(this.goodsSkuDetail.sku_image, {
|
},
|
||||||
size: 'big'
|
// 分享到微信朋友圈
|
||||||
}),
|
// #ifdef MP-WEIXIN
|
||||||
path: path,
|
onShareTimeline() {
|
||||||
success: res => {
|
let query = this.shareQuery;
|
||||||
},
|
if (this.memberInfo && this.memberInfo.member_id) query += '&source_member=' + this.memberInfo.member_id;
|
||||||
fail: res => {
|
return {
|
||||||
}
|
title: this.goodsSkuDetail.sku_name,
|
||||||
};
|
query: query,
|
||||||
},
|
imageUrl: this.$util.img(this.goodsSkuDetail.sku_image, {
|
||||||
// 分享到微信朋友圈
|
size: 'big'
|
||||||
// #ifdef MP-WEIXIN
|
})
|
||||||
onShareTimeline() {
|
};
|
||||||
let query = this.shareQuery;
|
}
|
||||||
var store_info = this.$store.state.globalStoreInfo;
|
// #endif
|
||||||
if (store_info) query+= '&store_id=' + store_info.store_id;
|
|
||||||
if (this.memberInfo && this.memberInfo.member_id) query += '&source_member=' + this.memberInfo.member_id;
|
|
||||||
return {
|
|
||||||
title: this.goodsSkuDetail.sku_name,
|
|
||||||
query: query,
|
|
||||||
imageUrl: this.$util.img(this.goodsSkuDetail.sku_image, {
|
|
||||||
size: 'big'
|
|
||||||
})
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
}
|
}
|
||||||
@@ -1,440 +1,440 @@
|
|||||||
import util from './util.js'
|
import util from './util.js'
|
||||||
/*
|
/*
|
||||||
* HTML5 Parser By Sam Blowes
|
* HTML5 Parser By Sam Blowes
|
||||||
*
|
*
|
||||||
* Designed for HTML5 documents
|
* Designed for HTML5 documents
|
||||||
*
|
*
|
||||||
* Original code by John Resig (ejohn.org)
|
* Original code by John Resig (ejohn.org)
|
||||||
* http://ejohn.org/blog/pure-javascript-html-parser/
|
* http://ejohn.org/blog/pure-javascript-html-parser/
|
||||||
* Original code by Erik Arvidsson, Mozilla Public License
|
* Original code by Erik Arvidsson, Mozilla Public License
|
||||||
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
|
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
|
||||||
*
|
*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* License
|
* License
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* This code is triple licensed using Apache Software License 2.0,
|
* This code is triple licensed using Apache Software License 2.0,
|
||||||
* Mozilla Public License or GNU Public License
|
* Mozilla Public License or GNU Public License
|
||||||
*
|
*
|
||||||
* ////////////////////////////////////////////////////////////////////////////
|
* ////////////////////////////////////////////////////////////////////////////
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
* use this file except in compliance with the License. You may obtain a copy
|
* use this file except in compliance with the License. You may obtain a copy
|
||||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* ////////////////////////////////////////////////////////////////////////////
|
* ////////////////////////////////////////////////////////////////////////////
|
||||||
*
|
*
|
||||||
* The contents of this file are subject to the Mozilla Public License
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
* Version 1.1 (the "License"); you may not use this file except in
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
* compliance with the License. You may obtain a copy of the License at
|
* compliance with the License. You may obtain a copy of the License at
|
||||||
* http://www.mozilla.org/MPL/
|
* http://www.mozilla.org/MPL/
|
||||||
*
|
*
|
||||||
* Software distributed under the License is distributed on an "AS IS"
|
* Software distributed under the License is distributed on an "AS IS"
|
||||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||||
* License for the specific language governing rights and limitations
|
* License for the specific language governing rights and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*
|
*
|
||||||
* The Original Code is Simple HTML Parser.
|
* The Original Code is Simple HTML Parser.
|
||||||
*
|
*
|
||||||
* The Initial Developer of the Original Code is Erik Arvidsson.
|
* The Initial Developer of the Original Code is Erik Arvidsson.
|
||||||
* Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
|
* Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
|
||||||
* Reserved.
|
* Reserved.
|
||||||
*
|
*
|
||||||
* ////////////////////////////////////////////////////////////////////////////
|
* ////////////////////////////////////////////////////////////////////////////
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Usage
|
* Usage
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* // Use like so:
|
* // Use like so:
|
||||||
* HTMLParser(htmlString, {
|
* HTMLParser(htmlString, {
|
||||||
* start: function(tag, attrs, unary) {},
|
* start: function(tag, attrs, unary) {},
|
||||||
* end: function(tag) {},
|
* end: function(tag) {},
|
||||||
* chars: function(text) {},
|
* chars: function(text) {},
|
||||||
* comment: function(text) {}
|
* comment: function(text) {}
|
||||||
* });
|
* });
|
||||||
*
|
*
|
||||||
* // or to get an XML string:
|
* // or to get an XML string:
|
||||||
* HTMLtoXML(htmlString);
|
* HTMLtoXML(htmlString);
|
||||||
*
|
*
|
||||||
* // or to get an XML DOM Document
|
* // or to get an XML DOM Document
|
||||||
* HTMLtoDOM(htmlString);
|
* HTMLtoDOM(htmlString);
|
||||||
*
|
*
|
||||||
* // or to inject into an existing document/DOM node
|
* // or to inject into an existing document/DOM node
|
||||||
* HTMLtoDOM(htmlString, document);
|
* HTMLtoDOM(htmlString, document);
|
||||||
* HTMLtoDOM(htmlString, document.body);
|
* HTMLtoDOM(htmlString, document.body);
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
// Regular Expressions for parsing tags and attributes
|
// Regular Expressions for parsing tags and attributes
|
||||||
var startTag =
|
var startTag =
|
||||||
/^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
|
/^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
|
||||||
var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
|
var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
|
||||||
var attr =
|
var attr =
|
||||||
/([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
|
/([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
|
||||||
|
|
||||||
var empty = makeMap(
|
var empty = makeMap(
|
||||||
'area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'
|
'area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'
|
||||||
); // Block Elements - HTML 5
|
); // Block Elements - HTML 5
|
||||||
// fixed by xxx 将 ins 标签从块级名单中移除
|
// fixed by xxx 将 ins 标签从块级名单中移除
|
||||||
|
|
||||||
var block = makeMap(
|
var block = makeMap(
|
||||||
'a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'
|
'a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'
|
||||||
); // Inline Elements - HTML 5
|
); // Inline Elements - HTML 5
|
||||||
|
|
||||||
var inline = makeMap(
|
var inline = makeMap(
|
||||||
'abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'
|
'abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'
|
||||||
); // Elements that you can, intentionally, leave open
|
); // Elements that you can, intentionally, leave open
|
||||||
// (and which close themselves)
|
// (and which close themselves)
|
||||||
|
|
||||||
var closeSelf = makeMap(
|
var closeSelf = makeMap(
|
||||||
'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
|
'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
|
||||||
|
|
||||||
var fillAttrs = makeMap(
|
var fillAttrs = makeMap(
|
||||||
'checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'
|
'checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'
|
||||||
); // Special Elements (can contain anything)
|
); // Special Elements (can contain anything)
|
||||||
|
|
||||||
var special = makeMap('script,style');
|
var special = makeMap('script,style');
|
||||||
|
|
||||||
function HTMLParser(html, handler) {
|
function HTMLParser(html, handler) {
|
||||||
var index;
|
var index;
|
||||||
var chars;
|
var chars;
|
||||||
var match;
|
var match;
|
||||||
var stack = [];
|
var stack = [];
|
||||||
var last = html;
|
var last = html;
|
||||||
|
|
||||||
stack.last = function() {
|
stack.last = function() {
|
||||||
return this[this.length - 1];
|
return this[this.length - 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
while (html) {
|
while (html) {
|
||||||
chars = true; // Make sure we're not in a script or style element
|
chars = true; // Make sure we're not in a script or style element
|
||||||
if (!stack.last() || !special[stack.last()]) {
|
if (!stack.last() || !special[stack.last()]) {
|
||||||
// Comment
|
// Comment
|
||||||
if (html.indexOf('<!--') == 0) {
|
if (html.indexOf('<!--') == 0) {
|
||||||
index = html.indexOf('-->');
|
index = html.indexOf('-->');
|
||||||
|
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
if (handler.comment) {
|
if (handler.comment) {
|
||||||
handler.comment(html.substring(4, index));
|
handler.comment(html.substring(4, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
html = html.substring(index + 3);
|
html = html.substring(index + 3);
|
||||||
chars = false;
|
chars = false;
|
||||||
} // end tag
|
} // end tag
|
||||||
|
|
||||||
} else if (html.indexOf('</') == 0) {
|
} else if (html.indexOf('</') == 0) {
|
||||||
match = html.match(endTag);
|
match = html.match(endTag);
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
html = html.substring(match[0].length);
|
html = html.substring(match[0].length);
|
||||||
match[0].replace(endTag, parseEndTag);
|
match[0].replace(endTag, parseEndTag);
|
||||||
chars = false;
|
chars = false;
|
||||||
} // start tag
|
} // start tag
|
||||||
|
|
||||||
} else if (html.indexOf('<') == 0) {
|
} else if (html.indexOf('<') == 0) {
|
||||||
match = html.match(startTag);
|
match = html.match(startTag);
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
html = html.substring(match[0].length);
|
html = html.substring(match[0].length);
|
||||||
match[0].replace(startTag, parseStartTag);
|
match[0].replace(startTag, parseStartTag);
|
||||||
chars = false;
|
chars = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chars) {
|
if (chars) {
|
||||||
index = html.indexOf('<');
|
index = html.indexOf('<');
|
||||||
var text = index < 0 ? html : html.substring(0, index);
|
var text = index < 0 ? html : html.substring(0, index);
|
||||||
html = index < 0 ? '' : html.substring(index);
|
html = index < 0 ? '' : html.substring(index);
|
||||||
|
|
||||||
if (handler.chars) {
|
if (handler.chars) {
|
||||||
handler.chars(text);
|
handler.chars(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function(all, text) {
|
html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function(all, text) {
|
||||||
text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
|
text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
|
||||||
|
|
||||||
if (handler.chars) {
|
if (handler.chars) {
|
||||||
handler.chars(text);
|
handler.chars(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
});
|
});
|
||||||
parseEndTag('', stack.last());
|
parseEndTag('', stack.last());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (html == last) {
|
if (html == last) {
|
||||||
throw 'Parse Error: ' + html;
|
throw 'Parse Error: ' + html;
|
||||||
}
|
}
|
||||||
|
|
||||||
last = html;
|
last = html;
|
||||||
} // Clean up any remaining tags
|
} // Clean up any remaining tags
|
||||||
|
|
||||||
|
|
||||||
parseEndTag();
|
parseEndTag();
|
||||||
|
|
||||||
function parseStartTag(tag, tagName, rest, unary) {
|
function parseStartTag(tag, tagName, rest, unary) {
|
||||||
tagName = tagName.toLowerCase();
|
tagName = tagName.toLowerCase();
|
||||||
|
|
||||||
if (block[tagName]) {
|
if (block[tagName]) {
|
||||||
while (stack.last() && inline[stack.last()]) {
|
while (stack.last() && inline[stack.last()]) {
|
||||||
parseEndTag('', stack.last());
|
parseEndTag('', stack.last());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closeSelf[tagName] && stack.last() == tagName) {
|
if (closeSelf[tagName] && stack.last() == tagName) {
|
||||||
parseEndTag('', tagName);
|
parseEndTag('', tagName);
|
||||||
}
|
}
|
||||||
|
|
||||||
unary = empty[tagName] || !!unary;
|
unary = empty[tagName] || !!unary;
|
||||||
|
|
||||||
if (!unary) {
|
if (!unary) {
|
||||||
stack.push(tagName);
|
stack.push(tagName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handler.start) {
|
if (handler.start) {
|
||||||
var attrs = [];
|
var attrs = [];
|
||||||
rest.replace(attr, function(match, name) {
|
rest.replace(attr, function(match, name) {
|
||||||
var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ?
|
var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ?
|
||||||
arguments[4] : fillAttrs[
|
arguments[4] : fillAttrs[
|
||||||
name] ? name : '';
|
name] ? name : '';
|
||||||
attrs.push({
|
attrs.push({
|
||||||
name: name,
|
name: name,
|
||||||
value: value,
|
value: value,
|
||||||
escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
|
escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (handler.start) {
|
if (handler.start) {
|
||||||
handler.start(tagName, attrs, unary);
|
handler.start(tagName, attrs, unary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseEndTag(tag, tagName) {
|
function parseEndTag(tag, tagName) {
|
||||||
// If no tag name is provided, clean shop
|
// If no tag name is provided, clean shop
|
||||||
if (!tagName) {
|
if (!tagName) {
|
||||||
var pos = 0;
|
var pos = 0;
|
||||||
} // Find the closest opened tag of the same type
|
} // Find the closest opened tag of the same type
|
||||||
else {
|
else {
|
||||||
for (var pos = stack.length - 1; pos >= 0; pos--) {
|
for (var pos = stack.length - 1; pos >= 0; pos--) {
|
||||||
if (stack[pos] == tagName) {
|
if (stack[pos] == tagName) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
// Close all the open elements, up the stack
|
// Close all the open elements, up the stack
|
||||||
for (var i = stack.length - 1; i >= pos; i--) {
|
for (var i = stack.length - 1; i >= pos; i--) {
|
||||||
if (handler.end) {
|
if (handler.end) {
|
||||||
handler.end(stack[i]);
|
handler.end(stack[i]);
|
||||||
}
|
}
|
||||||
} // Remove the open elements from the stack
|
} // Remove the open elements from the stack
|
||||||
|
|
||||||
|
|
||||||
stack.length = pos;
|
stack.length = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeMap(str) {
|
function makeMap(str) {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
var items = str.split(',');
|
var items = str.split(',');
|
||||||
|
|
||||||
for (var i = 0; i < items.length; i++) {
|
for (var i = 0; i < items.length; i++) {
|
||||||
obj[items[i]] = true;
|
obj[items[i]] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeDOCTYPE(html) {
|
function removeDOCTYPE(html) {
|
||||||
return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
|
return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 忽略注释
|
* 忽略注释
|
||||||
* @param {Object} html
|
* @param {Object} html
|
||||||
*/
|
*/
|
||||||
function replaceAnnotation(html) {
|
function replaceAnnotation(html) {
|
||||||
var html = html.replace(/<!--[\s\S]*-->/gi, '');
|
var html = html.replace(/<!--[\s\S]*-->/gi, '');
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 替换图片
|
* 替换图片
|
||||||
* @param {Object} html
|
* @param {Object} html
|
||||||
*/
|
*/
|
||||||
function replaceImage(html) {
|
function replaceImage(html) {
|
||||||
|
|
||||||
// #ifdef MP
|
// #ifdef MP
|
||||||
let info = uni.getWindowInfo();
|
let info = uni.getSystemInfoSync();
|
||||||
var screenWidth = info.windowWidth;
|
var screenWidth = info.windowWidth;
|
||||||
screenWidth -= 20;
|
screenWidth -= 20;
|
||||||
screenWidth += 'px';
|
screenWidth += 'px';
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
var screenWidth = '100%';
|
var screenWidth = '100%';
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
let rep = `<img style="width:100% !important;display:block;max-width: ${screenWidth} !important;"`;
|
let rep = `<img style="width:100% !important;display:block;max-width: ${screenWidth} !important;"`;
|
||||||
var html = html.replace(/\\/g, '').replace(/<img/g, rep);
|
var html = html.replace(/\\/g, '').replace(/<img/g, rep);
|
||||||
html = html.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, capture) => {
|
html = html.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, capture) => {
|
||||||
return rep + ' src="' + util.img(capture) + '"/>';
|
return rep + ' src="' + util.img(capture) + '"/>';
|
||||||
});
|
});
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
function replaceVideo(html){
|
function replaceVideo(html){
|
||||||
// #ifdef MP
|
// #ifdef MP
|
||||||
let info = uni.getWindowInfo();
|
let info = uni.getSystemInfoSync();
|
||||||
var screenWidth = info.windowWidth;
|
var screenWidth = info.windowWidth;
|
||||||
screenWidth -= 20;
|
screenWidth -= 20;
|
||||||
screenWidth += 'px';
|
screenWidth += 'px';
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
var screenWidth = '100%';
|
var screenWidth = '100%';
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
let rep = `<video style="width:100% !important;display:block;max-width: ${screenWidth} !important;"`;
|
let rep = `<video style="width:100% !important;display:block;max-width: ${screenWidth} !important;"`;
|
||||||
var html = html.replace(/\\/g, '').replace(/<video/g, rep);
|
var html = html.replace(/\\/g, '').replace(/<video/g, rep);
|
||||||
console.log(html)
|
console.log(html)
|
||||||
html = html.replace(/<video [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, capture) => {
|
html = html.replace(/<video [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, capture) => {
|
||||||
return rep + ' src="' + util.img(capture) + '"/>';
|
return rep + ' src="' + util.img(capture) + '"/>';
|
||||||
});
|
});
|
||||||
// console.log(html)
|
// console.log(html)
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将style属性中的双引号改为单引号
|
* 将style属性中的双引号改为单引号
|
||||||
* @param {Object} html
|
* @param {Object} html
|
||||||
*/
|
*/
|
||||||
function replaceStyleQuotes(html) {
|
function replaceStyleQuotes(html) {
|
||||||
var html = html.replace(/style\s*=\s*["][^>]*;[^"]?/gi, (match, capture) => {
|
var html = html.replace(/style\s*=\s*["][^>]*;[^"]?/gi, (match, capture) => {
|
||||||
match = match.replace(/[:](\s?)[\s\S]*/gi, (a, b) => {
|
match = match.replace(/[:](\s?)[\s\S]*/gi, (a, b) => {
|
||||||
return a.replace(/"/g, "'");
|
return a.replace(/"/g, "'");
|
||||||
});
|
});
|
||||||
return match;
|
return match;
|
||||||
});
|
});
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseAttrs(attrs) {
|
function parseAttrs(attrs) {
|
||||||
return attrs.reduce(function(pre, attr) {
|
return attrs.reduce(function(pre, attr) {
|
||||||
var value = attr.value;
|
var value = attr.value;
|
||||||
var name = attr.name;
|
var name = attr.name;
|
||||||
|
|
||||||
if (pre[name]) {
|
if (pre[name]) {
|
||||||
pre[name] = pre[name] + " " + value;
|
pre[name] = pre[name] + " " + value;
|
||||||
} else {
|
} else {
|
||||||
pre[name] = value;
|
pre[name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pre;
|
return pre;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseHtml(html) {
|
function parseHtml(html) {
|
||||||
html = removeDOCTYPE(html);
|
html = removeDOCTYPE(html);
|
||||||
html = replaceAnnotation(html); //忽略注释
|
html = replaceAnnotation(html); //忽略注释
|
||||||
html = replaceImage(html); //替换图片
|
html = replaceImage(html); //替换图片
|
||||||
html = replaceStyleQuotes(html); //将style属性中的双引号改为单引号
|
html = replaceStyleQuotes(html); //将style属性中的双引号改为单引号
|
||||||
|
|
||||||
html = replaceVideo(html); //替换视频链接
|
html = replaceVideo(html); //替换视频链接
|
||||||
var stacks = [];
|
var stacks = [];
|
||||||
var results = {
|
var results = {
|
||||||
node: 'root',
|
node: 'root',
|
||||||
children: []
|
children: []
|
||||||
};
|
};
|
||||||
HTMLParser(html, {
|
HTMLParser(html, {
|
||||||
start: function start(tag, attrs, unary) {
|
start: function start(tag, attrs, unary) {
|
||||||
var node = {
|
var node = {
|
||||||
name: tag
|
name: tag
|
||||||
};
|
};
|
||||||
|
|
||||||
if (attrs.length !== 0) {
|
if (attrs.length !== 0) {
|
||||||
node.attrs = parseAttrs(attrs);
|
node.attrs = parseAttrs(attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unary) {
|
if (unary) {
|
||||||
var parent = stacks[0] || results;
|
var parent = stacks[0] || results;
|
||||||
|
|
||||||
if (!parent.children) {
|
if (!parent.children) {
|
||||||
parent.children = [];
|
parent.children = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.children.push(node);
|
parent.children.push(node);
|
||||||
} else {
|
} else {
|
||||||
stacks.unshift(node);
|
stacks.unshift(node);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
end: function end(tag) {
|
end: function end(tag) {
|
||||||
var node = stacks.shift();
|
var node = stacks.shift();
|
||||||
if (node.name !== tag) console.error('invalid state: mismatch end tag');
|
if (node.name !== tag) console.error('invalid state: mismatch end tag');
|
||||||
if (stacks.length === 0) {
|
if (stacks.length === 0) {
|
||||||
results.children.push(node);
|
results.children.push(node);
|
||||||
} else {
|
} else {
|
||||||
var parent = stacks[0];
|
var parent = stacks[0];
|
||||||
|
|
||||||
if (!parent.children) {
|
if (!parent.children) {
|
||||||
parent.children = [];
|
parent.children = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.children.push(node);
|
parent.children.push(node);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
chars: function chars(text) {
|
chars: function chars(text) {
|
||||||
var node = {
|
var node = {
|
||||||
type: 'text',
|
type: 'text',
|
||||||
text: text
|
text: text
|
||||||
};
|
};
|
||||||
|
|
||||||
if (stacks.length === 0) {
|
if (stacks.length === 0) {
|
||||||
results.children.push(node);
|
results.children.push(node);
|
||||||
} else {
|
} else {
|
||||||
var parent = stacks[0];
|
var parent = stacks[0];
|
||||||
|
|
||||||
if (!parent.children) {
|
if (!parent.children) {
|
||||||
parent.children = [];
|
parent.children = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.children.push(node);
|
parent.children.push(node);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
comment: function comment(text) {
|
comment: function comment(text) {
|
||||||
var node = {
|
var node = {
|
||||||
node: 'comment',
|
node: 'comment',
|
||||||
text: text
|
text: text
|
||||||
};
|
};
|
||||||
var parent = stacks[0];
|
var parent = stacks[0];
|
||||||
|
|
||||||
if (!parent.children) {
|
if (!parent.children) {
|
||||||
parent.children = [];
|
parent.children = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.children.push(node);
|
parent.children.push(node);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return results.children;
|
return results.children;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default parseHtml;
|
export default parseHtml;
|
||||||
@@ -1,289 +1,255 @@
|
|||||||
import Config from './config.js'
|
import Config from './config.js'
|
||||||
import Util from './util.js'
|
import Util from './util.js'
|
||||||
import store from '@/store/index.js'
|
import store from '@/store/index.js'
|
||||||
import { Utils } from 'common/js/map-wx-jssdk.js';
|
|
||||||
|
// #ifdef H5
|
||||||
// #ifdef H5
|
const app_type = Util.isWeiXin() ? 'wechat' : 'h5';
|
||||||
const app_type = Util.isWeiXin() ? 'wechat' : 'h5';
|
const app_type_name = Util.isWeiXin() ? '微信公众号' : 'H5';
|
||||||
const app_type_name = Util.isWeiXin() ? '微信公众号' : 'H5';
|
// #endif
|
||||||
// #endif
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
// #ifdef MP-WEIXIN
|
const app_type = 'weapp';
|
||||||
const app_type = 'weapp';
|
const app_type_name = '微信小程序';
|
||||||
const app_type_name = '微信小程序';
|
// #endif
|
||||||
// #endif
|
|
||||||
|
// #ifdef MP-ALIPAY
|
||||||
// #ifdef MP-ALIPAY
|
const app_type = 'aliapp';
|
||||||
const app_type = 'aliapp';
|
const app_type_name = '支付宝小程序';
|
||||||
const app_type_name = '支付宝小程序';
|
// #endif
|
||||||
// #endif
|
|
||||||
|
// #ifdef MP-BAIDU
|
||||||
// #ifdef MP-BAIDU
|
const app_type = 'baiduapp';
|
||||||
const app_type = 'baiduapp';
|
const app_type_name = '百度小程序';
|
||||||
const app_type_name = '百度小程序';
|
// #endif
|
||||||
// #endif
|
|
||||||
|
// #ifdef MP-TOUTIAO
|
||||||
// #ifdef MP-TOUTIAO
|
const app_type = 'MP-TOUTIAO';
|
||||||
const app_type = 'MP-TOUTIAO';
|
const app_type_name = '头条小程序';
|
||||||
const app_type_name = '头条小程序';
|
// #endif
|
||||||
// #endif
|
|
||||||
|
// #ifdef MP-QQ
|
||||||
// #ifdef MP-QQ
|
const app_type = 'MP-QQ';
|
||||||
const app_type = 'MP-QQ';
|
const app_type_name = 'QQ小程序';
|
||||||
const app_type_name = 'QQ小程序';
|
// #endif
|
||||||
// #endif
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
// #ifdef APP-PLUS
|
const app_type = 'app';
|
||||||
const app_type = 'app';
|
const app_type_name = 'APP';
|
||||||
const app_type_name = 'APP';
|
// #endif
|
||||||
// #endif
|
|
||||||
|
export default {
|
||||||
export default {
|
sendRequest(params) {
|
||||||
sendRequest(params) {
|
if (!Config.baseUrl) {
|
||||||
if (!Config.baseUrl) {
|
uni.showToast({
|
||||||
uni.showToast({
|
title: '未配置请求域名',
|
||||||
title: '未配置请求域名',
|
'icon': 'none',
|
||||||
'icon': 'none',
|
duration: 10000
|
||||||
duration: 10000
|
});
|
||||||
});
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
var method = params.data != undefined ? 'POST' : 'GET', // 请求方式
|
||||||
var method = params.data != undefined ? 'POST' : 'GET', // 请求方式
|
url = Config.baseUrl + params.url, // 请求路径
|
||||||
url = Config.baseUrl + params.url, // 请求路径
|
data = {
|
||||||
data = {
|
app_type,
|
||||||
app_type,
|
app_type_name
|
||||||
app_type_name
|
};
|
||||||
};
|
|
||||||
|
// token
|
||||||
// token
|
data.token = store.state.token || '';
|
||||||
data.token = store.state.token || '';
|
data.uniacid = Config.uniacid
|
||||||
data.uniacid = Config.uniacid
|
// 门店id
|
||||||
// 门店id
|
var default_store_info = store.state.defaultStoreInfo;
|
||||||
var default_store_info = store.state.defaultStoreInfo;
|
if (default_store_info) {
|
||||||
if (default_store_info) {
|
data.store_id = default_store_info.store_id;
|
||||||
data.store_id = default_store_info.store_id;
|
}
|
||||||
}
|
|
||||||
|
var store_info = store.state.globalStoreInfo;
|
||||||
var store_info = store.state.globalStoreInfo;
|
|
||||||
|
if (store_info) data.store_id = store_info.store_id;
|
||||||
if (store_info) data.store_id = store_info.store_id;
|
|
||||||
|
// 参数
|
||||||
// 参数
|
if (params.data != undefined) Object.assign(data, params.data);
|
||||||
if (params.data != undefined) Object.assign(data, params.data);
|
|
||||||
|
if (params.async === false) {
|
||||||
if (params.async === false) {
|
//同步
|
||||||
//同步
|
return new Promise((resolve, reject) => {
|
||||||
return new Promise((resolve, reject) => {
|
uni.request({
|
||||||
uni.request({
|
url: url,
|
||||||
url: url,
|
method: method,
|
||||||
method: method,
|
data: data,
|
||||||
data: data,
|
header: params.header || {
|
||||||
header: params.header || {
|
// 'Accept': 'application/json',
|
||||||
// 'Accept': 'application/json',
|
'content-type': 'application/x-www-form-urlencoded;application/json'
|
||||||
'content-type': 'application/x-www-form-urlencoded;application/json'
|
},
|
||||||
},
|
dataType: params.dataType || 'json',
|
||||||
dataType: params.dataType || 'json',
|
responseType: params.responseType || 'text',
|
||||||
responseType: params.responseType || 'text',
|
success: (res) => {
|
||||||
success: (res) => {
|
// try {
|
||||||
// try {
|
// res.data = JSON.parse(res.data);
|
||||||
// res.data = JSON.parse(res.data);
|
// } catch (e) {
|
||||||
// } catch (e) {
|
// //TODO handle the exception
|
||||||
// //TODO handle the exception
|
// console.log('api error:', e);
|
||||||
// console.log('api error:', e);
|
// }
|
||||||
// }
|
if (res.data.code == -3 && store.state.siteState > 0) {
|
||||||
if (res.data.code == -3 && store.state.siteState > 0) {
|
store.commit('setSiteState', -3);
|
||||||
store.commit('setSiteState', -3);
|
Util.redirectTo('/pages_tool/storeclose/storeclose', {}, 'reLaunch');
|
||||||
Util.redirectTo('/pages_tool/storeclose/storeclose', {}, 'reLaunch');
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if (res.data.refreshtoken) {
|
||||||
if (res.data.refreshtoken) {
|
store.commit('setToken', res.data.refreshtoken);
|
||||||
store.commit('setToken', res.data.refreshtoken);
|
}
|
||||||
}
|
if (res.data.code == -10009 || res.data.code == -10010) {
|
||||||
if (res.data.code == -10009 || res.data.code == -10010) {
|
store.commit('setToken', '');
|
||||||
store.commit('setToken', '');
|
store.commit('setMemberInfo', '');
|
||||||
store.commit('setMemberInfo', '');
|
}
|
||||||
}
|
resolve(res.data);
|
||||||
resolve(res.data);
|
},
|
||||||
},
|
fail: (res) => {
|
||||||
fail: (res) => {
|
if (res.errMsg && res.errMsg == 'request:fail url not in domain list') {
|
||||||
if (res.errMsg && res.errMsg == 'request:fail url not in domain list') {
|
uni.showToast({
|
||||||
uni.showToast({
|
title: Config.baseUrl + '不在request 合法域名列表中',
|
||||||
title: Config.baseUrl + '不在request 合法域名列表中',
|
'icon': 'none',
|
||||||
'icon': 'none',
|
duration: 10000
|
||||||
duration: 10000
|
});
|
||||||
});
|
return;
|
||||||
return;
|
}
|
||||||
}
|
reject(res);
|
||||||
reject(res);
|
},
|
||||||
},
|
complete: (res) => {
|
||||||
complete: (res) => {
|
if ((res.errMsg && res.errMsg != "request:ok") || (res.statusCode && [200, 500].indexOf(res.statusCode) == -1)) {
|
||||||
if ((res.errMsg && res.errMsg != "request:ok") || (res.statusCode && [200, 500].indexOf(res.statusCode) == -1)) {
|
uni.showToast({
|
||||||
uni.showToast({
|
title: Config.baseUrl + '请求失败',
|
||||||
title: Config.baseUrl + '请求失败',
|
'icon': 'none',
|
||||||
'icon': 'none',
|
duration: 10000
|
||||||
duration: 10000
|
});
|
||||||
});
|
return;
|
||||||
return;
|
}
|
||||||
}
|
reject(res.data);
|
||||||
reject(res.data);
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
});
|
} else {
|
||||||
} else {
|
//异步
|
||||||
//异步
|
uni.request({
|
||||||
uni.request({
|
url: url,
|
||||||
url: url,
|
method: method,
|
||||||
method: method,
|
data: data,
|
||||||
data: data,
|
header: params.header || {
|
||||||
header: params.header || {
|
// 'Accept': 'application/json',
|
||||||
// 'Accept': 'application/json',
|
'content-type': 'application/x-www-form-urlencoded;application/json'
|
||||||
'content-type': 'application/x-www-form-urlencoded;application/json'
|
},
|
||||||
},
|
dataType: params.dataType || 'json',
|
||||||
dataType: params.dataType || 'json',
|
responseType: params.responseType || 'text',
|
||||||
responseType: params.responseType || 'text',
|
success: (res) => {
|
||||||
success: (res) => {
|
// try {
|
||||||
// try {
|
// res.data = JSON.parse(res.data);
|
||||||
// res.data = JSON.parse(res.data);
|
// } catch (e) {
|
||||||
// } catch (e) {
|
// //TODO handle the exception
|
||||||
// //TODO handle the exception
|
// console.log('api error:', e);
|
||||||
// console.log('api error:', e);
|
// }
|
||||||
// }
|
if (res.data.code == -3 && store.state.siteState > 0) {
|
||||||
if (res.data.code == -3 && store.state.siteState > 0) {
|
store.commit('setSiteState', -3);
|
||||||
store.commit('setSiteState', -3);
|
Util.redirectTo('/pages_tool/storeclose/storeclose', {}, 'reLaunch');
|
||||||
Util.redirectTo('/pages_tool/storeclose/storeclose', {}, 'reLaunch');
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if (res.data.refreshtoken) {
|
||||||
if (res.data.refreshtoken) {
|
store.commit('setToken', res.data.refreshtoken);
|
||||||
store.commit('setToken', res.data.refreshtoken);
|
}
|
||||||
}
|
if (res.data.code == -10009 || res.data.code == -10010) {
|
||||||
if (res.data.code == -10009 || res.data.code == -10010) {
|
store.commit('setToken', '');
|
||||||
store.commit('setToken', '');
|
store.commit('setMemberInfo', '');
|
||||||
store.commit('setMemberInfo', '');
|
}
|
||||||
}
|
typeof params.success == 'function' && params.success(res.data);
|
||||||
typeof params.success == 'function' && params.success(res.data);
|
},
|
||||||
},
|
fail: (res) => {
|
||||||
fail: (res) => {
|
if (res.errMsg && res.errMsg == 'request:fail url not in domain list') {
|
||||||
if (res.errMsg && res.errMsg == 'request:fail url not in domain list') {
|
uni.showToast({
|
||||||
uni.showToast({
|
title: Config.baseUrl + '不在request 合法域名列表中',
|
||||||
title: Config.baseUrl + '不在request 合法域名列表中',
|
'icon': 'none',
|
||||||
'icon': 'none',
|
duration: 10000
|
||||||
duration: 10000
|
});
|
||||||
});
|
return;
|
||||||
return;
|
}
|
||||||
}
|
typeof params.fail == 'function' && params.fail(res);
|
||||||
typeof params.fail == 'function' && params.fail(res);
|
},
|
||||||
},
|
complete: (res) => {
|
||||||
complete: (res) => {
|
if ((res.errMsg && res.errMsg != "request:ok") || (res.statusCode && [200, 500].indexOf(res.statusCode) == -1)) {
|
||||||
if ((res.errMsg && res.errMsg != "request:ok") || (res.statusCode && [200, 500].indexOf(res.statusCode) == -1)) {
|
uni.showToast({
|
||||||
uni.showToast({
|
title: Config.baseUrl + '请求失败',
|
||||||
title: Config.baseUrl + '请求失败',
|
'icon': 'none',
|
||||||
'icon': 'none',
|
duration: 10000
|
||||||
duration: 10000
|
});
|
||||||
});
|
return;
|
||||||
return;
|
}
|
||||||
}
|
typeof params.complete == 'function' && params.complete(res.data);
|
||||||
typeof params.complete == 'function' && params.complete(res.data);
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
},
|
||||||
},
|
uploadBase64(params) {
|
||||||
needMd5Fn(params,callback) {
|
uni.request({
|
||||||
uni.request({
|
url: Config.baseUrl + '/api/upload/headimgBase64',
|
||||||
url: Config.baseUrl + '/api/config/getApiConfig',
|
method: 'POST',
|
||||||
method: 'POST',
|
header: {
|
||||||
header: {
|
'content-type': 'application/x-www-form-urlencoded;application/json'
|
||||||
'content-type': 'application/x-www-form-urlencoded;application/json'
|
},
|
||||||
},
|
data: {
|
||||||
data: {
|
app_type,
|
||||||
app_type,
|
app_type_name,
|
||||||
app_type_name,
|
images: params.base64
|
||||||
},
|
},
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
responseType: 'text',
|
responseType: 'text',
|
||||||
success: res => {
|
success: res => {
|
||||||
var sign_str = Utils.hexMD5('key=' + res.data.data.key+'&time='+res.data.data.time)
|
typeof params.success == 'function' && params.success(res.data);
|
||||||
typeof callback == 'function' && callback(sign_str,res.data.data.time);
|
},
|
||||||
},
|
fail: () => {
|
||||||
fail: () => {
|
typeof params.fail == 'function' && params.fail(res);
|
||||||
typeof params.fail == 'function' && params.fail(res);
|
}
|
||||||
}
|
});
|
||||||
});
|
},
|
||||||
},
|
pullImage(params) {
|
||||||
uploadBase64(params) {
|
uni.request({
|
||||||
this.needMd5Fn(params,(sign_str,time)=>{
|
url: Config.baseUrl + '/api/upload/headimgPull',
|
||||||
uni.request({
|
method: 'POST',
|
||||||
url: Config.baseUrl + '/api/upload/headimgBase64',
|
header: {
|
||||||
method: 'POST',
|
'content-type': 'application/x-www-form-urlencoded;application/json'
|
||||||
header: {
|
},
|
||||||
'content-type': 'application/x-www-form-urlencoded;application/json'
|
data: {
|
||||||
},
|
app_type,
|
||||||
data: {
|
app_type_name,
|
||||||
app_type,
|
path: params.path
|
||||||
app_type_name,
|
},
|
||||||
images: params.base64,
|
dataType: 'json',
|
||||||
token: store.state.token || '',
|
responseType: 'text',
|
||||||
sign: sign_str,
|
success: res => {
|
||||||
time: time
|
typeof params.success == 'function' && params.success(res.data);
|
||||||
},
|
},
|
||||||
dataType: 'json',
|
fail: () => {
|
||||||
responseType: 'text',
|
typeof params.fail == 'function' && params.fail(res);
|
||||||
success: res => {
|
}
|
||||||
typeof params.success == 'function' && params.success(res.data);
|
});
|
||||||
},
|
},
|
||||||
fail: () => {
|
upload(params) {
|
||||||
typeof params.fail == 'function' && params.fail(res);
|
uni.uploadFile({
|
||||||
}
|
url: Config.baseUrl + params.url,
|
||||||
});
|
filePath: params.filePath,
|
||||||
})
|
name: params.name || 'file',
|
||||||
},
|
fileType: params.fileType || 'image',
|
||||||
pullImage(params) {
|
formData: {
|
||||||
this.needMd5Fn(params,(sign_str,time)=>{
|
app_type,
|
||||||
uni.request({
|
app_type_name,
|
||||||
url: Config.baseUrl + '/api/upload/headimgPull',
|
},
|
||||||
method: 'POST',
|
header: {
|
||||||
header: {
|
'content-type': 'application/x-www-form-urlencoded;application/json'
|
||||||
'content-type': 'application/x-www-form-urlencoded;application/json'
|
},
|
||||||
},
|
success: (res) => {
|
||||||
data: {
|
typeof params.success == 'function' && params.success(JSON.parse(res.data));
|
||||||
app_type,
|
},
|
||||||
app_type_name,
|
fail: (res) => {
|
||||||
path: params.path,
|
typeof params.fail == 'function' && params.fail(res);
|
||||||
token: store.state.token || '',
|
}
|
||||||
sign: sign_str,
|
});
|
||||||
time: time
|
}
|
||||||
},
|
|
||||||
dataType: 'json',
|
|
||||||
responseType: 'text',
|
|
||||||
success: res => {
|
|
||||||
typeof params.success == 'function' && params.success(res.data);
|
|
||||||
},
|
|
||||||
fail: () => {
|
|
||||||
typeof params.fail == 'function' && params.fail(res);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
},
|
|
||||||
upload(params) {
|
|
||||||
uni.uploadFile({
|
|
||||||
url: Config.baseUrl + params.url,
|
|
||||||
filePath: params.filePath,
|
|
||||||
name: params.name || 'file',
|
|
||||||
fileType: params.fileType || 'image',
|
|
||||||
formData: {
|
|
||||||
app_type,
|
|
||||||
app_type_name,
|
|
||||||
token: store.state.token || ''
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
'content-type': 'application/x-www-form-urlencoded;application/json'
|
|
||||||
},
|
|
||||||
success: (res) => {
|
|
||||||
typeof params.success == 'function' && params.success(JSON.parse(res.data));
|
|
||||||
},
|
|
||||||
fail: (res) => {
|
|
||||||
typeof params.fail == 'function' && params.fail(res);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
152
common/js/huaweiPay.js
Normal file
152
common/js/huaweiPay.js
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/**
|
||||||
|
* 华为支付核心工具类
|
||||||
|
* 适配端:华为快应用(原生支付)、微信小程序(H5支付)、H5端(H5支付)
|
||||||
|
* 核心:统一封装支付调用逻辑,返回H5支付链接适配web-view组件
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 华为支付调用封装
|
||||||
|
* @param {String} outTradeNo 前端生成的唯一订单号
|
||||||
|
* @param {Number} amount 支付金额(单位:元,保留2位小数)
|
||||||
|
* @param {String} subject 订单标题
|
||||||
|
* @param {String} payType 支付类型(默认huaweipay)
|
||||||
|
* @returns {Promise} 支付结果(含H5支付链接)
|
||||||
|
*/
|
||||||
|
export function invokeHuaweiPay(outTradeNo, amount, subject, payType = 'huaweipay') {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
// 1. 显示加载中提示
|
||||||
|
uni.showLoading({
|
||||||
|
title: '发起支付...'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. 调用后端生成订单
|
||||||
|
const orderRes = await uni.request({
|
||||||
|
url: getApiUrl() + '/api/huawei/pay/createOrder',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
out_trade_no: outTradeNo,
|
||||||
|
total_amount: amount,
|
||||||
|
subject: subject,
|
||||||
|
pay_type: payType
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. 校验后端返回结果
|
||||||
|
if (orderRes.data.code !== 0) {
|
||||||
|
uni.hideLoading();
|
||||||
|
reject(new Error(orderRes.data.msg || '生成支付订单失败'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 区分运行端处理
|
||||||
|
const systemInfo = uni.getSystemInfoSync();
|
||||||
|
const accountInfo = uni.getAccountInfoSync();
|
||||||
|
const isHuaweiQuickApp = systemInfo.platform === 'quickapp-huawei'; // 华为快应用
|
||||||
|
const isWechatMini = accountInfo?.miniProgram?.appId?.includes('wx'); // 微信小程序
|
||||||
|
const isH5 = systemInfo.platform === 'web' || !accountInfo?.miniProgram; // H5端
|
||||||
|
|
||||||
|
if (isHuaweiQuickApp) {
|
||||||
|
// 4.1 华为快应用:原生唤起支付控件
|
||||||
|
// 注意:这里需要根据实际的华为快应用支付SDK调用
|
||||||
|
try {
|
||||||
|
// 示例代码,实际需要根据华为快应用文档调整
|
||||||
|
const huaweiPay = require('@service.pay.huawei');
|
||||||
|
huaweiPay.pay({
|
||||||
|
orderInfo: orderRes.data.data.orderInfo,
|
||||||
|
success: (payRes) => {
|
||||||
|
uni.hideLoading();
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '华为支付控件唤起成功',
|
||||||
|
data: payRes
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
uni.hideLoading();
|
||||||
|
const errMsg = err.message || err.code || '未知错误';
|
||||||
|
reject(new Error(`支付失败:${errMsg}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (sdkError) {
|
||||||
|
// SDK不存在,降级到H5支付
|
||||||
|
if (orderRes.data.data.payUrl) {
|
||||||
|
uni.hideLoading();
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '跳转华为支付H5页面',
|
||||||
|
data: { payUrl: orderRes.data.data.payUrl }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.hideLoading();
|
||||||
|
reject(new Error('华为支付SDK不可用且无H5支付链接'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isWechatMini || isH5) {
|
||||||
|
// 4.2 微信小程序/H5端:返回H5支付链接(适配web-view)
|
||||||
|
if (!orderRes.data.data.payUrl) {
|
||||||
|
uni.hideLoading();
|
||||||
|
reject(new Error('未获取到华为支付H5跳转链接'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uni.hideLoading();
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '跳转华为支付H5页面',
|
||||||
|
data: { payUrl: orderRes.data.data.payUrl }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 4.3 其他端:提示不支持
|
||||||
|
uni.hideLoading();
|
||||||
|
reject(new Error('当前环境暂不支持华为支付'));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
uni.hideLoading();
|
||||||
|
reject(new Error(`支付异常:${err.message || '网络请求失败'}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验支付最终状态(统一适配所有支付方式)
|
||||||
|
* @param {String} outTradeNo 前端生成的订单号
|
||||||
|
* @returns {Promise} 校验结果(包含订单实际支付状态)
|
||||||
|
*/
|
||||||
|
export function checkPayStatus(outTradeNo) {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
// 统一调用后端状态校验接口(适配所有支付类型)
|
||||||
|
const checkRes = await uni.request({
|
||||||
|
url: getApiUrl() + '/api/pay/checkStatus',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
out_trade_no: outTradeNo
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resolve(checkRes.data);
|
||||||
|
} catch (err) {
|
||||||
|
reject(new Error(`校验支付状态失败:${err.message || '网络请求失败'}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取API基础URL
|
||||||
|
*/
|
||||||
|
function getApiUrl() {
|
||||||
|
// 尝试获取配置的API地址
|
||||||
|
try {
|
||||||
|
// #ifdef H5
|
||||||
|
const config = require('@/common/js/config.js').default;
|
||||||
|
return config.baseUrl || '';
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5
|
||||||
|
const config = require('@/common/js/config.js').default;
|
||||||
|
return config.baseUrl || '';
|
||||||
|
// #endif
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('获取API配置失败,使用空字符串');
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,107 +1,107 @@
|
|||||||
import TransformCoordinate from './transformCoordinate.js'
|
import TransformCoordinate from './transformCoordinate.js'
|
||||||
|
|
||||||
function openMapByDefault(latitude, longitude, name) {
|
function openMapByDefault(latitude, longitude, name) {
|
||||||
uni.openLocation({
|
uni.openLocation({
|
||||||
latitude: latitude,
|
latitude: latitude,
|
||||||
longitude: longitude,
|
longitude: longitude,
|
||||||
name: name,
|
name: name,
|
||||||
fail: (e) => {
|
fail: (e) => {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
content: '打开地图失败,请稍后重试'
|
content: '打开地图失败,请稍后重试'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function openMapByAndroid(latitude, longitude, name) {
|
function openMapByAndroid(latitude, longitude, name) {
|
||||||
let url = ''; // 回调地址
|
let url = ''; // 回调地址
|
||||||
let identity = ''; // 程序名称
|
let identity = ''; // 程序名称
|
||||||
if (plus.runtime.isApplicationExist({
|
if (plus.runtime.isApplicationExist({
|
||||||
pname: 'com.baidu.BaiduMap'
|
pname: 'com.baidu.BaiduMap'
|
||||||
})) {
|
})) {
|
||||||
url = `baidumap://map/marker?location=${latitude},${longitude}&title=${name}&coord_type=gcj02&src=andr.baidu.openAPIdemo`;
|
url =
|
||||||
identity = 'com.baidu.BaiduMap';
|
`baidumap://map/marker?location=${latitude},${longitude}&title=${name}&coord_type=gcj02&src=andr.baidu.openAPIdemo`
|
||||||
openURL(url, identity)
|
identity = 'com.baidu.BaiduMap'
|
||||||
} else if (plus.runtime.isApplicationExist({
|
openURL(url, identity)
|
||||||
pname: 'com.autonavi.minimap'
|
} else if (plus.runtime.isApplicationExist({
|
||||||
})) {
|
pname: 'com.autonavi.minimap'
|
||||||
// 高德
|
})) { // 高德
|
||||||
url = `androidamap://viewMap?sourceApplication=appname&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`;
|
url = `androidamap://viewMap?sourceApplication=appname&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`
|
||||||
identity = 'com.autonavi.minimap';
|
identity = 'com.autonavi.minimap'
|
||||||
openURL(url, identity)
|
openURL(url, identity)
|
||||||
} else {
|
} else {
|
||||||
openMapByDefault(latitude, longitude, name)
|
openMapByDefault(latitude, longitude, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function openMapByIos(latitude, longitude, name) {
|
function openMapByIos(latitude, longitude, name) {
|
||||||
let url = ''; // 回调地址
|
let url = ''; // 回调地址
|
||||||
let errorCB = ''; // url失败的回调地址
|
let errorCB = ''; // url失败的回调地址
|
||||||
let identity = ''; // 程序名称
|
let identity = ''; // 程序名称
|
||||||
|
|
||||||
if (plus.runtime.isApplicationExist({
|
if (plus.runtime.isApplicationExist({
|
||||||
action: 'baidumap://'
|
action: 'baidumap://'
|
||||||
})) {
|
})) {
|
||||||
url = `baidumap://map/marker?location=${latitude},${longitude}&title=${name}&content=${name}&src=ios.baidu.openAPIdemo&coord_type=gcj02`;
|
url =
|
||||||
openURL(url, identity)
|
`baidumap://map/marker?location=${latitude},${longitude}&title=${name}&content=${name}&src=ios.baidu.openAPIdemo&coord_type=gcj02`;
|
||||||
} else if (plus.runtime.isApplicationExist({
|
openURL(url, identity)
|
||||||
action: 'iosamap://'
|
} else if (plus.runtime.isApplicationExist({
|
||||||
})) {
|
action: 'iosamap://'
|
||||||
// 高德
|
})) { // 高德
|
||||||
url = `iosamap://viewMap?sourceApplication=applicationName&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`;
|
url = `iosamap://viewMap?sourceApplication=applicationName&poiname=${name}&lat=${latitude}&lon=${longitude}&dev=0`
|
||||||
openURL(url, identity)
|
openURL(url, identity)
|
||||||
} else {
|
} else {
|
||||||
openMapByDefault(latitude, longitude, name)
|
openMapByDefault(latitude, longitude, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function openURL(url, identity) {
|
function openURL(url, identity) {
|
||||||
let newurl = encodeURI(url);
|
let newurl = encodeURI(url);
|
||||||
plus.runtime.openURL(newurl, function(res) {
|
plus.runtime.openURL(newurl, function(res) {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
content: res.message
|
content: res.message
|
||||||
})
|
})
|
||||||
}, identity);
|
}, identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCoordByType(longitude, latitude, coord_type) {
|
function getCoordByType(longitude, latitude, coord_type) {
|
||||||
switch (coord_type) {
|
switch (coord_type) {
|
||||||
case 'gcj02':
|
case 'gcj02':
|
||||||
return [longitude, latitude]
|
return [longitude, latitude]
|
||||||
break;
|
break;
|
||||||
case 'bd09':
|
case 'bd09':
|
||||||
return TransformCoordinate.bd09togcj02(longitude, latitude)
|
return TransformCoordinate.bd09togcj02(longitude, latitude)
|
||||||
break;
|
break;
|
||||||
case 'wgs84':
|
case 'wgs84':
|
||||||
return TransformCoordinate.wgs84togcj02(longitude, latitude)
|
return TransformCoordinate.wgs84togcj02(longitude, latitude)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return [longitude, latitude]
|
return [longitude, latitude]
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default {
|
export default {
|
||||||
/* 打开地图 */
|
/* 打开地图 */
|
||||||
openMap(latitude, longitude, name, coord_type = 'gcj02') {
|
openMap(latitude, longitude, name, coord_type = 'gcj02') {
|
||||||
let arr = getCoordByType(longitude, latitude, coord_type)
|
let arr = getCoordByType(longitude, latitude, coord_type)
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
switch (uni.getSystemInfoSync().platform) {
|
switch (uni.getSystemInfoSync().platform) {
|
||||||
case 'android':
|
case 'android':
|
||||||
console.log('运行Android上')
|
console.log('运行Android上')
|
||||||
openMapByAndroid(arr[1], arr[0], name)
|
openMapByAndroid(arr[1], arr[0], name)
|
||||||
break;
|
break;
|
||||||
case 'ios':
|
case 'ios':
|
||||||
console.log('运行iOS上')
|
console.log('运行iOS上')
|
||||||
openMapByIos(arr[1], arr[0], name)
|
openMapByIos(arr[1], arr[0], name)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
openMapByDefault(arr[1], arr[0], name)
|
openMapByDefault(arr[1], arr[0], name)
|
||||||
console.log('运行在开发者工具上')
|
console.log('运行在开发者工具上')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
// #ifndef APP-PLUS
|
// #ifndef APP-PLUS
|
||||||
openMapByDefault(arr[1], arr[0], name)
|
openMapByDefault(arr[1], arr[0], name)
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
common/js/payCore.js
Normal file
28
common/js/payCore.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 全支付方式统一调用入口
|
||||||
|
* 整合微信/支付宝/华为支付的所有方法,简化页面引入逻辑
|
||||||
|
* 依赖:payUtils.js、huaweiPay.js(无需修改原文件)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 1. 引入原工具类的所有方法(修正方法名)
|
||||||
|
import {
|
||||||
|
invokeWechatPay, // 微信支付(完整方法名)
|
||||||
|
invokeAlipay, // 支付宝支付(完整方法名)
|
||||||
|
checkPayStatus as payUtilsCheck // 微信/支付宝支付状态校验(完整方法名)
|
||||||
|
} from './payUtils.js';
|
||||||
|
|
||||||
|
import {
|
||||||
|
invokeHuaweiPay, // 华为支付(完整方法名)
|
||||||
|
checkPayStatus as huaweiCheck // 华为支付状态校验(完整方法名)
|
||||||
|
} from './huaweiPay.js';
|
||||||
|
|
||||||
|
// 2. 导出所有支付调用方法(修正方法名,和原方法一致)
|
||||||
|
export {
|
||||||
|
invokeWechatPay,
|
||||||
|
invokeAlipay,
|
||||||
|
invokeHuaweiPay
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3. 导出统一的支付状态校验方法(两个工具类逻辑完全一致,任选其一即可)
|
||||||
|
export const checkPayStatus = payUtilsCheck;
|
||||||
|
// 若需使用华为支付工具类的校验逻辑,可替换为:export const checkPayStatus = huaweiCheck;
|
||||||
354
common/js/payUtils.js
Normal file
354
common/js/payUtils.js
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
/**
|
||||||
|
* 微信/支付宝支付工具类
|
||||||
|
* 适配端:微信小程序(全支付方式)、华为快应用(全支付方式)、H5(全支付方式)
|
||||||
|
* 核心:统一封装支付调用逻辑,返回H5支付链接适配web-view组件
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付调用封装
|
||||||
|
* @param {String} outTradeNo 前端生成的唯一订单号
|
||||||
|
* @param {Number} amount 支付金额(单位:元,保留2位小数)
|
||||||
|
* @param {String} subject 订单标题
|
||||||
|
* @returns {Promise} 支付结果(含H5支付链接)
|
||||||
|
*/
|
||||||
|
export function invokeWechatPay(outTradeNo, amount, subject) {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
// 1. 调用后端接口生成微信支付订单
|
||||||
|
const orderRes = await uni.request({
|
||||||
|
url: getApiUrl() + '/api/pay/wechat/createOrder',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
out_trade_no: outTradeNo,
|
||||||
|
total_amount: amount,
|
||||||
|
subject: subject,
|
||||||
|
pay_type: 'wechatpay'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. 校验后端返回结果
|
||||||
|
if (orderRes.data.code !== 0) {
|
||||||
|
reject(new Error(orderRes.data.msg || '生成微信支付订单失败'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 区分运行端处理
|
||||||
|
const systemInfo = uni.getSystemInfoSync();
|
||||||
|
const accountInfo = uni.getAccountInfoSync();
|
||||||
|
const isWechatMini = accountInfo?.miniProgram?.appId?.includes('wx'); // 微信小程序
|
||||||
|
const isHuaweiQuickApp = systemInfo.platform === 'quickapp-huawei'; // 华为快应用
|
||||||
|
|
||||||
|
if (isWechatMini) {
|
||||||
|
// 3.1 微信小程序:优先原生唤起,失败则返回H5链接
|
||||||
|
if (orderRes.data.data.timeStamp && orderRes.data.data.paySign) {
|
||||||
|
uni.requestPayment({
|
||||||
|
timeStamp: orderRes.data.data.timeStamp,
|
||||||
|
nonceStr: orderRes.data.data.nonceStr,
|
||||||
|
package: orderRes.data.data.package,
|
||||||
|
signType: 'MD5',
|
||||||
|
paySign: orderRes.data.data.paySign,
|
||||||
|
success: () => {
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '微信支付控件唤起成功',
|
||||||
|
data: {}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
// 原生唤起失败,返回H5链接适配web-view
|
||||||
|
if (orderRes.data.data.payUrl) {
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '原生支付失败,跳转H5支付',
|
||||||
|
data: { payUrl: orderRes.data.data.payUrl }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
reject(new Error(`微信支付失败:${err.errMsg || '无H5支付链接'}`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (orderRes.data.data.payUrl) {
|
||||||
|
// 无原生支付参数,直接返回H5链接
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '跳转微信支付H5页面',
|
||||||
|
data: { payUrl: orderRes.data.data.payUrl }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
reject(new Error('缺少微信支付参数(原生/H5)'));
|
||||||
|
}
|
||||||
|
} else if (isHuaweiQuickApp) {
|
||||||
|
// 3.2 华为快应用:返回H5支付链接
|
||||||
|
if (!orderRes.data.data.payUrl) {
|
||||||
|
reject(new Error('未获取到微信支付H5跳转链接'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '跳转微信支付H5页面',
|
||||||
|
data: { payUrl: orderRes.data.data.payUrl }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 3.3 H5端:直接跳转
|
||||||
|
if (!orderRes.data.data.payUrl) {
|
||||||
|
reject(new Error('未获取到微信支付跳转链接'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.location.href = orderRes.data.data.payUrl;
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '跳转微信支付页面成功',
|
||||||
|
data: {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
reject(new Error(`微信支付异常:${err.message || '网络请求失败'}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付宝支付调用封装(全端支持,返回H5链接适配web-view)
|
||||||
|
* @param {String} outTradeNo 前端生成的唯一订单号
|
||||||
|
* @param {Number} amount 支付金额(单位:元)
|
||||||
|
* @param {String} subject 订单标题
|
||||||
|
* @returns {Promise} 支付结果(含H5支付链接)
|
||||||
|
*/
|
||||||
|
export function invokeAlipay(outTradeNo, amount, subject) {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
// 1. 调用后端接口生成支付宝支付订单
|
||||||
|
const orderRes = await uni.request({
|
||||||
|
url: getApiUrl() + '/api/pay/alipay/createOrder',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
out_trade_no: outTradeNo,
|
||||||
|
total_amount: amount,
|
||||||
|
subject: subject,
|
||||||
|
pay_type: 'alipay'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. 校验后端返回结果
|
||||||
|
if (orderRes.data.code !== 0) {
|
||||||
|
reject(new Error(orderRes.data.msg || '生成支付宝支付订单失败'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 区分运行端处理(全端返回H5链接)
|
||||||
|
const accountInfo = uni.getAccountInfoSync();
|
||||||
|
const isWechatMini = accountInfo?.miniProgram?.appId?.includes('wx');
|
||||||
|
const isHuaweiQuickApp = uni.getSystemInfoSync().platform === 'quickapp-huawei';
|
||||||
|
|
||||||
|
if (!orderRes.data.data.payUrl) {
|
||||||
|
reject(new Error('未获取到支付宝支付H5跳转链接'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isWechatMini || isHuaweiQuickApp) {
|
||||||
|
// 3.1 微信小程序/华为快应用:返回H5链接(适配web-view)
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '跳转支付宝支付H5页面',
|
||||||
|
data: { payUrl: orderRes.data.data.payUrl }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 3.2 H5端:直接跳转
|
||||||
|
window.location.href = orderRes.data.data.payUrl;
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '跳转支付宝支付页面成功',
|
||||||
|
data: {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
reject(new Error(`支付宝支付异常:${err.message || '网络请求失败'}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一支付状态校验(和huaweiPay.js的checkPayStatus对齐)
|
||||||
|
* @param {String} outTradeNo 前端生成的订单号
|
||||||
|
* @returns {Promise} 校验结果(包含订单实际支付状态)
|
||||||
|
*/
|
||||||
|
export function checkPayStatus(outTradeNo) {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
// 统一调用后端状态校验接口(适配所有支付类型)
|
||||||
|
const checkRes = await uni.request({
|
||||||
|
url: getApiUrl() + '/api/pay/checkStatus', // 和huaweiPay.js使用同一接口
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
out_trade_no: outTradeNo
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resolve(checkRes.data);
|
||||||
|
} catch (err) {
|
||||||
|
reject(new Error(`校验支付状态失败:${err.message || '网络请求失败'}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 华为支付调用封装(适配全端:微信小程序/H5/华为快应用)
|
||||||
|
* @param {String} outTradeNo 前端生成的唯一订单号
|
||||||
|
* @param {Number} amount 支付金额(单位:元,保留2位小数)
|
||||||
|
* @param {String} subject 订单标题
|
||||||
|
* @returns {Promise} 支付结果(含H5支付链接/原生支付状态)
|
||||||
|
*/
|
||||||
|
export function invokeHuaweiPay(outTradeNo, amount, subject) {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
// ===== 1. 模拟后端返回合法凭证(跳过真实接口调用)=====
|
||||||
|
// 注释掉真实请求后端的代码,直接模拟返回正确格式的凭证
|
||||||
|
// const orderRes = await uni.request({
|
||||||
|
// url: getApiUrl() + '/api/pay/huawei/createOrder',
|
||||||
|
// method: 'POST',
|
||||||
|
// data: {
|
||||||
|
// out_trade_no: outTradeNo,
|
||||||
|
// total_amount: amount,
|
||||||
|
// subject: subject,
|
||||||
|
// pay_type: 'huaweipay'
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// 模拟后端返回的合法数据(重点:code=0,有orderInfo和payUrl)
|
||||||
|
const orderRes = {
|
||||||
|
data: {
|
||||||
|
code: 0,
|
||||||
|
msg: '生成华为支付订单成功',
|
||||||
|
data: {
|
||||||
|
orderInfo: 'test_order_info_123456', // 模拟华为原生SDK需要的参数
|
||||||
|
payUrl: 'https://pay.huawei.com/cashier/test' // 模拟H5支付链接
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
// ===== 2. 加日志:打印模拟的凭证,看是否拿到数据 =====
|
||||||
|
console.log('【华为支付测试】模拟后端返回的凭证:', orderRes.data);
|
||||||
|
|
||||||
|
// 3. 校验后端返回结果
|
||||||
|
if (orderRes.data.code !== 0) {
|
||||||
|
reject(new Error(orderRes.data.msg || '生成华为支付订单失败'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 区分运行端处理
|
||||||
|
const accountInfo = uni.getAccountInfoSync();
|
||||||
|
const systemInfo = uni.getSystemInfoSync();
|
||||||
|
const isWechatMini = accountInfo?.miniProgram?.appId?.includes('wx'); // 微信小程序
|
||||||
|
const isHuaweiQuickApp = systemInfo.platform === 'quickapp-huawei'; // 华为快应用
|
||||||
|
|
||||||
|
if (isHuaweiQuickApp) {
|
||||||
|
// ===== 3. 加日志:标记进入华为快应用逻辑 =====
|
||||||
|
console.log('【华为支付测试】进入华为快应用逻辑,尝试调起原生SDK');
|
||||||
|
|
||||||
|
// 3.1 华为快应用:优先原生SDK调起,失败则降级H5
|
||||||
|
if (orderRes.data.data.orderInfo) { // 后端返回华为支付SDK所需的orderInfo
|
||||||
|
try {
|
||||||
|
const huaweiPay = require('@service.pay.huawei'); // 华为快应用支付SDK
|
||||||
|
console.log('【华为支付测试】开始调用华为原生支付SDK');
|
||||||
|
huaweiPay.pay({
|
||||||
|
orderInfo: orderRes.data.data.orderInfo, // 后端返回的原生支付参数
|
||||||
|
success: (res) => {
|
||||||
|
console.log('【华为支付测试】原生SDK调起成功', res);
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '华为支付原生控件唤起成功',
|
||||||
|
data: {}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.log('【华为支付测试】原生SDK调起失败,降级到H5', err);
|
||||||
|
// 原生唤起失败,降级返回H5链接
|
||||||
|
if (orderRes.data.data.payUrl) {
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '原生支付失败,跳转H5支付',
|
||||||
|
data: { payUrl: orderRes.data.data.payUrl }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
reject(new Error(`华为支付失败:${err.message || '无H5支付链接'}`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (sdkErr) {
|
||||||
|
console.log('【华为支付测试】SDK加载失败,降级到H5', sdkErr);
|
||||||
|
// SDK加载失败,直接返回H5链接
|
||||||
|
if (orderRes.data.data.payUrl) {
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: 'SDK加载失败,跳转H5支付',
|
||||||
|
data: { payUrl: orderRes.data.data.payUrl }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
reject(new Error('华为支付SDK异常且无H5链接'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (orderRes.data.data.payUrl) {
|
||||||
|
console.log('【华为支付测试】无原生参数,直接返回H5链接');
|
||||||
|
// 无原生参数,直接返回H5链接
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '跳转华为支付H5页面',
|
||||||
|
data: { payUrl: orderRes.data.data.payUrl }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
reject(new Error('缺少华为支付参数(原生/H5)'));
|
||||||
|
}
|
||||||
|
} else if (isWechatMini) {
|
||||||
|
// ===== 4. 加日志:标记进入微信小程序逻辑 =====
|
||||||
|
console.log('【华为支付测试】进入微信小程序逻辑,返回H5链接');
|
||||||
|
|
||||||
|
// 3.2 微信小程序:返回H5链接(适配web-view)
|
||||||
|
if (!orderRes.data.data.payUrl) {
|
||||||
|
reject(new Error('未获取到华为支付H5跳转链接'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '跳转华为支付H5页面',
|
||||||
|
data: { payUrl: orderRes.data.data.payUrl }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// ===== 5. 加日志:标记进入H5端逻辑 =====
|
||||||
|
console.log('【华为支付测试】进入H5端逻辑,直接跳转');
|
||||||
|
|
||||||
|
// 3.3 H5端:直接跳转
|
||||||
|
if (!orderRes.data.data.payUrl) {
|
||||||
|
reject(new Error('未获取到华为支付跳转链接'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.location.href = orderRes.data.data.payUrl;
|
||||||
|
resolve({
|
||||||
|
code: 0,
|
||||||
|
msg: '跳转华为支付页面成功',
|
||||||
|
data: {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('【华为支付测试】整体异常:', err);
|
||||||
|
reject(new Error(`华为支付异常:${err.message || '网络请求失败'}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取API基础URL
|
||||||
|
*/
|
||||||
|
function getApiUrl() {
|
||||||
|
// 尝试获取配置的API地址
|
||||||
|
try {
|
||||||
|
// #ifdef H5
|
||||||
|
const config = require('@/common/js/config.js').default;
|
||||||
|
return config.baseUrl || '';
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5
|
||||||
|
const config = require('@/common/js/config.js').default;
|
||||||
|
return config.baseUrl || '';
|
||||||
|
// #endif
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('获取API配置失败,使用空字符串');
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,215 +1,207 @@
|
|||||||
import config from './config.js'
|
import config from './config.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
timeoutObj: null, //ping定时器
|
timeoutObj: null, //ping定时器
|
||||||
servicer_id: null, //绑定
|
servicer_id: null, //绑定
|
||||||
pingInterval: config.pingInterval //本地端主动给服务器ping的时间, 0 则不开启
|
pingInterval: config.pingInterval //本地端主动给服务器ping的时间, 0 则不开启
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
let that = this;
|
let that = this;
|
||||||
// 因为图片上传,所以不能onhide关闭长链接,但是每次打开客服都会有重复请求,所以优先关闭再去打开长链接
|
// 因为图片上传,所以不能onhide关闭长链接,但是每次打开客服都会有重复请求,所以优先关闭再去打开长链接
|
||||||
uni.closeSocket();
|
uni.closeSocket();
|
||||||
// .判断是否已连接
|
// .判断是否已连接
|
||||||
that.checkOpenSocket();
|
that.checkOpenSocket();
|
||||||
// uni.onSocketClose(function(res) {
|
// uni.onSocketClose(function(res) {
|
||||||
// console.log('WebSocket 已关闭!');
|
// console.log('WebSocket 已关闭!');
|
||||||
// });
|
// });
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 判断是否已连接
|
// 判断是否已连接
|
||||||
checkOpenSocket() {
|
checkOpenSocket() {
|
||||||
console.log('判断是否已连接');
|
console.log('判断是否已连接');
|
||||||
// alert('判断是否已连接')
|
// alert('判断是否已连接')
|
||||||
let self = this;
|
let self = this;
|
||||||
uni.sendSocketMessage({
|
uni.sendSocketMessage({
|
||||||
data: 'ping',
|
data: 'ping',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
console.log('连接成功,检查');
|
console.log('连接成功,检查');
|
||||||
// alert('连接成功,检查')
|
// alert('连接成功,检查')
|
||||||
// self.getChatList();
|
// self.getChatList();
|
||||||
},
|
},
|
||||||
fail: (err) => { // 未连接打开websocket连接
|
fail: (err) => { // 未连接打开websocket连接
|
||||||
console.log('连接失败');
|
console.log('连接失败');
|
||||||
// alert('连接失败')
|
// alert('连接失败')
|
||||||
self.openConnection();
|
self.openConnection();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
openConnection() { // 打开连接
|
openConnection() { // 打开连接
|
||||||
console.log('打开连接');
|
console.log('打开连接');
|
||||||
// alert('打开连接')
|
// alert('打开连接')
|
||||||
// uni.closeSocket(); // 确保已经关闭后再重新打开
|
// uni.closeSocket(); // 确保已经关闭后再重新打开
|
||||||
|
uni.connectSocket({
|
||||||
uni.connectSocket({
|
url: config.webSocket,
|
||||||
url: config.webSocket,
|
method: 'POST',
|
||||||
method: 'POST',
|
success(res) {
|
||||||
success(res) {
|
console.log('连接成功 connectSocket=', res);
|
||||||
console.log('连接成功 connectSocket=', res);
|
// alert('连接成功 connectSocket=', res);
|
||||||
// alert('连接成功 connectSocket=', res);
|
},
|
||||||
},
|
fail(err) {
|
||||||
fail(err) {
|
console.log('连接失败 connectSocket=', err);
|
||||||
console.log('连接失败 connectSocket=', err);
|
}
|
||||||
}
|
});
|
||||||
});
|
// uni.onSocketOpen((res) => {
|
||||||
// 监听 WebSocket 连接错误事件
|
// console.log('连接成功', res);
|
||||||
uni.onSocketError((res)=>{
|
// });
|
||||||
console.error('WebSocket 连接失败:', res.errMsg);
|
this.onSocketMessage(); // 打开成功监听服务器返回的消息
|
||||||
this.chatListInit();
|
},
|
||||||
this.getChatList();
|
// 打开成功监听服务器返回的消息
|
||||||
});
|
onSocketMessage() { // 消息
|
||||||
// uni.onSocketOpen((res) => {
|
console.log("开始监听");
|
||||||
// console.log('连接成功', res);
|
|
||||||
// });
|
let that = this;
|
||||||
this.onSocketMessage(); // 打开成功监听服务器返回的消息
|
this.pingInterval = config.pingInterval;
|
||||||
},
|
this.timeoutObj = null;
|
||||||
// 打开成功监听服务器返回的消息
|
uni.onSocketMessage((res) => { //type:init,connect,close,string,order,goods
|
||||||
onSocketMessage() { // 消息
|
let msg = JSON.parse(res.data);
|
||||||
console.log("开始监听");
|
console.log("监听该服务器消息", res);
|
||||||
|
if (msg.type == 'close') {
|
||||||
let that = this;
|
clearInterval(that.timeoutObj);
|
||||||
this.pingInterval = config.pingInterval;
|
that.timeoutObj = null;
|
||||||
if(this.timeoutObj) clearInterval(this.timeoutObj);
|
uni.closeSocket();
|
||||||
this.timeoutObj = null;
|
return;
|
||||||
uni.onSocketMessage((res) => { //type:init,connect,close,string,order,goods
|
}
|
||||||
let msg = JSON.parse(res.data);
|
this.reset();
|
||||||
console.log("监听该服务器消息", res);
|
this.getSocketMsg(res.data); // 监听到有新服务器消息
|
||||||
if (msg.type == 'close') {
|
});
|
||||||
clearInterval(that.timeoutObj);
|
},
|
||||||
that.timeoutObj = null;
|
// 监听到有新服务器消息
|
||||||
uni.closeSocket();
|
getSocketMsg(reData) { // 监听到服务器消息
|
||||||
return;
|
let that = this;
|
||||||
}
|
// console.log(reData)
|
||||||
this.reset();
|
let giveMsg = JSON.parse(reData);
|
||||||
this.getSocketMsg(res.data); // 监听到有新服务器消息
|
let data = {
|
||||||
});
|
isItMe: false,
|
||||||
},
|
};
|
||||||
// 监听到有新服务器消息
|
data.contentType = giveMsg.type;
|
||||||
getSocketMsg(reData) { // 监听到服务器消息
|
// alert(data.contentType)
|
||||||
let that = this;
|
if (giveMsg.type == 'init') {
|
||||||
let giveMsg = JSON.parse(reData);
|
// alert(123)
|
||||||
let data = {
|
that.$api.sendRequest({
|
||||||
isItMe: false,
|
url: '/servicer/api/chat/bind',
|
||||||
};
|
data: {
|
||||||
data.contentType = giveMsg.type;
|
client_id: giveMsg.data.client_id,
|
||||||
// alert(data.contentType)
|
site_id: that.siteId
|
||||||
if (giveMsg.type == 'init') {
|
},
|
||||||
// alert(123)
|
success(res) {
|
||||||
that.$api.sendRequest({
|
if (res.code == 0) {
|
||||||
url: '/servicer/api/chat/bind',
|
that.servicer_id = res.data.servicer_id;
|
||||||
data: {
|
} else {
|
||||||
client_id: giveMsg.data.client_id,
|
that.servicer_id = 0;
|
||||||
site_id: that.siteId
|
}
|
||||||
},
|
that.getChatList();
|
||||||
success(res) {
|
}
|
||||||
if (res.code == 0) {
|
})
|
||||||
that.servicer_id = res.data.servicer_id;
|
} else if (giveMsg.type == 'connect') {
|
||||||
} else {
|
// that.servicer_id = giveMsg.data.servicer_id;
|
||||||
that.servicer_id = 0;
|
// let NewArr = that.messageList;
|
||||||
}
|
// let index = null;
|
||||||
that.chatListInit();
|
// for (let i = 0; i < NewArr.length; i++) {
|
||||||
that.getChatList();
|
// if (NewArr[i].contentType == 'online' || NewArr[i].contentType == 'noline') {
|
||||||
}
|
// index = i;
|
||||||
})
|
// }
|
||||||
} else if (giveMsg.type == 'connect') {
|
// }
|
||||||
// that.servicer_id = giveMsg.data.servicer_id;
|
// NewArr.splice(index, 1)
|
||||||
// let NewArr = that.messageList;
|
// that.messageList = NewArr;
|
||||||
// let index = null;
|
// let obj = {}
|
||||||
// for (let i = 0; i < NewArr.length; i++) {
|
// if (that.servicer_id > 0) {
|
||||||
// if (NewArr[i].contentType == 'online' || NewArr[i].contentType == 'noline') {
|
// obj.contentType = 'online';
|
||||||
// index = i;
|
// } else if (that.servicer_id == 0) {
|
||||||
// }
|
// obj.contentType = 'noline';
|
||||||
// }
|
// }
|
||||||
// NewArr.splice(index, 1)
|
// that.messageList.push(obj);
|
||||||
// that.messageList = NewArr;
|
return false;
|
||||||
// let obj = {}
|
} else if (giveMsg.type == 'string') {
|
||||||
// if (that.servicer_id > 0) {
|
data.content = giveMsg.data.servicer_say;
|
||||||
// obj.contentType = 'online';
|
} else if (giveMsg.type == 'image') {
|
||||||
// } else if (that.servicer_id == 0) {
|
data.image = giveMsg.data.servicer_say;
|
||||||
// obj.contentType = 'noline';
|
} else if (giveMsg.type == 'order') {
|
||||||
// }
|
data.order_id = giveMsg.data.order_id;
|
||||||
// that.messageList.push(obj);
|
} else if (giveMsg.type == 'goodssku') {
|
||||||
return false;
|
data.sku_id = giveMsg.data.goods_sku_id;
|
||||||
} else if (giveMsg.type == 'string') {
|
}
|
||||||
data.content = giveMsg.data.servicer_say;
|
if (giveMsg.type == 'init') return;
|
||||||
} else if (giveMsg.type == 'image') {
|
that.messageList.push(data);
|
||||||
data.image = giveMsg.data.servicer_say;
|
that.$nextTick(() => {
|
||||||
} else if (giveMsg.type == 'order') {
|
that.setPageScrollTo()
|
||||||
data.order_id = giveMsg.data.order_id;
|
})
|
||||||
} else if (giveMsg.type == 'goodssku') {
|
},
|
||||||
data.sku_id = giveMsg.data.goods_sku_id;
|
// 检测心跳reset
|
||||||
}
|
reset() {
|
||||||
if (giveMsg.type == 'init') return;
|
console.log("检测心跳");
|
||||||
that.messageList.push(data);
|
clearInterval(this.timeoutObj);
|
||||||
that.$nextTick(() => {
|
this.start(); // 启动心跳
|
||||||
that.setPageScrollTo()
|
},
|
||||||
})
|
// 启动心跳 start
|
||||||
},
|
start() {
|
||||||
// 检测心跳reset
|
console.log("启动心跳");
|
||||||
reset() {
|
let self = this;
|
||||||
console.log("检测心跳");
|
this.timeoutObj = setInterval(function () {
|
||||||
clearInterval(this.timeoutObj);
|
uni.sendSocketMessage({
|
||||||
this.start(); // 启动心跳
|
data: 'ping',
|
||||||
},
|
success: (res) => {
|
||||||
// 启动心跳 start
|
console.log('连接中....');
|
||||||
start() {
|
},
|
||||||
console.log("启动心跳");
|
fail: (err) => {
|
||||||
let self = this;
|
console.log('连接失败重新连接....');
|
||||||
this.timeoutObj = setInterval(function () {
|
self.openConnection();
|
||||||
uni.sendSocketMessage({
|
}
|
||||||
data: 'ping',
|
});
|
||||||
success: (res) => {
|
}, this.pingInterval);
|
||||||
console.log('连接中....');
|
}
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
// onHide() {
|
||||||
console.log('连接失败重新连接....');
|
// // alert("关闭")
|
||||||
self.openConnection();
|
// // 改之前的
|
||||||
}
|
// // console.log("我出发了")
|
||||||
});
|
// // this.checkOpenSocket();
|
||||||
}, this.pingInterval);
|
// clearInterval(this.timeoutObj);
|
||||||
}
|
// this.timeoutObj = null;
|
||||||
},
|
// this.$api.sendRequest({
|
||||||
// onHide() {
|
// url: '/servicer/api/chat/bye',
|
||||||
// // alert("关闭")
|
// data: {
|
||||||
// // 改之前的
|
// servicer_id: this.servicer_id,
|
||||||
// // console.log("我出发了")
|
// site_id: this.siteId
|
||||||
// // this.checkOpenSocket();
|
// },
|
||||||
// clearInterval(this.timeoutObj);
|
// success(res) {
|
||||||
// this.timeoutObj = null;
|
// uni.closeSocket();
|
||||||
// this.$api.sendRequest({
|
// },
|
||||||
// url: '/servicer/api/chat/bye',
|
// fail: (err) => {
|
||||||
// data: {
|
// uni.closeSocket();
|
||||||
// servicer_id: this.servicer_id,
|
// }
|
||||||
// site_id: this.siteId
|
// });
|
||||||
// },
|
// },
|
||||||
// success(res) {
|
onUnload() {
|
||||||
// uni.closeSocket();
|
// alert("关闭")
|
||||||
// },
|
clearInterval(this.timeoutObj);
|
||||||
// fail: (err) => {
|
this.timeoutObj = null;
|
||||||
// uni.closeSocket();
|
this.$api.sendRequest({
|
||||||
// }
|
url: '/servicer/api/chat/bye',
|
||||||
// });
|
data: {
|
||||||
// },
|
servicer_id: this.servicer_id,
|
||||||
onUnload() {
|
site_id: this.siteId
|
||||||
// alert("关闭")
|
},
|
||||||
clearInterval(this.timeoutObj);
|
success(res) {
|
||||||
this.timeoutObj = null;
|
// alert("关闭1")
|
||||||
this.$api.sendRequest({
|
uni.closeSocket();
|
||||||
url: '/servicer/api/chat/bye',
|
},
|
||||||
data: {
|
fail: (err) => {
|
||||||
servicer_id: this.servicer_id,
|
// alert("关闭2")
|
||||||
site_id: this.siteId
|
uni.closeSocket();
|
||||||
},
|
}
|
||||||
success(res) {
|
});
|
||||||
// alert("关闭1")
|
}
|
||||||
uni.closeSocket();
|
}
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
// alert("关闭2")
|
|
||||||
uni.closeSocket();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
2184
common/js/util.js
2184
common/js/util.js
File diff suppressed because it is too large
Load Diff
@@ -1,142 +1,119 @@
|
|||||||
/**
|
/**
|
||||||
* 微信jssdk调用
|
* 微信jssdk调用
|
||||||
*/
|
*/
|
||||||
let Weixin = function () {
|
let Weixin = function () {
|
||||||
var wx = require('jweixin-module');
|
var wx = require('jweixin-module');
|
||||||
|
|
||||||
this.weixin = wx;
|
this.weixin = wx;
|
||||||
|
|
||||||
this.init = function (params) {
|
this.init = function (params) {
|
||||||
wx.config({
|
wx.config({
|
||||||
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
|
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
|
||||||
appId: params.appId, // 必填,公众号的唯一标识
|
appId: params.appId, // 必填,公众号的唯一标识
|
||||||
timestamp: params.timestamp, // 必填,生成签名的时间戳
|
timestamp: params.timestamp, // 必填,生成签名的时间戳
|
||||||
nonceStr: params.nonceStr, // 必填,生成签名的随机串
|
nonceStr: params.nonceStr, // 必填,生成签名的随机串
|
||||||
signature: params.signature, // 必填,签名
|
signature: params.signature, // 必填,签名
|
||||||
jsApiList: ['chooseWXPay', 'openAddress', 'updateAppMessageShareData',
|
jsApiList: ['chooseWXPay', 'openAddress', 'updateAppMessageShareData',
|
||||||
'updateTimelineShareData', 'scanQRCode', 'hideMenuItems'
|
'updateTimelineShareData', 'scanQRCode', 'hideMenuItems'
|
||||||
] // 必填,需要使用的JS接口列表
|
] // 必填,需要使用的JS接口列表
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发起支付
|
* 发起支付
|
||||||
* @param jsApiParame
|
* @param jsApiParame
|
||||||
* @param callback
|
* @param callback
|
||||||
* @param cancel
|
* @param cancel
|
||||||
*/
|
*/
|
||||||
this.pay = function (jsApiParame, callback, cancel) {
|
this.pay = function (jsApiParame, callback, cancel) {
|
||||||
wx.ready(function () {
|
wx.ready(function () {
|
||||||
wx.chooseWXPay({
|
wx.chooseWXPay({
|
||||||
timestamp: jsApiParame
|
timestamp: jsApiParame
|
||||||
.timestamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
|
.timestamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
|
||||||
nonceStr: jsApiParame.nonceStr, // 支付签名随机串,不长于 32 位
|
nonceStr: jsApiParame.nonceStr, // 支付签名随机串,不长于 32 位
|
||||||
package: jsApiParame.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
|
package: jsApiParame.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
|
||||||
signType: jsApiParame.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
|
signType: jsApiParame.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
|
||||||
paySign: jsApiParame.paySign, // 支付签名
|
paySign: jsApiParame.paySign, // 支付签名
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
typeof callback == 'function' && callback(res);
|
typeof callback == 'function' && callback(res);
|
||||||
},
|
},
|
||||||
cancel: function (res) {
|
cancel: function (res) {
|
||||||
typeof cancel == 'function' && cancel(res);
|
typeof cancel == 'function' && cancel(res);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取收货地址
|
* 获取收货地址
|
||||||
* @param {Object} callback
|
* @param {Object} callback
|
||||||
*/
|
*/
|
||||||
this.openAddress = function (callback) {
|
this.openAddress = function (callback) {
|
||||||
wx.ready(function () {
|
wx.ready(function () {
|
||||||
wx.openAddress({
|
wx.openAddress({
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
typeof callback == 'function' && callback(res);
|
typeof callback == 'function' && callback(res);
|
||||||
},
|
},
|
||||||
fail: (res) => {
|
fail: (res) => {
|
||||||
console.log('获取收货地址 fail',res);
|
console.log('获取收货地址 fail',res);
|
||||||
alert(JSON.stringify(res))
|
alert(JSON.stringify(res))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分享给好友
|
* 分享给好友
|
||||||
* @param {Object} params
|
* @param {Object} params
|
||||||
* @param {Object} callback
|
* @param {Object} callback
|
||||||
*/
|
*/
|
||||||
this.setShareData = function (params, callback) {
|
this.setShareData = function (params, callback) {
|
||||||
|
|
||||||
wx.ready(function () {
|
wx.ready(function () {
|
||||||
// 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
|
// 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
|
||||||
wx.updateAppMessageShareData({
|
wx.updateAppMessageShareData({
|
||||||
title: params.title || '', // 分享标题
|
title: params.title || '', // 分享标题
|
||||||
desc: params.desc || '', // 分享描述
|
desc: params.desc || '', // 分享描述
|
||||||
link: params.link || '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
link: params.link || '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
||||||
imgUrl: params.imgUrl || '', // 分享图标
|
imgUrl: params.imgUrl || '', // 分享图标
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
typeof callback == 'function' && callback(res);
|
typeof callback == 'function' && callback(res);
|
||||||
},
|
},
|
||||||
fail: function (err) {
|
fail: function (err) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 自定义“分享到朋友圈”及“分享到QQ空间”按钮的分享内容
|
// 自定义“分享到朋友圈”及“分享到QQ空间”按钮的分享内容
|
||||||
wx.updateTimelineShareData({
|
wx.updateTimelineShareData({
|
||||||
title: params.title || '', // 分享标题
|
title: params.title || '', // 分享标题
|
||||||
link: params.link || '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
link: params.link || '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
||||||
imgUrl: params.imgUrl || '', // 分享图标
|
imgUrl: params.imgUrl || '', // 分享图标
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
typeof callback == 'function' && callback(res);
|
typeof callback == 'function' && callback(res);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫一扫
|
* 扫一扫
|
||||||
* @param {Object} callback
|
* @param {Object} callback
|
||||||
*/
|
*/
|
||||||
this.scanQRCode = function (callback) {
|
this.scanQRCode = function (callback) {
|
||||||
wx.ready(function () {
|
wx.ready(function () {
|
||||||
wx.scanQRCode({
|
wx.scanQRCode({
|
||||||
needResult: 1,
|
needResult: 1,
|
||||||
scanType: ["qrCode"],
|
scanType: ["qrCode"],
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
typeof callback == 'function' && callback(res);
|
typeof callback == 'function' && callback(res);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提现
|
}
|
||||||
this.withdrawWechat = function (data,callback) {
|
|
||||||
wx.ready(function () {
|
export {
|
||||||
wx.checkJsApi({
|
Weixin
|
||||||
jsApiList: ['requestMerchantTransfer'],
|
|
||||||
success: function (res) {
|
|
||||||
if (res.checkResult['requestMerchantTransfer']) {
|
|
||||||
WeixinJSBridge.invoke('requestMerchantTransfer', {
|
|
||||||
mchId: data.mch_id,
|
|
||||||
appId: data.wechat_appid,
|
|
||||||
package: data.package_info,
|
|
||||||
},
|
|
||||||
function (res) {
|
|
||||||
typeof callback == 'function' && callback(res);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
alert('你的微信版本过低,请更新至最新版本。');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
Weixin
|
|
||||||
}
|
}
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
/**
|
|
||||||
* 企业微信JS-SDK调用
|
|
||||||
*/
|
|
||||||
let WxWork = function () {
|
|
||||||
// 企业微信JS-SDK
|
|
||||||
this.wxwork = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化企业微信JS-SDK
|
|
||||||
* @param {Object} params - 初始化参数
|
|
||||||
* @param {string} params.corpId - 企业ID
|
|
||||||
* @param {string} params.agentId - 应用ID
|
|
||||||
* @param {string} params.timestamp - 时间戳
|
|
||||||
* @param {string} params.nonceStr - 随机字符串
|
|
||||||
* @param {string} params.signature - 签名
|
|
||||||
* @param {Array} params.jsApiList - 需要使用的JS接口列表
|
|
||||||
*/
|
|
||||||
this.init = function (params) {
|
|
||||||
if (typeof wx !== 'undefined' && wx.config) {
|
|
||||||
// 小程序环境下的企业微信
|
|
||||||
this.wxwork = wx;
|
|
||||||
} else if (typeof WWOpenData !== 'undefined') {
|
|
||||||
// H5环境下的企业微信
|
|
||||||
this.wxwork = WWOpenData;
|
|
||||||
} else {
|
|
||||||
console.error('企业微信JS-SDK未加载');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.wxwork.config({
|
|
||||||
beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
|
|
||||||
debug: false, // 开启调试模式
|
|
||||||
corpId: params.corpId, // 必填,企业号的唯一标识
|
|
||||||
agentId: params.agentId, // 必填,企业微信应用ID
|
|
||||||
timestamp: params.timestamp, // 必填,生成签名的时间戳
|
|
||||||
nonceStr: params.nonceStr, // 必填,生成签名的随机串
|
|
||||||
signature: params.signature, // 必填,签名
|
|
||||||
jsApiList: params.jsApiList || [
|
|
||||||
'openUserProfile',
|
|
||||||
'openEnterpriseChat',
|
|
||||||
'getContext',
|
|
||||||
'getCurExternalContact',
|
|
||||||
'openExistedChatWithMsg'
|
|
||||||
] // 必填,需要使用的JS接口列表
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加企业微信联系人
|
|
||||||
* @param {Object} params - 参数
|
|
||||||
* @param {string} params.userId - 用户ID
|
|
||||||
* @param {Function} success - 成功回调
|
|
||||||
* @param {Function} fail - 失败回调
|
|
||||||
*/
|
|
||||||
this.addContact = function (params, success, fail) {
|
|
||||||
if (!this.wxwork) {
|
|
||||||
console.error('企业微信JS-SDK未初始化');
|
|
||||||
if (fail) fail('企业微信JS-SDK未初始化');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.wxwork.ready(() => {
|
|
||||||
this.wxwork.invoke('openUserProfile', {
|
|
||||||
type: 'external', // 外部联系人
|
|
||||||
userId: params.userId // 用户ID
|
|
||||||
}, (res) => {
|
|
||||||
if (res.err_msg === 'openUserProfile:ok') {
|
|
||||||
if (success) success(res);
|
|
||||||
} else {
|
|
||||||
console.error('打开用户资料失败:', res);
|
|
||||||
if (fail) fail(res.err_msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开企业微信客服会话
|
|
||||||
* @param {Object} params - 参数
|
|
||||||
* @param {string} params.corpId - 企业ID
|
|
||||||
* @param {string} params.url - 客服URL
|
|
||||||
* @param {string} params.name - 会话名称
|
|
||||||
* @param {Function} success - 成功回调
|
|
||||||
* @param {Function} fail - 失败回调
|
|
||||||
*/
|
|
||||||
this.openCustomerService = function (params, success, fail) {
|
|
||||||
if (!this.wxwork) {
|
|
||||||
console.error('企业微信JS-SDK未初始化');
|
|
||||||
if (fail) fail('企业微信JS-SDK未初始化');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.wxwork.ready(() => {
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
if (typeof wx !== 'undefined' && wx.openCustomerServiceChat) {
|
|
||||||
// 微信小程序环境
|
|
||||||
wx.openCustomerServiceChat({
|
|
||||||
extInfo: {
|
|
||||||
url: params.url
|
|
||||||
},
|
|
||||||
corpId: params.corpId,
|
|
||||||
showMessageCard: true,
|
|
||||||
sendMessageTitle: params.sendMessageTitle || '',
|
|
||||||
sendMessagePath: params.sendMessagePath || '',
|
|
||||||
sendMessageImg: params.sendMessageImg || ''
|
|
||||||
});
|
|
||||||
if (success) success();
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
// #ifdef H5
|
|
||||||
else if (typeof WWOpenData !== 'undefined') {
|
|
||||||
// H5环境
|
|
||||||
window.location.href = params.url;
|
|
||||||
if (success) success();
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
else {
|
|
||||||
// 直接跳转链接
|
|
||||||
window.location.href = params.url;
|
|
||||||
if (success) success();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成企业微信活码链接
|
|
||||||
* @param {Object} params - 参数
|
|
||||||
* @param {string} params.configId - 活码配置ID
|
|
||||||
* @param {string} params.userId - 用户ID
|
|
||||||
* @returns {string} 活码链接
|
|
||||||
*/
|
|
||||||
this.generateContactUrl = function (params) {
|
|
||||||
// 企业微信活码链接格式
|
|
||||||
const baseUrl = 'https://work.weixin.qq.com/kfid';
|
|
||||||
if (params.configId) {
|
|
||||||
return `${baseUrl}/${params.configId}`;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查环境是否支持企业微信
|
|
||||||
* @returns {boolean} 是否支持
|
|
||||||
*/
|
|
||||||
this.isSupported = function () {
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
return typeof wx !== 'undefined' && wx.openCustomerServiceChat;
|
|
||||||
// #endif
|
|
||||||
// #ifdef H5
|
|
||||||
return typeof WWOpenData !== 'undefined' || /wxwork/i.test(navigator.userAgent);
|
|
||||||
// #endif
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前环境信息
|
|
||||||
* @returns {Object} 环境信息
|
|
||||||
*/
|
|
||||||
this.getEnvironment = function () {
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
return {
|
|
||||||
platform: 'miniprogram',
|
|
||||||
isWxWork: false,
|
|
||||||
supportContact: typeof wx !== 'undefined' && wx.openCustomerServiceChat
|
|
||||||
};
|
|
||||||
// #endif
|
|
||||||
// #ifdef H5
|
|
||||||
const isWxWork = /wxwork/i.test(navigator.userAgent);
|
|
||||||
return {
|
|
||||||
platform: 'h5',
|
|
||||||
isWxWork: isWxWork,
|
|
||||||
supportContact: isWxWork || typeof WWOpenData !== 'undefined'
|
|
||||||
};
|
|
||||||
// #endif
|
|
||||||
return {
|
|
||||||
platform: 'unknown',
|
|
||||||
isWxWork: false,
|
|
||||||
supportContact: false
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
WxWork
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
638
components/common-payment/common-payment - 副本.vue
Normal file
638
components/common-payment/common-payment - 副本.vue
Normal file
@@ -0,0 +1,638 @@
|
|||||||
|
<template>
|
||||||
|
<view class="order-container" :class="{ 'safe-area': isIphoneX }">
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<view class="payment-navbar" :style="{ 'padding-top': menuButtonBounding.top + 'px', height: menuButtonBounding.height + 'px' }">
|
||||||
|
<view class="nav-wrap">
|
||||||
|
<text class="iconfont icon-back_light" @click="back"></text>
|
||||||
|
<view class="navbar-title">确认订单</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="payment-navbar-block" :style="{ height: menuButtonBounding.bottom + 'px' }"></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
<scroll-view scroll-y="true" class="order-scroll-container">
|
||||||
|
<view class="payment-navbar-block"></view>
|
||||||
|
<template v-if="paymentData">
|
||||||
|
<template v-if="paymentData.is_virtual">
|
||||||
|
<!-- 虚拟商品联系方式 -->
|
||||||
|
<view class="mobile-wrap">
|
||||||
|
<view class="tips color-base-text">
|
||||||
|
<text class="iconfont icongantanhao"></text>
|
||||||
|
购买虚拟类商品需填写手机号,方便商家与您联系
|
||||||
|
</view>
|
||||||
|
<view class="form-group">
|
||||||
|
<text class="icon">
|
||||||
|
<image :src="$util.img('public/uniapp/order/icon-mobile.png')" mode="widthFix"></image>
|
||||||
|
</text>
|
||||||
|
<text class="text">手机号码</text>
|
||||||
|
<input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<!-- 配送方式 -->
|
||||||
|
<view class="delivery-mode" v-if="goodsData.delivery.express_type.length > 1">
|
||||||
|
<view class="action">
|
||||||
|
<view :class="{ active: item.name == orderCreateData.delivery.delivery_type }" v-for="(item, index) in goodsData.delivery.express_type" :key="index" @click="selectDeliveryType(item)">
|
||||||
|
{{ item.title }}
|
||||||
|
<!-- 外圆角 -->
|
||||||
|
<view class="out-radio"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'express'">
|
||||||
|
<view class="info-wrap" v-if="memberAddress" @click="selectAddress">
|
||||||
|
<view class="content">
|
||||||
|
<text class="name">{{ memberAddress.name ? memberAddress.name : '' }}</text>
|
||||||
|
<text class="mobile">{{ memberAddress.mobile ? memberAddress.mobile : '' }}</text>
|
||||||
|
<view class="desc-wrap">
|
||||||
|
{{ memberAddress.full_address ? memberAddress.full_address : '' }}
|
||||||
|
{{ memberAddress.address ? memberAddress.address : '' }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<text class="cell-more iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
|
<view class="empty-wrap" v-else @click="selectAddress">
|
||||||
|
<view class="info">请设置收货地址</view>
|
||||||
|
<view class="cell-more">
|
||||||
|
<view class="iconfont icon-right"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'local'">
|
||||||
|
<view v-if="localMemberAddress">
|
||||||
|
<block v-if="storeList && Object.keys(storeList).length > 1">
|
||||||
|
<view class="local-delivery-store" v-if="storeInfo" @click="openPopup('deliveryPopup')">
|
||||||
|
<view class="info">
|
||||||
|
由
|
||||||
|
<text class="store-name">{{ storeInfo.store_name }}</text>
|
||||||
|
提供配送
|
||||||
|
</view>
|
||||||
|
<view class="cell-more">
|
||||||
|
<text>点击切换</text>
|
||||||
|
<text class="iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="local-delivery-store">
|
||||||
|
<view class="info">
|
||||||
|
<text class="store-name">您的附近没有可配送的门店,请选择其他配送方式</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<view class="info-wrap local" @click="selectAddress">
|
||||||
|
<view class="content">
|
||||||
|
<text class="name">{{ localMemberAddress.name ? localMemberAddress.name : '' }}
|
||||||
|
</text>
|
||||||
|
<text class="mobile">{{ localMemberAddress.mobile ? localMemberAddress.mobile : '' }}
|
||||||
|
</text>
|
||||||
|
<view class="desc-wrap">
|
||||||
|
{{ localMemberAddress.full_address ? localMemberAddress.full_address : '' }}
|
||||||
|
{{ localMemberAddress.address ? localMemberAddress.address : '' }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<text class="cell-more iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
|
<view class="local-box" v-if="calculateGoodsData.config.local && calculateGoodsData.delivery.local.info.time_is_open == 1">
|
||||||
|
<view class="pick-block" @click="localtime('')">
|
||||||
|
<view class="title font-size-base">送达时间</view>
|
||||||
|
<view class="time-picker">
|
||||||
|
<text :class="{ 'color-tip': !deliveryTime }">{{ deliveryTime ? deliveryTime : '请选择送达时间' }}</text>
|
||||||
|
<text class="iconfont icon-right cell-more"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="empty-wrap" v-else @click="selectAddress">
|
||||||
|
<view class="info">请设置收货地址</view>
|
||||||
|
<view class="cell-more">
|
||||||
|
<view class="iconfont icon-right"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 门店信息 -->
|
||||||
|
<view class="store-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'store'">
|
||||||
|
<block v-if="storeInfo">
|
||||||
|
<view @click="openPopup('deliveryPopup')" class="store-info">
|
||||||
|
<view class="store-address-info">
|
||||||
|
<view class="info-wrap">
|
||||||
|
<view class="title">
|
||||||
|
<text>{{ storeInfo.store_name }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="store-detail">
|
||||||
|
<view v-if="storeInfo.open_date">营业时间:{{ storeInfo.open_date }}</view>
|
||||||
|
<view class="address">{{ storeInfo.full_address }} {{ storeInfo.address }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="cell-more iconfont icon-right" v-if="storeList && Object.keys(storeList).length > 1"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="mobile-wrap store-mobile" v-if="orderCreateData.member_address">
|
||||||
|
<view class="form-group">
|
||||||
|
<text class="text">姓名</text>
|
||||||
|
<input type="text" placeholder-class="color-tip placeholder" class="input" disabled v-model="orderCreateData.member_address.name" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="mobile-wrap store-mobile" v-if="orderCreateData.member_address">
|
||||||
|
<view class="form-group">
|
||||||
|
<text class="text">预留手机</text>
|
||||||
|
<input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="store-time" @click="storetime('')">
|
||||||
|
<view class="left">提货时间</view>
|
||||||
|
<view class="right">
|
||||||
|
{{ deliveryTime }}
|
||||||
|
<text class="iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<view v-else class="empty">当前无自提门店,请选择其它配送方式</view>
|
||||||
|
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 店铺 -->
|
||||||
|
<view class="site-wrap order-goods" v-if="calculateGoodsData">
|
||||||
|
<view class="site-header">
|
||||||
|
<view class="iconfont icon-dianpu"></view>
|
||||||
|
<text class="site-name">门店</text>
|
||||||
|
</view>
|
||||||
|
<view class="site-body">
|
||||||
|
<!-- 商品 -->
|
||||||
|
<view class="goods-item" v-for="(goodsItem, goodsIndex) in calculateGoodsData.goods_list" :key="goodsIndex">
|
||||||
|
<view class="goods-wrap">
|
||||||
|
<view class="goods-img" @click="$util.redirectTo('/pages/goods/detail', { goods_id: goodsItem.goods_id })">
|
||||||
|
<image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" mode="aspectFill"/>
|
||||||
|
</view>
|
||||||
|
<view class="goods-info">
|
||||||
|
<view class="top-wrap">
|
||||||
|
<view @click="$util.redirectTo('/pages/goods/detail', { goods_id: goodsItem.goods_id })" class="goods-name">{{ goodsItem.sku_name }}</view>
|
||||||
|
<view class="sku" v-if="goodsItem.sku_spec_format">
|
||||||
|
<view class="goods-spec">
|
||||||
|
<block v-for="(x, i) in goodsItem.sku_spec_format" :key="i">
|
||||||
|
<view>{{ x.spec_value_name }}</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<block v-if="goodsItem.is_virtual == 0">
|
||||||
|
<view class="error-tips" v-if="orderCreateData.delivery &&
|
||||||
|
orderCreateData.delivery.delivery_type &&
|
||||||
|
goodsItem.support_trade_type &&
|
||||||
|
goodsItem.support_trade_type.indexOf(orderCreateData.delivery.delivery_type) == -1
|
||||||
|
">
|
||||||
|
<text class="iconfont icon-gantanhao"></text>
|
||||||
|
<text>该商品不支持{{ orderCreateData.delivery.delivery_type_name }}</text>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<view class="error-tips" v-if="goodsItem.error && goodsItem.error.message">
|
||||||
|
<text class="iconfont icon-gantanhao"></text>
|
||||||
|
<text>{{ goodsItem.error.message }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="goods-sub-section">
|
||||||
|
<view class="color-base-text">
|
||||||
|
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="goods-price price-style large">{{ parseFloat(goodsItem.price).toFixed(2).split('.')[0] }}</text>
|
||||||
|
<text class="unit price-style small">.{{ parseFloat(goodsItem.price).toFixed(2).split('.')[1] }}</text>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<text class="font-size-tag">x</text>
|
||||||
|
<text class="font-size-base">{{ goodsItem.num }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="member-goods-card order-cell" v-if="calculateGoodsData.goods_list[goodsIndex].member_card_list" @click="selectMemberGoodsCard(goodsIndex)">
|
||||||
|
<text class="tit">次卡抵扣</text>
|
||||||
|
<view class="box text-overflow">
|
||||||
|
<block v-if="calculateGoodsData.goods_list[goodsIndex].card_promotion_money">
|
||||||
|
<text class="text">次卡抵扣{{ calculateGoodsData.goods_list[goodsIndex].card_use_num }}张/{{ calculateGoodsData.goods_list[goodsIndex].card_use_num }}次</text>
|
||||||
|
<text class="price-font">-¥{{ calculateGoodsData.goods_list[goodsIndex].card_promotion_money | moneyFormat }}</text>
|
||||||
|
</block>
|
||||||
|
<text class="color-tip" v-else>请选择次卡</text>
|
||||||
|
</view>
|
||||||
|
<text class="iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
|
<view class="goods-form" v-if="goodsData.goods_list[goodsIndex].goods_form" @click="editForm(goodsIndex)">
|
||||||
|
<ns-form :data="goodsData.goods_list[goodsIndex].goods_form.json_data" ref="goodsForm" :custom-attr="{ sku_id: goodsItem.sku_id, form_id: goodsData.goods_list[goodsIndex].goods_form.id }"/>
|
||||||
|
<text class="cell-more iconfont icon-right"></text>
|
||||||
|
<view class="shade"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="site-wrap buyer-message">
|
||||||
|
<view class="order-cell">
|
||||||
|
<text class="tit">买家留言</text>
|
||||||
|
<view class="box text-overflow " @click="openPopup('buyerMessagePopup')">
|
||||||
|
<text v-if="orderCreateData.buyer_message">{{ orderCreateData.buyer_message }}</text>
|
||||||
|
<text class="color-sub" v-else>无留言</text>
|
||||||
|
</view>
|
||||||
|
<text class="iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="paymentData.system_form" class="system-form-wrap">
|
||||||
|
<view class="order-cell">
|
||||||
|
<text class="tit">{{ paymentData.system_form.form_name }}</text>
|
||||||
|
</view>
|
||||||
|
<ns-form :data="paymentData.system_form.json_data" ref="form"/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="site-wrap" v-if="calculateGoodsData || promotionInfo || (calculateGoodsData && calculateGoodsData.max_usable_point > 0) || goodsData.invoice">
|
||||||
|
<view class="site-footer">
|
||||||
|
<view class="order-cell coupon" v-if="modules.indexOf('coupon') != -1">
|
||||||
|
<text class="tit">优惠券</text>
|
||||||
|
<view class="box text-overflow" @click="openPopup('couponPopup')">
|
||||||
|
<template v-if="orderCreateData.coupon && orderCreateData.coupon.coupon_id">
|
||||||
|
<text>已使用优惠券,优惠</text>
|
||||||
|
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money price-font">{{ (calculateData && calculateData.coupon_money ? calculateData.coupon_money : 0) | moneyFormat }}</text>
|
||||||
|
</template>
|
||||||
|
<text v-else>不使用优惠券</text>
|
||||||
|
</view>
|
||||||
|
<text class="iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
|
<view class="order-cell" v-if="promotionInfo">
|
||||||
|
<text class="tit">活动优惠</text>
|
||||||
|
<view class="box text-overflow" @click="openPopup('promotionPopup')">
|
||||||
|
<text>{{ promotionInfo.title }}</text>
|
||||||
|
</view>
|
||||||
|
<text class="iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
|
<view class="order-cell point" v-if="calculateGoodsData && calculateGoodsData.max_usable_point > 0">
|
||||||
|
<text class="tit">
|
||||||
|
<text>使用{{ parseInt(calculateGoodsData.max_usable_point) }}积分可抵扣</text>
|
||||||
|
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money price-font">{{ calculateData.point_money | moneyFormat }}</text>
|
||||||
|
</text>
|
||||||
|
<view class="box"></view>
|
||||||
|
<ns-switch class="balance-switch" @change="usePoint" :checked="orderCreateData.is_point == 1"/>
|
||||||
|
</view>
|
||||||
|
<view class="order-cell order-invoice-cell" v-if="goodsData.invoice.invoice_status == 1">
|
||||||
|
<text class="tit">发票</text>
|
||||||
|
<view class="box text-overflow" @click="openPopup('invoicePopup')">
|
||||||
|
<text v-if="orderCreateData.is_invoice == 1">{{ orderCreateData.invoice_type == 1 ? '纸质' : '电子' }}发票({{ orderCreateData.invoice_content }})</text>
|
||||||
|
<text v-else>无需发票</text>
|
||||||
|
</view>
|
||||||
|
<text class="iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="site-wrap box member-card-wrap" v-if="paymentData.recommend_member_card && Object.keys(paymentData.recommend_member_card).length > 0">
|
||||||
|
<view class="head" @click="selectMemberCard">
|
||||||
|
<text class="iconfont icon-huiyuan"></text>
|
||||||
|
<view class="info">
|
||||||
|
开通{{ paymentData.recommend_member_card.level_name }}
|
||||||
|
<text>本单预计可省</text>
|
||||||
|
<text class="price-color">{{ paymentData.recommend_member_card.discount_money | moneyFormat }}</text>
|
||||||
|
<text>元</text>
|
||||||
|
</view>
|
||||||
|
<text class="iconfont" :class="orderCreateData.is_open_card == 1 ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></text>
|
||||||
|
</view>
|
||||||
|
<view class="body" v-if="orderCreateData.is_open_card">
|
||||||
|
<view class="item" :class="{ 'active color-base-border': item.key == orderCreateData.member_card_unit }" v-for="(item, index) in cardChargeType" :key="index" @click="selectMembercardUnit(item.key)">
|
||||||
|
<view class="title">{{ item.title }}</view>
|
||||||
|
<view class="price price-font">{{ $lang('common.currencySymbol') }}{{ parseFloat(item.value) }}/{{ item.unit }}</view>
|
||||||
|
<text class="iconfont icon-icon color-base-text price-font identify" v-if="item.key == orderCreateData.member_card_unit"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单金额 -->
|
||||||
|
<template v-if="calculateData">
|
||||||
|
<view class="order-money">
|
||||||
|
<view class="order-cell">
|
||||||
|
<text class="tit">商品金额</text>
|
||||||
|
<view class="box">
|
||||||
|
<text class="unit color-title price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money color-title price-font">{{ calculateData.goods_money | moneyFormat }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="order-cell" v-if="calculateData.is_virtual == 0 && calculateData.delivery_money > 0">
|
||||||
|
<text class="tit">运费</text>
|
||||||
|
<view class="box color-base-text">
|
||||||
|
<text class="operator">+</text>
|
||||||
|
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money price-font">{{ calculateData.delivery_money | moneyFormat }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_money > 0">
|
||||||
|
<text class="tit">
|
||||||
|
<text>税费</text>
|
||||||
|
<text class="color-base-text font-bold price-font">({{ goodsData.invoice.invoice_rate }}%)</text>
|
||||||
|
</text>
|
||||||
|
<view class="box color-base-text">
|
||||||
|
<text class="operator">+</text>
|
||||||
|
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money price-font">{{ calculateData.invoice_money | moneyFormat }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_delivery_money > 0">
|
||||||
|
<text class="tit">发票邮寄费</text>
|
||||||
|
<view class="box color-base-text">
|
||||||
|
<text class="operator">+</text>
|
||||||
|
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money price-font">{{ calculateData.invoice_delivery_money | moneyFormat }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="order-cell" v-if="calculateData.promotion_money > 0">
|
||||||
|
<text class="tit">优惠</text>
|
||||||
|
<view class="box color-base-text">
|
||||||
|
<text class="operator">-</text>
|
||||||
|
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money price-font">{{ calculateData.promotion_money | moneyFormat }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="order-cell" v-if="calculateData.coupon_money">
|
||||||
|
<text class="tit">优惠券</text>
|
||||||
|
<view class="box color-base-text">
|
||||||
|
<text class="operator">-</text>
|
||||||
|
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money price-font">{{ calculateData.coupon_money | moneyFormat }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="order-cell" v-if="calculateData.point_money > 0">
|
||||||
|
<text class="tit">积分抵扣</text>
|
||||||
|
<view class="box color-base-text">
|
||||||
|
<text class="operator">-</text>
|
||||||
|
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money price-font">{{ calculateData.point_money | moneyFormat }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="order-cell" v-if="calculateData.member_card_money > 0">
|
||||||
|
<text class="tit">会员卡</text>
|
||||||
|
<view class="box color-base-text">
|
||||||
|
<text class="operator">+</text>
|
||||||
|
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money price-font">{{ calculateData.member_card_money | moneyFormat }}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="transactionAgreement.title && transactionAgreement.content" class="agreement">购买前请先阅读<text @click="$refs.agreementPopup.open()">《{{ transactionAgreement.title }}》</text>,下单即代表同意该协议</view>
|
||||||
|
|
||||||
|
<view class="order-submit bottom-safe-area">
|
||||||
|
<view class="order-settlement-info">
|
||||||
|
<text class="font-size-base color-tip margin-right">共{{ calculateData.goods_num }}件</text>
|
||||||
|
<text class="font-size-base">合计:</text>
|
||||||
|
<text class=" unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class=" money price-font">{{ parseFloat(calculateData.pay_money).toFixed(2).split('.')[0] }}</text>
|
||||||
|
<text class=" unit price-font">.{{ parseFloat(calculateData.pay_money).toFixed(2).split('.')[1] }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="submit-btn">
|
||||||
|
<button type="primary" class="mini" size="mini" @click="create()" v-if="!surplusStartMoney()">提交订单</button>
|
||||||
|
<button v-else class="no-submit mini" size="mini">差{{ surplusStartMoney() | moneyFormat }}起送</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="order-submit-block"></view>
|
||||||
|
|
||||||
|
<payment ref="choosePaymentPopup" @close="payClose" v-if="calculateData"></payment>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 活动优惠弹窗 -->
|
||||||
|
<uni-popup ref="promotionPopup" type="bottom" v-if="promotionInfo">
|
||||||
|
<view class="promotion-popup popup">
|
||||||
|
<view class="popup-header">
|
||||||
|
<text class="tit">活动优惠</text>
|
||||||
|
<text class="iconfont icon-close" @click="closePopup('promotionPopup')"></text>
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
||||||
|
<view class="order-cell" style="align-items: baseline;">
|
||||||
|
<view class="tit">
|
||||||
|
<text class="promotion-mark ns-gradient-promotionpages-payment">{{ promotionInfo.title }}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
<view class="promotion-content">
|
||||||
|
<view class="tit tit-content" style="white-space: pre-line;" v-html="promotionInfo.content"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="popup-footer" :class="{ 'bottom-safe-area': isIphoneX }">
|
||||||
|
<view class="confirm-btn color-base-bg" @click="closePopup('promotionPopup')">确定</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
|
||||||
|
<!-- 门店列表弹窗 -->
|
||||||
|
<uni-popup ref="deliveryPopup" type="bottom">
|
||||||
|
<view class="delivery-popup popup">
|
||||||
|
<view class="popup-header">
|
||||||
|
<text class="tit">已为您甄选出附近所有相关门店</text>
|
||||||
|
<text class="iconfont icon-close" @click="closePopup('deliveryPopup')"></text>
|
||||||
|
</view>
|
||||||
|
<view class="popup-body store-popup" :class="{ 'safe-area': isIphoneX }">
|
||||||
|
|
||||||
|
<mescroll-uni @getData="getStore" ref="mescroll" top="50px">
|
||||||
|
<block slot="list">
|
||||||
|
<view class="delivery-content">
|
||||||
|
<block v-if="storeData">
|
||||||
|
<view class="item-wrap" v-for="(item, index) in storeData" :key="index" @click="selectPickupPoint(item)">
|
||||||
|
<view class="detail">
|
||||||
|
<view class="name" :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''">
|
||||||
|
<text>{{ item.store_name }}</text>
|
||||||
|
<text v-if="item.distance">({{ item.distance }}km)</text>
|
||||||
|
</view>
|
||||||
|
<view class="info">
|
||||||
|
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">营业时间:{{ item.open_date }}</view>
|
||||||
|
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">地址:{{ item.full_address }}{{ item.address }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="icon" v-if="item.store_id == orderCreateData.delivery.store_id">
|
||||||
|
<text class="iconfont icon-yuan_checked color-base-text"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<view v-else class="empty-wrap">
|
||||||
|
<ns-empty text="所选择收货地址附近没有可以自提的门店" :isIndex="false"></ns-empty>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</block>
|
||||||
|
</mescroll-uni>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
|
||||||
|
<!-- 留言弹窗 -->
|
||||||
|
<uni-popup ref="buyerMessagePopup" type="bottom">
|
||||||
|
<view style="height: auto;" class="buyermessag-popup popup" @touchmove.prevent.stop>
|
||||||
|
<view class="popup-header">
|
||||||
|
<text class="tit">买家留言</text>
|
||||||
|
<text class="iconfont icon-close" @click="closePopup('buyerMessagePopup')"></text>
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
||||||
|
<view>
|
||||||
|
<view class="buyermessag-cell">
|
||||||
|
<view class="buyermessag-form-group">
|
||||||
|
<textarea type="text" maxlength="100" placeholder="留言前建议先与商家协调一致" placeholder-class="color-tip" v-model="orderCreateData.buyer_message"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="popup-footer" @click="saveBuyerMessage" :class="{ 'bottom-safe-area': isIphoneX }">
|
||||||
|
<view class="confirm-btn color-base-bg">确定</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
|
||||||
|
<!-- 优惠券弹窗 -->
|
||||||
|
<uni-popup ref="couponPopup" type="bottom" v-if="calculateGoodsData" :mask-click="false">
|
||||||
|
<view class="coupon-popup popup" @touchmove.prevent.stop>
|
||||||
|
<view class="popup-header">
|
||||||
|
<text class="tit">优惠券</text>
|
||||||
|
<text class="iconfont icon-close" @click="closePopup('couponPopup')"></text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
||||||
|
<view v-if="coupon_list.length > 0">
|
||||||
|
<view class="coupon-item" v-for="(couponItem, couponIndex) in coupon_list" :key="couponIndex" @click="selectCoupon(couponItem)">
|
||||||
|
<view class="coupon-info" :style="{ backgroundColor: 'var(--main-color-shallow)' }">
|
||||||
|
<view class="info-wrap">
|
||||||
|
<image class="coupon-line" mode="heightFix" :src="$util.img('public/uniapp/coupon/coupon_line.png')"/>
|
||||||
|
<view class="coupon-money">
|
||||||
|
<template v-if="couponItem.type == 'divideticket'">
|
||||||
|
<text class="unit">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money">{{ parseFloat(couponItem.money) }}</text>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="couponItem.type == 'reward'">
|
||||||
|
<text class="unit">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="money">{{ parseFloat(couponItem.money) }}</text>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="couponItem.type == 'discount'">
|
||||||
|
<text class="money">{{ parseFloat(couponItem.discount) }}</text>
|
||||||
|
<text class="unit">折</text>
|
||||||
|
</template>
|
||||||
|
<view class="at-least">
|
||||||
|
<template v-if="couponItem.at_least > 0">
|
||||||
|
满{{ couponItem.at_least }}可用
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
无门槛
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="desc-wrap">
|
||||||
|
<view class="coupon-name">{{ couponItem.coupon_name }}</view>
|
||||||
|
<view v-if="couponItem.type == 'discount' && couponItem.discount_limit > 0" class="limit">最多可抵¥{{ couponItem.discount_limit }}</view>
|
||||||
|
<view class="time font-size-goods-tag">有效期:{{ couponItem.end_time ? $util.timeStampTurnTime(couponItem.end_time) : '长期有效' }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="iconfont" :class="orderCreateData.coupon.coupon_id == couponItem.coupon_id ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="coupon-empty">暂无可用的优惠券</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<view class="popup-footer" :class="{ 'bottom-safe-area': isIphoneX }">
|
||||||
|
<view class="confirm-btn color-base-bg" @click="useCpopon">确定</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
|
||||||
|
<!-- 交易协议 -->
|
||||||
|
<view @touchmove.prevent>
|
||||||
|
<uni-popup ref="agreementPopup" type="center" :maskClick="false">
|
||||||
|
<view class="agreement-conten-box">
|
||||||
|
<view class="close">
|
||||||
|
<text class="iconfont icon-close" @click="$refs.agreementPopup.close()"></text>
|
||||||
|
</view>
|
||||||
|
<view class="title">{{ transactionAgreement.title }}</view>
|
||||||
|
<view class="con">
|
||||||
|
<scroll-view scroll-y="true" class="con">
|
||||||
|
<rich-text :nodes="transactionAgreement.content"></rich-text>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 表单修改弹窗 -->
|
||||||
|
<uni-popup ref="editFormPopup" type="bottom">
|
||||||
|
<view style="height: auto;" class="form-popup popup" @touchmove.prevent.stop>
|
||||||
|
<view class="popup-header">
|
||||||
|
<text class="tit">买家信息</text>
|
||||||
|
<text class="iconfont icon-close" @click="$refs.editFormPopup.close()"></text>
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
||||||
|
<ns-form v-if="tempFormData" :data="tempFormData.json_data" ref="tempForm"></ns-form>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="popup-footer" @click="saveForm" :class="{ 'bottom-safe-area': isIphoneX }">
|
||||||
|
<view class="confirm-btn color-base-bg">确定</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
|
||||||
|
<uni-popup ref="memberGoodsCardPopup" type="bottom">
|
||||||
|
<view class="member-card-popup popup" @touchmove.prevent.stop>
|
||||||
|
<view class="popup-header">
|
||||||
|
<text class="tit">选择次卡</text>
|
||||||
|
<text class="iconfont icon-close" @click="$refs.memberGoodsCardPopup.close()"></text>
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
||||||
|
<view v-for="(item, index) in selectGoodsCard.cardList" class="card-item" @click="selectGoodsCard.click(item.item_id)">
|
||||||
|
<view class="content">
|
||||||
|
<view class="title">{{ item.goods_name }}</view>
|
||||||
|
<view class="info">
|
||||||
|
<text v-if="item.card_type == 'timecard'">不限次数</text>
|
||||||
|
<text v-if="item.card_type == 'oncecard'">剩余{{ item.num - item.use_num }}次</text>
|
||||||
|
<text v-if="item.card_type == 'commoncard'">剩余{{ item.total_num - item.total_use_num }}次</text>
|
||||||
|
<text>|</text>
|
||||||
|
<text>{{ item.end_time ? $util.timeStampTurnTime(item.end_time) : '长期有效' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="iconfont" :class="selectGoodsCard.itemId == item.item_id ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="popup-footer" @click="saveMemberGoodsCard" :class="{ 'bottom-safe-area': isIphoneX }">
|
||||||
|
<view class="confirm-btn color-base-bg">确定</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
</template>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<!-- 门店自提时间 -->
|
||||||
|
<ns-select-time @selectTime="selectPickupTime" ref="timePopup"></ns-select-time>
|
||||||
|
|
||||||
|
<ns-login ref="login"></ns-login>
|
||||||
|
<loading-cover ref="loadingCover"></loading-cover>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import payment from './payment.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'common-payment',
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
api: Object,
|
||||||
|
createDataKey: String
|
||||||
|
},
|
||||||
|
mixins: [payment]
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '@/common/css/order_parment.scss';
|
||||||
|
|
||||||
|
.order-cell .promotion-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -64,27 +64,30 @@
|
|||||||
|
|
||||||
<view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'local'">
|
<view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'local'">
|
||||||
<view v-if="localMemberAddress">
|
<view v-if="localMemberAddress">
|
||||||
<block v-if="storeList && Object.keys(storeList).length > 0">
|
<block v-if="storeList && Object.keys(storeList).length > 1">
|
||||||
<view class="local-delivery-store">
|
<view class="local-delivery-store" v-if="storeInfo" @click="openPopup('deliveryPopup')">
|
||||||
<view class="info" v-if="storeInfo">
|
<view class="info">
|
||||||
由
|
由
|
||||||
<text class="store-name">{{ storeInfo.store_name }}</text>
|
<text class="store-name">{{ storeInfo.store_name }}</text>
|
||||||
提供配送
|
提供配送
|
||||||
<view>营业时间:{{ storeInfo.open_date }}</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="info" v-else>
|
<view class="cell-more">
|
||||||
<text class="store-name">超出配送范围,请选择其他门店</text>
|
|
||||||
</view>
|
|
||||||
<view class="cell-more" v-if="Object.keys(storeList).length > 1" @click="openPopup('deliveryPopup')">
|
|
||||||
<text>点击切换</text>
|
<text>点击切换</text>
|
||||||
<text class="iconfont icon-right"></text>
|
<text class="iconfont icon-right"></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view v-else class="local-delivery-store">
|
||||||
|
<view class="info">
|
||||||
|
<text class="store-name">您的附近没有可配送的门店,请选择其他配送方式</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<view class="info-wrap local" @click="selectAddress">
|
<view class="info-wrap local" @click="selectAddress">
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<text class="name">{{ localMemberAddress.name ? localMemberAddress.name : '' }}</text>
|
<text class="name">{{ localMemberAddress.name ? localMemberAddress.name : '' }}
|
||||||
<text class="mobile">{{ localMemberAddress.mobile ? localMemberAddress.mobile : '' }}</text>
|
</text>
|
||||||
|
<text class="mobile">{{ localMemberAddress.mobile ? localMemberAddress.mobile : '' }}
|
||||||
|
</text>
|
||||||
<view class="desc-wrap">
|
<view class="desc-wrap">
|
||||||
{{ localMemberAddress.full_address ? localMemberAddress.full_address : '' }}
|
{{ localMemberAddress.full_address ? localMemberAddress.full_address : '' }}
|
||||||
{{ localMemberAddress.address ? localMemberAddress.address : '' }}
|
{{ localMemberAddress.address ? localMemberAddress.address : '' }}
|
||||||
@@ -122,9 +125,9 @@
|
|||||||
<text>{{ storeInfo.store_name }}</text>
|
<text>{{ storeInfo.store_name }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="store-detail">
|
<view class="store-detail">
|
||||||
<view class="close-desc" v-if="storeInfo.status == 0 && storeInfo.close_desc">{{ storeInfo.close_desc }}</view>
|
|
||||||
<view v-if="storeInfo.open_date">营业时间:{{ storeInfo.open_date }}</view>
|
<view v-if="storeInfo.open_date">营业时间:{{ storeInfo.open_date }}</view>
|
||||||
<view class="address">{{ storeInfo.full_address }} {{ storeInfo.address }}</view>
|
<view class="address">{{ storeInfo.full_address }} {{ storeInfo.address }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="cell-more iconfont icon-right" v-if="storeList && Object.keys(storeList).length > 1"></view>
|
<view class="cell-more iconfont icon-right" v-if="storeList && Object.keys(storeList).length > 1"></view>
|
||||||
@@ -142,14 +145,7 @@
|
|||||||
<input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" />
|
<input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="store-time" v-if="goodsData.jielong_id">
|
<view class="store-time" @click="storetime('')">
|
||||||
<view class="left">提货时间</view>
|
|
||||||
<view class="right">
|
|
||||||
{{ $util.timeStampTurnTime(goodsData.jielong_info.take_start_time,'Y/m/d') }} ~ {{ $util.timeStampTurnTime(goodsData.jielong_info.take_end_time,'Y/m/d') }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="store-time" @click="storetime('')" v-else>
|
|
||||||
<view class="left">提货时间</view>
|
<view class="left">提货时间</view>
|
||||||
<view class="right">
|
<view class="right">
|
||||||
{{ deliveryTime }}
|
{{ deliveryTime }}
|
||||||
@@ -163,10 +159,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 店铺 -->
|
<!-- 店铺 -->
|
||||||
<view class="site-wrap order-goods" v-if="calculateGoodsData">
|
|
||||||
|
<view class="site-wrap order-goods" v-for="(calculateGoodsData, siteIndex) in shop_goods_list" :key="siteIndex">
|
||||||
|
<view class="site-header">
|
||||||
|
<view class="iconfont icon-dianpu"></view>
|
||||||
|
<text class="site-name">{{calculateGoodsData.site_name}}</text>
|
||||||
|
</view>
|
||||||
<view class="site-body">
|
<view class="site-body">
|
||||||
<!-- 商品 -->
|
<!-- 商品 -->
|
||||||
<view class="goods-item" v-for="(goodsItem, goodsIndex) in calculateGoodsData.goods_list" :key="goodsIndex">
|
<view class="goods-item" v-for="(goodsItem, goodsIndex) in goodsSpecFormat(calculateGoodsData.goods_list)" :key="goodsIndex">
|
||||||
<view class="goods-wrap">
|
<view class="goods-wrap">
|
||||||
<view class="goods-img" @click="$util.redirectTo('/pages/goods/detail', { goods_id: goodsItem.goods_id })">
|
<view class="goods-img" @click="$util.redirectTo('/pages/goods/detail', { goods_id: goodsItem.goods_id })">
|
||||||
<image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" mode="aspectFill"/>
|
<image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" mode="aspectFill"/>
|
||||||
@@ -209,17 +210,6 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="member-goods-card order-cell" v-if="calculateGoodsData.goods_list[goodsIndex].member_card_list" @click="selectMemberGoodsCard(goodsIndex)">
|
|
||||||
<text class="tit">次卡抵扣</text>
|
|
||||||
<view class="box text-overflow">
|
|
||||||
<block v-if="calculateGoodsData.goods_list[goodsIndex].card_promotion_money">
|
|
||||||
<text class="text">次卡抵扣{{ calculateGoodsData.goods_list[goodsIndex].card_use_num }}张/{{ calculateGoodsData.goods_list[goodsIndex].card_use_num }}次</text>
|
|
||||||
<text class="price-font">-¥{{ calculateGoodsData.goods_list[goodsIndex].card_promotion_money | moneyFormat }}</text>
|
|
||||||
</block>
|
|
||||||
<text class="color-tip" v-else>请选择次卡</text>
|
|
||||||
</view>
|
|
||||||
<text class="iconfont icon-right"></text>
|
|
||||||
</view>
|
|
||||||
<view class="goods-form" v-if="goodsData.goods_list[goodsIndex].goods_form" @click="editForm(goodsIndex)">
|
<view class="goods-form" v-if="goodsData.goods_list[goodsIndex].goods_form" @click="editForm(goodsIndex)">
|
||||||
<ns-form :data="goodsData.goods_list[goodsIndex].goods_form.json_data" ref="goodsForm" :custom-attr="{ sku_id: goodsItem.sku_id, form_id: goodsData.goods_list[goodsIndex].goods_form.id }"/>
|
<ns-form :data="goodsData.goods_list[goodsIndex].goods_form.json_data" ref="goodsForm" :custom-attr="{ sku_id: goodsItem.sku_id, form_id: goodsData.goods_list[goodsIndex].goods_form.id }"/>
|
||||||
<text class="cell-more iconfont icon-right"></text>
|
<text class="cell-more iconfont icon-right"></text>
|
||||||
@@ -227,18 +217,48 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
|
<view class="site-wrap buyer-message">
|
||||||
<view class="site-wrap buyer-message">
|
|
||||||
<view class="order-cell">
|
</view>
|
||||||
<text class="tit">买家留言</text>
|
|
||||||
<view class="box text-overflow " @click="openPopup('buyerMessagePopup')">
|
<view class="order-money" style="margin: 0;">
|
||||||
<text v-if="orderCreateData.buyer_message">{{ orderCreateData.buyer_message }}</text>
|
<view class="order-cell">
|
||||||
<text class="color-sub" v-else>无留言</text>
|
<text class="tit">买家留言</text>
|
||||||
|
<view class="box text-overflow " @click="openPopup('buyerMessagePopup')">
|
||||||
|
<text v-if="orderCreateData.buyer_message">{{ orderCreateData.buyer_message[calculateGoodsData.merch_id] }}</text>
|
||||||
|
<text class="color-sub" v-else>无留言</text>
|
||||||
|
</view>
|
||||||
|
<text class="iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
|
<view class="order-cell coupon" v-if="modules.indexOf('coupon') != -1">
|
||||||
|
<text class="tit">优惠券</text>
|
||||||
|
<view class="box text-overflow"@click="openSiteCoupon(calculateGoodsData.merch_id)">
|
||||||
|
<template v-if="orderCreateData.coupon[calculateGoodsData.merch_id].coupon_id">
|
||||||
|
<text class="money price-font" style="max-width: 100%;">已选择1张优惠券</text>
|
||||||
|
<!-- <text class="unit price-font">优惠</text>
|
||||||
|
<text class="money price-font">{{ (calculateData && calculateData.coupon_money ? calculateData.coupon_money : 0) | moneyFormat }}</text> -->
|
||||||
|
</template>
|
||||||
|
<text v-else>不使用优惠券</text>
|
||||||
|
</view>
|
||||||
|
<text class="iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="site-wrap buyer-message">
|
||||||
|
<view class="order-cell">
|
||||||
|
<view class="box shop-item">
|
||||||
|
<text class="color-tip goods-num">共{{ calculateGoodsData.goods_num }}件</text>
|
||||||
|
<text class="font-size-base">小计:</text>
|
||||||
|
<text class="color-base-text unit">{{ $lang('common.currencySymbol') }}</text>
|
||||||
|
<text class="color-base-text money">{{ calculateGoodsData.goods_money | moneyFormat }}</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<text class="iconfont icon-right"></text>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<view v-if="paymentData.system_form" class="system-form-wrap">
|
<view v-if="paymentData.system_form" class="system-form-wrap">
|
||||||
<view class="order-cell">
|
<view class="order-cell">
|
||||||
@@ -247,7 +267,7 @@
|
|||||||
<ns-form :data="paymentData.system_form.json_data" ref="form"/>
|
<ns-form :data="paymentData.system_form.json_data" ref="form"/>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="site-wrap" v-if="calculateGoodsData || promotionInfo || (calculateGoodsData && calculateGoodsData.max_usable_point > 0) || goodsData.invoice">
|
<!-- <view class="site-wrap" v-if="calculateGoodsData || promotionInfo || (calculateGoodsData && calculateGoodsData.max_usable_point > 0) || goodsData.invoice">
|
||||||
<view class="site-footer">
|
<view class="site-footer">
|
||||||
<view class="order-cell coupon" v-if="modules.indexOf('coupon') != -1">
|
<view class="order-cell coupon" v-if="modules.indexOf('coupon') != -1">
|
||||||
<text class="tit">优惠券</text>
|
<text class="tit">优惠券</text>
|
||||||
@@ -286,8 +306,8 @@
|
|||||||
<text class="iconfont icon-right"></text>
|
<text class="iconfont icon-right"></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view> -->
|
||||||
|
|
||||||
<view class="site-wrap box member-card-wrap" v-if="paymentData.recommend_member_card && Object.keys(paymentData.recommend_member_card).length > 0">
|
<view class="site-wrap box member-card-wrap" v-if="paymentData.recommend_member_card && Object.keys(paymentData.recommend_member_card).length > 0">
|
||||||
<view class="head" @click="selectMemberCard">
|
<view class="head" @click="selectMemberCard">
|
||||||
<text class="iconfont icon-huiyuan"></text>
|
<text class="iconfont icon-huiyuan"></text>
|
||||||
@@ -300,7 +320,7 @@
|
|||||||
<text class="iconfont" :class="orderCreateData.is_open_card == 1 ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></text>
|
<text class="iconfont" :class="orderCreateData.is_open_card == 1 ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="body" v-if="orderCreateData.is_open_card">
|
<view class="body" v-if="orderCreateData.is_open_card">
|
||||||
<view class="item" :class="{ 'active color-base-border': item.key == orderCreateData.member_card_unit }" v-for="(item, index) in cardChargeType" :key="index" @click="selectMemberCardUnit(item.key)">
|
<view class="item" :class="{ 'active color-base-border': item.key == orderCreateData.member_card_unit }" v-for="(item, index) in cardChargeType" :key="index" @click="selectMembercardUnit(item.key)">
|
||||||
<view class="title">{{ item.title }}</view>
|
<view class="title">{{ item.title }}</view>
|
||||||
<view class="price price-font">{{ $lang('common.currencySymbol') }}{{ parseFloat(item.value) }}/{{ item.unit }}</view>
|
<view class="price price-font">{{ $lang('common.currencySymbol') }}{{ parseFloat(item.value) }}/{{ item.unit }}</view>
|
||||||
<text class="iconfont icon-icon color-base-text price-font identify" v-if="item.key == orderCreateData.member_card_unit"></text>
|
<text class="iconfont icon-icon color-base-text price-font identify" v-if="item.key == orderCreateData.member_card_unit"></text>
|
||||||
@@ -326,7 +346,7 @@
|
|||||||
<text class="money price-font">{{ calculateData.delivery_money | moneyFormat }}</text>
|
<text class="money price-font">{{ calculateData.delivery_money | moneyFormat }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_money > 0">
|
<!-- <view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_money > 0">
|
||||||
<text class="tit">
|
<text class="tit">
|
||||||
<text>税费</text>
|
<text>税费</text>
|
||||||
<text class="color-base-text font-bold price-font">({{ goodsData.invoice.invoice_rate }}%)</text>
|
<text class="color-base-text font-bold price-font">({{ goodsData.invoice.invoice_rate }}%)</text>
|
||||||
@@ -336,15 +356,15 @@
|
|||||||
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
<text class="money price-font">{{ calculateData.invoice_money | moneyFormat }}</text>
|
<text class="money price-font">{{ calculateData.invoice_money | moneyFormat }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view> -->
|
||||||
<view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_delivery_money > 0">
|
<!-- <view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_delivery_money > 0">
|
||||||
<text class="tit">发票邮寄费</text>
|
<text class="tit">发票邮寄费</text>
|
||||||
<view class="box color-base-text">
|
<view class="box color-base-text">
|
||||||
<text class="operator">+</text>
|
<text class="operator">+</text>
|
||||||
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
|
||||||
<text class="money price-font">{{ calculateData.invoice_delivery_money | moneyFormat }}</text>
|
<text class="money price-font">{{ calculateData.invoice_delivery_money | moneyFormat }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view> -->
|
||||||
<view class="order-cell" v-if="calculateData.promotion_money > 0">
|
<view class="order-cell" v-if="calculateData.promotion_money > 0">
|
||||||
<text class="tit">优惠</text>
|
<text class="tit">优惠</text>
|
||||||
<view class="box color-base-text">
|
<view class="box color-base-text">
|
||||||
@@ -369,7 +389,7 @@
|
|||||||
<text class="money price-font">{{ calculateData.point_money | moneyFormat }}</text>
|
<text class="money price-font">{{ calculateData.point_money | moneyFormat }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="order-cell" v-if="calculateData.member_card_money > 0">
|
<!-- <view class="order-cell" v-if="calculateData.member_card_money > 0">
|
||||||
<text class="tit">会员卡</text>
|
<text class="tit">会员卡</text>
|
||||||
<view class="box color-base-text">
|
<view class="box color-base-text">
|
||||||
<text class="operator">+</text>
|
<text class="operator">+</text>
|
||||||
@@ -377,7 +397,7 @@
|
|||||||
<text class="money price-font">{{ calculateData.member_card_money | moneyFormat }}
|
<text class="money price-font">{{ calculateData.member_card_money | moneyFormat }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view> -->
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="transactionAgreement.title && transactionAgreement.content" class="agreement">购买前请先阅读<text @click="$refs.agreementPopup.open()">《{{ transactionAgreement.title }}》</text>,下单即代表同意该协议</view>
|
<view v-if="transactionAgreement.title && transactionAgreement.content" class="agreement">购买前请先阅读<text @click="$refs.agreementPopup.open()">《{{ transactionAgreement.title }}》</text>,下单即代表同意该协议</view>
|
||||||
@@ -392,76 +412,14 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="submit-btn">
|
<view class="submit-btn">
|
||||||
<button type="primary" class="mini" size="mini" @click="create()" v-if="!surplusStartMoney()">提交订单</button>
|
<button type="primary" class="mini" size="mini" @click="create()" v-if="!surplusStartMoney()">提交订单</button>
|
||||||
<button v-else class="no-submit mini" size="mini">差{{ surplusStartMoney() | moneyFormat }}起送</button>
|
<!-- <button v-else class="no-submit mini" size="mini">差{{ surplusStartMoney() | moneyFormat }}起送</button> -->
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="order-submit-block"></view>
|
<view class="order-submit-block"></view>
|
||||||
|
|
||||||
<payment ref="choosePaymentPopup" @close="payClose" v-if="calculateData"></payment>
|
<payment ref="choosePaymentPopup" @close="payClose" v-if="calculateData"></payment>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 发票弹窗 -->
|
|
||||||
<uni-popup ref="invoicePopup" type="bottom" :mask-click="false">
|
|
||||||
<view :style="orderCreateData.is_invoice == 1 ? 'height: 83vh;' : 'height: 48vh;'" class="invoice-popup popup" @touchmove.prevent.stop>
|
|
||||||
<view class="popup-header">
|
|
||||||
<text class="tit">发票</text>
|
|
||||||
<text class="iconfont icon-close" @click="closePopup('invoicePopup')"></text>
|
|
||||||
</view>
|
|
||||||
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
|
||||||
<view>
|
|
||||||
<view class="invoice-cell" v-if="goodsData.invoice">
|
|
||||||
<text class="tit">需要发票</text>
|
|
||||||
<view class="option-grpup">
|
|
||||||
<view class="option-item" :class="{ 'color-base-bg active': orderCreateData.is_invoice == 0 }" @click="changeIsInvoice">不需要</view>
|
|
||||||
<view class="option-item" :class="{ 'color-base-bg active': orderCreateData.is_invoice == 1 }" @click="changeIsInvoice">需要</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<block v-if="orderCreateData.is_invoice == 1">
|
|
||||||
<view class="invoice-cell">
|
|
||||||
<text class="tit">发票类型</text>
|
|
||||||
<view class="option-grpup">
|
|
||||||
<view class="option-item" :class="{ 'color-base-bg active': orderCreateData.invoice_type == item }" @click="changeInvoiceType(item)" v-for="(item, index) in goodsData.invoice.invoice_type.split(',')" :key="index">
|
|
||||||
{{ item == 1 ? '纸质' : '电子' }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="invoice-cell">
|
|
||||||
<text class="tit">抬头类型</text>
|
|
||||||
<view class="option-grpup">
|
|
||||||
<view class="option-item" :class="{ 'color-base-bg active': orderCreateData.invoice_title_type == 1 }" @click="changeInvoiceTitleType(1)">
|
|
||||||
个人
|
|
||||||
</view>
|
|
||||||
<view class="option-item" :class="{ 'color-base-bg active': orderCreateData.invoice_title_type == 2 }" @click="changeInvoiceTitleType(2)">
|
|
||||||
企业
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="invoice-cell">
|
|
||||||
<text class="tit">发票信息</text>
|
|
||||||
<view class="invoice-form-group">
|
|
||||||
<input type="text" placeholder="请填写抬头名称" v-model.trim="orderCreateData.invoice_title" />
|
|
||||||
<input v-if="orderCreateData.invoice_title_type == 2" type="text" placeholder="请填写纳税人识别号" v-model.trim="orderCreateData.taxpayer_number" />
|
|
||||||
<input type="text" placeholder="请填写邮寄地址" v-model.trim="orderCreateData.invoice_full_address" v-if="orderCreateData.invoice_type == 1" />
|
|
||||||
<input type="text" placeholder="请填写邮箱" v-model.trim="orderCreateData.invoice_email" v-if="orderCreateData.invoice_type == 2" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="invoice-cell">
|
|
||||||
<text class="tit">发票内容</text>
|
|
||||||
<view class="option-grpup">
|
|
||||||
<view :key="index" v-for="(item, index) in goodsData.invoice.invoice_content_array" :class="{ 'color-base-bg active': item == orderCreateData.invoice_content }" @click="changeInvoiceContent(item)" class="option-item content">
|
|
||||||
{{ item }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
<view class="invoice-tops">发票内容将以根据税法调整,具体请以展示为准,发票内容显示详细商品名 称及价格信息</view>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
<view class="popup-footer" @click="saveInvoice" :class="{ 'bottom-safe-area': isIphoneX }">
|
|
||||||
<view class="confirm-btn color-base-bg">确定</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uni-popup>
|
|
||||||
|
|
||||||
<!-- 活动优惠弹窗 -->
|
<!-- 活动优惠弹窗 -->
|
||||||
<uni-popup ref="promotionPopup" type="bottom" v-if="promotionInfo">
|
<uni-popup ref="promotionPopup" type="bottom" v-if="promotionInfo">
|
||||||
@@ -473,7 +431,8 @@
|
|||||||
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
||||||
<view class="order-cell" style="align-items: baseline;">
|
<view class="order-cell" style="align-items: baseline;">
|
||||||
<view class="tit">
|
<view class="tit">
|
||||||
<text class="promotion-mark ns-gradient-promotionpages-payment">{{ promotionInfo.title }}</text>
|
<text class="promotion-mark ns-gradient-promotionpages-payment">{{ promotionInfo.title }}
|
||||||
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="promotion-content">
|
<view class="promotion-content">
|
||||||
<view class="tit tit-content" style="white-space: pre-line;" v-html="promotionInfo.content"></view>
|
<view class="tit tit-content" style="white-space: pre-line;" v-html="promotionInfo.content"></view>
|
||||||
@@ -506,7 +465,6 @@
|
|||||||
<text v-if="item.distance">({{ item.distance }}km)</text>
|
<text v-if="item.distance">({{ item.distance }}km)</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<view v-if="item.status == 0 && item.close_desc" class="close-desc">{{ item.close_desc }}</view>
|
|
||||||
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">营业时间:{{ item.open_date }}</view>
|
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">营业时间:{{ item.open_date }}</view>
|
||||||
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">地址:{{ item.full_address }}{{ item.address }}</view>
|
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">地址:{{ item.full_address }}{{ item.address }}</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -520,33 +478,6 @@
|
|||||||
<ns-empty text="所选择收货地址附近没有可以自提的门店" :isIndex="false"></ns-empty>
|
<ns-empty text="所选择收货地址附近没有可以自提的门店" :isIndex="false"></ns-empty>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- <block v-if="storeList">
|
|
||||||
<view class="item-wrap" v-for="(item, index) in storeList" :key="index"
|
|
||||||
@click="selectPickupPoint(item)">
|
|
||||||
<view class="detail">
|
|
||||||
<view class="name"
|
|
||||||
:class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''">
|
|
||||||
<text>{{ item.store_name }}</text>
|
|
||||||
<text v-if="item.distance">({{ item.distance }}km)</text>
|
|
||||||
</view>
|
|
||||||
<view class="info">
|
|
||||||
<view
|
|
||||||
:class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''"
|
|
||||||
class="font-size-goods-tag">
|
|
||||||
营业时间:{{ item.open_date }}
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
:class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''"
|
|
||||||
class="font-size-goods-tag">
|
|
||||||
地址:{{ item.full_address }}{{ item.address }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="icon" v-if="item.store_id == orderCreateData.delivery.store_id">
|
|
||||||
<text class="iconfont icon-yuan_checked color-base-text"></text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</block> -->
|
|
||||||
|
|
||||||
</block>
|
</block>
|
||||||
</mescroll-uni>
|
</mescroll-uni>
|
||||||
@@ -578,7 +509,7 @@
|
|||||||
</uni-popup>
|
</uni-popup>
|
||||||
|
|
||||||
<!-- 优惠券弹窗 -->
|
<!-- 优惠券弹窗 -->
|
||||||
<uni-popup ref="couponPopup" type="bottom" v-if="calculateGoodsData" :mask-click="false">
|
<uni-popup ref="couponPopup" type="bottom" :mask-click="false">
|
||||||
<view class="coupon-popup popup" @touchmove.prevent.stop>
|
<view class="coupon-popup popup" @touchmove.prevent.stop>
|
||||||
<view class="popup-header">
|
<view class="popup-header">
|
||||||
<text class="tit">优惠券</text>
|
<text class="tit">优惠券</text>
|
||||||
@@ -586,8 +517,8 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
||||||
<view v-if="coupon_list.length > 0">
|
<view v-if="merchCoupon.data.length > 0">
|
||||||
<view class="coupon-item" v-for="(couponItem, couponIndex) in coupon_list" :key="couponIndex" @click="selectCoupon(couponItem)">
|
<view class="coupon-item" v-for="(couponItem, couponIndex) in merchCoupon.data" :key="couponIndex" @click="selectCoupon(couponItem,merchCoupon.merch_id)">
|
||||||
<view class="coupon-info" :style="{ backgroundColor: 'var(--main-color-shallow)' }">
|
<view class="coupon-info" :style="{ backgroundColor: 'var(--main-color-shallow)' }">
|
||||||
<view class="info-wrap">
|
<view class="info-wrap">
|
||||||
<image class="coupon-line" mode="heightFix" :src="$util.img('public/uniapp/coupon/coupon_line.png')"/>
|
<image class="coupon-line" mode="heightFix" :src="$util.img('public/uniapp/coupon/coupon_line.png')"/>
|
||||||
@@ -605,8 +536,12 @@
|
|||||||
<text class="unit">折</text>
|
<text class="unit">折</text>
|
||||||
</template>
|
</template>
|
||||||
<view class="at-least">
|
<view class="at-least">
|
||||||
<template v-if="couponItem.at_least > 0">满{{ couponItem.at_least }}可用</template>
|
<template v-if="couponItem.at_least > 0">
|
||||||
<template v-else>无门槛</template>
|
满{{ couponItem.at_least }}可用
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
无门槛
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -615,7 +550,7 @@
|
|||||||
<view v-if="couponItem.type == 'discount' && couponItem.discount_limit > 0" class="limit">最多可抵¥{{ couponItem.discount_limit }}</view>
|
<view v-if="couponItem.type == 'discount' && couponItem.discount_limit > 0" class="limit">最多可抵¥{{ couponItem.discount_limit }}</view>
|
||||||
<view class="time font-size-goods-tag">有效期:{{ couponItem.end_time ? $util.timeStampTurnTime(couponItem.end_time) : '长期有效' }}</view>
|
<view class="time font-size-goods-tag">有效期:{{ couponItem.end_time ? $util.timeStampTurnTime(couponItem.end_time) : '长期有效' }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="iconfont" :class="orderCreateData.coupon.coupon_id == couponItem.coupon_id ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></view>
|
<view class="iconfont" :class="selectCouponId == couponItem.coupon_id ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -623,7 +558,7 @@
|
|||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<view class="popup-footer" :class="{ 'bottom-safe-area': isIphoneX }">
|
<view class="popup-footer" :class="{ 'bottom-safe-area': isIphoneX }">
|
||||||
<view class="confirm-btn color-base-bg" @click="useCoupon">确定</view>
|
<view class="confirm-btn color-base-bg" @click="useCpopon">确定</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
@@ -638,7 +573,7 @@
|
|||||||
<view class="title">{{ transactionAgreement.title }}</view>
|
<view class="title">{{ transactionAgreement.title }}</view>
|
||||||
<view class="con">
|
<view class="con">
|
||||||
<scroll-view scroll-y="true" class="con">
|
<scroll-view scroll-y="true" class="con">
|
||||||
<ns-mp-html :content="transactionAgreement.content"></ns-mp-html>
|
<rich-text :nodes="transactionAgreement.content"></rich-text>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -653,7 +588,7 @@
|
|||||||
<text class="iconfont icon-close" @click="$refs.editFormPopup.close()"></text>
|
<text class="iconfont icon-close" @click="$refs.editFormPopup.close()"></text>
|
||||||
</view>
|
</view>
|
||||||
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
||||||
<ns-form v-if="tempFormData" :data="tempFormData.json_data" ref="tempForm" />
|
<ns-form v-if="tempFormData" :data="tempFormData.json_data" ref="tempForm"></ns-form>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<view class="popup-footer" @click="saveForm" :class="{ 'bottom-safe-area': isIphoneX }">
|
<view class="popup-footer" @click="saveForm" :class="{ 'bottom-safe-area': isIphoneX }">
|
||||||
<view class="confirm-btn color-base-bg">确定</view>
|
<view class="confirm-btn color-base-bg">确定</view>
|
||||||
@@ -668,7 +603,7 @@
|
|||||||
<text class="iconfont icon-close" @click="$refs.memberGoodsCardPopup.close()"></text>
|
<text class="iconfont icon-close" @click="$refs.memberGoodsCardPopup.close()"></text>
|
||||||
</view>
|
</view>
|
||||||
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
|
||||||
<view v-for="(item, index) in selectGoodsCard.cardList" class="card-item" @click="selectGoodsCard.click(item.item_id)" :key="item.item_id">
|
<view v-for="(item, index) in selectGoodsCard.cardList" class="card-item" @click="selectGoodsCard.click(item.item_id)">
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="title">{{ item.goods_name }}</view>
|
<view class="title">{{ item.goods_name }}</view>
|
||||||
<view class="info">
|
<view class="info">
|
||||||
@@ -720,4 +655,4 @@
|
|||||||
.order-cell .promotion-content {
|
.order-cell .promotion-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,27 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="value.pageStyle" v-if="loading || (list && list.length)">
|
<x-skeleton data-component-name="diy-article" type="list" :loading="loading" :configs="skeletonConfig">
|
||||||
<x-skeleton type="list" :loading="loading" :configs="skeletonConfig">
|
<view class="article-wrap" :style="warpCss">
|
||||||
<view class="article-wrap" :style="warpCss">
|
<view :class="['list-wrap', value.style]" :style="warpCss">
|
||||||
<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="['item', value.ornament.type]" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :style="itemCss">
|
<view class="article-img">
|
||||||
<view class="article-img">
|
<image class="cover-img" :src="$util.img(item.cover_img)" mode="widthFix" @error="imgError(index)" />
|
||||||
<image class="cover-img" :src="$util.img(item.cover_img)" mode="widthFix" @error="imgError(index)" />
|
</view>
|
||||||
</view>
|
<view class="info-wrap">
|
||||||
<view class="info-wrap">
|
<text class="title">{{ item.article_title }}</text>
|
||||||
<text class="title">{{ item.article_title }}</text>
|
<text class="desc" style="color:#888;font-size: 24rpx; display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2;overflow: hidden;text-overflow: ellipsis;">{{ item.article_abstract }}</text>
|
||||||
<view class="read-wrap">
|
<view class="read-wrap">
|
||||||
<block v-if="item.category_name">
|
<block v-if="item.category_name">
|
||||||
<text class="category-icon"></text>
|
<text class="category-icon"></text>
|
||||||
<text>{{ item.category_name }}</text>
|
<text>{{ item.category_name }}</text>
|
||||||
</block>
|
</block>
|
||||||
<text class="date">{{ $util.timeStampTurnTime(item.create_time, 'Y-m-d') }}</text>
|
<text class="date">{{ $util.timeStampTurnTime(item.create_time, 'date') }}</text>
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</x-skeleton>
|
</view>
|
||||||
</view>
|
</x-skeleton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -30,10 +29,7 @@
|
|||||||
name: 'diy-article',
|
name: 'diy-article',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 音频
|
// 视频
|
||||||
export default {
|
export default {
|
||||||
name: 'diy-audio',
|
name: 'diy-audio',
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="value.pageStyle" v-if="loading || (list && list.length)">
|
|
||||||
<x-skeleton data-component-name="diy-bargain" :type="skeletonType" :loading="loading" :configs="skeletonConfig">
|
<x-skeleton data-component-name="diy-bargain" :type="skeletonType" :loading="loading" :configs="skeletonConfig">
|
||||||
<view class="diy-bargain" :class="[value.template, value.style]" :style="warpCss">
|
<view class="diy-bargain" :class="[value.template, value.style]" :style="warpCss">
|
||||||
|
|
||||||
@@ -124,7 +123,6 @@
|
|||||||
|
|
||||||
</view>
|
</view>
|
||||||
</x-skeleton>
|
</x-skeleton>
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -132,10 +130,7 @@
|
|||||||
name: 'diy-bargain',
|
name: 'diy-bargain',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -33,13 +33,14 @@
|
|||||||
</block>
|
</block>
|
||||||
|
|
||||||
<block v-if="type == 'goods'">
|
<block v-if="type == 'goods'">
|
||||||
<view class="categoty-goods-wrap" v-if="loadType == 'part'" :style="'padding-top:' + (value.search ? 0 : '20rpx')">
|
<view class="categoty-goods-wrap" v-if="loadType == 'part'"
|
||||||
|
:style="'padding-top:' + (value.search ? 0 : '20rpx')">
|
||||||
<!-- 分类筛选 -->
|
<!-- 分类筛选 -->
|
||||||
<block v-if="category.child_list && value.goodsLevel == 2">
|
<block v-if="category.child_list && value.goodsLevel == 2">
|
||||||
<view class="screen-category-wrap">
|
<view class="screen-category-wrap">
|
||||||
<scroll-view scroll-x="true" class="screen-category" :class="{ 'screen-category-4': value.template == 4 }" :scroll-with-animation="true" :scroll-into-view="scrollIntoView">
|
<scroll-view scroll-x="true" class="screen-category" :class="{ 'screen-category-4': value.template == 4 }" :scroll-with-animation="true" :scroll-into-view="scrollIntoView">
|
||||||
<view class="item" id="category-2--1" :class="{ selected: categoryId == -1 }" @click="selectCategory(-1)">全部</view>
|
<view class="item" id="category-2--1" :class="{ selected: categoryId == -1 }" @click="selectCategoey(-1)">全部</view>
|
||||||
<view class="item" :id="'category-2-' + oneIndex" :class="{ selected: categoryId == oneIndex }" @click="selectCategory(oneIndex)" v-for="(one, oneIndex) in category.child_list" :key="oneIndex">
|
<view class="item" :id="'category-2-' + oneIndex" :class="{ selected: categoryId == oneIndex }" @click="selectCategoey(oneIndex)" v-for="(one, oneIndex) in category.child_list" :key="oneIndex">
|
||||||
{{ one.category_name }}
|
{{ one.category_name }}
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
@@ -49,14 +50,14 @@
|
|||||||
<view class="screen-category-popup" @click="$refs.screenCategoryPopup.close()">
|
<view class="screen-category-popup" @click="$refs.screenCategoryPopup.close()">
|
||||||
<scroll-view scroll-y="true" class="screen-category" :class="{ 'screen-category-4': value.template == 4 }">
|
<scroll-view scroll-y="true" class="screen-category" :class="{ 'screen-category-4': value.template == 4 }">
|
||||||
<view class="title">全部</view>
|
<view class="title">全部</view>
|
||||||
<view class="item" :class="{ selected: categoryId == oneIndex }" @click="selectCategory(oneIndex)" v-for="(one, oneIndex) in category.child_list" :key="oneIndex">
|
<view class="item" :class="{ selected: categoryId == oneIndex }" @click="selectCategoey(oneIndex)" v-for="(one, oneIndex) in category.child_list" :key="oneIndex">
|
||||||
{{ one.category_name }}
|
{{ one.category_name }}
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</block>
|
</block>
|
||||||
|
<!---->
|
||||||
<scroll-view scroll-y="true" class="scroll-goods-view" lower-threshold="300" :scroll-top="scrollTop" @scrolltolower="scrolltolower" @touchstart="touchstart" @touchend="touchend" @scroll="listenScroll">
|
<scroll-view scroll-y="true" class="scroll-goods-view" lower-threshold="300" :scroll-top="scrollTop" @scrolltolower="scrolltolower" @touchstart="touchstart" @touchend="touchend" @scroll="listenScroll">
|
||||||
|
|
||||||
<!--一级分类展示商品显示-->
|
<!--一级分类展示商品显示-->
|
||||||
@@ -69,9 +70,6 @@
|
|||||||
<view class="goods-img" @click="toDetail(item)">
|
<view class="goods-img" @click="toDetail(item)">
|
||||||
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"/>
|
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"/>
|
||||||
<view class="color-base-bg goods-tag" v-if="item.label_name">{{ item.label_name }}</view>
|
<view class="color-base-bg goods-tag" v-if="item.label_name">{{ item.label_name }}</view>
|
||||||
<view class="sell-out" v-if="item.goods_stock <= 0">
|
|
||||||
<text class="iconfont icon-shuqing"></text>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="info-wrap">
|
<view class="info-wrap">
|
||||||
<view class="name-wrap" @click="toDetail(item)">
|
<view class="name-wrap" @click="toDetail(item)">
|
||||||
@@ -295,7 +293,7 @@
|
|||||||
oneCategorySelect: function() {
|
oneCategorySelect: function() {
|
||||||
this.scrollTop = -1;
|
this.scrollTop = -1;
|
||||||
this.goodsList = [];
|
this.goodsList = [];
|
||||||
this.selectCategory(-1);
|
this.selectCategoey(-1);
|
||||||
},
|
},
|
||||||
select: function() {
|
select: function() {
|
||||||
if (this.index == this.select) {
|
if (this.index == this.select) {
|
||||||
@@ -609,7 +607,7 @@
|
|||||||
}
|
}
|
||||||
this.$emit('selectsku', data);
|
this.$emit('selectsku', data);
|
||||||
},
|
},
|
||||||
selectCategory(index) {
|
selectCategoey(index) {
|
||||||
this.categoryId = index;
|
this.categoryId = index;
|
||||||
this.pageIndex = 0;
|
this.pageIndex = 0;
|
||||||
this.totalPage = 1;
|
this.totalPage = 1;
|
||||||
@@ -669,7 +667,7 @@
|
|||||||
this.$emit('switch', index);
|
this.$emit('switch', index);
|
||||||
} else {
|
} else {
|
||||||
let index = this.categoryId - 1;
|
let index = this.categoryId - 1;
|
||||||
this.selectCategory(index);
|
this.selectCategoey(index);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.categoryId == -1 || (this.category.child_list && this.categoryId == this.category.child_list.length - 1)) {
|
if (this.categoryId == -1 || (this.category.child_list && this.categoryId == this.category.child_list.length - 1)) {
|
||||||
@@ -677,7 +675,7 @@
|
|||||||
this.$emit('switch', index);
|
this.$emit('switch', index);
|
||||||
} else {
|
} else {
|
||||||
let index = this.categoryId + 1;
|
let index = this.categoryId + 1;
|
||||||
this.selectCategory(index);
|
this.selectCategoey(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -997,27 +995,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.sell-out{
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
width: 180rpx;
|
|
||||||
height: 180rpx;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
border-radius: $border-radius;
|
|
||||||
text{
|
|
||||||
color: #fff;
|
|
||||||
font-size: 150rpx;
|
|
||||||
position: absolute;
|
|
||||||
left:50%;
|
|
||||||
top:50%;
|
|
||||||
transform: translateX(-50%) translateY(-50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.info-wrap {
|
.info-wrap {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -1193,28 +1171,10 @@
|
|||||||
height: auto;
|
height: auto;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
position: relative;
|
|
||||||
image {
|
image {
|
||||||
border-radius: 8rpx;
|
border-radius: 8rpx;
|
||||||
}
|
}
|
||||||
.sell-out{
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
bottom:0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
border-radius: $border-radius;
|
|
||||||
text{
|
|
||||||
color: #fff;
|
|
||||||
font-size: 240rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-sku {
|
.select-sku {
|
||||||
@@ -1240,7 +1200,7 @@
|
|||||||
|
|
||||||
.screen-category-wrap {
|
.screen-category-wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-top: 20rpx;
|
|
||||||
.icon-unfold {
|
.icon-unfold {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #999;
|
color: #999;
|
||||||
|
|||||||
@@ -2,20 +2,20 @@
|
|||||||
<view data-component-name="diy-category" :class="['category-page-wrap', 'category-template-' + value.template]"
|
<view data-component-name="diy-category" :class="['category-page-wrap', 'category-template-' + value.template]"
|
||||||
:style="{height: 'calc(100vh - '+ tabBarHeight +')' }">
|
:style="{height: 'calc(100vh - '+ tabBarHeight +')' }">
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<block v-if="value.template == 4">
|
<!-- <block v-if="value.template == 4">
|
||||||
<view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="navbarInnerStyle">
|
<view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="navbarInnerStyle">
|
||||||
<view class="search-content">
|
<view class="search-content">
|
||||||
<input type="text" class="uni-input font-size-tag" maxlength="50" :placeholder="$lang('search')" confirm-type="search" readonly="true" disabled="true" />
|
<input type="text" class="uni-input font-size-tag" maxlength="50" :placeholder="$lang('search')" confirm-type="search" disabled="true" />
|
||||||
<text class="iconfont icon-sousuo3"></text>
|
<text class="iconfont icon-sousuo3"></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view :style="navbarInnerStyle" v-if="!value.search">商品分类</view>
|
<view :style="navbarInnerStyle" v-if="!value.search">商品分类</view>
|
||||||
</block>
|
</block> -->
|
||||||
<block v-if="value.template != 4">
|
<block v-if="value.template != 4">
|
||||||
<view :style="navbarInnerStyle">商品分类</view>
|
<!-- <view :style="navbarInnerStyle">商品分类</view> -->
|
||||||
<view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="wxSearchHeight">
|
<view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="wxSearchHeight">
|
||||||
<view class="search-content">
|
<view class="search-content">
|
||||||
<input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')" confirm-type="search" readonly="true" disabled="true" />
|
<input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')" confirm-type="search" disabled="true" />
|
||||||
<text class="iconfont icon-sousuo3"></text>
|
<text class="iconfont icon-sousuo3"></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -24,12 +24,11 @@
|
|||||||
<!-- #ifdef H5 -->
|
<!-- #ifdef H5 -->
|
||||||
<view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')">
|
<view class="search-box" v-if="value.search" @click="$util.redirectTo('/pages_tool/goods/search')">
|
||||||
<view class="search-content">
|
<view class="search-content">
|
||||||
<input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')" confirm-type="search" readonly="true" disabled="true" />
|
<input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')" confirm-type="search" disabled="true" />
|
||||||
<text class="iconfont icon-sousuo3"></text>
|
<text class="iconfont icon-sousuo3"></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
|
|
||||||
<view class="template-four wx" v-if="value.template == 4">
|
<view class="template-four wx" v-if="value.template == 4">
|
||||||
<scroll-view scroll-x="true" class="template-four-wrap" :scroll-with-animation="true" :scroll-into-view="'category-one-' + oneCategorySelect" enable-flex="true">
|
<scroll-view scroll-x="true" class="template-four-wrap" :scroll-with-animation="true" :scroll-into-view="'category-one-' + oneCategorySelect" enable-flex="true">
|
||||||
<view class="category-item" :id="'category-one-' + index" v-for="(item, index) in templateFourData" :key="index" :class="{ select: oneCategorySelect == index }" @click="templateFourOneFn(index)">
|
<view class="category-item" :id="'category-one-' + index" v-for="(item, index) in templateFourData" :key="index" :class="{ select: oneCategorySelect == index }" @click="templateFourOneFn(index)">
|
||||||
@@ -72,13 +71,12 @@
|
|||||||
{ 'border-bottom': value.template == 4 && select + 1 === index },
|
{ 'border-bottom': value.template == 4 && select + 1 === index },
|
||||||
{ 'border-top': value.template == 4 && select - 1 === index }
|
{ 'border-top': value.template == 4 && select - 1 === index }
|
||||||
]" @click="switchOneCategory(index)">
|
]" @click="switchOneCategory(index)">
|
||||||
<view>{{ item.category_name }}</view>
|
<view class="">{{ item.category_name }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<view class="right-flex-wrap">
|
<view class="right-flex-wrap">
|
||||||
|
|
||||||
<scroll-view scroll-y="true" class="content-wrap" v-if="value.template == 1 || loadType == 'all'"
|
<scroll-view scroll-y="true" class="content-wrap" v-if="value.template == 1 || loadType == 'all'"
|
||||||
ref="contentWrap" :scroll-into-view="categoryId" :scroll-with-animation="true"
|
ref="contentWrap" :scroll-into-view="categoryId" :scroll-with-animation="true"
|
||||||
@scroll="listenScroll" @touchstart="touchStart" :refresher-enabled="true"
|
@scroll="listenScroll" @touchstart="touchStart" :refresher-enabled="true"
|
||||||
@@ -115,8 +113,8 @@
|
|||||||
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix"></image>
|
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix"></image>
|
||||||
<view class="tips">暂时没有分类哦!</view>
|
<view class="tips">暂时没有分类哦!</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="cart-bottom-block" v-if="(value.template == 2 || value.template == 4) && value.quickBuy && storeToken && categoryTree && categoryTree.length"></view>
|
|
||||||
<view class="cart-box" v-if="(value.template == 2 || value.template == 4) && value.quickBuy && storeToken && categoryTree && categoryTree.length" :style="{ bottom: tabBarHeight }" :class="{ active: isIphoneX }">
|
<!-- <view class="cart-box" v-if="(value.template == 2 || value.template == 4) && value.quickBuy && storeToken && categoryTree && categoryTree.length">
|
||||||
<view class="left-wrap">
|
<view class="left-wrap">
|
||||||
<view class="cart-icon" ref="cartIcon" :animation="cartAnimation" @click="$util.redirectTo('/pages/goods/cart')">
|
<view class="cart-icon" ref="cartIcon" :animation="cartAnimation" @click="$util.redirectTo('/pages/goods/cart')">
|
||||||
<text class="iconfont icon-ziyuan1"></text>
|
<text class="iconfont icon-ziyuan1"></text>
|
||||||
@@ -129,10 +127,9 @@
|
|||||||
<text class="unit font-size-tag price-font">.{{ cartTotalMoney[1] ? cartTotalMoney[1] : '00' }}</text>
|
<text class="unit font-size-tag price-font">.{{ cartTotalMoney[1] ? cartTotalMoney[1] : '00' }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="right-wrap">
|
<view class="right-wrap"><button type="primary" class="settlement-btn" @click="settlement">去结算</button>
|
||||||
<button type="primary" class="settlement-btn" @click="settlement">去结算</button>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view> -->
|
||||||
|
|
||||||
<view class="cart-point" :style="{ left: item.left + 'px', top: item.top + 'px' }" :key="index" v-for="(item, index) in carIconList"></view>
|
<view class="cart-point" :style="{ left: item.left + 'px', top: item.top + 'px' }" :key="index" v-for="(item, index) in carIconList"></view>
|
||||||
|
|
||||||
@@ -179,27 +176,34 @@
|
|||||||
cartAnimation: {},
|
cartAnimation: {},
|
||||||
loadType: '',
|
loadType: '',
|
||||||
templateFourData: [],
|
templateFourData: [],
|
||||||
isIphoneX: false, //判断手机是否是iphoneX以上,
|
|
||||||
lang:uni.getStorageSync("lang")//en-us 英文
|
lang:uni.getStorageSync("lang")//en-us 英文
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.isIphoneX = this.$util.uniappIsIPhoneX();
|
|
||||||
this.getCategoryTree();
|
this.getCategoryTree();
|
||||||
this.loadType = this.value.goodsLevel == 1 && this.value.loadType == 'all' ? 'all' : 'part';
|
this.loadType = this.value.goodsLevel == 1 && this.value.loadType == 'all' ? 'all' : 'part';
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
query = uni.createSelectorQuery().in(this);
|
query = uni.createSelectorQuery().in(this);
|
||||||
query.select('.content-wrap').boundingClientRect(data => {
|
query
|
||||||
if (data) contentWrapHeight = data.height;
|
.select('.content-wrap')
|
||||||
}).exec();
|
.boundingClientRect(data => {
|
||||||
|
if (data) contentWrapHeight = data.height;
|
||||||
|
})
|
||||||
|
.exec();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
query.select('.end-tips').boundingClientRect(data => {
|
query
|
||||||
if (data && data.top > contentWrapHeight) this.endTips = 1;
|
.select('.end-tips')
|
||||||
}).exec();
|
.boundingClientRect(data => {
|
||||||
query.select('.cart-icon').boundingClientRect(data => {
|
if (data && data.top > contentWrapHeight) this.endTips = 1;
|
||||||
if (data) cartPosition = data;
|
})
|
||||||
}).exec();
|
.exec();
|
||||||
|
query
|
||||||
|
.select('.cart-icon')
|
||||||
|
.boundingClientRect(data => {
|
||||||
|
if (data) cartPosition = data;
|
||||||
|
})
|
||||||
|
.exec();
|
||||||
if (this.value.template == 1) this.getHeightArea(-1);
|
if (this.value.template == 1) this.getHeightArea(-1);
|
||||||
}, 500);
|
}, 500);
|
||||||
},
|
},
|
||||||
@@ -246,7 +250,7 @@
|
|||||||
style += 'padding-top:' + this.navbarHeight + 'px;';
|
style += 'padding-top:' + this.navbarHeight + 'px;';
|
||||||
style += 'text-align: center;';
|
style += 'text-align: center;';
|
||||||
style += 'line-height:' + menuButtonInfo.height * 2 + 'rpx;';
|
style += 'line-height:' + menuButtonInfo.height * 2 + 'rpx;';
|
||||||
style += 'font-size: 16px;';
|
style += 'font-size: 14px;';
|
||||||
style += 'padding-bottom: 10rpx;';
|
style += 'padding-bottom: 10rpx;';
|
||||||
}
|
}
|
||||||
return style;
|
return style;
|
||||||
@@ -278,48 +282,27 @@
|
|||||||
pageShow() {
|
pageShow() {
|
||||||
this.$store.dispatch('getCartNumber');
|
this.$store.dispatch('getCartNumber');
|
||||||
if (!this.heightArea.length) this.getHeightArea(-1);
|
if (!this.heightArea.length) this.getHeightArea(-1);
|
||||||
this.dealCategoryData()
|
|
||||||
},
|
|
||||||
dealCategoryData() {
|
|
||||||
if (uni.getStorageSync('tabBarParams')) {
|
|
||||||
if (this.value.template != 4) {
|
|
||||||
this.categoryTree.forEach((item,index) => {
|
|
||||||
if(item.category_id == uni.getStorageSync('tabBarParams').split('=')[1]) {
|
|
||||||
this.select = index;
|
|
||||||
this.categoryId = 'category-' + index;
|
|
||||||
// 阻止切换分类之后滚动事件也立即执行
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.templateFourData.forEach((item,index) => {
|
|
||||||
if(item.category_id == uni.getStorageSync('tabBarParams').split('=')[1]) {
|
|
||||||
this.oneCategorySelect = index;
|
|
||||||
this.categoryId = 'category-' + index;
|
|
||||||
// 阻止切换分类之后滚动事件也立即执行
|
|
||||||
this.categoryTree = this.templateFourData[index].child_list || [];
|
|
||||||
this.select = 0;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
uni.removeStorageSync('tabBarParams')
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 获取高度区间
|
* 获取高度区间
|
||||||
*/
|
*/
|
||||||
getHeightArea(index) {
|
getHeightArea(index) {
|
||||||
let heightArea = [];
|
let heightArea = [];
|
||||||
query.selectAll('.content-wrap .child-category').boundingClientRect(data => {
|
query
|
||||||
if (data && data.length) {
|
.selectAll('.content-wrap .child-category')
|
||||||
data.forEach((item, index) => {
|
.boundingClientRect(data => {
|
||||||
if (index == 0) heightArea.push([0, item.height]);
|
if (data && data.length) {
|
||||||
else heightArea.push([heightArea[index - 1][1], heightArea[index - 1][1] + item.height]);
|
data.forEach((item, index) => {
|
||||||
});
|
if (index == 0) heightArea.push([0, item.height]);
|
||||||
}
|
else heightArea.push([heightArea[index - 1][1], heightArea[index - 1][1] +
|
||||||
}).exec();
|
item.height
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.exec();
|
||||||
this.heightArea = heightArea;
|
this.heightArea = heightArea;
|
||||||
if (index != -1 && index < this.categoryTree.length - 1) this.$refs.categoryItem[index + 1].getGoodsList();
|
if (index != -1 && index < this.categoryTree.length - 1) this.$refs.categoryItem[index + 1].getGoodsList();
|
||||||
this.refreshData();
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 获取全部分类
|
* 获取全部分类
|
||||||
@@ -349,7 +332,6 @@
|
|||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.dealCategoryData()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -382,7 +364,8 @@
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.value.template != 1 && this.value.loadType == 'all' && this.heightArea[this.select][1] - scrollTop - contentWrapHeight < 300) {
|
if (this.value.template != 1 && this.value.loadType == 'all' && this.heightArea[this.select][1] -
|
||||||
|
scrollTop - contentWrapHeight < 300) {
|
||||||
this.$refs.categoryItem[this.select].getGoodsList();
|
this.$refs.categoryItem[this.select].getGoodsList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -450,37 +433,6 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
settlement() {
|
settlement() {
|
||||||
|
|
||||||
// 是否有商品库存不足 不足最小购买数 超过最大购买数
|
|
||||||
var no_buy = false;
|
|
||||||
|
|
||||||
for (let k in this.cartList) {
|
|
||||||
let item = this.cartList[k];
|
|
||||||
|
|
||||||
for (let sku in item) {
|
|
||||||
if (item.max_buy && item.num > item.max_buy){
|
|
||||||
no_buy = true;
|
|
||||||
this.$util.showToast({title: '商品' + item.goods_name+'商品最多可购买'+item.max_buy+'件'})
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (typeof item[sku] == 'object') {
|
|
||||||
if (item[sku].num > item[sku].stock){
|
|
||||||
no_buy = true;
|
|
||||||
this.$util.showToast({title: '商品' + item.goods_name+'库存不足'})
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (item[sku].min_buy && item[sku].num < item[sku].min_buy){
|
|
||||||
no_buy = true;
|
|
||||||
this.$util.showToast({title: '商品' + item.goods_name+'商品最少要购买'+item[sku].min_buy+'件'})
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(no_buy) return;
|
|
||||||
|
|
||||||
if (!this.cartIds.length || this.isSub) return;
|
if (!this.cartIds.length || this.isSub) return;
|
||||||
this.isSub = true;
|
this.isSub = true;
|
||||||
|
|
||||||
@@ -568,7 +520,7 @@
|
|||||||
},
|
},
|
||||||
// 操作多规格商品弹框后,刷新商品数据
|
// 操作多规格商品弹框后,刷新商品数据
|
||||||
refreshData() {
|
refreshData() {
|
||||||
if(this.$refs.categoryItem) this.$refs.categoryItem[this.select].loadGoodsCartNum(true);
|
this.$refs.categoryItem[this.select].loadGoodsCartNum(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -577,8 +529,7 @@
|
|||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.category-page-wrap {
|
.category-page-wrap {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
// height: calc(100vh - var(--tab-bar-height, 0));
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
@@ -633,16 +584,10 @@
|
|||||||
view {
|
view {
|
||||||
color: #222222;
|
color: #222222;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
// white-space: nowrap;
|
white-space: nowrap;
|
||||||
// text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
line-height: 1.3;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
// display: -webkit-box;
|
|
||||||
// -webkit-line-clamp: 2;
|
|
||||||
// -webkit-box-orient: vertical;
|
|
||||||
word-break: break-all;
|
|
||||||
max-height: 100rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.border-top {
|
&.border-top {
|
||||||
@@ -722,11 +667,6 @@
|
|||||||
.cart-box {
|
.cart-box {
|
||||||
height: 100rpx;
|
height: 100rpx;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
bottom: var(--tab-bar-height, 0);
|
|
||||||
// bottom: calc( constant(safe-area-inset-bottom) + 110rpx );
|
|
||||||
// bottom: calc( env(safe-area-inset-bottom) + 110rpx );
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-top: 1px solid #f5f5f5;
|
border-top: 1px solid #f5f5f5;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -799,11 +739,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cart-box.active {
|
|
||||||
bottom: calc(constant(safe-area-inset-bottom) + 110rpx) !important;
|
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 110rpx) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cart-point {
|
.cart-point {
|
||||||
width: 26rpx;
|
width: 26rpx;
|
||||||
height: 26rpx;
|
height: 26rpx;
|
||||||
@@ -850,7 +785,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cart-box {
|
.cart-box {
|
||||||
// position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -930,30 +865,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
padding: 2rpx 0;
|
padding: 2rpx 16rpx;
|
||||||
border-radius: 40rpx;
|
border-radius: 40rpx;
|
||||||
font-size: $font-size-tag;
|
font-size: $font-size-tag;
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
text-align: center;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
}
|
|
||||||
.ellipsis {
|
|
||||||
// text-overflow: ellipsis;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-line-clamp: 1;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
.text {
|
.text {
|
||||||
background-color: $base-color;
|
background-color: $base-color;
|
||||||
color: var(--btn-text-color);
|
color: var(--btn-text-color);
|
||||||
line-height: 1.3;
|
|
||||||
border: 4rpx solid transparent;
|
|
||||||
border-color: $base-color;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1084,7 +1004,4 @@
|
|||||||
border-bottom-right-radius: 8rpx;
|
border-bottom-right-radius: 8rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cart-bottom-block {
|
|
||||||
height: 100rpx;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view data-component-name="diy-comp-extend" :style="value.pageStyle">
|
<view data-component-name="diy-comp-extend"></view>
|
||||||
<view></view>
|
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -10,10 +8,7 @@ export default {
|
|||||||
name: 'diy-comp-extend',
|
name: 'diy-comp-extend',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -1,91 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="value.pageStyle" v-if="loading || (computedCouponList && computedCouponList.length)">
|
<x-skeleton data-component-name="diy-coupon" type="banner" :loading="loading" :configs="skeletonConfig">
|
||||||
<x-skeleton type="banner" :loading="loading" :configs="skeletonConfig">
|
<view class="coupon-wrap" :class="'coupon-box-' + value.style" :style="[
|
||||||
<view class="coupon-wrap" :class="'coupon-box-' + value.style" :style="[
|
value.couponType == 'img' && { backgroundImage: 'url(' + $util.img(value.couponBgUrl) + ')' },
|
||||||
value.couponType == 'img' && { backgroundImage: 'url(' + $util.img(value.couponBgUrl) + ')' },
|
value.couponType == 'color' && { backgroundColor: value.couponBgColor }
|
||||||
value.couponType == 'color' && { backgroundColor: value.couponBgColor }
|
]">
|
||||||
]">
|
|
||||||
|
|
||||||
<template v-if="value.style == '1'">
|
<template v-if="value.style == '1'">
|
||||||
<swiper class="coupon-style-one" circular>
|
<swiper class="coupon-style-one" circular>
|
||||||
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
|
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
|
||||||
|
|
||||||
<view v-for="(item, index) in computedCouponList" class="coupon-item" v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
|
<view v-for="(item, index) in computedCouponList" class="coupon-item"
|
||||||
color: value.moneyColor,
|
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
|
||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style1-bg.png') + ')',
|
color: value.moneyColor,
|
||||||
marginRight: couponItemHeight + 'px',
|
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style1-bg.png') + ')',
|
||||||
marginLeft: couponItemHeight + 'px'
|
marginRight: couponItemHeight + 'px',
|
||||||
}" @click="couponAction(item, index)">
|
marginLeft: couponItemHeight + 'px'
|
||||||
|
}" @click="couponAction(item, index)">
|
||||||
|
|
||||||
<view class="coupon-info">
|
<view class="coupon-info">
|
||||||
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
|
|
||||||
<text class="font-size-tag coupon-sign">¥</text>
|
|
||||||
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else>
|
|
||||||
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
|
|
||||||
<text class="font-size-tag coupon-sign">折</text>
|
|
||||||
</view>
|
|
||||||
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }">
|
|
||||||
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text }}</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</swiper-item>
|
|
||||||
</swiper>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="value.style == '2'">
|
|
||||||
<swiper class="coupon-style-two" circular>
|
|
||||||
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
|
|
||||||
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index"
|
|
||||||
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
|
|
||||||
color: value.moneyColor,
|
|
||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_bg1.png') + ')',
|
|
||||||
marginRight: couponItemHeight + 'px',
|
|
||||||
marginLeft: couponItemHeight + 'px'
|
|
||||||
}" @click="couponAction(item, index)">
|
|
||||||
<view class="coupon-info">
|
|
||||||
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
|
|
||||||
<text class="font-size-tag coupon-sign">¥</text>
|
|
||||||
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else>
|
|
||||||
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
|
|
||||||
<text class="font-size-tag coupon-sign">折</text>
|
|
||||||
</view>
|
|
||||||
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }">
|
|
||||||
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text || '领取' }}</view>
|
|
||||||
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
|
|
||||||
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
|
|
||||||
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
|
|
||||||
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
|
|
||||||
</view>
|
|
||||||
</swiper-item>
|
|
||||||
</swiper>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="value.style == '3'">
|
|
||||||
<swiper class="coupon-style-three" circular>
|
|
||||||
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
|
|
||||||
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index"
|
|
||||||
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
|
|
||||||
color: value.moneyColor,
|
|
||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_shu.png') + ')',
|
|
||||||
marginRight: couponItemHeight + 'px',
|
|
||||||
marginLeft: couponItemHeight + 'px'
|
|
||||||
}" @click="couponAction(item, index)">
|
|
||||||
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
|
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
|
||||||
<text class="font-size-tag coupon-sign">¥</text>
|
<text class="font-size-tag coupon-sign">¥</text>
|
||||||
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
|
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
|
||||||
@@ -94,188 +26,125 @@
|
|||||||
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
|
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
|
||||||
<text class="font-size-tag coupon-sign">折</text>
|
<text class="font-size-tag coupon-sign">折</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="coupon-type font-size-tag">
|
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }">
|
||||||
<text :style="{ color: value.limitColor }">{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}</text>
|
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}
|
||||||
<view class="item-text">{{item.goods_type_name}}</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text || '领取' }}</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
|
|
||||||
</view>
|
</view>
|
||||||
</swiper-item>
|
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0">
|
||||||
</swiper>
|
{{ value.btnStyle.text }}
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="value.style == '4'">
|
|
||||||
<swiper class="coupon-style-four" circular>
|
|
||||||
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
|
|
||||||
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index"
|
|
||||||
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
|
|
||||||
color: value.moneyColor,
|
|
||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style4_bg.png') + ')',
|
|
||||||
marginRight: couponItemHeight + 'px',
|
|
||||||
marginLeft: couponItemHeight + 'px'
|
|
||||||
}" @click="couponAction(item, index)">
|
|
||||||
<view class="coupon-info">
|
|
||||||
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
|
|
||||||
<text class="font-size-tag coupon-sign">¥</text>
|
|
||||||
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else>
|
|
||||||
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
|
|
||||||
<text class="font-size-tag coupon-sign">折</text>
|
|
||||||
</view>
|
|
||||||
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }">
|
|
||||||
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text || '立即领取' }}</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
|
|
||||||
</view>
|
</view>
|
||||||
</swiper-item>
|
<view class="coupon-get" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用</view>
|
||||||
</swiper>
|
</view>
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="value.style == '5'">
|
</swiper-item>
|
||||||
<view class="coupon-style-five">
|
</swiper>
|
||||||
<view class="coupon-all">
|
</template>
|
||||||
<view class="coupon-box">
|
|
||||||
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index" @click="couponAction(item, index)">
|
<template v-if="value.style == '2'">
|
||||||
<image :src="$util.img('public/uniapp/coupon/style5_bg.png')"></image>
|
<swiper class="coupon-style-two" circular>
|
||||||
<view class="coupon">
|
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
|
||||||
<view class="coupon-info">
|
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index"
|
||||||
<view class="coupon-num" v-if="item.discount == '0.00'" :style="{ color: value.moneyColor }">
|
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
|
||||||
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
|
color: value.moneyColor,
|
||||||
<text class="font-size-tag coupon-sign">元</text>
|
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_bg1.png') + ')',
|
||||||
</view>
|
marginRight: couponItemHeight + 'px',
|
||||||
<view class="coupon-num" v-else :style="{ color: value.moneyColor }">
|
marginLeft: couponItemHeight + 'px'
|
||||||
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
|
}" @click="couponAction(item, index)">
|
||||||
<text class="font-size-tag coupon-sign">折</text>
|
<view class="coupon-info">
|
||||||
</view>
|
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
|
||||||
</view>
|
<text class="font-size-tag coupon-sign">¥</text>
|
||||||
<view class="coupon-line"></view>
|
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
|
||||||
<view class="coupon-content">
|
|
||||||
<view class="coupon-type">
|
|
||||||
<view class="coupon-name" :style="{ color: value.nameColor }">{{ item.coupon_name }}</view>
|
|
||||||
<text class="coupon-least" :style="{ color: value.limitColor }" v-if="item.at_least > 0">满{{ Number(item.at_least) }}元可用</text>
|
|
||||||
<text class="coupon-least" :style="{ color: value.limitColor }" v-else>无门槛优惠券</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text || '立即领取' }}</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
|
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else>
|
||||||
|
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
|
||||||
|
<text class="font-size-tag coupon-sign">折</text>
|
||||||
|
</view>
|
||||||
|
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }">
|
||||||
|
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0">
|
||||||
|
{{ value.btnStyle.text || '领取' }}
|
||||||
|
</view>
|
||||||
|
<view class="coupon-get use" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</swiper-item>
|
||||||
</template>
|
</swiper>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-if="value.style == '6'">
|
<template v-if="value.style == '3'">
|
||||||
<swiper class="coupon-style-six" circular>
|
<swiper class="coupon-style-three" circular>
|
||||||
<swiper-item class="style-six-wrap" v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex">
|
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
|
||||||
<view class="coupon" v-for="(item, index) in computedCouponList" :key="index"
|
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index"
|
||||||
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
|
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
|
||||||
color: value.moneyColor,
|
color: value.moneyColor,
|
||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-1.png') + ')',
|
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_shu.png') + ')',
|
||||||
marginRight: couponItemHeight + 'px',
|
marginRight: couponItemHeight + 'px',
|
||||||
marginLeft: couponItemHeight + 'px'
|
marginLeft: couponItemHeight + 'px'
|
||||||
}" @click="couponAction(item, index)">
|
}" @click="couponAction(item, index)">
|
||||||
<view class="coupon-content">
|
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
|
||||||
<view class="price-wrap">
|
<text class="font-size-tag coupon-sign">¥</text>
|
||||||
<text class="price" :style="{ color: value.moneyColor }">{{ (item.discount == '0.00' ? item.money : item.discount) | moneyConduct }}</text>
|
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
|
||||||
<text class="unit">{{ item.discount == '0.00' ? '元' : '折' }}</text>
|
</view>
|
||||||
</view>
|
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else>
|
||||||
<text class="text">优惠券</text>
|
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
|
||||||
</view>
|
<text class="font-size-tag coupon-sign">折</text>
|
||||||
<!-- <text class="btn" v-if="item.useState == 0" :style="{
|
</view>
|
||||||
color: value.btnStyle.textColor,
|
<view class="coupon-type font-size-tag">
|
||||||
backgroundColor: value.btnStyle.bgColor,
|
<text :style="{ color: value.limitColor }">{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}</text>
|
||||||
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
|
<view class="item-text" v-if="item.goods_type == 1">所有商品可用</view>
|
||||||
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
<view class="item-text" v-else-if="item.goods_type == 2">指定商品可用</view>
|
||||||
}">
|
<view class="item-text" v-else-if="item.goods_type == 3">指定商品不可用</view>
|
||||||
<text class="btn-content">{{ value.btnStyle.text }}</text>
|
|
||||||
</text>
|
|
||||||
<text class="btn" v-if="parseInt(item.useState)" :style="{
|
|
||||||
color: value.btnStyle.textColor,
|
|
||||||
backgroundColor: value.btnStyle.bgColor,
|
|
||||||
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
|
|
||||||
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
|
||||||
}">
|
|
||||||
<text class="btn-content">去使用</text>
|
|
||||||
</text> -->
|
|
||||||
|
|
||||||
<text class="btn" v-if="item.useState == 0" :style="{
|
|
||||||
color: value.btnStyle.textColor,
|
|
||||||
backgroundColor: value.btnStyle.bgColor,
|
|
||||||
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
|
|
||||||
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
|
||||||
}">
|
|
||||||
<text class="btn-content">{{ value.btnStyle.text }}</text>
|
|
||||||
</text>
|
|
||||||
<text class="btn to-use" v-if="item.useState == 1" :style="{
|
|
||||||
color: value.btnStyle.textColor,
|
|
||||||
backgroundColor: value.btnStyle.bgColor,
|
|
||||||
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
|
|
||||||
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
|
||||||
}">
|
|
||||||
<text class="btn-content">去使用</text>
|
|
||||||
</text>
|
|
||||||
<text class="btn disabled" v-if="item.useState == 2" :style="{
|
|
||||||
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
|
|
||||||
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
|
||||||
}">
|
|
||||||
<text class="btn-content">已抢光</text>
|
|
||||||
</text>
|
|
||||||
<text class="btn disabled" v-if="item.useState == 3" :style="{
|
|
||||||
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
|
|
||||||
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
|
||||||
}">
|
|
||||||
<text class="btn-content">已失效</text>
|
|
||||||
</text>
|
|
||||||
<text class="btn disabled" v-if="item.useState == 4" :style="{
|
|
||||||
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
|
|
||||||
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
|
||||||
}">
|
|
||||||
<text class="btn-content">已使用</text>
|
|
||||||
</text>
|
|
||||||
|
|
||||||
<text class="limit" :style="{ color: value.limitColor }" v-if="parseFloat(item.at_least) > 0">满{{ item.at_least | moneyConduct }}元使用</text>
|
|
||||||
<text class="limit" :style="{ color: value.limitColor }" v-else>无门槛使用</text>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<div v-if="computedCouponList.length <= 2" @click="$util.redirectTo('/pages/goods/category')"
|
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0">
|
||||||
class="coupon coupon-null" :style="{
|
{{ value.btnStyle.text || '领取' }}
|
||||||
color: value.moneyColor,
|
</view>
|
||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-2.png') + ')',
|
<view class="coupon-get" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用</view>
|
||||||
marginRight: couponItemHeight + 'px',
|
</view>
|
||||||
marginLeft: couponItemHeight + 'px'
|
</swiper-item>
|
||||||
}">
|
</swiper>
|
||||||
<div class="coupon-content" :style="{ color: value.moneyColor }">
|
</template>
|
||||||
<span class="price">+</span>
|
|
||||||
<span class="text">暂无优惠券</span>
|
|
||||||
</div>
|
|
||||||
<span class="limit" :style="{ color: value.limitColor }">去逛逛</span>
|
|
||||||
</div>
|
|
||||||
</swiper-item>
|
|
||||||
</swiper>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="value.style == '7'">
|
<template v-if="value.style == '4'">
|
||||||
<scroll-view class="coupon-style-seven" scroll-x="true">
|
<swiper class="coupon-style-four" circular>
|
||||||
<view class="wrap">
|
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
|
||||||
|
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index"
|
||||||
|
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
|
||||||
|
color: value.moneyColor,
|
||||||
|
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style4_bg.png') + ')',
|
||||||
|
marginRight: couponItemHeight + 'px',
|
||||||
|
marginLeft: couponItemHeight + 'px'
|
||||||
|
}" @click="couponAction(item, index)">
|
||||||
|
<view class="coupon-info">
|
||||||
|
<view class="coupon-num" :style="{ color: value.moneyColor }" v-if="!parseInt(item.discount)">
|
||||||
|
<text class="font-size-tag coupon-sign">¥</text>
|
||||||
|
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="coupon-num" :style="{ color: value.moneyColor }" v-else>
|
||||||
|
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
|
||||||
|
<text class="font-size-tag coupon-sign">折</text>
|
||||||
|
</view>
|
||||||
|
<view class="coupon-type font-size-tag" :style="{ color: value.limitColor }">
|
||||||
|
{{ item.at_least > 0 ? '满' + Number(item.at_least) + '元可用' : '无门槛优惠券' }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0">
|
||||||
|
{{ value.btnStyle.text || '立即使用' }}
|
||||||
|
</view>
|
||||||
|
<view class="coupon-get" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用</view>
|
||||||
|
</view>
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="value.style == '5'">
|
||||||
|
<view class="coupon-style-five">
|
||||||
|
<view class="coupon-all">
|
||||||
|
<view class="coupon-box">
|
||||||
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index" @click="couponAction(item, index)">
|
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index" @click="couponAction(item, index)">
|
||||||
<image :src="$util.img('public/uniapp/coupon/style7_bg.png')"></image>
|
<image :src="$util.img('public/uniapp/coupon/style5_bg.png')"></image>
|
||||||
<view class="coupon">
|
<view class="coupon">
|
||||||
<view class="coupon-info">
|
<view class="coupon-info">
|
||||||
<view class="coupon-num" v-if="item.discount == '0.00'" :style="{ color: value.moneyColor }">
|
<view class="coupon-num" v-if="item.discount == '0.00'" :style="{ color: value.moneyColor }">
|
||||||
@@ -287,32 +156,115 @@
|
|||||||
<text class="font-size-tag coupon-sign">折</text>
|
<text class="font-size-tag coupon-sign">折</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="coupon-type">
|
|
||||||
<text class="coupon-name" :style="{ color: value.limitColor }" v-if="item.at_least > 0">满{{ Number(item.at_least) }}元可用</text>
|
|
||||||
<text class="coupon-name" :style="{ color: value.limitColor }" v-else>无门槛优惠券</text>
|
|
||||||
<view class="coupon-least" v-if="item.validity_type == 0" :style="{ color: value.limitColor }">有效期至{{ $util.timeStampTurnTime(item.end_time, 'Y-m-d') }}</view>
|
|
||||||
<view class="coupon-least" v-else-if="item.validity_type == 1" :style="{ color: value.limitColor }">领取后{{ item.fixed_term }}天有效</view>
|
|
||||||
<view class="coupon-least" v-else :style="{ color: value.limitColor }">领取后长期有效</view>
|
|
||||||
</view>
|
|
||||||
<view class="coupon-line"></view>
|
<view class="coupon-line"></view>
|
||||||
|
<view class="coupon-content">
|
||||||
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0" >{{ value.btnStyle.text || '立即领取' }}</view>
|
<view class="coupon-type">
|
||||||
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 1" >去使用</view>
|
<view class="coupon-name" :style="{ color: value.nameColor }">{{ item.coupon_name }}</view>
|
||||||
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 2">已抢光</view>
|
<text class="coupon-least" :style="{ color: value.limitColor }" v-if="item.at_least > 0">满{{ Number(item.at_least) }}元可用</text>
|
||||||
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 3">已失效</view>
|
<text class="coupon-least" :style="{ color: value.limitColor }" v-else>无门槛优惠券</text>
|
||||||
<view class="coupon-get three-text" :style="couponBtnStyle" v-if="item.useState == 4">已使用</view>
|
</view>
|
||||||
|
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0">{{ value.btnStyle.text || '立即领取' }}</view>
|
||||||
|
<view class="coupon-get" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</view>
|
||||||
</template>
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
<ns-login ref="login"></ns-login>
|
<template v-if="value.style == '6'">
|
||||||
|
<swiper class="coupon-style-six" circular>
|
||||||
|
<swiper-item class="style-six-wrap" v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex">
|
||||||
|
<view class="coupon" v-for="(item, index) in computedCouponList" :key="index"
|
||||||
|
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
|
||||||
|
color: value.moneyColor,
|
||||||
|
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-1.png') + ')',
|
||||||
|
marginRight: couponItemHeight + 'px',
|
||||||
|
marginLeft: couponItemHeight + 'px'
|
||||||
|
}" @click="couponAction(item, index)">
|
||||||
|
<view class="coupon-content">
|
||||||
|
<view class="price-wrap">
|
||||||
|
<text class="price" :style="{ color: value.moneyColor }">{{ (item.discount == '0.00' ? item.money : item.discount) | moneyConduct }}</text>
|
||||||
|
<text class="unit">{{ item.discount == '0.00' ? '元' : '折' }}</text>
|
||||||
|
</view>
|
||||||
|
<text class="text">优惠券</text>
|
||||||
|
</view>
|
||||||
|
<text class="btn" v-if="item.useState == 0" :style="{
|
||||||
|
color: value.btnStyle.textColor,
|
||||||
|
backgroundColor: value.btnStyle.bgColor,
|
||||||
|
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
|
||||||
|
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
||||||
|
}">
|
||||||
|
<text class="btn-content">{{ value.btnStyle.text }}</text>
|
||||||
|
</text>
|
||||||
|
<text class="btn" v-if="parseInt(item.useState)" :style="{
|
||||||
|
color: value.btnStyle.textColor,
|
||||||
|
backgroundColor: value.btnStyle.bgColor,
|
||||||
|
borderTopLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx',
|
||||||
|
borderBottomLeftRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
||||||
|
}">
|
||||||
|
<text class="btn-content">去使用</text>
|
||||||
|
</text>
|
||||||
|
<text class="limit" :style="{ color: value.limitColor }" v-if="parseFloat(item.at_least) > 0">满{{ item.at_least | moneyConduct }}元使用</text>
|
||||||
|
<text class="limit" :style="{ color: value.limitColor }" v-else>无门槛使用</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
</view>
|
<div v-if="computedCouponList.length <= 2" @click="$util.redirectTo('/pages/goods/category')"
|
||||||
|
class="coupon coupon-null" :style="{
|
||||||
|
color: value.moneyColor,
|
||||||
|
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-2.png') + ')',
|
||||||
|
marginRight: couponItemHeight + 'px',
|
||||||
|
marginLeft: couponItemHeight + 'px'
|
||||||
|
}">
|
||||||
|
<div class="coupon-content" :style="{ color: value.moneyColor }">
|
||||||
|
<span class="price">+</span>
|
||||||
|
<span class="text">暂无优惠券</span>
|
||||||
|
</div>
|
||||||
|
<span class="limit" :style="{ color: value.limitColor }">去逛逛</span>
|
||||||
|
</div>
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
</template>
|
||||||
|
|
||||||
</x-skeleton>
|
<template v-if="value.style == '7'">
|
||||||
</view>
|
<scroll-view class="coupon-style-seven" scroll-x="true">
|
||||||
|
<view class="wrap">
|
||||||
|
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index" @click="couponAction(item, index)">
|
||||||
|
<image :src="$util.img('public/uniapp/coupon/style7_bg.png')"></image>
|
||||||
|
<view class="coupon">
|
||||||
|
<view class="coupon-info">
|
||||||
|
<view class="coupon-num" v-if="item.discount == '0.00'" :style="{ color: value.moneyColor }">
|
||||||
|
<text class="coupon-size">{{ item.money | moneyConduct }}</text>
|
||||||
|
<text class="font-size-tag coupon-sign">元</text>
|
||||||
|
</view>
|
||||||
|
<view class="coupon-num" v-else :style="{ color: value.moneyColor }">
|
||||||
|
<text class="coupon-size">{{ item.discount | moneyConduct }}</text>
|
||||||
|
<text class="font-size-tag coupon-sign">折</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="coupon-type">
|
||||||
|
<text class="coupon-name" :style="{ color: value.limitColor }" v-if="item.at_least > 0">满{{ Number(item.at_least) }}元可用</text>
|
||||||
|
<text class="coupon-name" :style="{ color: value.limitColor }" v-else>无门槛优惠券</text>
|
||||||
|
<view class="coupon-least" :style="{ color: value.limitColor }">有效期至{{ $util.timeStampTurnTime(item.end_time, 'yearmonthday') }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="coupon-line"></view>
|
||||||
|
<view class="coupon-get" :style="couponBtnStyle" v-if="item.useState == 0">
|
||||||
|
{{ value.btnStyle.text || '立即领取' }}
|
||||||
|
</view>
|
||||||
|
<view class="coupon-get" :style="couponBtnStyle" v-if="parseInt(item.useState)">去使用
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<ns-login ref="login"></ns-login>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</x-skeleton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -361,11 +313,17 @@
|
|||||||
couponItemHeight() {
|
couponItemHeight() {
|
||||||
var width = '';
|
var width = '';
|
||||||
const screenWidth = uni.getSystemInfoSync().windowWidth;
|
const screenWidth = uni.getSystemInfoSync().windowWidth;
|
||||||
if (this.value.style == '1') width = [screenWidth - this.rpxUpPx(210) * 3 - this.rpxUpPx(this.value.margin.both * 2) * 2] / 6;
|
if (this.value.style == '1') width = [screenWidth - this.rpxUpPx(210) * 3 - this.rpxUpPx(this.value.margin
|
||||||
else if (this.value.style == '2') width = [screenWidth - this.rpxUpPx(210) * 3 - this.rpxUpPx(this.value.margin.both * 2) * 2] / 6;
|
.both * 2) * 2] / 6;
|
||||||
else if (this.value.style == '3') width = [screenWidth - this.rpxUpPx(24) * 2 - this.rpxUpPx(194) * 3 - this.rpxUpPx(this.value.margin.both * 2) * 2] / 6;
|
else if (this.value.style == '2') width = [screenWidth - this.rpxUpPx(210) * 3 - this.rpxUpPx(this.value
|
||||||
else if (this.value.style == '4') width = [screenWidth - this.rpxUpPx(206) * 3 - this.rpxUpPx(this.value.margin.both * 2) * 2] / 6;
|
.margin.both * 2) * 2] / 6;
|
||||||
else if (this.value.style == '6') width = [screenWidth - this.rpxUpPx(208) * 3 - this.rpxUpPx(this.value.margin.both * 2) * 2] / 6;
|
else if (this.value.style == '3') width = [screenWidth - this.rpxUpPx(24) * 2 - this.rpxUpPx(194) * 3 -
|
||||||
|
this.rpxUpPx(this.value.margin.both * 2) * 2
|
||||||
|
] / 6;
|
||||||
|
else if (this.value.style == '4') width = [screenWidth - this.rpxUpPx(206) * 3 - this.rpxUpPx(this.value
|
||||||
|
.margin.both * 2) * 2] / 6;
|
||||||
|
else if (this.value.style == '6') width = [screenWidth - this.rpxUpPx(208) * 3 - this.rpxUpPx(this.value
|
||||||
|
.margin.both * 2) * 2] / 6;
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
},
|
},
|
||||||
@@ -399,18 +357,12 @@
|
|||||||
if (data != null) {
|
if (data != null) {
|
||||||
this.couponList = data;
|
this.couponList = data;
|
||||||
this.couponList.forEach(v => {
|
this.couponList.forEach(v => {
|
||||||
// if (v.count == v.lead_count) v.useState = 2;
|
if (v.max_fetch != 0 && v.member_coupon_num && v.member_coupon_num >= v
|
||||||
// else if (v.max_fetch != 0 && v.member_coupon_num && v.member_coupon_num >= v.max_fetch) v.useState = 1;
|
.max_fetch) {
|
||||||
// else v.useState = 0;
|
v.useState = 1;
|
||||||
// if(v.received_type && v.received_type == 'expire'){
|
} else {
|
||||||
// v.useState = 2;
|
v.useState = 0;
|
||||||
// }
|
}
|
||||||
|
|
||||||
if (v.count == v.lead_count) v.useState = 2;
|
|
||||||
else if (v.max_fetch == 0 || (v.max_fetch != 0 && !v.member_coupon_num) || (v.max_fetch != 0 && v.member_coupon_num && v.max_fetch > v.member_coupon_num)) v.useState = 0;
|
|
||||||
else if (v.wait_coupon_num) v.useState = 1
|
|
||||||
else if (v.lose_coupon_num) v.useState = 3;
|
|
||||||
else if (v.use_coupon_num) v.useState = 4;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
@@ -420,34 +372,18 @@
|
|||||||
couponAction(item, index) {
|
couponAction(item, index) {
|
||||||
if (item.useState == 0) {
|
if (item.useState == 0) {
|
||||||
this.receiveCoupon(item, index);
|
this.receiveCoupon(item, index);
|
||||||
} else {
|
} else if (parseInt(item.useState)) {
|
||||||
this.couponTap(item, index);
|
this.couponTap(item, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if(item.received_type == 'out'){
|
|
||||||
// this.$util.showToast({
|
|
||||||
// title: '该优惠券已抢光'
|
|
||||||
// });
|
|
||||||
// }else if(item.received_type == 'expire'){
|
|
||||||
// this.$util.showToast({
|
|
||||||
// title: '该优惠券已过期'
|
|
||||||
// });
|
|
||||||
// }else if(item.received_type == 'limit'){
|
|
||||||
// this.$util.showToast({
|
|
||||||
// title: '该优惠券领取已达上限'
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
couponTap(item, index) {
|
couponTap(item, index) {
|
||||||
if(item.useState == 2){
|
if (item.count == item.lead_count) {
|
||||||
this.$util.showToast({
|
this.$util.showToast({
|
||||||
title: '该优惠券已抢光'
|
title: '该优惠券已抢光'
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (item.useState == 0) this.receiveCoupon(item, index);
|
if (item.useState == 0) this.receiveCoupon(item, index);
|
||||||
else if (item.useState == 3 || item.useState == 4) this.$util.redirectTo('/pages_tool/member/coupon',{state: item.useState == 4 ? 2 : item.useState})
|
|
||||||
else this.toGoodsList(item);
|
else this.toGoodsList(item);
|
||||||
},
|
},
|
||||||
// 领取优惠券
|
// 领取优惠券
|
||||||
@@ -591,21 +527,17 @@
|
|||||||
|
|
||||||
.coupon-get {
|
.coupon-get {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 0;
|
top: 2rpx;
|
||||||
right: 12rpx;
|
right: 12rpx;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
letter-spacing: 16rpx;
|
letter-spacing: 16rpx;
|
||||||
width: 26rpx;
|
width: 26rpx;
|
||||||
|
|
||||||
&.use {
|
&.use {
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 4rpx;
|
right: 4rpx;
|
||||||
letter-spacing: 4rpx;
|
letter-spacing: 4rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.three-text {
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.coupon-info {
|
.coupon-info {
|
||||||
@@ -941,12 +873,6 @@
|
|||||||
line-height: 1;
|
line-height: 1;
|
||||||
transform: scale(0.8);
|
transform: scale(0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled {
|
|
||||||
background-color: #eee;
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.coupon-content {
|
.coupon-content {
|
||||||
@@ -1119,11 +1045,6 @@
|
|||||||
font-size: $font-size-tag;
|
font-size: $font-size-tag;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
&.three-text {
|
|
||||||
writing-mode: vertical-rl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,276 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view :style="componentStyle">
|
|
||||||
<scroll-view
|
|
||||||
:class="['graphic-nav', value.showStyle == 'fixed' ? 'fixed-layout' : value.showStyle]"
|
|
||||||
:scroll-x="value.showStyle == 'singleSlide'"
|
|
||||||
>
|
|
||||||
<view class="uni-scroll-view-content">
|
|
||||||
<view
|
|
||||||
v-for="(item, index) in value.list"
|
|
||||||
:key="index"
|
|
||||||
:class="['graphic-nav-item', value.mode, value.mode === 'text' ? 'newright' : '']"
|
|
||||||
:style="{ width: (100 / value.rowCount + '%') + ';' }"
|
|
||||||
>
|
|
||||||
<view style="display:flex;">
|
|
||||||
<view :style="{
|
|
||||||
'line-height': '1.2;',
|
|
||||||
'font-size': (value.font.titlesize * 2 + 'rpx') + ';',
|
|
||||||
'font-weight': '600;',
|
|
||||||
'color': value.font.titlecolor + ';'
|
|
||||||
}">
|
|
||||||
<uv-count-to
|
|
||||||
:ref="`countTo-${index}`"
|
|
||||||
:autoplay="true"
|
|
||||||
:startVal="30"
|
|
||||||
:endVal="item.title"
|
|
||||||
:decimals="getvalue(item.title)"
|
|
||||||
decimal="."
|
|
||||||
></uv-count-to>
|
|
||||||
<text :style="{
|
|
||||||
'margin-left': '4rpx;',
|
|
||||||
'font-size': (value.font.unitsize * 2 + 'rpx') + ';',
|
|
||||||
'font-weight': value.font.weight + ';',
|
|
||||||
'color': value.font.unitcolor + ';'
|
|
||||||
}">{{ item.unit }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="graphic-text">
|
|
||||||
<text :style="{
|
|
||||||
'font-size': (value.font.descsize * 2 + 'rpx') + ';',
|
|
||||||
'font-weight': value.font.weight + ';',
|
|
||||||
'color': value.font.desccolor + ';'
|
|
||||||
}">{{ item.desc }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
<ns-login ref="login"></ns-login>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import uvCountTo from '@/components/uv-count-to/uv-count-to.vue'
|
|
||||||
import nsLogin from '@/components/ns-login/ns-login.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'diy-digit',
|
|
||||||
components: {
|
|
||||||
uvCountTo,
|
|
||||||
nsLogin
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
value: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
pageWidth: '',
|
|
||||||
indicatorDots: false,
|
|
||||||
swiperCurrent: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// 组件创建时的逻辑
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
componentRefresh(newValue) {
|
|
||||||
// 监听组件刷新
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
componentStyle() {
|
|
||||||
let style = '';
|
|
||||||
style += 'background-image:url(' + this.$util.img(this.value.imageUrl) + ');background-size:100% 100%;';
|
|
||||||
|
|
||||||
if (this.value.componentAngle == 'round') {
|
|
||||||
style += 'border-top-left-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
|
|
||||||
style += 'border-top-right-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
|
|
||||||
style += 'border-bottom-left-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
|
|
||||||
style += 'border-bottom-right-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
|
|
||||||
}
|
|
||||||
|
|
||||||
style += 'box-shadow:' + (this.value.ornament.type == 'shadow' ? '0 0 10rpx ' + this.value.ornament.color : '') + ';';
|
|
||||||
style += 'border:' + (this.value.ornament.type == 'stroke' ? '2rpx solid ' + this.value.ornament.color : '') + ';';
|
|
||||||
|
|
||||||
return style;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 获取小数位数
|
|
||||||
getvalue(value) {
|
|
||||||
return value % 1 !== 0 ? 2 : 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 页面跳转
|
|
||||||
redirectTo(item) {
|
|
||||||
if (!item.wap_url || this.$util.getCurrRoute() != 'pages/member/index' || this.storeToken) {
|
|
||||||
console.log(item);
|
|
||||||
this.$util.diyRedirectTo(item);
|
|
||||||
} else {
|
|
||||||
this.$refs.login.open(item.wap_url);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 轮播切换
|
|
||||||
swiperChange(event) {
|
|
||||||
this.swiperCurrent = event.detail.current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.graphic-nav {
|
|
||||||
padding: 16rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&.fixed-layout {
|
|
||||||
.uni-scroll-view-content {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.singleSlide {
|
|
||||||
.uni-scroll-view-content {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.graphic-nav-item {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.pageSlide {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.uni-swiper-dots-horizontal {
|
|
||||||
bottom: 0rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.straightLine {
|
|
||||||
.uni-swiper-dot {
|
|
||||||
width: 30rpx;
|
|
||||||
border-radius: 0;
|
|
||||||
height: 8rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.circle {
|
|
||||||
.uni-swiper-dot {
|
|
||||||
width: 14rpx;
|
|
||||||
height: 14rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.graphic-nav-wrap {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.graphic-nav-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 14rpx 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.graphic-text {
|
|
||||||
line-height: 1.3;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
&.alone {
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text {
|
|
||||||
.graphic-text {
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.graphic-img {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100rpx;
|
|
||||||
height: 100rpx;
|
|
||||||
font-size: 90rpx;
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
position: absolute;
|
|
||||||
top: -10rpx;
|
|
||||||
right: -24rpx;
|
|
||||||
color: #fff;
|
|
||||||
border-radius: 24rpx;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
-webkit-transform: scale(0.8);
|
|
||||||
transform: scale(0.8);
|
|
||||||
padding: 8rpx 16rpx;
|
|
||||||
line-height: 1;
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
font-size: 50rpx;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.pageSlide {
|
|
||||||
.graphic-nav-item {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.newright {
|
|
||||||
margin-right: 16rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swiper-dot-box {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: -20rpx;
|
|
||||||
padding-bottom: 8rpx;
|
|
||||||
|
|
||||||
.swiper-dot {
|
|
||||||
background-color: rgba(0, 0, 0, 0.3);
|
|
||||||
margin: 8rpx;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background-color: #000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.straightLine {
|
|
||||||
.swiper-dot {
|
|
||||||
width: 30rpx;
|
|
||||||
border-radius: 0;
|
|
||||||
height: 8rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.circle {
|
|
||||||
.swiper-dot {
|
|
||||||
width: 15rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
height: 15rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,48 +1,48 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="value.pageStyle" v-if="list && list.length">
|
<view data-component-name="diy-fenxiao-goods-list" class="diy-fenxiao" v-if="list.length" :class="['goods-list', value.template, value.style]" :style="goodsListWarpCss">
|
||||||
<view class="diy-fenxiao" v-if="list.length" :class="['goods-list', value.template, value.style]" :style="goodsListWarpCss">
|
<view class="goods-item" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="goods-item" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
<view class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<view class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)"/>
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)"/>
|
</view>
|
||||||
|
<view class="info-wrap" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
|
||||||
|
<view class="name-wrap">
|
||||||
|
<view v-if="value.goodsNameStyle.control" class="goods-name"
|
||||||
|
:style="{ color: value.theme == 'diy' ? value.goodsNameStyle.color : '', fontWeight: value.goodsNameStyle.fontWeight ? 'bold' : '' }"
|
||||||
|
:class="[{ 'using-hidden': value.nameLineMode == 'single' }, { 'multi-hidden': value.nameLineMode == 'multiple' }]"
|
||||||
|
>
|
||||||
|
{{ item.goods_name }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-wrap" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
|
<view class="pro-info">
|
||||||
<view class="name-wrap">
|
<view class="discount-price">
|
||||||
<view v-if="value.goodsNameStyle.control" class="goods-name"
|
<view class="price-wrap" v-if="value.priceStyle.mainControl">
|
||||||
:style="{ color: value.theme == 'diy' ? value.goodsNameStyle.color : '', fontWeight: value.goodsNameStyle.fontWeight ? 'bold' : '' }"
|
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">赚 ¥</text>
|
||||||
:class="[{ 'using-hidden': value.nameLineMode == 'single' }, { 'multi-hidden': value.nameLineMode == 'multiple' }]"
|
<text class="price price-style large" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">{{ item.commission_money.split('.')[0] }}</text>
|
||||||
|
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">{{ '.' + item.commission_money.split('.')[1] }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="sale-btn" v-if="value.btnStyle.control && item.is_collect == 0"
|
||||||
|
:style="{
|
||||||
|
background: value.btnStyle.theme == 'diy' ? 'linear-gradient(to right,' + value.btnStyle.bgColorStart + ',' + value.btnStyle.bgColorEnd + ')' : '',
|
||||||
|
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
|
||||||
|
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
||||||
|
}"
|
||||||
|
@click.stop="followGoods(item, index)"
|
||||||
>
|
>
|
||||||
{{ item.goods_name }}
|
关注
|
||||||
|
</view>
|
||||||
|
<view class="sale-btn" v-if="value.btnStyle.control && item.is_collect == 1"
|
||||||
|
:style="{
|
||||||
|
background: value.btnStyle.theme == 'diy' ? 'linear-gradient(to right,' + value.btnStyle.bgColorStart + ',' + value.btnStyle.bgColorEnd + ')' : '',
|
||||||
|
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
|
||||||
|
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
||||||
|
}"
|
||||||
|
@click.stop="delFollowTip(item, index)"
|
||||||
|
>
|
||||||
|
取消关注
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="pro-info">
|
<view class="delete-price" v-if="value.priceStyle.lineControl" :style="{ color: value.theme == 'diy' ? value.priceStyle.lineColor : '' }">
|
||||||
<view class="discount-price">
|
¥{{ item.discount_price }}
|
||||||
<view class="price-wrap" v-if="value.priceStyle.mainControl">
|
|
||||||
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">赚 ¥</text>
|
|
||||||
<text class="price price-style large" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">{{ item.commission_money.split('.')[0] }}</text>
|
|
||||||
<text class="unit price-style small" :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">{{ '.' + item.commission_money.split('.')[1] }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="sale-btn" v-if="value.btnStyle.control && item.is_collect == 0"
|
|
||||||
:style="{
|
|
||||||
background: value.btnStyle.theme == 'diy' ? 'linear-gradient(to right,' + value.btnStyle.bgColorStart + ',' + value.btnStyle.bgColorEnd + ')' : '',
|
|
||||||
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
|
|
||||||
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
|
||||||
}"
|
|
||||||
@click.stop="followGoods(item, index)">
|
|
||||||
关注
|
|
||||||
</view>
|
|
||||||
<view class="sale-btn" v-if="value.btnStyle.control && item.is_collect == 1"
|
|
||||||
:style="{
|
|
||||||
background: value.btnStyle.theme == 'diy' ? 'linear-gradient(to right,' + value.btnStyle.bgColorStart + ',' + value.btnStyle.bgColorEnd + ')' : '',
|
|
||||||
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
|
|
||||||
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
|
||||||
}"
|
|
||||||
@click.stop="delFollowTip(item, index)">
|
|
||||||
取消关注
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="delete-price" v-if="value.priceStyle.lineControl" :style="{ color: value.theme == 'diy' ? value.priceStyle.lineColor : '' }">
|
|
||||||
¥{{ item.discount_price }}
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -55,10 +55,7 @@ export default {
|
|||||||
name: 'diy-fenxiao-goods-list',
|
name: 'diy-fenxiao-goods-list',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="value.pageStyle">
|
<view data-component-name="diy-float-btn" class="float-btn" :class="{ left_top: value.bottomPosition == 1, right_top: value.bottomPosition == 2, left_bottom: value.bottomPosition == 3, right_bottom: value.bottomPosition == 4 }" :style="style">
|
||||||
<view 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">
|
||||||
<block v-for="(item, index) in value.list" :key="index">
|
<view class="button-box" @click="$util.diyRedirectTo(item.link)" :style="{ width: value.imageSize + 'px', height: value.imageSize + 'px', fontSize: value.imageSize + 'px' }">
|
||||||
<view class="button-box" @click="$util.diyRedirectTo(item.link)" :style="{ width: value.imageSize + 'px', height: value.imageSize + 'px', fontSize: value.imageSize + 'px' }">
|
<image v-if="!item.iconType || item.iconType == 'img'" :src="$util.img(item.imageUrl)" mode="aspectFit" :show-menu-by-longpress="true"/>
|
||||||
<image v-if="!item.iconType || item.iconType == 'img'" :src="$util.img(item.imageUrl)" mode="aspectFit" :show-menu-by-longpress="true"/>
|
<diy-icon v-else-if="item.iconType && item.iconType == 'icon'" :icon="item.icon"
|
||||||
<diy-icon v-else-if="item.iconType && item.iconType == 'icon'" :icon="item.icon" :value="item.style ? item.style : null"></diy-icon>
|
:value="item.style ? item.style : null"></diy-icon>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- #ifdef MP -->
|
<!-- #ifdef MP -->
|
||||||
<view :style="value.pageStyle">
|
<view data-component-name="diy-follow-official-account" v-if="value.isShow">
|
||||||
<view v-if="value.isShow">
|
<official-account></official-account>
|
||||||
<official-account></official-account>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<!--#endif -->
|
<!--#endif -->
|
||||||
</template>
|
</template>
|
||||||
@@ -14,10 +12,7 @@
|
|||||||
name: 'diy-follow-official-account',
|
name: 'diy-follow-official-account',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="value.pageStyle" v-if="loading || (list && list.length)">
|
<x-skeleton data-component-name="diy-goods-brand" type="waterfall" :loading="loading" :configs="skeletonConfig">
|
||||||
<x-skeleton type="waterfall" :loading="loading" :configs="skeletonConfig">
|
<view :class="['brand-wrap', value.ornament.type]" :style="warpCss">
|
||||||
<view :class="['brand-wrap', value.ornament.type]" :style="warpCss">
|
<view :class="[value.style]">
|
||||||
<view :class="[value.style]">
|
<view class="title-wrap" v-show="value.title" :style="{ color: value.textColor, fontWeight: value.fontWeight ? 'bold' : '' }">{{ value.title }}
|
||||||
<view class="title-wrap" v-show="value.title" :style="{ color: value.textColor, fontWeight: value.fontWeight ? 'bold' : '' }">{{ value.title }}</view>
|
</view>
|
||||||
<view class="ul-wrap">
|
<view class="ul-wrap">
|
||||||
<view class="li-item" v-for="(item, index) in list" :key="index">
|
<view class="li-item" v-for="(item, index) in list" :key="index">
|
||||||
<image class="brand-pic" :src="$util.img(item.image_url)" mode="aspectFit" @click="toDetail(item)" @error="imgError(index)" :style="itemCss"/>
|
<image class="brand-pic" :src="$util.img(item.image_url)" mode="aspectFit" @click="handlerClick(item)" @tap="handlerClick(item)" @error="imgError(index)" :style="itemCss"/>
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</x-skeleton>
|
</view>
|
||||||
</view>
|
</x-skeleton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -26,10 +25,7 @@
|
|||||||
name: 'diy-goods-brand',
|
name: 'diy-goods-brand',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<block v-if="value.showStyle == 'pageSlide'">
|
<block v-if="value.showStyle == 'pageSlide'">
|
||||||
<swiper :class="['graphic-nav', 'pageSlide', value.carousel.type]" circular :indicator-dots="false" :style="swiperHeight" @change="swiperChange">
|
<swiper :class="['graphic-nav', 'pageSlide', value.carousel.type]" circular :indicator-dots="false" :style="swiperHeight" @change="swiperChange">
|
||||||
<swiper-item class="graphic-nav-wrap"
|
<swiper-item class="graphic-nav-wrap"
|
||||||
v-for="(numItem, numIndex) in Math.ceil(value.list.length / (value.pageCount * value.rowCount))" :key="numIndex">
|
v-for="(numItem, numIndex) in Math.ceil(value.list.length / (value.pageCount * value.rowCount))">
|
||||||
<!-- #ifdef MP -->
|
<!-- #ifdef MP -->
|
||||||
<view class="graphic-nav-item" :class="[value.mode]" v-for="(item, index) in value.list"
|
<view class="graphic-nav-item" :class="[value.mode]" v-for="(item, index) in value.list"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
|||||||
@@ -223,7 +223,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 组件组
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@@ -1,290 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view :style="componentStyle">
|
|
||||||
<scroll-view
|
|
||||||
:class="['image-nav', value.showStyle == 'fixed' ? 'fixed-layout' : value.showStyle]"
|
|
||||||
:scroll-x="value.showStyle == 'singleSlide'"
|
|
||||||
>
|
|
||||||
<view class="uni-scroll-view-content">
|
|
||||||
<view
|
|
||||||
v-for="(item, index) in value.list"
|
|
||||||
:key="index"
|
|
||||||
:class="['image-nav-item', value.mode]"
|
|
||||||
style="margin-right: 28rpx;"
|
|
||||||
>
|
|
||||||
<!-- 图片部分 -->
|
|
||||||
<view v-if="value.mode != 'text'" class="image-img" :style="{
|
|
||||||
'font-size': (value.imageSize * 2 + 'rpx') + ';',
|
|
||||||
'width': (item.imgWidth / 2 + 'rpx') + ';',
|
|
||||||
'height': (item.imgHeight / 2 + 'rpx') + ';'
|
|
||||||
}">
|
|
||||||
<image
|
|
||||||
v-if="item.link.wap_url"
|
|
||||||
:style="{
|
|
||||||
'width': (item.imgWidth / 2 + 'rpx') + ';',
|
|
||||||
'height': (item.imgHeight / 2 + 'rpx') + ';'
|
|
||||||
}"
|
|
||||||
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
|
||||||
:show-menu-by-longpress="true"
|
|
||||||
@tap="redirectTo(item.link)"
|
|
||||||
></image>
|
|
||||||
<image
|
|
||||||
v-else
|
|
||||||
:style="{
|
|
||||||
'width': (item.imgWidth / 2 + 'rpx') + ';',
|
|
||||||
'height': (item.imgHeight / 2 + 'rpx') + ';'
|
|
||||||
}"
|
|
||||||
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
|
||||||
:show-menu-by-longpress="true"
|
|
||||||
@tap="previewImg(item.imageUrl)"
|
|
||||||
></image>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 文字部分 -->
|
|
||||||
<text class="image-text" :style="{
|
|
||||||
'width': (item.imgWidth / 2 + 'rpx') + ';',
|
|
||||||
'font-size': (value.font.size * 2 + 'rpx') + ';',
|
|
||||||
'font-weight': value.font.weight + ';',
|
|
||||||
'color': value.font.color + ';'
|
|
||||||
}">{{ item.title }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
<ns-login ref="login"></ns-login>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import nsLogin from '@/components/ns-login/ns-login.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'diy-image-nav',
|
|
||||||
components: {
|
|
||||||
nsLogin
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
value: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
pageWidth: '',
|
|
||||||
indicatorDots: false,
|
|
||||||
swiperCurrent: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// 组件创建时的逻辑
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
componentRefresh(newValue) {
|
|
||||||
// 监听组件刷新
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
componentStyle() {
|
|
||||||
let style = '';
|
|
||||||
style += 'background-color:' + this.value.componentBgColor + ';';
|
|
||||||
|
|
||||||
if (this.value.componentAngle == 'round') {
|
|
||||||
style += 'border-top-left-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
|
|
||||||
style += 'border-top-right-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
|
|
||||||
style += 'border-bottom-left-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
|
|
||||||
style += 'border-bottom-right-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
|
|
||||||
}
|
|
||||||
|
|
||||||
style += 'box-shadow:' + (this.value.ornament.type == 'shadow' ? '0 0 10rpx ' + this.value.ornament.color : '') + ';';
|
|
||||||
style += 'border:' + (this.value.ornament.type == 'stroke' ? '2rpx solid ' + this.value.ornament.color : '') + ';';
|
|
||||||
|
|
||||||
return style;
|
|
||||||
},
|
|
||||||
|
|
||||||
swiperHeight() {
|
|
||||||
let height = 0;
|
|
||||||
|
|
||||||
if (this.value.mode == 'graphic') {
|
|
||||||
height = (49 + this.value.imageSize) * this.value.pageCount;
|
|
||||||
} else if (this.value.mode == 'img') {
|
|
||||||
height = (22 + this.value.imageSize) * this.value.pageCount;
|
|
||||||
} else if (this.value.mode == 'text') {
|
|
||||||
height = 43 * this.value.pageCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'height:' + (2 * height) + 'rpx';
|
|
||||||
},
|
|
||||||
|
|
||||||
isIndicatorDots() {
|
|
||||||
return this.value.carousel.type != 'hide' &&
|
|
||||||
1 != Math.ceil(this.value.list.length / (this.value.pageCount * this.value.rowCount));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 预览图片
|
|
||||||
previewImg(imageUrl) {
|
|
||||||
uni.previewImage({
|
|
||||||
current: 0,
|
|
||||||
urls: [this.$util.img(imageUrl)],
|
|
||||||
success: (res) => {},
|
|
||||||
fail: (res) => {},
|
|
||||||
complete: (res) => {}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 页面跳转
|
|
||||||
redirectTo(link) {
|
|
||||||
if (!link.wap_url || this.$util.getCurrRoute() != 'pages/member/index' || this.storeToken) {
|
|
||||||
this.$util.diyRedirectTo(link);
|
|
||||||
} else {
|
|
||||||
this.$refs.login.open(link.wap_url);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 轮播切换
|
|
||||||
swiperChange(event) {
|
|
||||||
this.swiperCurrent = event.detail.current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.image-nav {
|
|
||||||
padding: 16rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&.fixed-layout {
|
|
||||||
.uni-scroll-view-content {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.singleSlide {
|
|
||||||
.uni-scroll-view-content {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-nav-item {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.pageSlide {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.uni-swiper-dots-horizontal {
|
|
||||||
bottom: 0rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.straightLine {
|
|
||||||
.uni-swiper-dot {
|
|
||||||
width: 30rpx;
|
|
||||||
border-radius: 0;
|
|
||||||
height: 8rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.circle {
|
|
||||||
.uni-swiper-dot {
|
|
||||||
width: 14rpx;
|
|
||||||
height: 14rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-nav-wrap {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-nav-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 14rpx 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.image-text {
|
|
||||||
padding-top: 12rpx;
|
|
||||||
line-height: 1.5;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
&.alone {
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text {
|
|
||||||
.image-text {
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-img {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 90rpx;
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
position: absolute;
|
|
||||||
top: -10rpx;
|
|
||||||
right: -24rpx;
|
|
||||||
color: #fff;
|
|
||||||
border-radius: 24rpx;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
-webkit-transform: scale(0.8);
|
|
||||||
transform: scale(0.8);
|
|
||||||
padding: 8rpx 16rpx;
|
|
||||||
line-height: 1;
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
font-size: 50rpx;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.swiper-dot-box {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: -20rpx;
|
|
||||||
padding-bottom: 8rpx;
|
|
||||||
|
|
||||||
.swiper-dot {
|
|
||||||
background-color: rgba(0, 0, 0, 0.3);
|
|
||||||
margin: 8rpx;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background-color: #000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.straightLine {
|
|
||||||
.swiper-dot {
|
|
||||||
width: 30rpx;
|
|
||||||
border-radius: 0;
|
|
||||||
height: 8rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.circle {
|
|
||||||
.swiper-dot {
|
|
||||||
width: 15rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
height: 15rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -268,7 +268,7 @@
|
|||||||
.exec();
|
.exec();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setModuleLocationFn();
|
this.setModuleLocatinoFn();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initPageIndex() {
|
initPageIndex() {
|
||||||
@@ -415,7 +415,7 @@
|
|||||||
this.isUnfold = !this.isUnfold;
|
this.isUnfold = !this.isUnfold;
|
||||||
},
|
},
|
||||||
// 向vuex中的diyIndexPositionObj增加分类导航组件定位位置
|
// 向vuex中的diyIndexPositionObj增加分类导航组件定位位置
|
||||||
setModuleLocationFn() {
|
setModuleLocatinoFn() {
|
||||||
const query = uni.createSelectorQuery().in(this);
|
const query = uni.createSelectorQuery().in(this);
|
||||||
query.select('.nav-top-category')
|
query.select('.nav-top-category')
|
||||||
.boundingClientRect(data => {
|
.boundingClientRect(data => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<view data-component-name="diy-kefu" class="diy-kefu" :style="style">
|
<view data-component-name="diy-kefu" class="diy-kefu" :style="style">
|
||||||
<view class="fui-list-group merchgroup" v-for="(item,index) in value.list" :key="index">
|
<view class="fui-list-group merchgroup" v-for="(item,index) in value.list">
|
||||||
<view class="fui-list jump" v-if="index == 0">
|
<view class="fui-list jump" v-if="index == 0">
|
||||||
<view class="fui-list-media">
|
<view class="fui-list-media">
|
||||||
<image class="round" :src="$util.img(item.imageUrl)" style="border-radius:6rpx"></image>
|
<image class="round" :src="$util.img(item.imageUrl)" style="border-radius:6rpx"></image>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<view class="fui-cell-group">
|
<view class="fui-cell-group">
|
||||||
<!-- <image mode="widthFix" style="width: 100%;" :src="$util.img(item.imageUrl)"></image> -->
|
<!-- <image mode="widthFix" style="width: 100%;" :src="$util.img(item.imageUrl)"></image> -->
|
||||||
|
|
||||||
<view v-for="(item,index) in value.list" @click="redirectTo(item.link)" class="fui-cell" :class="item.iconType == 'img'?'img-cell':''" :key="index">
|
<view v-for="(item,index) in value.list" @click="redirectTo(item.link)" class="fui-cell" :class="item.iconType == 'img'?'img-cell':''">
|
||||||
<view class="fui-cell-icon" style="color:diyitem.style.iconcolo">
|
<view class="fui-cell-icon" style="color:diyitem.style.iconcolo">
|
||||||
<diy-icon v-if="item.iconType == 'icon'" :icon="item.icon"
|
<diy-icon v-if="item.iconType == 'icon'" :icon="item.icon"
|
||||||
:value="item.style ? item.style : null"
|
:value="item.style ? item.style : null"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<view data-component-name="diy-map" class="diy-map" :style="style">
|
<view data-component-name="diy-map" class="diy-map" :style="style">
|
||||||
<view class="fui-list-group merchgroup" style="margin-top:0" v-for="(item,index) in value.list" :key="index">
|
<view class="fui-list-group merchgroup" style="margin-top:0" v-for="(item,index) in value.list">
|
||||||
<map
|
<map
|
||||||
id="map"
|
id="map"
|
||||||
style="width: 100%; height:600rpx"
|
style="width: 100%; height:600rpx"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view data-component-name="diy-picture" class="diy-picture" :style="style">
|
<view data-component-name="diy-picture" class="diy-picture" :style="style">
|
||||||
<view class="fui-picture">
|
<view class="fui-picture">
|
||||||
<view v-for="(item,index) in value.list" style="line-height: 0;" :key="index">
|
<view v-for="(item,index) in value.list" style="line-height: 0;">
|
||||||
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-if="item.link.wap_url" @click="handlerClick(item)" @tap="handlerClick(item)"></image>
|
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-if="item.link.wap_url" @click="handlerClick(item)" @tap="handlerClick(item)"></image>
|
||||||
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-else @click="handlerClick(item)" @tap="handlerClick(item)"></image>
|
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-else @click="handlerClick(item)" @tap="handlerClick(item)"></image>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -173,7 +173,7 @@
|
|||||||
if (this.value.ornament.type == 'stroke') {
|
if (this.value.ornament.type == 'stroke') {
|
||||||
obj += 'border:' + '2rpx solid ' + this.value.ornament.color + ';';
|
obj += 'border:' + '2rpx solid ' + this.value.ornament.color + ';';
|
||||||
}
|
}
|
||||||
const screenWidth = uni.getWindowInfo().windowWidth;
|
const screenWidth = uni.getSystemInfoSync().windowWidth;
|
||||||
if (this.value.template == 'horizontal-slide') {
|
if (this.value.template == 'horizontal-slide') {
|
||||||
var width = "";
|
var width = "";
|
||||||
if (this.value.slideMode == 'scroll' && this.value.goodsMarginType == 'diy')
|
if (this.value.slideMode == 'scroll' && this.value.goodsMarginType == 'diy')
|
||||||
@@ -217,7 +217,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
rpxUpPx(res) {
|
rpxUpPx(res) {
|
||||||
const screenWidth = uni.getWindowInfo().windowWidth;
|
const screenWidth = uni.getSystemInfoSync().windowWidth;
|
||||||
var data = screenWidth * parseInt(res) / 750;
|
var data = screenWidth * parseInt(res) / 750;
|
||||||
return Math.floor(data);
|
return Math.floor(data);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="value.pageStyle">
|
|
||||||
<view data-component-name="diy-search" class="diy-search">
|
<view data-component-name="diy-search" class="diy-search">
|
||||||
<view class="diy-search-wrap" :class="value.positionWay" :style="fixedCss">
|
<view class="diy-search-wrap" :class="value.positionWay" :style="fixedCss">
|
||||||
<view :class="['search-box','search-box-'+value.searchStyle]" :style="searchWrapCss" @click="handlerSearchClick" @tap="handlerSearchClick">
|
<view :class="['search-box','search-box-'+value.searchStyle]" :style="searchWrapCss" @click="handlerSearchClick" @tap="handlerSearchClick">
|
||||||
@@ -34,19 +33,11 @@
|
|||||||
<view v-if="value.positionWay == 'fixed'" class="u-navbar-placeholder" :style="{ width: '100%', paddingTop: moduleHeight }"></view>
|
<view v-if="value.positionWay == 'fixed'" class="u-navbar-placeholder" :style="{ width: '100%', paddingTop: moduleHeight }"></view>
|
||||||
<ns-login ref="login"></ns-login>
|
<ns-login ref="login"></ns-login>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 获取系统状态栏的高度
|
// 获取系统状态栏的高度
|
||||||
let systemInfo = {};
|
let systemInfo = uni.getSystemInfoSync();
|
||||||
try {
|
|
||||||
// 合并设备信息和窗口信息
|
|
||||||
systemInfo = {...uni.getDeviceInfo(), ...uni.getWindowInfo()};
|
|
||||||
} catch (e) {
|
|
||||||
// 兼容旧版本
|
|
||||||
systemInfo = uni.getSystemInfoSync();
|
|
||||||
}
|
|
||||||
let menuButtonInfo = {};
|
let menuButtonInfo = {};
|
||||||
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||||
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||||
@@ -134,7 +125,7 @@
|
|||||||
},
|
},
|
||||||
fixedTop() {
|
fixedTop() {
|
||||||
let diyPositionObj = this.$store.state.diyGroupPositionObj;
|
let diyPositionObj = this.$store.state.diyGroupPositionObj;
|
||||||
let data = 0;
|
let data = 0
|
||||||
if (diyPositionObj.diySearch && diyPositionObj.diyIndexPage && diyPositionObj.nsNavbar) {
|
if (diyPositionObj.diySearch && diyPositionObj.diyIndexPage && diyPositionObj.nsNavbar) {
|
||||||
if (diyPositionObj.diySearch.moduleIndex > diyPositionObj.diyIndexPage.moduleIndex) {
|
if (diyPositionObj.diySearch.moduleIndex > diyPositionObj.diyIndexPage.moduleIndex) {
|
||||||
data = diyPositionObj.nsNavbar.originalVal + diyPositionObj.diyIndexPage.originalVal;
|
data = diyPositionObj.nsNavbar.originalVal + diyPositionObj.diyIndexPage.originalVal;
|
||||||
@@ -184,7 +175,7 @@
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.value.positionWay == 'fixed')
|
if (this.value.positionWay == 'fixed')
|
||||||
this.setModuleLocationFn();
|
this.setModuleLocatinoFn();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
search() {
|
search() {
|
||||||
@@ -213,7 +204,7 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 向vuex中的diyIndexPositionObj增加搜索组件定位位置
|
// 向vuex中的diyIndexPositionObj增加搜索组件定位位置
|
||||||
setModuleLocationFn() {
|
setModuleLocatinoFn() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
const query = uni.createSelectorQuery().in(this);
|
const query = uni.createSelectorQuery().in(this);
|
||||||
query.select('.diy-search-wrap')
|
query.select('.diy-search-wrap')
|
||||||
|
|||||||
@@ -181,7 +181,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 秒杀
|
|
||||||
export default {
|
export default {
|
||||||
name: 'diy-seckill',
|
name: 'diy-seckill',
|
||||||
props: {
|
props: {
|
||||||
@@ -258,7 +257,7 @@
|
|||||||
if (this.value.ornament.type == 'stroke') {
|
if (this.value.ornament.type == 'stroke') {
|
||||||
obj += 'border:' + '2rpx solid ' + this.value.ornament.color + ';';
|
obj += 'border:' + '2rpx solid ' + this.value.ornament.color + ';';
|
||||||
}
|
}
|
||||||
const screenWidth = uni.getWindowInfo().windowWidth;
|
const screenWidth = uni.getSystemInfoSync().windowWidth;
|
||||||
if (this.value.template == 'horizontal-slide') {
|
if (this.value.template == 'horizontal-slide') {
|
||||||
var width = '';
|
var width = '';
|
||||||
if (this.value.slideMode == 'scroll' && this.value.goodsMarginType == 'diy') width = this.rpxUpPx(this.value.goodsMarginNum * 2);
|
if (this.value.slideMode == 'scroll' && this.value.goodsMarginType == 'diy') width = this.rpxUpPx(this.value.goodsMarginNum * 2);
|
||||||
@@ -312,7 +311,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
rpxUpPx(res) {
|
rpxUpPx(res) {
|
||||||
const screenWidth = uni.getWindowInfo().screenWidth;
|
const screenWidth = uni.getSystemInfoSync().screenWidth;
|
||||||
var data = (screenWidth * parseInt(res)) / 750;
|
var data = (screenWidth * parseInt(res)) / 750;
|
||||||
return Math.floor(data);
|
return Math.floor(data);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="value.pageStyle">
|
|
||||||
<x-skeleton data-component-name="diy-store-label" type="banner" :loading="loading" :configs="skeletonConfig">
|
<x-skeleton data-component-name="diy-store-label" type="banner" :loading="loading" :configs="skeletonConfig">
|
||||||
<view class="diy-store-label">
|
<view class="diy-store-label">
|
||||||
<block v-if="businessConfig.store_business == 'store'">
|
<block v-if="businessConfig.store_business == 'store'">
|
||||||
<scroll-view scroll-x="true" :class="[value.contentStyle, { between: list.length == 3 }]" :style="storeLabelWrapCss" :enable-flex="true">
|
<scroll-view scroll-x="true" :class="[value.contentStyle, { between: list.length == 3 }]" :style="storeLabelWrapCss" :enable-flex="true">
|
||||||
<view v-for="(item, index) in storeLabel" :class="['item']" :key="index">
|
<view v-for="(item, index) in storeLabel" :class="['item']">
|
||||||
<diy-icon v-if="value.icon" class="icon-box" :icon="value.icon" :value="value.style ? value.style : 'null'"></diy-icon>
|
<diy-icon v-if="value.icon" class="icon-box" :icon="value.icon" :value="value.style ? value.style : 'null'"></diy-icon>
|
||||||
<text class="label-name" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx', fontWeight: value.fontWeight }">{{ item }}</text>
|
<text class="label-name" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx', fontWeight: value.fontWeight }">{{ item }}</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -12,7 +11,7 @@
|
|||||||
</block>
|
</block>
|
||||||
<block v-else>
|
<block v-else>
|
||||||
<scroll-view scroll-x="true" :class="[value.contentStyle, { between: list.length == 3 }]" :style="storeLabelWrapCss" :enable-flex="true">
|
<scroll-view scroll-x="true" :class="[value.contentStyle, { between: list.length == 3 }]" :style="storeLabelWrapCss" :enable-flex="true">
|
||||||
<view v-for="(item, index) in list" :class="['item']" :key="item.label_id || index">
|
<view v-for="(item, index) in list" :class="['item']">
|
||||||
<diy-icon v-if="value.icon" class="icon-box" :icon="value.icon" :value="value.style ? value.style : 'null'"></diy-icon>
|
<diy-icon v-if="value.icon" class="icon-box" :icon="value.icon" :value="value.style ? value.style : 'null'"></diy-icon>
|
||||||
<text class="label-name" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx', fontWeight: value.fontWeight }">{{ item.label_name }}</text>
|
<text class="label-name" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx', fontWeight: value.fontWeight }">{{ item.label_name }}</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -20,7 +19,6 @@
|
|||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
</x-skeleton>
|
</x-skeleton>
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
// 门店标签
|
// 门店标签
|
||||||
@@ -28,10 +26,7 @@
|
|||||||
name: 'diy-store-label',
|
name: 'diy-store-label',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="value.pageStyle">
|
|
||||||
<view data-component-name="diy-store" class="store-wrap">
|
<view data-component-name="diy-store" class="store-wrap">
|
||||||
<block v-if="value.style == 1">
|
<block v-if="value.style == 1">
|
||||||
<view class="store-box store-one">
|
<view class="store-box store-one">
|
||||||
@@ -66,7 +65,6 @@
|
|||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -76,10 +74,7 @@ export default {
|
|||||||
name: 'diy-store',
|
name: 'diy-store',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="value.pageStyle">
|
|
||||||
<view data-component-name="diy-text" class="diy-text" @click="handlerClick(value.link)" @tap="handlerClick(value.link)" :style="warpCss">
|
<view data-component-name="diy-text" class="diy-text" @click="handlerClick(value.link)" @tap="handlerClick(value.link)" :style="warpCss">
|
||||||
<view :class="value.style == 'style-8' ? 'title2' : 'title'" :style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor }">
|
<view :class="value.style == 'style-8' ? 'title2' : 'title'" :style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor }">
|
||||||
<block v-if="value.style == 'style-0'" style="height: 40rpx; line-height: 40rpx;">
|
<block v-if="value.style == 'style-0'" style="height: 40rpx; line-height: 40rpx;">
|
||||||
@@ -255,7 +254,6 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -265,10 +263,7 @@ export default {
|
|||||||
name: 'diy-text',
|
name: 'diy-text',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -1,704 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view :style="componentStyle">
|
|
||||||
<!-- 固定布局模式 -->
|
|
||||||
<view v-if="value.showStyle == 'fixed'" :class="['goods-list', 'row1-of' + value.rowCount]" style="padding:20rpx;">
|
|
||||||
<view
|
|
||||||
v-for="(item, index) in value.list"
|
|
||||||
:key="index"
|
|
||||||
class="goods-item"
|
|
||||||
@tap="showVideo(item)"
|
|
||||||
>
|
|
||||||
<view class="goods-img-wrap">
|
|
||||||
<image
|
|
||||||
class="goods-img"
|
|
||||||
style="border-radius:10rpx 10rpx 0 0;"
|
|
||||||
:src="$util.img(item.imageUrl)"
|
|
||||||
mode="widthFix"
|
|
||||||
@error="imgError(index)"
|
|
||||||
></image>
|
|
||||||
<view style="position:absolute;top:10rpx;right:10rpx;">
|
|
||||||
<image style="width:30rpx;" :src="$util.img('addon/personnel/shop/view/enterprise/play.png')" mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="info-wrap">
|
|
||||||
<view
|
|
||||||
class="goods-name"
|
|
||||||
:style="{
|
|
||||||
'font-size': (value.font.size * 2 + 'rpx') + ';',
|
|
||||||
'font-weight': value.font.weight + ';',
|
|
||||||
'color': value.font.color + ';'
|
|
||||||
}"
|
|
||||||
>{{ item.title }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 其他布局模式 -->
|
|
||||||
<scroll-view
|
|
||||||
v-else
|
|
||||||
:class="['video-nav', value.showStyle == 'fixed' ? 'fixed-layout' : value.showStyle]"
|
|
||||||
:scroll-x="value.showStyle == 'singleSlide'"
|
|
||||||
>
|
|
||||||
<view class="uni-scroll-view-content">
|
|
||||||
<view
|
|
||||||
v-for="(item, index) in value.list"
|
|
||||||
:key="index"
|
|
||||||
:class="['video-nav-item', value.mode]"
|
|
||||||
:style="{ width: (100 / value.rowCount + '%') + ';' }"
|
|
||||||
@tap="showVideo(item)"
|
|
||||||
>
|
|
||||||
<view class="video-img">
|
|
||||||
<image
|
|
||||||
v-if="item.iconType == 'img'"
|
|
||||||
:style="{
|
|
||||||
'max-width': '200rpx;',
|
|
||||||
'max-height': '200rpx;',
|
|
||||||
'border-radius': '8rpx;'
|
|
||||||
}"
|
|
||||||
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
|
||||||
mode="widthFix"
|
|
||||||
:show-menu-by-longpress="true"
|
|
||||||
></image>
|
|
||||||
<view style="position:absolute;top:10rpx;right:10rpx;">
|
|
||||||
<image style="width:30rpx;" :src="$util.img('addon/personnel/shop/view/enterprise/play.png')" mode="widthFix"></image>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
class="video-text"
|
|
||||||
:style="{
|
|
||||||
'margin-left': '16rpx;',
|
|
||||||
'font-size': (value.font.size * 2 + 'rpx') + ';',
|
|
||||||
'font-weight': value.font.weight + ';',
|
|
||||||
'color': value.font.color + ';'
|
|
||||||
}"
|
|
||||||
>{{ item.title }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
|
|
||||||
<!-- 视频播放弹窗 -->
|
|
||||||
<uni-popup
|
|
||||||
ref="videoPopup"
|
|
||||||
type="center"
|
|
||||||
style="background:transparent;width:100%;height:100%;"
|
|
||||||
>
|
|
||||||
<view class="video-container" style="position:fixed;top:30%;width:100%;left:0;">
|
|
||||||
<video
|
|
||||||
class="adaptive-video"
|
|
||||||
:autoPauseIfNavigate="true"
|
|
||||||
:autoPauseIfOpenNative="true"
|
|
||||||
:autoplay="false"
|
|
||||||
:enableAutoRotation="true"
|
|
||||||
id="myVideo"
|
|
||||||
:src="video_url"
|
|
||||||
:controls="true"
|
|
||||||
></video>
|
|
||||||
</view>
|
|
||||||
</uni-popup>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import uniPopup from '@/components/uni-popup/uni-popup.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'diy-video-list',
|
|
||||||
components: {
|
|
||||||
uniPopup
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
value: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
pageWidth: '',
|
|
||||||
indicatorDots: false,
|
|
||||||
swiperCurrent: 0,
|
|
||||||
video_url: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// 组件创建时的逻辑
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
componentRefresh(newValue) {
|
|
||||||
// 监听组件刷新
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
componentStyle() {
|
|
||||||
let style = '';
|
|
||||||
style += 'background-color:' + this.value.componentBgColor + ';';
|
|
||||||
|
|
||||||
if (this.value.componentAngle == 'round') {
|
|
||||||
style += 'border-top-left-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
|
|
||||||
style += 'border-top-right-radius:' + (2 * this.value.topAroundRadius) + 'rpx;';
|
|
||||||
style += 'border-bottom-left-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
|
|
||||||
style += 'border-bottom-right-radius:' + (2 * this.value.bottomAroundRadius) + 'rpx;';
|
|
||||||
}
|
|
||||||
|
|
||||||
style += 'box-shadow:' + (this.value.ornament.type == 'shadow' ? '0 0 10rpx ' + this.value.ornament.color : '') + ';';
|
|
||||||
style += 'border:' + (this.value.ornament.type == 'stroke' ? '2rpx solid ' + this.value.ornament.color : '') + ';';
|
|
||||||
|
|
||||||
console.log(this.value);
|
|
||||||
|
|
||||||
return style;
|
|
||||||
},
|
|
||||||
|
|
||||||
swiperHeight() {
|
|
||||||
let height = 0;
|
|
||||||
|
|
||||||
if (this.value.mode == 'graphic') {
|
|
||||||
height = (49 + this.value.imageSize) * this.value.pageCount;
|
|
||||||
} else if (this.value.mode == 'img') {
|
|
||||||
height = (22 + this.value.imageSize) * this.value.pageCount;
|
|
||||||
} else if (this.value.mode == 'text') {
|
|
||||||
height = 43 * this.value.pageCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'height:' + (2 * height) + 'rpx';
|
|
||||||
},
|
|
||||||
|
|
||||||
isIndicatorDots() {
|
|
||||||
return this.value.carousel.type != 'hide' &&
|
|
||||||
1 != Math.ceil(this.value.list.length / (this.value.pageCount * this.value.rowCount));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 显示视频播放弹窗
|
|
||||||
showVideo(item) {
|
|
||||||
this.video_url = item.videoUrl;
|
|
||||||
this.$refs.videoPopup.open();
|
|
||||||
},
|
|
||||||
|
|
||||||
// 图片加载错误处理
|
|
||||||
imgError(index) {
|
|
||||||
// 图片加载失败的处理逻辑
|
|
||||||
console.log('图片加载失败:', index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.goods-name {
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.goods-list {
|
|
||||||
&.row1-of3 {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
.goods-item {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-top: 20rpx;
|
|
||||||
width: calc(33.3333333% - 14rpx);
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&:nth-child(3n + 3) {
|
|
||||||
width: calc(33.33% - 15rpx);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(1), &:nth-of-type(2), &:nth-of-type(3) {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(3n) {
|
|
||||||
width: calc(33.3333333% - 15rpx);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(3n-1) {
|
|
||||||
margin-left: 20rpx;
|
|
||||||
margin-right: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.shadow {
|
|
||||||
width: calc(33.3333333% - 18rpx);
|
|
||||||
|
|
||||||
&:nth-of-type(1), &:nth-of-type(2), &:nth-of-type(3) {
|
|
||||||
margin-top: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(1n) {
|
|
||||||
margin-left: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(3n-1) {
|
|
||||||
margin-left: 20rpx;
|
|
||||||
margin-right: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(3n) {
|
|
||||||
margin-right: 0;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.goods-img-wrap {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
height: 220rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.goods-img {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-wrap {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
.pro-info {
|
|
||||||
margin-top: auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
.discount-price {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.price-wrap {
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
.unit {
|
|
||||||
font-size: 24rpx !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.price {
|
|
||||||
font-size: 32rpx;
|
|
||||||
|
|
||||||
text {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-price {
|
|
||||||
text-decoration: line-through;
|
|
||||||
flex: 1;
|
|
||||||
line-height: 28rpx;
|
|
||||||
color: #909399;
|
|
||||||
font-size: 20rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.style-1 {
|
|
||||||
.pro-info {
|
|
||||||
.price-wrap {
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discount-price {
|
|
||||||
justify-content: unset !important;
|
|
||||||
align-items: baseline !important;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-price {
|
|
||||||
margin-left: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.style-2 {
|
|
||||||
.pro-info {
|
|
||||||
position: relative;
|
|
||||||
flex-direction: row !important;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.price-wrap {
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discount-price {
|
|
||||||
align-items: flex-end !important;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: unset !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-price {
|
|
||||||
margin: 20rpx 0;
|
|
||||||
flex-basis: 100% !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buy-btn {
|
|
||||||
min-width: 112rpx;
|
|
||||||
height: 52rpx;
|
|
||||||
padding: 0 20rpx;
|
|
||||||
line-height: 52rpx;
|
|
||||||
text-align: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sell-out {
|
|
||||||
text {
|
|
||||||
font-size: 150rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.row1-of2 {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
.goods-item {
|
|
||||||
position: relative;
|
|
||||||
margin-top: 20rpx;
|
|
||||||
width: calc(50% - 10rpx);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&:nth-child(2n) {
|
|
||||||
margin-right: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(1), &:nth-of-type(2) {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.shadow {
|
|
||||||
width: calc(50% - 18rpx);
|
|
||||||
|
|
||||||
&:nth-child(2n-1) {
|
|
||||||
margin-left: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2n) {
|
|
||||||
margin-right: 8rpx !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-of-type(1), &:nth-of-type(2) {
|
|
||||||
margin-top: 8rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.goods-img-wrap {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
height: 340rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.goods-img {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-wrap {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
.sale {
|
|
||||||
flex-basis: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pro-info {
|
|
||||||
margin-top: auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
.discount-price {
|
|
||||||
.price-wrap {
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
.unit {
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 24rpx !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.price {
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 32rpx !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-price {
|
|
||||||
text-decoration: line-through;
|
|
||||||
flex: 1;
|
|
||||||
line-height: 28rpx;
|
|
||||||
color: #909399;
|
|
||||||
font-size: 20rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.style-1 {
|
|
||||||
.pro-info {
|
|
||||||
.discount-price {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: baseline;
|
|
||||||
|
|
||||||
.price-wrap {
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
text {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-price {
|
|
||||||
margin-top: 6rpx;
|
|
||||||
flex-basis: 100% !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.style-2 {
|
|
||||||
.pro-info {
|
|
||||||
position: relative;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.price-wrap {
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discount-price {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-price {
|
|
||||||
margin-top: 4rpx;
|
|
||||||
flex-basis: 100% !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sale {
|
|
||||||
line-height: 1;
|
|
||||||
margin-top: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buy-btn {
|
|
||||||
min-width: 140rpx;
|
|
||||||
height: 52rpx;
|
|
||||||
padding: 0 20rpx;
|
|
||||||
line-height: 52rpx;
|
|
||||||
text-align: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.style-3 {
|
|
||||||
.pro-info {
|
|
||||||
.member-price {
|
|
||||||
margin-right: auto;
|
|
||||||
align-self: flex-end;
|
|
||||||
margin-bottom: 4rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sale {
|
|
||||||
line-height: 1;
|
|
||||||
align-self: center;
|
|
||||||
margin-top: 8rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discount-price {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
flex: 1;
|
|
||||||
align-content: center;
|
|
||||||
|
|
||||||
.price-wrap {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
line-height: 1;
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.swiper {
|
|
||||||
padding: 20rpx 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sell-out {
|
|
||||||
text {
|
|
||||||
font-size: 250rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-container {
|
|
||||||
width: 100%;
|
|
||||||
height: 300px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.adaptive-video {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: contain;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-nav {
|
|
||||||
padding: 16rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&.fixed-layout {
|
|
||||||
.uni-scroll-view-content {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.singleSlide {
|
|
||||||
.uni-scroll-view-content {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-nav-item {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.pageSlide {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.uni-swiper-dots-horizontal {
|
|
||||||
bottom: 0rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.straightLine {
|
|
||||||
.uni-swiper-dot {
|
|
||||||
width: 30rpx;
|
|
||||||
border-radius: 0;
|
|
||||||
height: 8rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.circle {
|
|
||||||
.uni-swiper-dot {
|
|
||||||
width: 14rpx;
|
|
||||||
height: 14rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-nav-wrap {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-nav-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
padding: 14rpx 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.video-text {
|
|
||||||
padding-top: 12rpx;
|
|
||||||
line-height: 1.5;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
&.alone {
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text {
|
|
||||||
.video-text {
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.video-img {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 90rpx;
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
position: absolute;
|
|
||||||
top: -10rpx;
|
|
||||||
right: -24rpx;
|
|
||||||
color: #fff;
|
|
||||||
border-radius: 24rpx;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
-webkit-transform: scale(0.8);
|
|
||||||
transform: scale(0.8);
|
|
||||||
padding: 8rpx 16rpx;
|
|
||||||
line-height: 1;
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
font-size: 50rpx;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.swiper-dot-box {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: -20rpx;
|
|
||||||
padding-bottom: 8rpx;
|
|
||||||
|
|
||||||
.swiper-dot {
|
|
||||||
background-color: rgba(0, 0, 0, 0.3);
|
|
||||||
margin: 8rpx;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background-color: #000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.straightLine {
|
|
||||||
.swiper-dot {
|
|
||||||
width: 30rpx;
|
|
||||||
border-radius: 0;
|
|
||||||
height: 8rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.circle {
|
|
||||||
.swiper-dot {
|
|
||||||
width: 15rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
height: 15rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="value.pageStyle">
|
|
||||||
<video data-component-name="diy-video" class="diy-video" :src="$util.img(value.videoUrl)" :poster="$util.img(value.imageUrl)" :style="videoWarpCss" objectFit="cover" @click="handlerClick(value.videoUrl)" @tap="handlerClick(value.videoUrl)"></video>
|
<video data-component-name="diy-video" class="diy-video" :src="$util.img(value.videoUrl)" :poster="$util.img(value.imageUrl)" :style="videoWarpCss" objectFit="cover" @click="handlerClick(value.videoUrl)" @tap="handlerClick(value.videoUrl)"></video>
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -11,10 +9,7 @@
|
|||||||
name: 'diy-video',
|
name: 'diy-video',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -64,10 +64,7 @@ export default {
|
|||||||
longitude: null, // 经度
|
longitude: null, // 经度
|
||||||
evaluateCount: 0, // 商品评论数量
|
evaluateCount: 0, // 商品评论数量
|
||||||
deliveryType: null, // 配送方式
|
deliveryType: null, // 配送方式
|
||||||
isVirtual: 0 ,//是否为虚拟商品
|
isVirtual: 0 //是否为虚拟商品
|
||||||
hasGlobalStore:false,
|
|
||||||
saleStore:'all',
|
|
||||||
isInitStoreData:false,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -76,7 +73,10 @@ export default {
|
|||||||
if (this.location) {
|
if (this.location) {
|
||||||
this.latitude = this.location.latitude;
|
this.latitude = this.location.latitude;
|
||||||
this.longitude = this.location.longitude;
|
this.longitude = this.location.longitude;
|
||||||
|
} else {
|
||||||
|
this.$util.getLocation();
|
||||||
}
|
}
|
||||||
|
this.getStoreData();
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
location: function (nVal) {
|
location: function (nVal) {
|
||||||
@@ -95,24 +95,26 @@ export default {
|
|||||||
this.source_member = params.source_member;
|
this.source_member = params.source_member;
|
||||||
this.whetherCollection = params.whetherCollection;
|
this.whetherCollection = params.whetherCollection;
|
||||||
this.posterParams = params.posterParams;
|
this.posterParams = params.posterParams;
|
||||||
|
|
||||||
this.shareUrl = params.shareUrl;
|
this.shareUrl = params.shareUrl;
|
||||||
this.goodsRoute = params.goodsRoute;
|
this.goodsRoute = params.goodsRoute;
|
||||||
this.posterApi = params.posterApi;
|
this.posterApi = params.posterApi;
|
||||||
this.isVirtual = params.isVirtual;
|
this.isVirtual = params.isVirtual;
|
||||||
this.deliveryType = params.deliveryType;
|
this.deliveryType = params.deliveryType;
|
||||||
this.evaluateConfig = params.evaluateConfig;
|
this.evaluateConfig = params.evaluateConfig;
|
||||||
this.saleStore = params.sale_store;
|
|
||||||
if (this.evaluateConfig.evaluate_show == 1) {
|
if (this.evaluateConfig.evaluate_show == 1) {
|
||||||
//商品评论
|
//商品评论
|
||||||
this.getGoodsEvaluate(params.evaluateList);
|
this.getGoodsEvaluate(params.evaluateList);
|
||||||
this.evaluateCount = params.evaluateCount;
|
this.evaluateCount = params.evaluateCount;
|
||||||
}
|
}
|
||||||
if( params.goods_class != 2 && params.goods_class !=3) this.isShowStore = true;
|
|
||||||
if(!this.isInitStoreData){
|
for (let k in this.deliveryType) {
|
||||||
this.isInitStoreData = true;
|
if (k == 'store') {
|
||||||
this.getStoreData();
|
this.isShowStore = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getService();
|
this.getService();
|
||||||
|
|
||||||
this.videoContext = uni.createVideoContext('goodsVideo');
|
this.videoContext = uni.createVideoContext('goodsVideo');
|
||||||
@@ -142,12 +144,11 @@ export default {
|
|||||||
closeStoreListPopup() {
|
closeStoreListPopup() {
|
||||||
this.$refs.storeListPopup.close();
|
this.$refs.storeListPopup.close();
|
||||||
},
|
},
|
||||||
getStoreData(){
|
getStoreData() {
|
||||||
//门店列表
|
//门店列表
|
||||||
let data = {
|
let data = {
|
||||||
page: this.storeList.page,
|
page: this.storeList.page,
|
||||||
page_size: this.storeList.page_size,
|
page_size: this.storeList.page_size
|
||||||
store_ids:this.saleStore
|
|
||||||
};
|
};
|
||||||
if (this.latitude && this.longitude) {
|
if (this.latitude && this.longitude) {
|
||||||
data.latitude = this.latitude;
|
data.latitude = this.latitude;
|
||||||
@@ -160,9 +161,6 @@ export default {
|
|||||||
if (this.storeList.page == 1) this.storeList.data == [];
|
if (this.storeList.page == 1) this.storeList.data == [];
|
||||||
if (res.code >= 0 && res.data) {
|
if (res.code >= 0 && res.data) {
|
||||||
this.storeList.data = this.storeList.data.concat(res.data.list);
|
this.storeList.data = this.storeList.data.concat(res.data.list);
|
||||||
res.data.list.forEach(item=>{
|
|
||||||
if(item.store_id == this.globalStoreInfo.store_id) this.hasGlobalStore = true;
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
this.$util.showToast({
|
this.$util.showToast({
|
||||||
title: res.message
|
title: res.message
|
||||||
@@ -191,6 +189,9 @@ export default {
|
|||||||
if (this.goodsEvaluate[index].images) this.goodsEvaluate[index].images = this.goodsEvaluate[index].images.split(",");
|
if (this.goodsEvaluate[index].images) this.goodsEvaluate[index].images = this.goodsEvaluate[index].images.split(",");
|
||||||
if (this.goodsEvaluate[index].is_anonymous == 1) this.goodsEvaluate[index].member_name = this.goodsEvaluate[index].member_name.replace(this.goodsEvaluate[index].member_name.substring(1, this.goodsEvaluate[index].member_name.length - 1), '***')
|
if (this.goodsEvaluate[index].is_anonymous == 1) this.goodsEvaluate[index].member_name = this.goodsEvaluate[index].member_name.replace(this.goodsEvaluate[index].member_name.substring(1, this.goodsEvaluate[index].member_name.length - 1), '***')
|
||||||
})
|
})
|
||||||
|
// if (this.goodsEvaluate.images) this.goodsEvaluate.images = this.goodsEvaluate.images.split(",");
|
||||||
|
// if (this.goodsEvaluate.is_anonymous == 1) this.goodsEvaluate.member_name = this.goodsEvaluate.member_name.replace(
|
||||||
|
// this.goodsEvaluate.member_name.substring(1, this.goodsEvaluate.member_name.length - 1), '***')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 预览评价图片
|
// 预览评价图片
|
||||||
@@ -262,8 +263,6 @@ export default {
|
|||||||
copyUrl() {
|
copyUrl() {
|
||||||
let text = this.$config.h5Domain + this.shareUrl;
|
let text = this.$config.h5Domain + this.shareUrl;
|
||||||
if (this.memberInfo && this.memberInfo.member_id) text += '&source_member=' + this.memberInfo.member_id;
|
if (this.memberInfo && this.memberInfo.member_id) text += '&source_member=' + this.memberInfo.member_id;
|
||||||
var store_info = this.$store.state.globalStoreInfo;
|
|
||||||
if (store_info) text += '&store_id=' + store_info.store_id;
|
|
||||||
this.$util.copy(text, () => {
|
this.$util.copy(text, () => {
|
||||||
this.closeSharePopup();
|
this.closeSharePopup();
|
||||||
});
|
});
|
||||||
@@ -284,11 +283,10 @@ export default {
|
|||||||
getGoodsPoster() {
|
getGoodsPoster() {
|
||||||
uni.showLoading({
|
uni.showLoading({
|
||||||
'title': '海报生成中...'
|
'title': '海报生成中...'
|
||||||
});
|
})
|
||||||
//活动海报信息
|
//活动海报信息
|
||||||
if (this.memberInfo && this.memberInfo.member_id) this.posterParams.source_member = this.memberInfo.member_id;
|
if (this.memberInfo && this.memberInfo.member_id) this.posterParams.source_member = this.memberInfo.member_id;
|
||||||
var store_info = this.$store.state.globalStoreInfo;
|
|
||||||
if (store_info) this.posterParams.store_id= store_info.store_id;
|
|
||||||
this.$api.sendRequest({
|
this.$api.sendRequest({
|
||||||
url: this.posterApi,
|
url: this.posterApi,
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
@@ -39,37 +39,37 @@
|
|||||||
<slot name="price"></slot>
|
<slot name="price"></slot>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="newdetail margin-bottom">
|
<view class="newdetail margin-bottom" v-if="goodsSkuDetail.isinformation == 0">
|
||||||
|
|
||||||
<!-- 入口区域 -->
|
<!-- 入口区域 -->
|
||||||
<slot name="entrance"></slot>
|
<slot name="entrance"></slot>
|
||||||
|
|
||||||
<!-- 配送 -->
|
<!-- 配送 -->
|
||||||
<view class="item delivery-type" v-if="goodsSkuDetail.is_virtual == 0" @click="$refs.deliveryType.open()">
|
<!-- @click="$refs.deliveryType.open()" -->
|
||||||
<view class="label">配送</view>
|
<view class="item delivery-type" v-if="goodsSkuDetail.is_virtual == 0" >
|
||||||
|
<view class="label">{{$lang('send')}}</view>
|
||||||
<block v-if="deliveryType">
|
<block v-if="deliveryType">
|
||||||
<view class="box">
|
<view class="box">
|
||||||
<block v-for="(item, index) in deliveryType" :key="index">
|
<block v-for="(item, index) in deliveryType" :key="index">
|
||||||
<text v-if="goodsSkuDetail.support_trade_type.indexOf(index) != -1">{{ item.name }}</text>
|
<text v-if="goodsSkuDetail.support_trade_type.indexOf(index) != -1">{{$lang('express')}}</text>
|
||||||
|
<!-- {{ item.name }} -->
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
<text class="iconfont icon-right"></text>
|
<text class="iconfont icon-right"></text>
|
||||||
</block>
|
</block>
|
||||||
<block v-else>
|
<block v-else>
|
||||||
<view class="box">商家未配置配送方式</view>
|
<view class="box">未配置</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 门店 -->
|
<!-- 门店 -->
|
||||||
<view class="item store-wrap" @click="openStoreListPopup()" v-if="addonIsExist.store && globalStoreInfo && isShowStore">
|
<!-- <view class="item store-wrap" @click="openStoreListPopup()" v-if="addonIsExist.store && globalStoreInfo && isShowStore">
|
||||||
<view class="label">适用门店</view>
|
<view class="label">门店</view>
|
||||||
<view class="list-wrap" v-if="hasGlobalStore">
|
<view class="list-wrap">
|
||||||
<view class="name-wrap">
|
<view class="name-wrap">
|
||||||
<text class="icondiy icon-system-shop"></text>
|
<text class="icondiy icon-system-shop"></text>
|
||||||
<text class="name">{{ globalStoreInfo.store_name}}</text>
|
<text class="name">{{globalStoreInfo.store_name}}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="close-desc" v-if="globalStoreInfo.status == 0 && globalStoreInfo.close_desc">
|
|
||||||
{{ globalStoreInfo.close_desc }}
|
|
||||||
</view>
|
|
||||||
<view class="other-wrap">
|
<view class="other-wrap">
|
||||||
<text class="distance" v-if="parseFloat(globalStoreInfo.distance)">距离{{ globalStoreInfo.distance > 1 ? globalStoreInfo.distance + 'km' : globalStoreInfo.distance * 1000 + 'm' }}</text>
|
<text class="distance" v-if="parseFloat(globalStoreInfo.distance)">距离{{ globalStoreInfo.distance > 1 ? globalStoreInfo.distance + 'km' : globalStoreInfo.distance * 1000 + 'm' }}</text>
|
||||||
<text class="decorate" v-if="parseFloat(globalStoreInfo.distance)">.</text>
|
<text class="decorate" v-if="parseFloat(globalStoreInfo.distance)">.</text>
|
||||||
@@ -77,23 +77,8 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="list-wrap" v-else-if="storeList && storeList.data.length">
|
|
||||||
<view class="name-wrap">
|
|
||||||
<text class="icondiy icon-system-shop"></text>
|
|
||||||
<text class="name">{{ storeList.data[0].store_name}}</text>
|
|
||||||
</view>
|
|
||||||
<view class="close-desc" v-if="storeList.data[0].status == 0 && storeList.data[0].close_desc">
|
|
||||||
{{ storeList.data[0].close_desc }}
|
|
||||||
</view>
|
|
||||||
<view class="other-wrap">
|
|
||||||
<text class="distance" v-if="parseFloat(storeList.data[0].distance)">距离{{ storeList.data[0].distance > 1 ? storeList.data[0].distance + 'km' : storeList.data[0].distance * 1000 + 'm' }}</text>
|
|
||||||
<text class="decorate" v-if="parseFloat(storeList.data[0].distance)">.</text>
|
|
||||||
<view class="address">{{ storeList.data[0].full_address + storeList.data[0].address }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<text class="iconfont icon-right"></text>
|
<text class="iconfont icon-right"></text>
|
||||||
</view>
|
</view> -->
|
||||||
|
|
||||||
<view class="item service" @click="openMerchantsServicePopup()" v-if="goodsSkuDetail.goods_service.length">
|
<view class="item service" @click="openMerchantsServicePopup()" v-if="goodsSkuDetail.goods_service.length">
|
||||||
<view class="label">服务</view>
|
<view class="label">服务</view>
|
||||||
@@ -111,6 +96,34 @@
|
|||||||
</view>
|
</view>
|
||||||
<text class="iconfont icon-right"></text>
|
<text class="iconfont icon-right"></text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!--多规格区域-->
|
||||||
|
<view class="newdetail margin-bottom" v-if="goodsSkuDetail.sku_spec_format">
|
||||||
|
<!-- 入口区域 -->
|
||||||
|
<slot name="skuspec"></slot>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view class="newdetail margin-bottom" v-if="goodsSkuDetail.merch_id > 0">
|
||||||
|
<!-- 入口区域 -->
|
||||||
|
<slot name="entrance"></slot>
|
||||||
|
<!-- 商家 -->
|
||||||
|
<view class="item store-wrap" @click="$util.redirectTo('/pages_promotion/merch/detail', { merch_id: goodsSkuDetail.merch_id })">
|
||||||
|
<view class="list-wrap" style="display: flex;">
|
||||||
|
<view class="name-wrap">
|
||||||
|
<image :src="$util.img(goodsSkuDetail.merchinfo.merch_image)" mode="widthFix" style="width: 100rpx;height: 100rpx;border-radius: 50rpx;"></image>
|
||||||
|
</view>
|
||||||
|
<view class="other-wrap">
|
||||||
|
<view class="address" style="margin-left: 30rpx;">
|
||||||
|
<view>{{goodsSkuDetail.merchinfo.merch_name}}</view>
|
||||||
|
<view style="font-size: 24rpx;color: #888;">官方认证商家,值得信赖!</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<text class="iconfont icon-right"></text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 配送方式 -->
|
<!-- 配送方式 -->
|
||||||
@@ -169,7 +182,7 @@
|
|||||||
<uni-popup ref="storeListPopup" type="bottom">
|
<uni-popup ref="storeListPopup" type="bottom">
|
||||||
<view class="goods-merchants-service-popup-layer popup-layer store-list-wrap">
|
<view class="goods-merchants-service-popup-layer popup-layer store-list-wrap">
|
||||||
<view class="head-wrap" @click="closeStoreListPopup()">
|
<view class="head-wrap" @click="closeStoreListPopup()">
|
||||||
<text>适用门店</text>
|
<text>门店列表</text>
|
||||||
<text class="iconfont icon-close"></text>
|
<text class="iconfont icon-close"></text>
|
||||||
</view>
|
</view>
|
||||||
<scroll-view scroll-y>
|
<scroll-view scroll-y>
|
||||||
@@ -187,8 +200,6 @@
|
|||||||
距离{{ item.distance > 1 ? item.distance + 'km' : item.distance * 1000 + 'm' }}
|
距离{{ item.distance > 1 ? item.distance + 'km' : item.distance * 1000 + 'm' }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="item-close-desc" v-if="item.status == 0 && item.close_desc">{{ item.close_desc }}
|
|
||||||
</view>
|
|
||||||
<view class="item-time" v-if="item.open_date">营业时间:{{ item.open_date }}
|
<view class="item-time" v-if="item.open_date">营业时间:{{ item.open_date }}
|
||||||
</view>
|
</view>
|
||||||
<view class="item-address">{{ item.full_address + item.address }}</view>
|
<view class="item-address">{{ item.full_address + item.address }}</view>
|
||||||
@@ -217,7 +228,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 促销 -->
|
<!-- 促销 -->
|
||||||
<view class="community-model" @touchmove.prevent.stop @click.stop="onCloseCommunity()" v-show="isCommunity">
|
<!-- <view class="community-model" @touchmove.prevent.stop @click.stop="onCloseCommunity()" v-show="isCommunity">
|
||||||
<view class="community-model-content" @click.stop>
|
<view class="community-model-content" @click.stop>
|
||||||
<view class="community-model-content-radius">
|
<view class="community-model-content-radius">
|
||||||
<view>添加社群</view>
|
<view>添加社群</view>
|
||||||
@@ -230,13 +241,13 @@
|
|||||||
<view class="community-model-close" @click.stop="onCloseCommunity()">
|
<view class="community-model-close" @click.stop="onCloseCommunity()">
|
||||||
<text class="iconfont icon-close"></text>
|
<text class="iconfont icon-close"></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view> -->
|
||||||
|
|
||||||
<!-- 参与流程 -->
|
<!-- 参与流程 -->
|
||||||
<slot name="articipation"></slot>
|
<slot name="articipation"></slot>
|
||||||
|
|
||||||
<!-- 商品评价 -->
|
<!-- 商品评价 -->
|
||||||
<view class="group-wrap" v-if="evaluateConfig.evaluate_show == 1">
|
<view class="group-wrap" v-if="evaluateConfig.evaluate_show == 1 && goodsSkuDetail.isinformation == 0" style="display: none;">
|
||||||
<view class="goods-evaluate" @click="toEvaluateDetail(goodsSkuDetail.goods_id)">
|
<view class="goods-evaluate" @click="toEvaluateDetail(goodsSkuDetail.goods_id)">
|
||||||
<view class="tit">
|
<view class="tit">
|
||||||
<!-- <view class="tit" :class="{ active: goodsEvaluate.content }"> -->
|
<!-- <view class="tit" :class="{ active: goodsEvaluate.content }"> -->
|
||||||
@@ -252,7 +263,8 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="evaluate-item" v-for="(item, index) in goodsEvaluate" :key="index" v-if="item.content">
|
<view class="evaluate-item" v-for="(item, index) in goodsEvaluate" :key="index"
|
||||||
|
v-if="item.content">
|
||||||
<view class="evaluator">
|
<view class="evaluator">
|
||||||
<view class="evaluator-info">
|
<view class="evaluator-info">
|
||||||
<view class="evaluator-face">
|
<view class="evaluator-face">
|
||||||
@@ -282,7 +294,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="goods-attr" v-if="goodsSkuDetail.goods_attr_format && goodsSkuDetail.goods_attr_format.length > 0">
|
<view class="goods-attr" v-if="goodsSkuDetail.goods_attr_format && goodsSkuDetail.goods_attr_format.length > 0">
|
||||||
<view class="title">规格属性</view>
|
<view class="title">规格属性</view>
|
||||||
<view class="attr-wrap">
|
<view class="attr-wrap">
|
||||||
@@ -303,19 +315,24 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 详情 -->
|
<!-- 详情 -->
|
||||||
<view class="goods-detail-tab">
|
<view class="goods-detail-tab">
|
||||||
<view class="detail-tab">
|
<view class="detail-tab">
|
||||||
<view class="tab-item">商品详情</view>
|
<view class="tab-item">{{$lang('details')}}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="detail-content active">
|
<view class="detail-content active">
|
||||||
<view class="detail-content-item">
|
<view class="detail-content-item">
|
||||||
<view class="goods-details" v-if="goodsSkuDetail.goods_content">
|
<view class="goods-details" v-if="goodsSkuDetail.goods_content">
|
||||||
<ns-mp-html :content="goodsSkuDetail.goods_content"></ns-mp-html>
|
<!-- <rich-text :nodes="goodsSkuDetail.goods_content" @click="showImg($event)" :data-nodes="goodsSkuDetail.goods_content"></rich-text> -->
|
||||||
|
<!-- {{goodsSkuDetail.goods_content}} -->
|
||||||
|
<mp-html :content="goodsSkuDetail.goods_content" />
|
||||||
|
<!-- :loading="loading" @preview="preview" @navigate="navigate" -->
|
||||||
</view>
|
</view>
|
||||||
<view class="goods-details active" v-else>该商家暂无上传相关详情哦!</view>
|
<view class="goods-details active" v-else></view>
|
||||||
<view class="goods-details" v-if="service && service.is_display == 1 && service.content">
|
<view class="goods-details" v-if="service && service.is_display == 1 && service.content">
|
||||||
<ns-mp-html :content="service.content"></ns-mp-html>
|
<rich-text :nodes="service.content" @click="showImg($event)" :data-nodes="service.content"></rich-text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1,307 +1,213 @@
|
|||||||
<template>
|
<template>
|
||||||
<view v-if="pageCount == 1 || need" class="fixed-box" :style="{ height: fixBtnShow ? (isH5 ? '180rpx' : '330rpx') : '120rpx' }">
|
<!-- 悬浮按钮 -->
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
<view v-if="pageCount == 1 || need" class="fixed-box" :style="{ height: fixBtnShow ? '330rpx' : '120rpx' }">
|
||||||
<!-- 微信小程序:根据配置自动选择官方客服/自定义客服 -->
|
<!-- <view class="btn-item" v-if="fixBtnShow" @click="$util.redirectTo('/pages/index/index')"> -->
|
||||||
<button
|
|
||||||
class="btn-item"
|
<!-- AI智能助手 -->
|
||||||
v-if="fixBtnShow"
|
<view class="btn-item" v-if="fixBtnShow && enableAIChat" @click="openAIChat" :style="{backgroundImage:'url('+(aiAgentimg?aiAgentimg:'')+')',backgroundSize:'100% 100%'}">
|
||||||
hoverClass="none"
|
<text class="ai-icon" v-if="!aiAgentimg">🤖</text>
|
||||||
:open-type="weappOfficialService ? 'contact' : ''"
|
<!-- 未读消息小红点 -->
|
||||||
@click="weappOfficialService ? '' : handleWeappCustomerService"
|
<view v-if="unreadCount > 0" class="unread-badge">
|
||||||
:style="{ backgroundImage: 'url(' + (kefuimg ? kefuimg : '') + ')', backgroundSize: '100% 100%' }"
|
<text class="badge-text">{{ unreadCount > 99 ? '99+' : unreadCount }}</text>
|
||||||
>
|
</view>
|
||||||
<text class="icox icox-kefu" v-if="!kefuimg"></text>
|
</view>
|
||||||
</button>
|
|
||||||
<!-- #endif -->
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<button class="btn-item" v-if="fixBtnShow" hoverClass="none" openType="contact" sessionFrom="weapp" showMessageCard="true" :style="{backgroundImage:'url('+(kefuimg?kefuimg:'')+')',backgroundSize:'100% 100%'}">
|
||||||
<!-- #ifdef H5 -->
|
<text class="icox icox-kefu" v-if="!kefuimg"></text>
|
||||||
<!-- H5逻辑保持不变 -->
|
<!-- <view>首页</view> -->
|
||||||
<button
|
</button>
|
||||||
class="btn-item"
|
<!-- #endif -->
|
||||||
v-if="fixBtnShow"
|
|
||||||
hoverClass="none"
|
<!-- 电话 -->
|
||||||
@click="handleCustomerService"
|
<view class="btn-item" v-if="fixBtnShow" @click="call()" :style="{backgroundImage:'url('+(phoneimg?phoneimg:'')+')',backgroundSize:'100% 100%'}">
|
||||||
:style="{ backgroundImage: 'url(' + (kefuimg ? kefuimg : '') + ')', backgroundSize: '100% 100%' }"
|
<text class="iconfont icon-dianhua" v-if="!phoneimg"></text>
|
||||||
>
|
<!-- <view>我的</view> -->
|
||||||
<text class="icox icox-kefu" v-if="!kefuimg"></text>
|
</view>
|
||||||
<view v-if="unreadCount > 0 && isDifyService" class="unread-badge">
|
|
||||||
<text class="badge-text">{{ unreadCount > 99 ? '99+' : unreadCount }}</text>
|
<!-- <view class="btn-item icon-xiala" v-if="fixBtnShow" @click="fixBtnShow ? (fixBtnShow = false) : (fixBtnShow = true)">
|
||||||
</view>
|
<text class="iconfont icon-unfold"></text>
|
||||||
</button>
|
</view>
|
||||||
<!-- #endif -->
|
<view class="btn-item switch" v-else :class="{ show: fixBtnShow }"
|
||||||
|
@click="fixBtnShow ? (fixBtnShow = false) : (fixBtnShow = true)">
|
||||||
<!-- #ifndef H5 -->
|
<view class="">快捷</view>
|
||||||
<view
|
<view>导航</view>
|
||||||
class="btn-item"
|
</view> -->
|
||||||
v-if="fixBtnShow && isDifyService"
|
</view>
|
||||||
@click="handleCustomerService"
|
</template>
|
||||||
:style="{ backgroundImage: 'url(' + (aiAgentimg ? aiAgentimg : '') + ')', backgroundSize: '100% 100%' }"
|
|
||||||
>
|
<script>
|
||||||
<text class="ai-icon" v-if="!aiAgentimg">🤖</text>
|
import { mapGetters, mapMutations } from 'vuex'
|
||||||
<view v-if="unreadCount > 0" class="unread-badge">
|
|
||||||
<text class="badge-text">{{ unreadCount > 99 ? '99+' : unreadCount }}</text>
|
export default {
|
||||||
</view>
|
name: 'hover-nav',
|
||||||
</view>
|
props: {
|
||||||
<!-- #endif -->
|
need: {
|
||||||
|
type: Boolean,
|
||||||
<view
|
default: false
|
||||||
class="btn-item"
|
},
|
||||||
v-if="fixBtnShow"
|
},
|
||||||
@click="call()"
|
data() {
|
||||||
:style="{ backgroundImage: 'url(' + (phoneimg ? phoneimg : '') + ')', backgroundSize: '100% 100%' }"
|
return {
|
||||||
>
|
pageCount: 0,
|
||||||
<text class="iconfont icon-dianhua" v-if="!phoneimg"></text>
|
fixBtnShow: true,
|
||||||
</view>
|
tel:'',
|
||||||
</view>
|
kefuimg:'',
|
||||||
</template>
|
phoneimg:''
|
||||||
|
};
|
||||||
<script>
|
},
|
||||||
import { createCustomerService } from '@/common/js/customer-service.js';
|
created() {
|
||||||
import { mapGetters, mapMutations } from 'vuex';
|
this.kefuimg = this.$util.getDefaultImage().kefu
|
||||||
|
this.phoneimg = this.$util.getDefaultImage().phone
|
||||||
export default {
|
this.pageCount = getCurrentPages().length;
|
||||||
name: 'hover-nav',
|
|
||||||
props: {
|
|
||||||
need: {
|
var that = this
|
||||||
type: Boolean,
|
uni.getStorage({
|
||||||
default: false
|
key:'shopInfo',
|
||||||
}
|
success(e){
|
||||||
},
|
that.tel = e.data.mobile
|
||||||
data() {
|
}
|
||||||
return {
|
})
|
||||||
pageCount: 0,
|
|
||||||
fixBtnShow: true,
|
},
|
||||||
tel: '',
|
computed: {
|
||||||
kefuimg: '',
|
...mapGetters([
|
||||||
phoneimg: '',
|
'globalAIAgentConfig',
|
||||||
customerService: null,
|
'aiUnreadCount'
|
||||||
buttonConfig: null,
|
]),
|
||||||
isH5: false,
|
aiAgentimg() {
|
||||||
platformConfig: null,
|
return this.globalAIAgentConfig?.icon || this.$util.getDefaultImage().aiAgent || '' // AI智能助手的头像
|
||||||
latestConfig: null,
|
},
|
||||||
weappOfficialService: false // 微信小程序是否使用官方客服
|
unreadCount() {
|
||||||
};
|
return this.aiUnreadCount
|
||||||
},
|
},
|
||||||
created() {
|
enableAIChat() {
|
||||||
// 1. 判断平台类型
|
return this.globalAIAgentConfig?.enable || true // 是否开启AI智能助手
|
||||||
// #ifdef H5
|
},
|
||||||
this.isH5 = true;
|
},
|
||||||
// #endif
|
methods: {
|
||||||
// #ifdef MP-WEIXIN
|
...mapMutations([
|
||||||
this.isH5 = false;
|
'setAiUnreadCount'
|
||||||
// #endif
|
]),
|
||||||
|
|
||||||
// 2. 初始化资源
|
//拨打电话
|
||||||
this.kefuimg = this.$util.getDefaultImage().kefu;
|
call(){
|
||||||
this.phoneimg = this.$util.getDefaultImage().phone;
|
uni.makePhoneCall({
|
||||||
this.pageCount = getCurrentPages().length;
|
phoneNumber:this.tel+''
|
||||||
|
})
|
||||||
// 3. 获取店铺电话
|
},
|
||||||
this.getShopTel();
|
|
||||||
|
// 打开AI聊天弹窗
|
||||||
// 4. 首次加载获取最新配置
|
openAIChat() {
|
||||||
this.getLatestConfig().then(config => {
|
if (this.enableAIChat) {
|
||||||
this.latestConfig = config;
|
this.setAiUnreadCount(0);
|
||||||
this.initCustomerService(config);
|
}
|
||||||
// 微信小程序:判断是否使用官方客服
|
|
||||||
this.initWeappServiceType();
|
this.$util.redirectTo('/pages_tool/ai-chat/index')
|
||||||
});
|
}
|
||||||
},
|
|
||||||
computed: {
|
}
|
||||||
...mapGetters([
|
};
|
||||||
'globalAIKefuConfig',
|
</script>
|
||||||
'aiUnreadCount'
|
|
||||||
]),
|
<style lang="scss">
|
||||||
isDifyService() {
|
.container-box {
|
||||||
const serviceType = this.platformConfig?.type || '';
|
width: 100%;
|
||||||
return serviceType === 'aikefu';
|
|
||||||
},
|
.item-wrap {
|
||||||
aiAgentimg() {
|
border-radius: 10rpx;
|
||||||
return this.globalAIKefuConfig?.icon || this.$util.getDefaultImage().aiAgent || '';
|
|
||||||
},
|
.image-box {
|
||||||
unreadCount() {
|
border-radius: 10rpx;
|
||||||
return this.aiUnreadCount;
|
}
|
||||||
}
|
|
||||||
},
|
image {
|
||||||
methods: {
|
width: 100%;
|
||||||
...mapMutations([
|
height: auto;
|
||||||
'setAiUnreadCount'
|
border-radius: 10rpx;
|
||||||
]),
|
will-change: transform;
|
||||||
/**
|
}
|
||||||
* 获取最新配置(H5禁用缓存,小程序保留默认)
|
}
|
||||||
*/
|
}
|
||||||
async getLatestConfig() {
|
|
||||||
return new Promise((resolve) => {
|
//悬浮按钮
|
||||||
// H5:强制请求最新配置;小程序:优先用vuex缓存
|
.fixed-box {
|
||||||
if (this.isH5) {
|
position: fixed;
|
||||||
this.$api.sendRequest({
|
right: 0rpx;
|
||||||
url: '/api/site/getServicerConfig',
|
bottom: 200rpx;
|
||||||
header: {
|
z-index: 10;
|
||||||
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
// background: #fff;
|
||||||
'Pragma': 'no-cache',
|
// box-shadow: 2rpx 2rpx 22rpx rgba(0, 0, 0, 0.3);
|
||||||
'Expires': '0'
|
border-radius: 120rpx;
|
||||||
},
|
padding: 20rpx 0;
|
||||||
data: { t: new Date().getTime() },
|
display: flex;
|
||||||
success: (res) => {
|
justify-content: center;
|
||||||
const config = res.code === 0 ? res.data : this.$store.state.servicerConfig || {};
|
flex-direction: column;
|
||||||
this.$store.commit('setServicerConfig', config);
|
width: 100rpx;
|
||||||
resolve(config);
|
box-sizing: border-box;
|
||||||
},
|
transition: 0.3s;
|
||||||
fail: () => resolve(this.$store.state.servicerConfig || {})
|
overflow: hidden;
|
||||||
});
|
|
||||||
} else {
|
.btn-item {
|
||||||
// 小程序:直接用vuex缓存(后台修改后需重启开发者工具)
|
display: flex;
|
||||||
resolve(this.$store.state.servicerConfig || {});
|
justify-content: center;
|
||||||
}
|
text-align: center;
|
||||||
});
|
flex-direction: column;
|
||||||
},
|
line-height: 1;
|
||||||
/**
|
margin: 14rpx 0;
|
||||||
* 初始化客服服务
|
transition: 0.1s;
|
||||||
*/
|
background: #fff;
|
||||||
initCustomerService(config = null) {
|
border-radius: 50rpx;
|
||||||
this.customerService = createCustomerService(this, config || this.latestConfig);
|
width: 80rpx;
|
||||||
this.platformConfig = this.customerService.refreshConfig(config || this.latestConfig);
|
height: 80rpx;
|
||||||
this.buttonConfig = this.customerService.getButtonConfig();
|
padding: 0;
|
||||||
},
|
position: relative;
|
||||||
/**
|
text {
|
||||||
* 微信小程序:初始化服务类型(官方/自定义)
|
font-size: 36rpx;
|
||||||
*/
|
font-weight: bold;
|
||||||
initWeappServiceType() {
|
}
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
// 从buttonConfig中获取官方客服标识
|
view {
|
||||||
this.weappOfficialService = this.buttonConfig?.openType === 'contact';
|
font-size: 26rpx;
|
||||||
// #endif
|
font-weight: bold;
|
||||||
},
|
}
|
||||||
/**
|
|
||||||
* 获取店铺电话
|
&.show {
|
||||||
*/
|
transform: rotate(180deg);
|
||||||
getShopTel() {
|
}
|
||||||
uni.getStorage({
|
|
||||||
key: 'shopInfo',
|
&.switch {}
|
||||||
success: (e) => {
|
|
||||||
if (e.data && e.data.mobile && /^1[3-9]\d{9}$/.test(e.data.mobile)) {
|
&.icon-xiala {
|
||||||
this.tel = e.data.mobile;
|
margin: 0;
|
||||||
}
|
margin-top: 0.1rpx;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
},
|
// 未读消息小红点
|
||||||
/**
|
.unread-badge {
|
||||||
* 拨打电话
|
position: absolute;
|
||||||
*/
|
top: -5rpx;
|
||||||
call() {
|
right: -5rpx;
|
||||||
if (!this.tel || !/^1[3-9]\d{9}$/.test(this.tel)) {
|
background-color: #ff4544;
|
||||||
uni.showToast({ title: '暂无有效联系电话', icon: 'none' });
|
color: white;
|
||||||
return;
|
border-radius: 20rpx;
|
||||||
}
|
min-width: 30rpx;
|
||||||
uni.makePhoneCall({
|
height: 30rpx;
|
||||||
phoneNumber: this.tel,
|
font-size: 10rpx;
|
||||||
fail: (err) => {
|
line-height: 30rpx;
|
||||||
if (err.errMsg !== 'makePhoneCall:fail cancel') {
|
text-align: center;
|
||||||
uni.showToast({ title: '拨号失败,请稍后重试', icon: 'none' });
|
padding: 0 8rpx;
|
||||||
}
|
z-index: 1;
|
||||||
}
|
box-shadow: 0 2rpx 10rpx rgba(255, 69, 68, 0.3);
|
||||||
});
|
|
||||||
},
|
.badge-text {
|
||||||
/**
|
font-size: 8rpx;
|
||||||
* H5客服点击逻辑(保持不变)
|
// #ifdef MP-WEIXIN
|
||||||
*/
|
font-size: 20rpx;
|
||||||
async handleCustomerService() {
|
// #endif
|
||||||
if (this.isH5) {
|
}
|
||||||
uni.showLoading({ title: '加载中...', mask: true });
|
}
|
||||||
try {
|
}
|
||||||
const newConfig = await this.getLatestConfig();
|
}
|
||||||
this.latestConfig = newConfig;
|
|
||||||
this.initCustomerService(newConfig);
|
|
||||||
this.customerService.handleCustomerClick();
|
|
||||||
} catch (e) {
|
|
||||||
uni.showToast({ title: '操作失败', icon: 'none' });
|
|
||||||
} finally {
|
|
||||||
uni.hideLoading();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 小程序:直接调用客服逻辑
|
|
||||||
this.customerService.handleCustomerClick();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 微信小程序自定义客服点击逻辑
|
|
||||||
*/
|
|
||||||
handleWeappCustomerService() {
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
this.customerService.handleCustomerClick();
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
/* 父容器:不限制高度,避免挤压按钮 */
|
|
||||||
.fixed-box {
|
|
||||||
position: fixed;
|
|
||||||
right: 20rpx; /* 增加右侧边距,避免贴边 */
|
|
||||||
bottom: 200rpx;
|
|
||||||
z-index: 9999;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: 14rpx; /* 替代margin,更稳定 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 核心:强制按钮为正方形+正圆 */
|
|
||||||
.btn-item {
|
|
||||||
/* 宽高强制相等,必须是正方形 */
|
|
||||||
width: 88rpx !important;
|
|
||||||
height: 88rpx !important;
|
|
||||||
/* 强制正圆(优先级最高) */
|
|
||||||
border-radius: 50% !important;
|
|
||||||
/* 白色背景(确保是圆) */
|
|
||||||
background-color: #ffffff !important;
|
|
||||||
/* 背景图居中显示,不拉伸 */
|
|
||||||
background-size: 60% 60% !important;
|
|
||||||
background-position: center !important;
|
|
||||||
background-repeat: no-repeat !important;
|
|
||||||
/* 清除默认样式 */
|
|
||||||
border: none !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
margin: 0 !important;
|
|
||||||
/* 居中内容 */
|
|
||||||
display: flex !important;
|
|
||||||
justify-content: center !important;
|
|
||||||
align-items: center !important;
|
|
||||||
/* 阴影增强视觉(可选) */
|
|
||||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
/* 清除button标签的默认点击样式(微信小程序/浏览器) */
|
|
||||||
.btn-item::after {
|
|
||||||
border: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.unread-badge {
|
|
||||||
position: absolute;
|
|
||||||
top: -5rpx;
|
|
||||||
right: -5rpx;
|
|
||||||
background: #ff4544;
|
|
||||||
color: #fff;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
min-width: 30rpx;
|
|
||||||
height: 30rpx;
|
|
||||||
line-height: 30rpx;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 10rpx;
|
|
||||||
padding: 0 8rpx;
|
|
||||||
box-shadow: 0 2rpx 10rpx rgba(255, 73, 72, 0.3);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 微信小程序字体适配 */
|
|
||||||
/* #ifdef MP-WEIXIN */
|
|
||||||
.unread-badge {
|
|
||||||
font-size: 20rpx;
|
|
||||||
}
|
|
||||||
/* #endif */
|
|
||||||
|
|
||||||
.ai-icon {
|
|
||||||
font-size: 40rpx;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
@@ -10,9 +10,9 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="birthday-title-desc" v-else>感谢您一直以来的支持,在您生日到来之际,特为您送上最真诚的祝福!</view>
|
<view class="birthday-title-desc" v-else>感谢您一直以来的支持,在您生日到来之际,特为您送上最真诚的祝福!</view>
|
||||||
<view class="birthday-title-hint">
|
<view class="birthday-title-hint">
|
||||||
<image :src="$util.img('public/uniapp/birthday_gift/birthday_gift_left.png')" mode="" class="birthday-img-all" />
|
<image :src="$util.img('public/uniapp/birthday_gift/birthday_gift_left.png')" mode="" class="birthday-img-all"/>
|
||||||
<view class="font-size-toolbar">生日贺礼</view>
|
<view class="font-size-toolbar">生日贺礼</view>
|
||||||
<image :src="$util.img('public/uniapp/birthday_gift/birthday_gift_right.png')" mode="" class="birthday-img-all" />
|
<image :src="$util.img('public/uniapp/birthday_gift/birthday_gift_right.png')" mode="" class="birthday-img-all"/>
|
||||||
</view>
|
</view>
|
||||||
<scroll-view scroll-y="true" class="register-box">
|
<scroll-view scroll-y="true" class="register-box">
|
||||||
<view class="reward-content">
|
<view class="reward-content">
|
||||||
@@ -51,14 +51,18 @@
|
|||||||
<block v-for="(item, index) in birthday.coupon_list" :key="index">
|
<block v-for="(item, index) in birthday.coupon_list" :key="index">
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<text class="num" v-if="item.type == 'reward'">
|
<block v-if="item.type == 'reward'">
|
||||||
{{ parseFloat(item.money) }}
|
<text class="num">
|
||||||
<text class="type">元优惠劵</text>
|
{{ parseFloat(item.money) }}
|
||||||
</text>
|
<text class="type">元优惠劵</text>
|
||||||
<text class="num" v-else-if="item.type == 'discount'">
|
</text>
|
||||||
{{ item.discount }}
|
</block>
|
||||||
<text class="type">折</text>
|
<block v-else-if="item.type == 'discount'">
|
||||||
</text>
|
<text class="num">
|
||||||
|
{{ item.discount }}
|
||||||
|
<text class="type">折</text>
|
||||||
|
</text>
|
||||||
|
</block>
|
||||||
<view class="desc">用于下单时抵现或兑换商品等</view>
|
<view class="desc">用于下单时抵现或兑换商品等</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="tip" @click="closeRewardPopup('3')">立即查看</view>
|
<view class="tip" @click="closeRewardPopup('3')">立即查看</view>
|
||||||
@@ -89,8 +93,7 @@
|
|||||||
birthday: {
|
birthday: {
|
||||||
flag: false,
|
flag: false,
|
||||||
coupon_list: {}
|
coupon_list: {}
|
||||||
},
|
}
|
||||||
callback: null
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -114,8 +117,7 @@
|
|||||||
this.init();
|
this.init();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init(callback = null) {
|
init() {
|
||||||
if (callback) this.callback = callback;
|
|
||||||
this.getBirthdayGift();
|
this.getBirthdayGift();
|
||||||
},
|
},
|
||||||
cancel() {
|
cancel() {
|
||||||
@@ -146,9 +148,7 @@
|
|||||||
data: {
|
data: {
|
||||||
id: this.birthday.id
|
id: this.birthday.id
|
||||||
},
|
},
|
||||||
success: res => {
|
success: res => {}
|
||||||
if (this.callback) this.callback();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.register-box {
|
.register-box {
|
||||||
max-height: 320rpx;
|
max-height: 300rpx;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
/* margin-top:350rpx; */
|
/* margin-top:350rpx; */
|
||||||
}
|
}
|
||||||
@@ -187,12 +187,12 @@
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.reward-wrap {
|
.reward-wrap {
|
||||||
width: 600rpx;
|
width: 85vw;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
|
||||||
.wrap {
|
.wrap {
|
||||||
width: 600rpx;
|
width: 100%;
|
||||||
height: 932rpx;
|
height: auto;
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
padding-bottom: 40rpx;
|
padding-bottom: 40rpx;
|
||||||
@@ -266,8 +266,7 @@
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 10rpx;
|
border-radius: 10rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
box-sizing: border-box;
|
|
||||||
height: 136rpx;
|
|
||||||
.info {
|
.info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
@@ -324,6 +323,13 @@
|
|||||||
height: 40rpx;
|
height: 40rpx;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
line-height: 40rpx;
|
line-height: 40rpx;
|
||||||
|
/* margin: 20rpx 140rpx;
|
||||||
|
border: none;
|
||||||
|
background: linear-gradient(90deg, #FF6A00, #FF3C00);
|
||||||
|
border-radius: 40rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center; */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,170 +1,171 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="contact-wrap">
|
<view class="contact-wrap">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
<!-- #ifdef MP-ALIPAY -->
|
<!-- #ifdef MP-ALIPAY -->
|
||||||
<view class="contact-button" @click="contactServicer">
|
<view class="contact-button" @click="contactServicer">
|
||||||
<contact-button :tnt-inst-id="config.instid" :scene="config.scene" size="1000rpx"
|
<contact-button :tnt-inst-id="config.instid" :scene="config.scene" size="1000rpx" v-if="config.type == 'aliapp'"/>
|
||||||
v-if="config.type == 'aliapp'" />
|
</view>
|
||||||
</view>
|
<!-- #endif -->
|
||||||
<!-- #endif -->
|
<!-- #ifndef MP-ALIPAY -->
|
||||||
|
<button
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
type="default"
|
||||||
<!-- 微信小程序官方客服按钮 -->
|
hover-class="none"
|
||||||
<button v-if="useOfficialService" type="default" hover-class="none" open-type="contact"
|
:open-type="openType"
|
||||||
class="contact-button" sessionFrom="weapp" showMessageCard="true"
|
class="contact-button"
|
||||||
:send-message-title="sendMessageTitle" :send-message-path="sendMessagePath"
|
@click="contactServicer"
|
||||||
:send-message-img="sendMessageImg"></button>
|
:send-message-title="sendMessageTitle"
|
||||||
|
:send-message-path="sendMessagePath"
|
||||||
<!-- 微信小程序自定义客服按钮 -->
|
:send-message-img="sendMessageImg"
|
||||||
<button v-else type="default" hover-class="none" class="contact-button" @click="contactServicer"></button>
|
:show-message-card="true"></button>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
|
<uni-popup ref="servicePopup" type="center">
|
||||||
<!-- #ifndef MP-WEIXIN && MP-ALIPAY -->
|
<view class="service-popup-wrap">
|
||||||
<!-- 其他平台保持原逻辑 -->
|
<view class="head-wrap" @click="$refs.servicePopup.close()">
|
||||||
<button type="default" hover-class="none" :open-type="openType" class="contact-button" @click="contactServicer"
|
<text>联系客服</text>
|
||||||
:send-message-title="sendMessageTitle" :send-message-path="sendMessagePath"
|
<text class="iconfont icon-close"></text>
|
||||||
:send-message-img="sendMessageImg" :show-message-card="true"></button>
|
</view>
|
||||||
<!-- #endif -->
|
<view class="body-wrap">{{ siteInfo.site_tel ? '请联系客服,客服电话是' + siteInfo.site_tel : '抱歉,商家暂无客服,请线下联系' }}</view>
|
||||||
|
</view>
|
||||||
<uni-popup ref="servicePopup" type="center">
|
</uni-popup>
|
||||||
<view class="service-popup-wrap">
|
</view>
|
||||||
<view class="head-wrap" @click="$refs.servicePopup.close()">
|
</template>
|
||||||
<text>联系客服</text>
|
|
||||||
<text class="iconfont icon-close"></text>
|
<!-- 客服组件 -->
|
||||||
</view>
|
<script>
|
||||||
<view class="body-wrap">{{ siteInfo.site_tel ? '请联系客服,客服电话是' + siteInfo.site_tel : '抱歉,商家暂无客服,请线下联系' }}
|
export default {
|
||||||
</view>
|
name: 'ns-contact',
|
||||||
</view>
|
props: {
|
||||||
</uni-popup>
|
niushop: {
|
||||||
</view>
|
type: Object,
|
||||||
</template>
|
default: function() {
|
||||||
|
return {};
|
||||||
<!-- 客服组件 -->
|
}
|
||||||
<script>
|
},
|
||||||
import { createCustomerService } from '@/common/js/customer-service.js';
|
sendMessageTitle: {
|
||||||
|
type: String,
|
||||||
export default {
|
default: ''
|
||||||
name: 'ns-contact',
|
},
|
||||||
props: {
|
sendMessagePath: {
|
||||||
niushop: {
|
type: String,
|
||||||
type: Object,
|
default: ''
|
||||||
default: function () {
|
},
|
||||||
return {};
|
sendMessageImg: {
|
||||||
}
|
type: String,
|
||||||
},
|
default: ''
|
||||||
sendMessageTitle: {
|
}
|
||||||
type: String,
|
},
|
||||||
default: ''
|
data() {
|
||||||
},
|
return {
|
||||||
sendMessagePath: {
|
config: null,
|
||||||
type: String,
|
openType: ''
|
||||||
default: ''
|
};
|
||||||
},
|
},
|
||||||
sendMessageImg: {
|
created() {
|
||||||
type: String,
|
if (this.servicerConfig) {
|
||||||
default: ''
|
// #ifdef H5
|
||||||
}
|
this.config = this.servicerConfig.h5;
|
||||||
},
|
// #endif
|
||||||
data() {
|
|
||||||
return {
|
// #ifdef MP-WEIXIN
|
||||||
customerService: null,
|
this.config = this.servicerConfig.weapp;
|
||||||
buttonConfig: null
|
if (this.config.type == 'weapp') this.openType = 'contact';
|
||||||
};
|
// #endif
|
||||||
},
|
|
||||||
computed: {
|
// #ifdef MP-ALIPAY
|
||||||
/**
|
this.config = this.servicerConfig.aliapp;
|
||||||
* 是否使用官方客服
|
if (this.config.type == 'aliapp') this.openType = 'contact';
|
||||||
*/
|
// #endif
|
||||||
useOfficialService() {
|
}
|
||||||
if (!this.buttonConfig) return true;
|
},
|
||||||
|
methods: {
|
||||||
// #ifdef MP-WEIXIN
|
/**
|
||||||
// 如果是微信小程序,检查配置
|
* 联系客服
|
||||||
if (this.buttonConfig.type === 'weapp') {
|
*/
|
||||||
// 默认使用官方客服,除非明确设置为false
|
contactServicer() {
|
||||||
return this.buttonConfig.useOfficial !== false;
|
if (this.config.type == 'none') {
|
||||||
}
|
this.$refs.servicePopup.open();
|
||||||
// #endif
|
}
|
||||||
|
if (this.openType == 'contact') return;
|
||||||
return false;
|
|
||||||
},
|
switch (this.config.type) {
|
||||||
|
case 'wxwork':
|
||||||
/**
|
// #ifdef H5
|
||||||
* 客服配置
|
location.href = this.config.wxwork_url;
|
||||||
*/
|
// #endif
|
||||||
config() {
|
// #ifdef MP-WEIXIN
|
||||||
return this.customerService?.getPlatformConfig() || {};
|
wx.openCustomerServiceChat({
|
||||||
},
|
extInfo: { url: this.config.wxwork_url },
|
||||||
|
corpId: this.config.corpid,
|
||||||
/**
|
showMessageCard: true,
|
||||||
* 打开类型
|
sendMessageTitle: this.sendMessageTitle,
|
||||||
*/
|
sendMessagePath: this.sendMessagePath,
|
||||||
openType() {
|
sendMessageImg: this.sendMessageImg
|
||||||
return this.buttonConfig?.openType || '';
|
});
|
||||||
}
|
// #endif
|
||||||
},
|
break;
|
||||||
created() {
|
case 'third':
|
||||||
// 初始化客服服务
|
location.href = this.config.third_url;
|
||||||
this.customerService = createCustomerService(this);
|
break;
|
||||||
this.buttonConfig = this.customerService.getButtonConfig();
|
case 'niushop':
|
||||||
},
|
this.$util.redirectTo('/pages_tool/chat/room', this.niushop);
|
||||||
methods: {
|
break;
|
||||||
/**
|
default:
|
||||||
* 联系客服
|
this.makePhoneCall();
|
||||||
*/
|
}
|
||||||
contactServicer() {
|
},
|
||||||
// 如果是微信/支付宝小程序客服,由系统自动处理
|
/**
|
||||||
if (this.buttonConfig.openType === 'contact') {
|
* 店铺联系方式
|
||||||
return;
|
*/
|
||||||
}
|
makePhoneCall() {
|
||||||
|
this.$api.sendRequest({
|
||||||
// 使用统一客服处理
|
url: '/api/site/shopcontact',
|
||||||
this.customerService.handleCustomerClick({
|
success: res => {
|
||||||
niushop: this.niushop,
|
if (res.code == 0 && res.data.mobile) uni.makePhoneCall({
|
||||||
sendMessageTitle: this.sendMessageTitle,
|
phoneNumber: res.data
|
||||||
sendMessagePath: this.sendMessagePath,
|
.mobile
|
||||||
sendMessageImg: this.sendMessageImg
|
});
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
};
|
||||||
|
</script>
|
||||||
<style lang="scss">
|
|
||||||
.contact-wrap {
|
<style lang="scss">
|
||||||
width: 100%;
|
.contact-wrap {
|
||||||
height: 100%;
|
width: 100%;
|
||||||
position: relative;
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
.contact-button {
|
|
||||||
width: 100%;
|
.contact-button {
|
||||||
height: 100%;
|
width: 100%;
|
||||||
position: absolute;
|
height: 100%;
|
||||||
left: 0;
|
position: absolute;
|
||||||
top: 0;
|
left: 0;
|
||||||
z-index: 5;
|
top: 0;
|
||||||
padding: 0;
|
z-index: 5;
|
||||||
margin: 0;
|
padding: 0;
|
||||||
opacity: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
opacity: 0;
|
||||||
}
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.service-popup-wrap {
|
|
||||||
width: 600rpx;
|
.service-popup-wrap {
|
||||||
|
width: 600rpx;
|
||||||
.head-wrap {
|
|
||||||
display: flex;
|
.head-wrap {
|
||||||
justify-content: space-between;
|
display: flex;
|
||||||
align-items: center;
|
justify-content: space-between;
|
||||||
padding: 0 30rpx;
|
align-items: center;
|
||||||
height: 90rpx;
|
padding: 0 30rpx;
|
||||||
}
|
height: 90rpx;
|
||||||
|
}
|
||||||
.body-wrap {
|
|
||||||
text-align: center;
|
.body-wrap {
|
||||||
padding: 30rpx;
|
text-align: center;
|
||||||
height: 100rpx;
|
padding: 30rpx;
|
||||||
}
|
height: 100rpx;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,92 +1,95 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="empty" :class="{ fixed: fixed }">
|
<view class="empty" :class="{ fixed: fixed }">
|
||||||
<view class="empty_img"><image :src="$util.img('public/uniapp/common/common-empty.png')" mode="aspectFit"></image></view>
|
<view class="empty_img"><image :src="$util.img('public/uniapp/common/common-empty.png')" mode="aspectFit"></image></view>
|
||||||
<view class="color-tip margin-top title" :style="{ color: textColor + ' !important' }">{{ text }}</view>
|
<view class="color-tip margin-top title" :style="{ color: textColor + ' !important' }">{{ text }}</view>
|
||||||
<view class="color-tip margin-bottom font-size-sub">{{ subText }}</view>
|
<view class="color-tip margin-bottom font-size-sub">{{ subText }}</view>
|
||||||
<button type="primary" size="mini" class="button mini" @click="goIndex()" v-if="isIndex">{{ emptyBtn.text }}</button>
|
<button type="primary" size="mini" class="button mini" @click="goIndex()" v-if="isIndex">{{ emptyBtn.text }}</button>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
text: {
|
text: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '暂无相关数据'
|
default: '暂无相关数据'
|
||||||
},
|
},
|
||||||
subText: {
|
subText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
isIndex: {
|
isIndex: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
emptyBtn: {
|
emptyBtn: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {
|
default: () => {
|
||||||
return { text: '去逛逛' };
|
return { text: '去逛逛' };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fixed: {
|
fixed: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
textColor: {
|
textColor: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
goIndex() {
|
goIndex() {
|
||||||
if (this.emptyBtn.url) {
|
if (this.emptyBtn.url) {
|
||||||
this.$util.redirectTo(this.emptyBtn.url, {}, 'redirectTo');
|
this.$util.redirectTo(this.emptyBtn.url, {}, 'redirectTo');
|
||||||
} else {
|
} else {
|
||||||
this.$util.redirectTo('/pages/index/index');
|
this.$util.redirectTo('/pages/index/index');
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
re(text) {
|
||||||
};
|
this.text = text;
|
||||||
</script>
|
}
|
||||||
|
}
|
||||||
<style lang="scss">
|
};
|
||||||
.empty {
|
</script>
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
<style lang="scss">
|
||||||
flex-direction: column;
|
.empty {
|
||||||
align-items: center;
|
width: 100%;
|
||||||
padding: $padding;
|
display: flex;
|
||||||
box-sizing: border-box;
|
flex-direction: column;
|
||||||
justify-content: center;
|
align-items: center;
|
||||||
.title {
|
padding: $padding;
|
||||||
font-size: 30rpx;
|
box-sizing: border-box;
|
||||||
}
|
justify-content: center;
|
||||||
.empty_img {
|
.title {
|
||||||
width: 50%;
|
font-size: 30rpx;
|
||||||
height: 450rpx;
|
}
|
||||||
|
.empty_img {
|
||||||
image {
|
width: 50%;
|
||||||
width: 100%;
|
height: 450rpx;
|
||||||
height: 100%;
|
|
||||||
padding-bottom: $padding;
|
image {
|
||||||
}
|
width: 100%;
|
||||||
}
|
height: 100%;
|
||||||
button {
|
padding-bottom: $padding;
|
||||||
min-width: 300rpx;
|
}
|
||||||
margin-top: 100rpx;
|
}
|
||||||
height: 70rpx;
|
button {
|
||||||
line-height: 70rpx !important;
|
min-width: 300rpx;
|
||||||
font-size: $font-size-base;
|
margin-top: 100rpx;
|
||||||
font-weight: bold;
|
height: 70rpx;
|
||||||
border-radius: 100rpx;
|
line-height: 70rpx !important;
|
||||||
}
|
font-size: $font-size-base;
|
||||||
}
|
font-weight: bold;
|
||||||
.fixed {
|
border-radius: 100rpx;
|
||||||
position: fixed;
|
}
|
||||||
left: 0;
|
}
|
||||||
top: 20vh;
|
.fixed {
|
||||||
}
|
position: fixed;
|
||||||
</style>
|
left: 0;
|
||||||
|
top: 20vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -220,7 +220,7 @@
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
formData:[]
|
formData: this.data
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -229,26 +229,23 @@
|
|||||||
watch: {
|
watch: {
|
||||||
data: function() {
|
data: function() {
|
||||||
this.setFormData();
|
this.setFormData();
|
||||||
},
|
}
|
||||||
formData: {
|
|
||||||
handler(newVal, oldVal) {
|
|
||||||
this.$emit('changeFormVal',newVal)
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setFormData() {
|
setFormData() {
|
||||||
let formData = JSON.parse(JSON.stringify(this.data));
|
this.formData = this.data;
|
||||||
formData.forEach(item => {
|
|
||||||
|
this.formData.forEach(item => {
|
||||||
if (!item.val) item.val = item.value.default ? item.value.default : '';
|
if (!item.val) item.val = item.value.default ? item.value.default : '';
|
||||||
|
|
||||||
if (item.value.options) {
|
if (item.value.options) {
|
||||||
item.option_lists = [];
|
item.option_lists = [];
|
||||||
item.value.options.forEach((v, k) => {
|
item.value.options.forEach((v, k) => {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.value = v;
|
obj.value = v;
|
||||||
obj.checked = false;
|
obj.checked = false;
|
||||||
if (item.controller == 'Radio' && ((!item.val && k == 0) || (item.val && item.val == v))) {
|
if (item.controller == 'Radio' && ((!item.val && k == 0) || (item.val &&
|
||||||
|
item.val == v))) {
|
||||||
obj.checked = true;
|
obj.checked = true;
|
||||||
item.val = v;
|
item.val = v;
|
||||||
}
|
}
|
||||||
@@ -362,7 +359,6 @@
|
|||||||
else item.default_regions = [];
|
else item.default_regions = [];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.formData = JSON.parse(JSON.stringify(formData))
|
|
||||||
},
|
},
|
||||||
verify() {
|
verify() {
|
||||||
let verify = true;
|
let verify = true;
|
||||||
@@ -396,7 +392,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 验证手机号
|
// 验证手机号
|
||||||
|
|
||||||
if (item.name == 'MOBILE' && this.$util.verifyMobile(item.val) === false) {
|
if (item.name == 'MOBILE' && this.$util.verifyMobile(item.val) === false) {
|
||||||
verify = !item.value.required;
|
verify = !item.value.required;
|
||||||
if (verify == false) {
|
if (verify == false) {
|
||||||
@@ -520,7 +515,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(verify)
|
|
||||||
if (verify) {
|
if (verify) {
|
||||||
return this.formData;
|
return this.formData;
|
||||||
} else return verify;
|
} else return verify;
|
||||||
@@ -683,7 +678,7 @@
|
|||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
border-bottom: 0;
|
border-bottom: solid 1px #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.align-top {
|
&.align-top {
|
||||||
@@ -841,9 +836,6 @@
|
|||||||
checkbox {
|
checkbox {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
label {
|
|
||||||
padding:10rpx 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox {
|
.checkbox {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,146 +1,146 @@
|
|||||||
<template>
|
<template>
|
||||||
<view>
|
<view>
|
||||||
<block v-if="text == '客服' || text == 'Contact'">
|
<block v-if="text == '客服'">
|
||||||
<!-- <ns-contact :niushop="chatParam" :send-message-title="sendData.title" :send-message-path="sendData.path" :send-message-img="sendData.img"> -->
|
<!-- <ns-contact :niushop="chatParam" :send-message-title="sendData.title" :send-message-path="sendData.path" :send-message-img="sendData.img"> -->
|
||||||
<button hoverClass="none" openType="contact" sessionFrom="weapp" showMessageCard="true" class="action-icon-wrap" style="background: transparent;padding: 0;margin: 0;">
|
<button hoverClass="none" openType="contact" sessionFrom="weapp" showMessageCard="true" class="action-icon-wrap" style="background: transparent;padding: 0;margin: 0;">
|
||||||
<view class="iconfont color-title" :class="icon"></view>
|
<view class="iconfont color-title" :class="icon"></view>
|
||||||
<text>{{ text }}</text>
|
<text>{{ text }}</text>
|
||||||
<view class="corner-mark color-base-bg" v-if="cornerMark.length" :style="{ background: cornerMarkBg+'!important', color: cornerMarkColor }">{{ cornerMark }}</view>
|
<view class="corner-mark color-base-bg" v-if="cornerMark.length" :style="{ background: cornerMarkBg+'!important', color: cornerMarkColor }">{{ cornerMark }}</view>
|
||||||
</button>
|
</button>
|
||||||
<!-- </ns-contact> -->
|
<!-- </ns-contact> -->
|
||||||
</block>
|
</block>
|
||||||
<block v-else>
|
<block v-else>
|
||||||
<view class="action-icon-wrap" @click="clickEvent">
|
<view class="action-icon-wrap" @click="clickEvent">
|
||||||
<view class="iconfont color-title" :class="icon"></view>
|
<view class="iconfont " :class="icon"></view>
|
||||||
<text>{{ text }}</text>
|
<text>{{ text }}</text>
|
||||||
<view class="corner-mark color-base-bg" :class="{'max' : parseInt(cornerMark)>99}" v-if="cornerMark.length" :style="{ background: cornerMarkBg+'!important', color: cornerMarkColor }">{{ cornerMark > 99 ? '99+' : cornerMark }}</view>
|
<view class="corner-mark color-base-bg" :class="{'max' : parseInt(cornerMark)>99}" v-if="cornerMark.length" :style="{ background: cornerMarkBg+'!important', color: cornerMarkColor }">{{ cornerMark > 99 ? '99+' : cornerMark }}</view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import nsContact from '@/components/ns-contact/ns-contact.vue';
|
import nsContact from '@/components/ns-contact/ns-contact.vue';
|
||||||
export default {
|
export default {
|
||||||
name: 'ns-goods-action-icon',
|
name: 'ns-goods-action-icon',
|
||||||
props: {
|
props: {
|
||||||
// 商品底部icon导航icon图标
|
// 商品底部icon导航icon图标
|
||||||
icon: {
|
icon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
// 商品底部icon导航文字
|
// 商品底部icon导航文字
|
||||||
text: {
|
text: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
// 角标文字
|
// 角标文字
|
||||||
cornerMark: {
|
cornerMark: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
// 角标背景色
|
// 角标背景色
|
||||||
cornerMarkBg: {
|
cornerMarkBg: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
// 角标文字颜色
|
// 角标文字颜色
|
||||||
cornerMarkColor: {
|
cornerMarkColor: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '#fff'
|
default: '#fff'
|
||||||
},
|
},
|
||||||
// 开放能力
|
// 开放能力
|
||||||
openType: {
|
openType: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
// 发送内容 openType="contact"时有效
|
// 发送内容 openType="contact"时有效
|
||||||
sendData: {
|
sendData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: function() {
|
default: function() {
|
||||||
return {
|
return {
|
||||||
title: '',
|
title: '',
|
||||||
path: '',
|
path: '',
|
||||||
img: ''
|
img: ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
chatParam: {
|
chatParam: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: function(){
|
default: function(){
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components:{
|
components:{
|
||||||
nsContact
|
nsContact
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
clickEvent() {
|
clickEvent() {
|
||||||
this.$emit('click');
|
this.$emit('click');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.action-icon-wrap {
|
.action-icon-wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 100rpx;
|
height: 100rpx;
|
||||||
min-width: 90rpx;
|
min-width: 90rpx;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-right: 6rpx;
|
margin-right: 6rpx;
|
||||||
}
|
}
|
||||||
.action-icon-wrap button {
|
.action-icon-wrap button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border: none;
|
border: none;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background: none;
|
background: none;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-icon-wrap button::after {
|
.action-icon-wrap button::after {
|
||||||
border: none !important;
|
border: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-icon-wrap .iconfont {
|
.action-icon-wrap .iconfont {
|
||||||
margin: 0 auto 10rpx;
|
margin: 0 auto 10rpx;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
font-size: 40rpx;
|
font-size: 40rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-icon-wrap .corner-mark {
|
.action-icon-wrap .corner-mark {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
font-size: $font-size-activity-tag;
|
font-size: $font-size-activity-tag;
|
||||||
top: 4rpx;
|
top: 4rpx;
|
||||||
right: 12rpx;
|
right: 12rpx;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 24rpx;
|
width: 24rpx;
|
||||||
height: 24rpx;
|
height: 24rpx;
|
||||||
padding: 6rpx;
|
padding: 6rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
&.max{
|
&.max{
|
||||||
right:-4rpx;
|
right:-4rpx;
|
||||||
width: 40rpx;
|
width: 40rpx;
|
||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-icon-wrap text {
|
.action-icon-wrap text {
|
||||||
font-size: $font-size-tag;
|
font-size: $font-size-tag;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ export default {
|
|||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.ns-goods-promotion {
|
.ns-goods-promotion {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
& > view {
|
||||||
|
}
|
||||||
.item {
|
.item {
|
||||||
display: flex;
|
display: flex;
|
||||||
font-size: $font-size-base;
|
font-size: $font-size-base;
|
||||||
|
|||||||
@@ -1,93 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="goods-recommend" v-if="list.length">
|
<view></view>
|
||||||
<view class="goods-recommend-title">
|
|
||||||
<text class="title">{{ config.title }}</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="goods-list double-column">
|
|
||||||
<view class="goods-item margin-bottom" v-for="(item, index) in list" :key="index" @click="toDetail(item)">
|
|
||||||
<view class="goods-img">
|
|
||||||
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)" :lazy-load="true" />
|
|
||||||
<view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }}</view>
|
|
||||||
<view class="sell-out" v-if="item.goods_stock <= 0">
|
|
||||||
<text class="iconfont icon-shuqing"></text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="info-wrap">
|
|
||||||
<view class="goods-name" :class="[{ 'using-hidden': config.nameLineMode == 'single' }, { 'multi-hidden': config.nameLineMode == 'multiple' }]">
|
|
||||||
{{ item.goods_name }}
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="lineheight-clear">
|
|
||||||
<view class="discount-price">
|
|
||||||
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
|
|
||||||
<text class="price price-style large">{{ parseFloat(showPrice(item)).toFixed(2).split('.')[0] }}</text>
|
|
||||||
<text class="unit price-style small">.{{ parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="member-price-tag" v-if="item.member_price && item.member_price == showPrice(item)">
|
|
||||||
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix"/>
|
|
||||||
</view>
|
|
||||||
<view class="member-price-tag" v-else-if="item.promotion_type == 1">
|
|
||||||
<image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix"/>
|
|
||||||
</view>
|
|
||||||
<view class="delete-price font-size-activity-tag color-tip price-font" v-if="showMarketPrice(item)">
|
|
||||||
<text class="unit">{{ $lang('common.currencySymbol') }}</text>
|
|
||||||
<text>{{ showMarketPrice(item) }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="pro-info">
|
|
||||||
<view class="block-wrap">
|
|
||||||
<view class="sale font-size-activity-tag color-tip" v-if="item.sale_show">已售{{ item.sale_num }}{{ item.unit ? item.unit : '件' }}</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="cart-action-wrap" v-if="config.control && item.is_virtual == 0">
|
|
||||||
<!-- 购物车图标 -->
|
|
||||||
<view v-if="config.style == 'icon-cart'" :style="{
|
|
||||||
color: config.theme == 'diy' ? config.textColor : '',
|
|
||||||
borderColor: config.theme == 'diy' ? config.textColor : ''
|
|
||||||
}" class="cart shopping-cart-btn iconfont icon-gouwuche click-wrap" :id="'goods-' + item.id"
|
|
||||||
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
|
|
||||||
<view class="click-event"></view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!--加号图标 -->
|
|
||||||
<view v-else-if="config.style == 'icon-add'" :style="{
|
|
||||||
color: config.theme == 'diy' ? config.textColor : '',
|
|
||||||
borderColor: config.theme == 'diy' ? config.textColor : ''
|
|
||||||
}" class="cart plus-sign-btn iconfont icon-add1 click-wrap" :id="'goods-' + item.id"
|
|
||||||
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
|
|
||||||
<view class="click-event"></view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 按钮 -->
|
|
||||||
<view v-else-if="config.style == 'button'" :style="{
|
|
||||||
backgroundColor: config.theme == 'diy' ? config.bgColor : '',
|
|
||||||
color: config.theme == 'diy' ? config.textColor : '',
|
|
||||||
fontWeight: config.theme == 'diy' ? (config.fontWeight ? 'bold' : 'normal') : '',
|
|
||||||
padding: config.theme == 'diy' ? '12rpx ' + config.padding * 2 + 'rpx' : ''
|
|
||||||
}" class="cart buy-btn click-wrap" :id="'goods-' + item.id"
|
|
||||||
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
|
|
||||||
{{ config.text }}
|
|
||||||
<view class="click-event"></view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!--自定义图标 -->
|
|
||||||
<view v-else-if="config.style == 'icon-diy'" :style="{
|
|
||||||
color: config.theme == 'diy' ? config.textColor : ''
|
|
||||||
}" class="icon-diy click-wrap" :id="'goods-' + item.id"
|
|
||||||
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
|
|
||||||
<view class="click-event"></view>
|
|
||||||
<diy-icon :icon="config.iconDiy.icon" :value="config.iconDiy.style ? config.iconDiy.style : null"></diy-icon>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="circle-box" v-if="showLoading && load"><ns-loading></ns-loading></view>
|
|
||||||
|
|
||||||
<ns-goods-sku-index ref="goodsSkuIndex" @cartListChange="cartListChange" @addCart="addCart"></ns-goods-sku-index>
|
|
||||||
</view>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -344,22 +256,6 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
// transform: translateY(-50%);
|
// transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
.sell-out{
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
text{
|
|
||||||
color: #fff;
|
|
||||||
font-size: 220rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods-tag {
|
.goods-tag {
|
||||||
|
|||||||
@@ -31,11 +31,9 @@
|
|||||||
@click="change(item_value.sku_id, item_value.spec_id)">
|
@click="change(item_value.sku_id, item_value.spec_id)">
|
||||||
<image v-if="item_value.image" :src="$util.img(item_value.image, { size: 'small' })" @error="valueImageError(index, index_value)" />
|
<image v-if="item_value.image" :src="$util.img(item_value.image, { size: 'small' })" @error="valueImageError(index, index_value)" />
|
||||||
<text>{{ item_value.spec_value_name }}</text>
|
<text>{{ item_value.spec_value_name }}</text>
|
||||||
<view class="empty-stock" v-if="item_value.stock == 0">缺货</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<ns-form :data="goodsForm" v-if="goodsForm" ref="form"></ns-form>
|
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<view class="footer">
|
<view class="footer">
|
||||||
@@ -52,12 +50,12 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="footer-right">
|
<view class="footer-right">
|
||||||
<view class="change_num" v-if="cartInputLock">
|
<view class="change_num" v-if="number > 0">
|
||||||
<view class="num-action" @click="changeNum('-')">
|
<view class="num-action" @click="changeNum('-')">
|
||||||
<text class="desc iconfont icon-jianshao color-base-text"></text>
|
<text class="desc iconfont icon-jianshao color-base-text"></text>
|
||||||
<view class="click-event"></view>
|
<view class="click-event"></view>
|
||||||
</view>
|
</view>
|
||||||
<input type="number" class="uni-input" @blur="blur" v-model.lazy="number" placeholder="0" @input="keyInput(false,null,true)" />
|
<input type="number" class="uni-input" @blur="blur" v-model="number" placeholder="0" @input="keyInput(false)" />
|
||||||
<view class="num-action" :id="'select-sku-num-' + goodsDetail.goods_id" @click="changeNum('+', $event)">
|
<view class="num-action" :id="'select-sku-num-' + goodsDetail.goods_id" @click="changeNum('+', $event)">
|
||||||
<text class="add iconfont icon-add-fill color-base-text change_hover"></text>
|
<text class="add iconfont icon-add-fill color-base-text change_hover"></text>
|
||||||
<view class="click-event"></view>
|
<view class="click-event"></view>
|
||||||
@@ -117,9 +115,7 @@
|
|||||||
maxBuy: 0,
|
maxBuy: 0,
|
||||||
minBuy: 0,
|
minBuy: 0,
|
||||||
isLoad: false,
|
isLoad: false,
|
||||||
timeout: null,
|
timeout: null
|
||||||
goodsForm: null,
|
|
||||||
skuList: []
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -128,44 +124,21 @@
|
|||||||
watch: {
|
watch: {
|
||||||
pointLimit(newNum, oldNum) {
|
pointLimit(newNum, oldNum) {
|
||||||
this.limitNumber = Number(newNum);
|
this.limitNumber = Number(newNum);
|
||||||
}
|
},
|
||||||
},
|
minBuy(newData, oldData) {
|
||||||
computed:{
|
if (this.minBuy > 1) {
|
||||||
cartInputLock:function() {
|
this.number = Number(this.minBuy);
|
||||||
if(!this.isLoad){
|
|
||||||
return true
|
|
||||||
}else if(this.number>0){
|
|
||||||
return true
|
|
||||||
}else{
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
calcSkuStock() {
|
|
||||||
if(this.goodsDetail.goods_spec_format && this.goodsDetail.goods_spec_format.length){
|
|
||||||
this.goodsDetail.goods_spec_format.forEach(spec => {
|
|
||||||
spec.value.forEach(val => {
|
|
||||||
this.skuList.forEach(sku => {
|
|
||||||
if (val.sku_id == sku.sku_id) {
|
|
||||||
this.$set(val,'stock',sku.stock);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
show(data) {
|
show(data) {
|
||||||
this.number = 0 ; // 每次打开要初始化
|
|
||||||
this.isLoad = true;
|
this.isLoad = true;
|
||||||
this.goodsDetail = data;
|
this.goodsDetail = data;
|
||||||
this.goodsId = this.goodsDetail.goods_id;
|
this.goodsId = this.goodsDetail.goods_id;
|
||||||
this.skuId = this.goodsDetail.sku_id;
|
this.skuId = this.goodsDetail.sku_id;
|
||||||
this.maxBuy = this.goodsDetail.max_buy;
|
this.maxBuy = this.goodsDetail.max_buy;
|
||||||
this.minBuy = this.goodsDetail.min_buy;
|
this.minBuy = this.goodsDetail.min_buy;
|
||||||
this.goodsForm = null
|
|
||||||
this.getGoodsForm()
|
|
||||||
this.getGoodsSkuList(this.goodsId);
|
this.getGoodsSkuList(this.goodsId);
|
||||||
this.keyInput(false);
|
this.keyInput(false);
|
||||||
if (this.getCurrentCart()) {
|
if (this.getCurrentCart()) {
|
||||||
@@ -173,19 +146,6 @@
|
|||||||
}
|
}
|
||||||
this.$refs.skuPopup.open();
|
this.$refs.skuPopup.open();
|
||||||
},
|
},
|
||||||
getGoodsForm(){
|
|
||||||
this.$api.sendRequest({
|
|
||||||
url: "/form/api/form/goodsform",
|
|
||||||
data: {
|
|
||||||
goods_id: this.goodsDetail.goods_id
|
|
||||||
},
|
|
||||||
success: res => {
|
|
||||||
if (res.code == 0 && res.data) {
|
|
||||||
this.goodsForm = res.data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
hide() {
|
hide() {
|
||||||
if(this.$refs.skuPopup) this.$refs.skuPopup.close();
|
if(this.$refs.skuPopup) this.$refs.skuPopup.close();
|
||||||
},
|
},
|
||||||
@@ -215,7 +175,6 @@
|
|||||||
} else {
|
} else {
|
||||||
this.number = 0;
|
this.number = 0;
|
||||||
}
|
}
|
||||||
this.calcSkuStock()
|
|
||||||
},
|
},
|
||||||
//查看规格图片
|
//查看规格图片
|
||||||
previewMedia() {
|
previewMedia() {
|
||||||
@@ -241,7 +200,7 @@
|
|||||||
if (res.code >= 0) {
|
if (res.code >= 0) {
|
||||||
let data = res.data,
|
let data = res.data,
|
||||||
obj = {};
|
obj = {};
|
||||||
|
|
||||||
res.data.forEach((item, index) => {
|
res.data.forEach((item, index) => {
|
||||||
// 当前商品SKU规格
|
// 当前商品SKU规格
|
||||||
if (item.sku_spec_format) item.sku_spec_format = JSON.parse(item.sku_spec_format);
|
if (item.sku_spec_format) item.sku_spec_format = JSON.parse(item.sku_spec_format);
|
||||||
@@ -269,8 +228,6 @@
|
|||||||
obj['sku_' + item.sku_id] = item;
|
obj['sku_' + item.sku_id] = item;
|
||||||
});
|
});
|
||||||
this.goodsSkuList = obj;
|
this.goodsSkuList = obj;
|
||||||
this.skuList = res.data;
|
|
||||||
this.calcSkuStock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -324,11 +281,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const query = uni.createSelectorQuery().in(this);
|
const query = uni.createSelectorQuery().in(this);
|
||||||
query.select('#' + event.currentTarget.id + ' .click-event').boundingClientRect(data => {
|
query.select('#' + event.currentTarget.id + ' .click-event')
|
||||||
if (data) {
|
.boundingClientRect(data => {
|
||||||
this.$emit('addCart', data.left, data.top);
|
if (data) {
|
||||||
}
|
this.$emit('addCart', data.left, data.top);
|
||||||
}).exec();
|
}
|
||||||
|
}).exec();
|
||||||
} else if (tag == '-') {
|
} else if (tag == '-') {
|
||||||
// 减
|
// 减
|
||||||
if (this.number > min) {
|
if (this.number > min) {
|
||||||
@@ -367,16 +325,14 @@
|
|||||||
|
|
||||||
let newNumber = parseInt(this.number);
|
let newNumber = parseInt(this.number);
|
||||||
|
|
||||||
this.isLoad = true;
|
this.isLoad = false;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.number = newNumber;
|
this.number = newNumber;
|
||||||
this.cartNumChange(this.number);
|
this.cartNumChange(this.number);
|
||||||
}, 0);
|
}, 0);
|
||||||
},
|
},
|
||||||
//输入数量
|
//输入数量
|
||||||
keyInput(flag, callback,isInput) {
|
keyInput(flag, callback) {
|
||||||
if(isInput) this.isLoad = false
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
var stock = this.goodsDetail.stock;
|
var stock = this.goodsDetail.stock;
|
||||||
|
|
||||||
@@ -396,7 +352,7 @@
|
|||||||
this.number = stock;
|
this.number = stock;
|
||||||
}
|
}
|
||||||
// 商品起售数
|
// 商品起售数
|
||||||
if (flag && this.minBuy > 1 && this.number < this.minBuy) {
|
if (this.minBuy > 1 && this.number < this.minBuy) {
|
||||||
this.number = this.minBuy;
|
this.number = this.minBuy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,13 +374,7 @@
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.$refs.form) {
|
|
||||||
if (!this.$refs.form.verify()) return;
|
|
||||||
uni.setStorageSync('goodFormData', {
|
|
||||||
goods_id: this.goodsDetail.goods_id,
|
|
||||||
form_data: this.$refs.form.formData
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.number = 1;
|
this.number = 1;
|
||||||
//纠正数量
|
//纠正数量
|
||||||
this.keyInput(true, () => {
|
this.keyInput(true, () => {
|
||||||
@@ -726,20 +676,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.body-item .sku-list-wrap .empty-stock{
|
|
||||||
font-size: 18rpx;
|
|
||||||
line-height: 22rpx;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
border-radius: 4rpx;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
padding: 0 2rpx;
|
|
||||||
color: #989898;
|
|
||||||
background-color: #f0f1f2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sku-layer .body-item .sku-list-wrap .items {
|
.sku-layer .body-item .sku-list-wrap .items {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -51,7 +51,12 @@
|
|||||||
* @param {Object} data 商品项
|
* @param {Object} data 商品项
|
||||||
*/
|
*/
|
||||||
singleSpecificationGoods(data, event) {
|
singleSpecificationGoods(data, event) {
|
||||||
let cart = this.cartList['goods_' + data.goods_id] && this.cartList['goods_' + data.goods_id]['sku_' + data.sku_id] ? this.cartList['goods_' + data.goods_id]['sku_' + data.sku_id] : null;
|
let cart =
|
||||||
|
this.cartList['goods_' + data.goods_id] && this.cartList['goods_' + data.goods_id]['sku_' + data
|
||||||
|
.sku_id
|
||||||
|
] ?
|
||||||
|
this.cartList['goods_' + data.goods_id]['sku_' + data.sku_id] :
|
||||||
|
null;
|
||||||
|
|
||||||
let cartNum = cart ? cart.num : 0;
|
let cartNum = cart ? cart.num : 0;
|
||||||
let api = cart && cart.cart_id ? '/api/cart/edit' : '/api/cart/add';
|
let api = cart && cart.cart_id ? '/api/cart/edit' : '/api/cart/add';
|
||||||
@@ -61,7 +66,6 @@
|
|||||||
if(cart && cart.cart_id){
|
if(cart && cart.cart_id){
|
||||||
_num = _num + (data.min_buy > 0 ? data.min_buy : 1)
|
_num = _num + (data.min_buy > 0 ? data.min_buy : 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
let cart_id = cart ? cart.cart_id : 0;
|
let cart_id = cart ? cart.cart_id : 0;
|
||||||
if (_num > parseInt(data.stock)) {
|
if (_num > parseInt(data.stock)) {
|
||||||
this.$util.showToast({
|
this.$util.showToast({
|
||||||
@@ -115,7 +119,8 @@
|
|||||||
this.isRepeat = false;
|
this.isRepeat = false;
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
if (cart_id == 0) {
|
if (cart_id == 0) {
|
||||||
this.cartList['goods_' + data.goods_id]['sku_' + data.sku_id].cart_id = res.data;
|
this.cartList['goods_' + data.goods_id]['sku_' + data.sku_id].cart_id =
|
||||||
|
res.data;
|
||||||
}
|
}
|
||||||
this.$util.showToast({
|
this.$util.showToast({
|
||||||
title: "商品添加购物车成功"
|
title: "商品添加购物车成功"
|
||||||
|
|||||||
@@ -153,7 +153,6 @@
|
|||||||
}" class="items" @click="change(item_value.sku_id, item_value.spec_id)">
|
}" class="items" @click="change(item_value.sku_id, item_value.spec_id)">
|
||||||
<image v-if="item_value.image" :src="$util.img(item_value.image, { size: 'small' })" @error="valueImageError(index, index_value)" />
|
<image v-if="item_value.image" :src="$util.img(item_value.image, { size: 'small' })" @error="valueImageError(index, index_value)" />
|
||||||
<text>{{ item_value.spec_value_name }}</text>
|
<text>{{ item_value.spec_value_name }}</text>
|
||||||
<view class="empty-stock" v-if="item_value.stock == 0">缺货</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -174,8 +173,8 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<ns-form :data="goodsForm" v-if="goodsForm" ref="form" @changeFormVal="changeFormVal"></ns-form>
|
<ns-form :data="goodsForm" v-if="goodsForm" ref="form"></ns-form>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<view class="footer" @click="confirm()">
|
<view class="footer" @click="confirm()">
|
||||||
@@ -183,8 +182,7 @@
|
|||||||
<block v-if="type == 'point'">
|
<block v-if="type == 'point'">
|
||||||
<block v-if="goodsDetail.type == 1">
|
<block v-if="goodsDetail.type == 1">
|
||||||
<!-- 兑换商品 -->
|
<!-- 兑换商品 -->
|
||||||
<button v-if="goodsDetail.point * number > memberPoint" disabled="true" type="primary">积分不足</button>
|
<button v-if="goodsDetail.stock && goodsDetail.stock != 0" type="primary">兑换</button>
|
||||||
<button v-else-if="goodsDetail.stock && goodsDetail.stock != 0" type="primary">兑换</button>
|
|
||||||
<button type="primary" v-else disabled="true">库存不足</button>
|
<button type="primary" v-else disabled="true">库存不足</button>
|
||||||
</block>
|
</block>
|
||||||
<block v-else-if="goodsDetail.type == 2 || goodsDetail.type == 3">
|
<block v-else-if="goodsDetail.type == 2 || goodsDetail.type == 3">
|
||||||
@@ -197,8 +195,7 @@
|
|||||||
<button type="primary" v-else-if="goodsDetail.stock && goodsDetail.stock != 0 && type == 'buy_now'">立即购买</button>
|
<button type="primary" v-else-if="goodsDetail.stock && goodsDetail.stock != 0 && type == 'buy_now'">立即购买</button>
|
||||||
<button type="primary" v-else-if="goodsDetail.stock && goodsDetail.stock != 0 && type == 'confirm'">确认</button>
|
<button type="primary" v-else-if="goodsDetail.stock && goodsDetail.stock != 0 && type == 'confirm'">确认</button>
|
||||||
<template v-else-if="goodsDetail.stock && goodsDetail.stock != 0">
|
<template v-else-if="goodsDetail.stock && goodsDetail.stock != 0">
|
||||||
<!-- 拼团和拼返的buy_num代表最大购买数量,不是最小购买数量 -->
|
<template v-if="goodsDetail.buy_num">
|
||||||
<template v-if="type != 'pintuan' && type != 'pinfan' && goodsDetail.buy_num">
|
|
||||||
<button type="primary" v-if="goodsDetail.buy_num <= goodsDetail.stock">立即抢购</button>
|
<button type="primary" v-if="goodsDetail.buy_num <= goodsDetail.stock">立即抢购</button>
|
||||||
<button type="primary" v-else disabled="true">库存不足</button>
|
<button type="primary" v-else disabled="true">库存不足</button>
|
||||||
</template>
|
</template>
|
||||||
@@ -229,10 +226,6 @@
|
|||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
memberPoint: {
|
|
||||||
type: [Number, String],
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
goodsDetail: {
|
goodsDetail: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null
|
default: null
|
||||||
@@ -251,12 +244,6 @@
|
|||||||
minBuy: {
|
minBuy: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
|
||||||
goodsFormVal: {
|
|
||||||
type: Array,
|
|
||||||
default () {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -278,8 +265,7 @@
|
|||||||
pintuan_num_field: 'pintuan_num',
|
pintuan_num_field: 'pintuan_num',
|
||||||
goodsSkuInfo: null, //所有的商品规格信息
|
goodsSkuInfo: null, //所有的商品规格信息
|
||||||
goodsForm: null,
|
goodsForm: null,
|
||||||
isLoad: false ,// 是否首次加载
|
isLoad: false // 是否首次加载
|
||||||
skuList: [],//所有规格数据
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -324,8 +310,8 @@
|
|||||||
this.pintuan_num_field = newData.pintuan_num_field;
|
this.pintuan_num_field = newData.pintuan_num_field;
|
||||||
}
|
}
|
||||||
if (this.goodsDetail.goods_form && !this.goodsForm) this.goodsForm = this.goodsDetail.goods_form;
|
if (this.goodsDetail.goods_form && !this.goodsForm) this.goodsForm = this.goodsDetail.goods_form;
|
||||||
|
|
||||||
// 切换商品,重新赋值
|
// 切换商品,重新赋值
|
||||||
this.calcSkuStock()
|
|
||||||
if (newData.goods_id != oldData.goods_id) {
|
if (newData.goods_id != oldData.goods_id) {
|
||||||
if (this.goodsDetail.pintuan_id) {
|
if (this.goodsDetail.pintuan_id) {
|
||||||
this.getPintuanGoodsSkuList();
|
this.getPintuanGoodsSkuList();
|
||||||
@@ -392,34 +378,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
calcSkuStock() {
|
|
||||||
if(this.goodsDetail.goods_spec_format && this.goodsDetail.goods_spec_format.length){
|
|
||||||
this.goodsDetail.goods_spec_format.forEach(spec => {
|
|
||||||
spec.value.forEach(val => {
|
|
||||||
this.skuList.forEach(sku => {
|
|
||||||
if (val.sku_id == sku.sku_id) {
|
|
||||||
this.$set(val,'stock',sku.stock);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
changeFormVal(e) {
|
|
||||||
this.$emit('detailChangeVal',e)
|
|
||||||
},
|
|
||||||
getGoodsForm(){
|
|
||||||
this.$api.sendRequest({
|
|
||||||
url: "/form/api/form/goodsform",
|
|
||||||
data: {
|
|
||||||
goods_id: this.goodsDetail.goods_id
|
|
||||||
},
|
|
||||||
success: res => {
|
|
||||||
if (res.code == 0 && res.data) this.$set(this.goodsDetail, 'goods_form', res.data);
|
|
||||||
if(this.goodsFormVal.length) Object.assign(this.goodsDetail.goods_form,this.goodsFormVal)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
//【普通商品】获取所有规格信息
|
//【普通商品】获取所有规格信息
|
||||||
getGeneralGoodsSkuList(callback) {
|
getGeneralGoodsSkuList(callback) {
|
||||||
this.$api.sendRequest({
|
this.$api.sendRequest({
|
||||||
@@ -429,7 +387,9 @@
|
|||||||
},
|
},
|
||||||
success: res => {
|
success: res => {
|
||||||
if (res.code >= 0) {
|
if (res.code >= 0) {
|
||||||
let obj = {};
|
let data = res.data,
|
||||||
|
obj = {};
|
||||||
|
|
||||||
res.data.forEach((item, index) => {
|
res.data.forEach((item, index) => {
|
||||||
item = this.handleData(item);
|
item = this.handleData(item);
|
||||||
|
|
||||||
@@ -455,8 +415,6 @@
|
|||||||
if (this.skuId == 0) this.skuId = res.data[0].sku_id;
|
if (this.skuId == 0) this.skuId = res.data[0].sku_id;
|
||||||
this.goodsSkuInfo = obj;
|
this.goodsSkuInfo = obj;
|
||||||
this.isLoad = false;
|
this.isLoad = false;
|
||||||
this.skuList = res.data;
|
|
||||||
this.calcSkuStock();
|
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
} else {
|
} else {
|
||||||
this.$util.redirectTo('/pages/index/index');
|
this.$util.redirectTo('/pages/index/index');
|
||||||
@@ -535,7 +493,7 @@
|
|||||||
item = this.handleData(item);
|
item = this.handleData(item);
|
||||||
item.show_price = this.goodsDetail.groupbuy_price;
|
item.show_price = this.goodsDetail.groupbuy_price;
|
||||||
item.save_price = item.price - item.show_price > 0 ? (item.price - item.show_price).toFixed(2) : 0;
|
item.save_price = item.price - item.show_price > 0 ? (item.price - item.show_price).toFixed(2) : 0;
|
||||||
//团购buy_num指最少购买数量
|
|
||||||
if (data.stock > data.buy_num) {
|
if (data.stock > data.buy_num) {
|
||||||
this.number = this.goodsDetail.buy_num;
|
this.number = this.goodsDetail.buy_num;
|
||||||
this.minNumber = this.goodsDetail.buy_num;
|
this.minNumber = this.goodsDetail.buy_num;
|
||||||
@@ -772,9 +730,6 @@
|
|||||||
popclose() {
|
popclose() {
|
||||||
if (this.$refs.skuPopup.showPopup) {
|
if (this.$refs.skuPopup.showPopup) {
|
||||||
this.$emit('hideSkuPop');
|
this.$emit('hideSkuPop');
|
||||||
}else{
|
|
||||||
this.goodsForm = null
|
|
||||||
this.getGoodsForm()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//查看规格图片
|
//查看规格图片
|
||||||
@@ -811,6 +766,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.goodsSkuDetail = this.goodsSkuInfo['sku_' + this.skuId];
|
this.goodsSkuDetail = this.goodsSkuInfo['sku_' + this.skuId];
|
||||||
this.$emit('refresh', this.goodsSkuDetail);
|
this.$emit('refresh', this.goodsSkuDetail);
|
||||||
this.$emit('getSkuId', this.skuId);
|
this.$emit('getSkuId', this.skuId);
|
||||||
@@ -825,7 +781,6 @@
|
|||||||
this.confirmDisabled = false;
|
this.confirmDisabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.keyInput(true);
|
this.keyInput(true);
|
||||||
},
|
},
|
||||||
showPrice(price) {
|
showPrice(price) {
|
||||||
@@ -1058,7 +1013,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.type != 'pintuan' && this.type != 'pinfan' && this.goodsDetail.buy_num > this.goodsDetail.stock) {
|
if (this.goodsDetail.buy_num > this.goodsDetail.stock) {
|
||||||
this.$util.showToast({
|
this.$util.showToast({
|
||||||
title: '库存小于最低购买数量'
|
title: '库存小于最低购买数量'
|
||||||
});
|
});
|
||||||
@@ -1122,7 +1077,7 @@
|
|||||||
title: '加入购物车成功'
|
title: '加入购物车成功'
|
||||||
});
|
});
|
||||||
this.cartNum += this.number;
|
this.cartNum += this.number;
|
||||||
this.$store.dispatch('getCartNumber');
|
|
||||||
let discount_price = this.goodsDetail.discount_price;
|
let discount_price = this.goodsDetail.discount_price;
|
||||||
if (this.goodsDetail.member_price > 0 && Number(this.goodsDetail.member_price) <= Number(this.goodsDetail.discount_price)) {
|
if (this.goodsDetail.member_price > 0 && Number(this.goodsDetail.member_price) <= Number(this.goodsDetail.discount_price)) {
|
||||||
discount_price = this.goodsDetail.member_price;
|
discount_price = this.goodsDetail.member_price;
|
||||||
@@ -1258,29 +1213,28 @@
|
|||||||
});
|
});
|
||||||
} else if (this.type == 'bargain') {
|
} else if (this.type == 'bargain') {
|
||||||
// 砍价
|
// 砍价
|
||||||
if (this.callback) {
|
this.$api.sendRequest({
|
||||||
this.callback();
|
url: '/bargain/api/bargain/launch',
|
||||||
}else {
|
data: {
|
||||||
this.$api.sendRequest({
|
id: this.goodsDetail.id
|
||||||
url: '/bargain/api/bargain/launch',
|
},
|
||||||
data: {
|
success: res => {
|
||||||
id: this.goodsDetail.id
|
this.btnSwitch = false;
|
||||||
},
|
if (res.code == 0) {
|
||||||
success: res => {
|
this.$util.redirectTo(
|
||||||
this.btnSwitch = false;
|
'/pages_promotion/bargain/detail', {
|
||||||
if (res.code == 0) {
|
|
||||||
this.$util.redirectTo('/pages_promotion/bargain/detail', {
|
|
||||||
b_id: this.goodsDetail.bargain_id,
|
b_id: this.goodsDetail.bargain_id,
|
||||||
l_id: res.data
|
l_id: res.data
|
||||||
}, 'redirectTo');
|
},
|
||||||
} else {
|
'redirectTo'
|
||||||
this.$util.showToast({
|
);
|
||||||
title: res.message
|
} else {
|
||||||
});
|
this.$util.showToast({
|
||||||
}
|
title: res.message
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
} else if (this.type == 'point') {
|
} else if (this.type == 'point') {
|
||||||
// 积分兑换
|
// 积分兑换
|
||||||
var data = {
|
var data = {
|
||||||
@@ -1445,27 +1399,13 @@
|
|||||||
|
|
||||||
.body-item .sku-list-wrap {
|
.body-item .sku-list-wrap {
|
||||||
padding-bottom: 0rpx;
|
padding-bottom: 0rpx;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.body-item .sku-list-wrap .title {
|
.body-item .sku-list-wrap .title {
|
||||||
padding: 20rpx 0;
|
padding: 20rpx 0;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.body-item .sku-list-wrap .empty-stock{
|
|
||||||
font-size: 18rpx;
|
|
||||||
line-height: 22rpx;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
border-radius: 4rpx;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
padding: 0 2rpx;
|
|
||||||
color: #989898;
|
|
||||||
background-color: #f0f1f2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.body-item .sku-list-wrap .items {
|
.body-item .sku-list-wrap .items {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,25 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="mp-html">
|
|
||||||
<mp-html :content="content"></mp-html>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
content: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.mp-html{
|
|
||||||
/deep/ img{
|
|
||||||
width:100% !important;
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,400 +1,404 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="ns-navbar-wrap" :class="'style-' + data.navStyle">
|
<!-- <view class="ns-navbar-wrap" :class="'style-' + data.navStyle">
|
||||||
<!-- #ifndef MP-ALIPAY -->
|
|
||||||
<view class="u-navbar" :style="{ backgroundColor: bgColor, paddingTop: navbarHeight + 'px' }">
|
<view class="u-navbar" :style="{ backgroundColor: bgColor, paddingTop: navbarHeight + 'px' }">
|
||||||
<view class="navbar-inner" :style="navbarInnerStyle">
|
<view class="navbar-inner" :style="navbarInnerStyle">
|
||||||
<view class="back-wrap" v-if="isBack && isBackShow" @tap="goBack">
|
<view class="back-wrap" v-if="isBack && isBackShow" @tap="goBack">
|
||||||
<text class="iconfont icon-back_light" :style="{ color: titleColor }"></text>
|
<text class="iconfont icon-back_light" :style="{ color: titleColor }"></text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="data.navStyle == 1" class="content-wrap" :class="[data.textImgPosLink, isBack && isBackShow ? 'have-back' : '']" @click="toLink(data.moreLink.wap_url)">
|
<view v-if="data.navStyle == 1" class="content-wrap" :class="[data.textImgPosLink, isBack && isBackShow ? 'have-back' : '']" @click="toLink(data.moreLink.wap_url)">
|
||||||
<view class="title-wrap" :style="{ fontSize: '16px', color: data.textNavColor, textAlign: data.textImgPosLink }">
|
<view class="title-wrap" :style="{ fontSize: '14px', color: data.textNavColor, textAlign: data.textImgPosLink }">
|
||||||
{{ data.title }}
|
{{ data.title }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="data.navStyle == 2" class="content-wrap" @click="toLink(data.moreLink.wap_url)">
|
<view v-if="data.navStyle == 2" class="content-wrap" @click="toLink(data.moreLink.wap_url)">
|
||||||
<view class="title-wrap" :style="{ color: data.textNavColor }">
|
<view class="title-wrap" :style="{ color: data.textNavColor }">
|
||||||
<view>
|
<view>
|
||||||
<image :src="$util.img(data.topNavImg)" mode="heightFix"></image>
|
<image :src="$util.img(data.topNavImg)" mode="heightFix"></image>
|
||||||
</view>
|
</view>
|
||||||
<view :style="{ color: data.textNavColor }">{{ data.title }}</view>
|
<view :style="{ color: data.textNavColor }">{{ data.title }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="data.navStyle == 3" class="content-wrap">
|
<view v-if="data.navStyle == 3" class="content-wrap">
|
||||||
<view class="title-wrap" @click="toLink(data.moreLink.wap_url)">
|
<view class="title-wrap" @click="toLink(data.moreLink.wap_url)">
|
||||||
<image :src="$util.img(data.topNavImg)" mode="aspectFit"></image>
|
<image :src="$util.img(data.topNavImg)" mode="aspectFit"></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="{ height: menuButtonInfo.height - 2 + 'px', lineHeight: menuButtonInfo.height - 2 + 'px' }">
|
<view class="search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="{ height: menuButtonInfo.height - 2 + 'px', lineHeight: menuButtonInfo.height - 2 + 'px' }">
|
||||||
<text class="iconfont icon-sousuo3"></text>
|
<text class="iconfont icon-sousuo3"></text>
|
||||||
<text>请输入商品名称</text>
|
<text>请输入商品名称</text>
|
||||||
</view>
|
</view>
|
||||||
<view :style="{ 'width': capsuleWidth }"></view>
|
<view :style="{ 'width': capsuleWidth }"></view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="data.navStyle == 4" class="content-wrap" :class="{ 'have-back': isBack && isBackShow }" @click="chooseOtherStore()">
|
<view v-if="data.navStyle == 4" class="content-wrap" :class="{ 'have-back': isBack && isBackShow }" @click="chooseOtherStore()">
|
||||||
<text class="iconfont icon-dizhi" :style="{ color: data.textNavColor }"></text>
|
<text class="iconfont icon-dizhi" :style="{ color: data.textNavColor }"></text>
|
||||||
<view v-if="globalStoreInfo && globalStoreInfo.store_id" class="title-wrap" :style="{ color: data.textNavColor }">{{ globalStoreInfo.store_name }}</view>
|
<view v-if="globalStoreInfo && globalStoreInfo.store_id" class="title-wrap" :style="{ color: data.textNavColor }">{{ globalStoreInfo.store_name }}</view>
|
||||||
<view v-else class="title-wrap" :style="{ color: data.textNavColor }">定位中...</view>
|
<view v-else class="title-wrap" :style="{ color: data.textNavColor }">定位中...</view>
|
||||||
<text class="iconfont icon-right" :style="{ color: data.textNavColor }"></text>
|
<text class="iconfont icon-right" :style="{ color: data.textNavColor }"></text>
|
||||||
<view class="nearby-store-name" :style="{ color: data.textNavColor }">附近门店</view>
|
<view class="nearby-store-name" :style="{ color: data.textNavColor }">附近门店</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 解决fixed定位后导航栏塌陷的问题 -->
|
<view class="u-navbar-placeholder" :style="{ width: '100%', paddingTop: placeholderHeight + 'px' }"></view>
|
||||||
<view class="u-navbar-placeholder" :style="{ width: '100%', paddingTop: placeholderHeight + 'px' }"></view>
|
|
||||||
<!-- #endif -->
|
</view> -->
|
||||||
</view>
|
</template>
|
||||||
</template>
|
|
||||||
|
<script>
|
||||||
<script>
|
// 获取系统状态栏的高度
|
||||||
// 获取系统状态栏的高度
|
let systemInfo = uni.getSystemInfoSync();
|
||||||
let systemInfo = uni.getSystemInfoSync();
|
let menuButtonInfo = {};
|
||||||
let menuButtonInfo = {};
|
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
||||||
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
|
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
||||||
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
|
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
// #endif
|
||||||
// #endif
|
|
||||||
|
// 自定义导航栏
|
||||||
// 自定义导航栏
|
export default {
|
||||||
export default {
|
name: 'ns-navbar',
|
||||||
name: 'ns-navbar',
|
props: {
|
||||||
props: {
|
data: {
|
||||||
data: {
|
type: Object,
|
||||||
type: Object,
|
default() {
|
||||||
default() {
|
return {};
|
||||||
return {};
|
}
|
||||||
}
|
},
|
||||||
},
|
// 标题的颜色
|
||||||
// 标题的颜色
|
titleColor: {
|
||||||
titleColor: {
|
type: String,
|
||||||
type: String,
|
default: '#606266'
|
||||||
default: '#606266'
|
},
|
||||||
},
|
// 自定义返回逻辑
|
||||||
// 自定义返回逻辑
|
customBack: {
|
||||||
customBack: {
|
type: Function,
|
||||||
type: Function,
|
default: null
|
||||||
default: null
|
},
|
||||||
},
|
scrollTop: {
|
||||||
scrollTop: {
|
type: [String, Number],
|
||||||
type: [String, Number],
|
default: '0'
|
||||||
default: '0'
|
},
|
||||||
},
|
// 是否显示导航栏左边返回图标和辅助文字
|
||||||
// 是否显示导航栏左边返回图标和辅助文字
|
isBack: {
|
||||||
isBack: {
|
type: Boolean,
|
||||||
type: Boolean,
|
default: true
|
||||||
default: true
|
}
|
||||||
}
|
},
|
||||||
},
|
data() {
|
||||||
data() {
|
return {
|
||||||
return {
|
menuButtonInfo: menuButtonInfo,
|
||||||
menuButtonInfo: menuButtonInfo,
|
isBackShow: false,
|
||||||
isBackShow: false,
|
placeholderHeight: 0
|
||||||
placeholderHeight: 0
|
};
|
||||||
};
|
},
|
||||||
},
|
computed: {
|
||||||
computed: {
|
// 导航栏内部盒子的样式
|
||||||
// 导航栏内部盒子的样式
|
navbarInnerStyle() {
|
||||||
navbarInnerStyle() {
|
let style = '';
|
||||||
let style = '';
|
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
||||||
// 导航栏宽度,如果在小程序下,导航栏宽度为胶囊的左边到屏幕左边的距离
|
style += 'height:' + menuButtonInfo.height * 2 + 'rpx;';
|
||||||
style += 'height:' + menuButtonInfo.height * 2 + 'rpx;';
|
return style;
|
||||||
return style;
|
},
|
||||||
},
|
// 转换字符数值为真正的数值
|
||||||
// 转换字符数值为真正的数值
|
navbarHeight() {
|
||||||
navbarHeight() {
|
// #ifdef APP-PLUS || H5
|
||||||
// #ifdef APP-PLUS || H5
|
return 25;
|
||||||
return 25;
|
// #endif
|
||||||
// #endif
|
// #ifdef MP
|
||||||
// #ifdef MP
|
// 小程序特别处理,让导航栏高度 = 胶囊高度 + 两倍胶囊顶部与状态栏底部的距离之差(相当于同时获得了导航栏底部与胶囊底部的距离)
|
||||||
// 小程序特别处理,让导航栏高度 = 胶囊高度 + 两倍胶囊顶部与状态栏底部的距离之差(相当于同时获得了导航栏底部与胶囊底部的距离)
|
let height = menuButtonInfo.top;
|
||||||
let height = menuButtonInfo.top;
|
return height;
|
||||||
return height;
|
// #endif
|
||||||
// #endif
|
},
|
||||||
},
|
bgColor() {
|
||||||
bgColor() {
|
var color = '';
|
||||||
var color = '';
|
if (this.data.topNavBg) {
|
||||||
if (this.data.topNavBg) {
|
// 顶部透明
|
||||||
// 顶部透明
|
color = 'transparent';
|
||||||
color = 'transparent';
|
let top = 0;
|
||||||
let top = 0;
|
|
||||||
|
if (this.data.navStyle == 4) {
|
||||||
if (this.data.navStyle == 4) {
|
// #ifdef H5
|
||||||
// #ifdef H5
|
top = 15;
|
||||||
top = 15;
|
// #endif
|
||||||
// #endif
|
// #ifdef MP
|
||||||
// #ifdef MP
|
top = this.navbarHeight - 25;
|
||||||
top = this.navbarHeight - 25;
|
// #endif
|
||||||
// #endif
|
}
|
||||||
}
|
|
||||||
|
if (this.scrollTop > top) {
|
||||||
if (this.scrollTop > top) {
|
color = this.data.topNavColor;
|
||||||
color = this.data.topNavColor;
|
} else {
|
||||||
} else {
|
color = 'transparent';
|
||||||
color = 'transparent';
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
color = this.data.topNavColor;
|
||||||
color = this.data.topNavColor;
|
}
|
||||||
}
|
return color;
|
||||||
return color;
|
},
|
||||||
},
|
capsuleWidth() {
|
||||||
capsuleWidth() {
|
let width = `calc(100vw - ${this.menuButtonInfo.right}px + ${this.menuButtonInfo.width}px + 10px)`;
|
||||||
let width = `calc(100vw - ${this.menuButtonInfo.right}px + ${this.menuButtonInfo.width}px + 10px)`;
|
return width;
|
||||||
return width;
|
}
|
||||||
}
|
},
|
||||||
},
|
created(e) {
|
||||||
created(e) {
|
// var pages = getCurrentPages();
|
||||||
var pages = getCurrentPages();
|
// if (pages.length > 1) {
|
||||||
if (pages.length > 1) {
|
// this.isBackShow = true;
|
||||||
this.isBackShow = true;
|
// }
|
||||||
}
|
// this.navbarPlaceholderHeight();
|
||||||
this.navbarPlaceholderHeight();
|
},
|
||||||
},
|
mounted() {
|
||||||
mounted() {
|
// this.setModuleLocatinoFn();
|
||||||
this.setModuleLocationFn();
|
},
|
||||||
},
|
methods: {
|
||||||
methods: {
|
toLink(val) {
|
||||||
toLink(val) {
|
if (val) this.$util.redirectTo(val);
|
||||||
if (val) this.$util.redirectTo(val);
|
},
|
||||||
},
|
goBack() {
|
||||||
goBack() {
|
// 如果自定义了点击返回按钮的函数,则执行,否则执行返回逻辑
|
||||||
// 如果自定义了点击返回按钮的函数,则执行,否则执行返回逻辑
|
if (typeof this.customBack === 'function') {
|
||||||
if (typeof this.customBack === 'function') {
|
this.customBack();
|
||||||
this.customBack();
|
} else {
|
||||||
} else {
|
uni.navigateBack();
|
||||||
uni.navigateBack();
|
}
|
||||||
}
|
},
|
||||||
},
|
// 选择其他门店
|
||||||
// 选择其他门店
|
chooseOtherStore() {
|
||||||
chooseOtherStore() {
|
if (this.globalStoreConfig && this.globalStoreConfig.is_allow_change == 1) {
|
||||||
if (this.globalStoreConfig && this.globalStoreConfig.is_allow_change == 1) {
|
this.$util.redirectTo('/pages_tool/store/list');
|
||||||
this.$util.redirectTo('/pages_tool/store/list');
|
} else if (this.globalStoreInfo) {
|
||||||
} else if (this.globalStoreInfo) {
|
// 禁止切换门店,进入门店详情
|
||||||
// 禁止切换门店,进入门店详情
|
this.$util.redirectTo('/pages_tool/store/detail', {
|
||||||
this.$util.redirectTo('/pages_tool/store/detail', {
|
store_id: this.globalStoreInfo.store_id
|
||||||
store_id: this.globalStoreInfo.store_id
|
});
|
||||||
});
|
}
|
||||||
}
|
},
|
||||||
},
|
navbarPlaceholderHeight() {
|
||||||
navbarPlaceholderHeight() {
|
let height = 0;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const query = uni.createSelectorQuery().in(this);
|
const query = uni.createSelectorQuery().in(this);
|
||||||
query.select('.ns-navbar-wrap .u-navbar').boundingClientRect(data => {
|
query
|
||||||
// 获取公告自身高度
|
.select('.ns-navbar-wrap .u-navbar')
|
||||||
this.placeholderHeight = data.height;
|
.boundingClientRect(data => {
|
||||||
}).exec();
|
// 获取公告自身高度
|
||||||
});
|
this.placeholderHeight = data.height;
|
||||||
},
|
})
|
||||||
// 向vuex中的diyIndexPositionObj增加公告导航组件定位位置
|
.exec();
|
||||||
setModuleLocationFn() {
|
});
|
||||||
const query = uni.createSelectorQuery().in(this);
|
},
|
||||||
query.select('.ns-navbar-wrap .u-navbar').boundingClientRect(data => {
|
// 向vuex中的diyIndexPositionObj增加公告导航组件定位位置
|
||||||
let diyIndexPage = {
|
setModuleLocatinoFn() {
|
||||||
originalVal: data.height || 0, //自身高度 px
|
const query = uni.createSelectorQuery().in(this);
|
||||||
currVal: 0 //定位高度
|
query.select('.ns-navbar-wrap .u-navbar')
|
||||||
};
|
.boundingClientRect(data => {
|
||||||
this.$store.commit('setDiyGroupPositionObj', {
|
let diyIndexPage = {
|
||||||
'nsNavbar': diyIndexPage
|
originalVal: data.height || 0, //自身高度 px
|
||||||
});
|
currVal: 0 //定位高度
|
||||||
}).exec();
|
};
|
||||||
}
|
this.$store.commit('setDiyGroupPositionObj', {
|
||||||
}
|
'nsNavbar': diyIndexPage
|
||||||
};
|
});
|
||||||
</script>
|
}).exec();
|
||||||
|
}
|
||||||
<style scoped lang="scss">
|
}
|
||||||
/* #ifdef H5 */
|
};
|
||||||
.style-1,
|
</script>
|
||||||
.style-2,
|
|
||||||
.style-3 {
|
<style scoped lang="scss">
|
||||||
display: none;
|
/* #ifdef H5 */
|
||||||
}
|
.style-1,
|
||||||
|
.style-2,
|
||||||
/* #endif */
|
.style-3 {
|
||||||
|
display: none;
|
||||||
.u-navbar {
|
}
|
||||||
width: 100%;
|
|
||||||
transition: background 0.3s;
|
/* #endif */
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
.u-navbar {
|
||||||
right: 0;
|
width: 100%;
|
||||||
top: 0;
|
transition: background 0.3s;
|
||||||
z-index: 991;
|
position: fixed;
|
||||||
}
|
left: 0;
|
||||||
|
right: 0;
|
||||||
.navbar-inner {
|
top: 0;
|
||||||
display: flex;
|
z-index: 991;
|
||||||
justify-content: space-between;
|
}
|
||||||
position: relative;
|
|
||||||
align-items: center;
|
.navbar-inner {
|
||||||
padding-bottom: 20rpx;
|
display: flex;
|
||||||
/* #ifdef H5 */
|
justify-content: space-between;
|
||||||
padding-bottom: 40rpx;
|
position: relative;
|
||||||
/* #endif */
|
align-items: center;
|
||||||
}
|
padding-bottom: 20rpx;
|
||||||
|
/* #ifdef H5 */
|
||||||
.back-wrap {
|
padding-bottom: 40rpx;
|
||||||
padding: 0 14rpx 0 24rpx;
|
/* #endif */
|
||||||
|
}
|
||||||
.iconfont {
|
|
||||||
font-size: 44rpx;
|
.back-wrap {
|
||||||
}
|
padding: 0 14rpx 0 24rpx;
|
||||||
}
|
|
||||||
|
.iconfont {
|
||||||
.content-wrap {
|
font-size: 44rpx;
|
||||||
display: flex;
|
}
|
||||||
align-items: center;
|
}
|
||||||
justify-content: flex-start;
|
|
||||||
flex: 1;
|
.content-wrap {
|
||||||
position: absolute;
|
display: flex;
|
||||||
left: 0;
|
align-items: center;
|
||||||
right: 0;
|
justify-content: flex-start;
|
||||||
top: 0;
|
flex: 1;
|
||||||
height: 60rpx;
|
position: absolute;
|
||||||
text-align: center;
|
left: 0;
|
||||||
flex-shrink: 0;
|
right: 0;
|
||||||
}
|
top: 0;
|
||||||
|
height: 60rpx;
|
||||||
.title-wrap {
|
text-align: center;
|
||||||
line-height: 1;
|
flex-shrink: 0;
|
||||||
flex: 1;
|
}
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
.title-wrap {
|
||||||
white-space: nowrap;
|
line-height: 1;
|
||||||
font-size: 32rpx;
|
flex: 1;
|
||||||
color: #000000;
|
overflow: hidden;
|
||||||
}
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
.ns-navbar-wrap {
|
font-size: 32rpx;
|
||||||
|
color: #000000;
|
||||||
&.style-1 {
|
}
|
||||||
.content-wrap {
|
|
||||||
.title-wrap {
|
.ns-navbar-wrap {
|
||||||
font-size: 27rpx;
|
|
||||||
}
|
&.style-1 {
|
||||||
|
.content-wrap {
|
||||||
&.left {
|
.title-wrap {
|
||||||
left: 30rpx;
|
font-size: 27rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.center {
|
&.left {
|
||||||
left: 0;
|
left: 30rpx;
|
||||||
padding-right: 0;
|
}
|
||||||
}
|
|
||||||
|
&.center {
|
||||||
&.have-back {
|
left: 0;
|
||||||
left: 90rpx;
|
padding-right: 0;
|
||||||
padding-right: 200rpx;
|
}
|
||||||
}
|
|
||||||
}
|
&.have-back {
|
||||||
}
|
left: 90rpx;
|
||||||
|
padding-right: 200rpx;
|
||||||
&.style-2 {
|
}
|
||||||
.content-wrap {
|
}
|
||||||
.title-wrap {
|
}
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
&.style-2 {
|
||||||
text-align: left;
|
.content-wrap {
|
||||||
|
.title-wrap {
|
||||||
>view {
|
display: flex;
|
||||||
height: 56rpx;
|
align-items: center;
|
||||||
line-height: 56rpx;
|
text-align: left;
|
||||||
max-width: 300rpx;
|
|
||||||
margin-left: 30rpx;
|
>view {
|
||||||
font-size: 27rpx;
|
height: 56rpx;
|
||||||
|
line-height: 56rpx;
|
||||||
image {
|
max-width: 300rpx;
|
||||||
width: 100%;
|
margin-left: 30rpx;
|
||||||
height: 100%;
|
font-size: 27rpx;
|
||||||
}
|
|
||||||
|
image {
|
||||||
&:last-child {
|
width: 100%;
|
||||||
overflow: hidden; //超出的文本隐藏
|
height: 100%;
|
||||||
text-overflow: ellipsis; //用省略号显示
|
}
|
||||||
white-space: nowrap; //不换行
|
|
||||||
flex: 1;
|
&:last-child {
|
||||||
}
|
overflow: hidden; //超出的文本隐藏
|
||||||
}
|
text-overflow: ellipsis; //用省略号显示
|
||||||
}
|
white-space: nowrap; //不换行
|
||||||
}
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&.style-3 {
|
}
|
||||||
.content-wrap {
|
}
|
||||||
.title-wrap {
|
}
|
||||||
height: 60rpx;
|
|
||||||
width: 170rpx;
|
&.style-3 {
|
||||||
max-width: 170rpx;
|
.content-wrap {
|
||||||
margin-left: 30rpx;
|
.title-wrap {
|
||||||
flex: initial;
|
height: 60rpx;
|
||||||
text-align: center;
|
width: 170rpx;
|
||||||
margin-right: 10rpx;
|
max-width: 170rpx;
|
||||||
|
margin-left: 30rpx;
|
||||||
image {
|
flex: initial;
|
||||||
height: 100%;
|
text-align: center;
|
||||||
width: 100%;
|
margin-right: 10rpx;
|
||||||
}
|
|
||||||
}
|
image {
|
||||||
|
height: 100%;
|
||||||
.search {
|
width: 100%;
|
||||||
flex: 1;
|
}
|
||||||
padding: 0 20rpx;
|
}
|
||||||
background-color: #fff;
|
|
||||||
text-align: left;
|
.search {
|
||||||
border-radius: 60rpx;
|
flex: 1;
|
||||||
height: 60rpx;
|
padding: 0 20rpx;
|
||||||
line-height: 60rpx;
|
background-color: #fff;
|
||||||
border: 1px solid #eeeeee;
|
text-align: left;
|
||||||
color: rgb(102, 102, 102);
|
border-radius: 60rpx;
|
||||||
display: flex;
|
height: 60rpx;
|
||||||
align-items: center;
|
line-height: 60rpx;
|
||||||
margin-right: 10rpx;
|
border: 1px solid #eeeeee;
|
||||||
|
color: rgb(102, 102, 102);
|
||||||
.iconfont {
|
display: flex;
|
||||||
color: #909399;
|
align-items: center;
|
||||||
font-size: 32rpx;
|
margin-right: 10rpx;
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
.iconfont {
|
||||||
}
|
color: #909399;
|
||||||
}
|
font-size: 32rpx;
|
||||||
}
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
&.style-4 {
|
}
|
||||||
.icon-dizhi{
|
}
|
||||||
font-size: 28rpx;
|
}
|
||||||
}
|
|
||||||
.content-wrap {
|
&.style-4 {
|
||||||
top: initial;
|
.icon-dizhi{
|
||||||
text-align: left;
|
font-size: 28rpx;
|
||||||
padding-left: 30rpx;
|
}
|
||||||
|
.content-wrap {
|
||||||
&.have-back {
|
top: initial;
|
||||||
left: 60rpx;
|
text-align: left;
|
||||||
right: 190rpx;
|
padding-left: 30rpx;
|
||||||
}
|
|
||||||
|
&.have-back {
|
||||||
.title-wrap {
|
left: 60rpx;
|
||||||
flex: none;
|
right: 190rpx;
|
||||||
margin: 0 10rpx;
|
}
|
||||||
max-width: 360rpx;
|
|
||||||
font-size: 27rpx;
|
.title-wrap {
|
||||||
}
|
flex: none;
|
||||||
|
margin: 0 10rpx;
|
||||||
.icon-right {
|
max-width: 360rpx;
|
||||||
font-size: 24rpx;
|
font-size: 27rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nearby-store-name {
|
.icon-right {
|
||||||
margin: 0 10rpx;
|
font-size: 24rpx;
|
||||||
background: rgba(0, 0, 0, .2);
|
}
|
||||||
font-size: 22rpx;
|
|
||||||
border-radius: 40rpx;
|
.nearby-store-name {
|
||||||
padding: 10rpx 20rpx;
|
margin: 0 10rpx;
|
||||||
line-height: 1;
|
background: rgba(0, 0, 0, .2);
|
||||||
}
|
font-size: 22rpx;
|
||||||
}
|
border-radius: 40rpx;
|
||||||
}
|
padding: 10rpx 20rpx;
|
||||||
}
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,349 +1,349 @@
|
|||||||
<template>
|
<template>
|
||||||
<view>
|
<view>
|
||||||
<view @touchmove.prevent.stop v-if="newgift" class="reward-popup">
|
<view @touchmove.prevent.stop v-if="newgift" class="reward-popup">
|
||||||
<uni-popup ref="nsNewGift" type="center" :maskClick="false">
|
<uni-popup ref="nsNewGift" type="center" :maskClick="false">
|
||||||
<view class="reward-wrap">
|
<view class="reward-wrap">
|
||||||
<view class="newgift-content" :style="{ backgroundImage: 'url(' + $util.img('public/uniapp/new_gift/holiday_polite-bg.png') + ')' }">
|
<view class="newgift-content" :style="{ backgroundImage: 'url(' + $util.img('public/uniapp/new_gift/holiday_polite-bg.png') + ')' }">
|
||||||
<view class="content-title-holiday">
|
<view class="content-title-holiday">
|
||||||
<image :src="$util.img('public/uniapp/new_gift/holiday_polite_left.png')" mode="" class="birthday-img-all" />
|
<image :src="$util.img('public/uniapp/new_gift/holiday_polite_left.png')" mode="" class="birthday-img-all"/>
|
||||||
<view class="font-size-toolbar activity-name">{{ newgift.activity_name }}</view>
|
<view class="font-size-toolbar activity-name">{{ newgift.activity_name }}</view>
|
||||||
<image :src="$util.img('public/uniapp/new_gift/holiday_polite_right.png')" mode="" class="birthday-img-all" />
|
<image :src="$util.img('public/uniapp/new_gift/holiday_polite_right.png')" mode="" class="birthday-img-all"/>
|
||||||
</view>
|
</view>
|
||||||
<view class="content-title-name" v-if="memberInfo">Dear {{ memberInfo.nickname }}</view>
|
<view class="content-title-name" v-if="memberInfo">Dear {{ memberInfo.nickname }}</view>
|
||||||
<view class="content-title-hint" v-if="newgift.remark">{{ newgift.remark }}</view>
|
<view class="content-title-hint" v-if="newgift.remark">{{ newgift.remark }}</view>
|
||||||
<view class="content-title-hint" v-else>感谢您一直以来的支持,为回馈会员,商城{{ newgift.activity_name ? newgift.activity_name : 'xx' }}节日,为您提供以下福利</view>
|
<view class="content-title-hint" v-else>感谢您一直以来的支持,为回馈会员,商城{{ newgift.activity_name ? newgift.activity_name : 'xx' }}节日,为您提供以下福利</view>
|
||||||
<scroll-view scroll-y="true" class="register-box">
|
<scroll-view scroll-y="true" class="register-box">
|
||||||
<view :class="introduction > 38 ? 'reward-content' : 'reward-content-two'">
|
<view :class="introduction > 38 ? 'reward-content' : 'reward-content-two'">
|
||||||
<view class="content" v-if="newgift.award_list.point > 0">
|
<view class="content" v-if="newgift.award_list.point > 0">
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<text class="num">
|
<text class="num">
|
||||||
{{ newgift.award_list.point }}
|
{{ newgift.award_list.point }}
|
||||||
<text class="type">积分</text>
|
<text class="type">积分</text>
|
||||||
</text>
|
</text>
|
||||||
<view class="desc">用于参与活动购买商品时抵扣</view>
|
<view class="desc">用于参与活动购买商品时抵扣</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="tip" @click="closeRewardPopup('1')">立即查看</view>
|
<view class="tip" @click="closeRewardPopup('1')">立即查看</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="content" v-if="newgift.award_list.balance_type == 0 && newgift.award_list.balance > 0">
|
<view class="content" v-if="newgift.award_list.balance_type == 0 && newgift.award_list.balance > 0">
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<text class="num">
|
<text class="num">
|
||||||
{{ newgift.award_list.balance | int }}
|
{{ newgift.award_list.balance | int }}
|
||||||
<text class="type">元红包</text>
|
<text class="type">元红包</text>
|
||||||
</text>
|
</text>
|
||||||
<view class="desc">不可提现红包</view>
|
<view class="desc">不可提现红包</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="tip" @click="closeRewardPopup('2')">立即查看</view>
|
<view class="tip" @click="closeRewardPopup('2')">立即查看</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="content" v-if="newgift.award_list.balance_type == 1 && newgift.award_list.balance_money > 0">
|
<view class="content" v-if="newgift.award_list.balance_type == 1 && newgift.award_list.balance_money > 0">
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<text class="num">
|
<text class="num">
|
||||||
{{ newgift.award_list.balance_money | int }}
|
{{ newgift.award_list.balance_money | int }}
|
||||||
<text class="type">元红包</text>
|
<text class="type">元红包</text>
|
||||||
</text>
|
</text>
|
||||||
<view class="desc">可提现红包</view>
|
<view class="desc">可提现红包</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="tip" @click="closeRewardPopup('2')">立即查看</view>
|
<view class="tip" @click="closeRewardPopup('2')">立即查看</view>
|
||||||
</view>
|
</view>
|
||||||
<block v-if="newgift.award_list.coupon_list.length > 0">
|
<block v-if="newgift.award_list.coupon_list.length > 0">
|
||||||
<block v-for="(item, index) in newgift.award_list.coupon_list" :key="index">
|
<block v-for="(item, index) in newgift.award_list.coupon_list" :key="index">
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<text v-if="item.type == 'reward'" class="num">
|
<text v-if="item.type == 'reward'" class="num">
|
||||||
{{ parseFloat(item.money) }}
|
{{ parseFloat(item.money) }}
|
||||||
<text class="type">元优惠劵</text>
|
<text class="type">元优惠劵</text>
|
||||||
</text>
|
</text>
|
||||||
<text v-else-if="item.type == 'discount'" class="num">
|
<text v-else-if="item.type == 'discount'" class="num">
|
||||||
{{ item.discount | int }}
|
{{ item.discount | int }}
|
||||||
<text class="type">折</text>
|
<text class="type">折</text>
|
||||||
</text>
|
</text>
|
||||||
<view class="desc">用于下单时抵现或兑换商品等</view>
|
<view class="desc">用于下单时抵现或兑换商品等</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="tip" @click="closeRewardPopup('3')">立即查看</view>
|
<view class="tip" @click="closeRewardPopup('3')">立即查看</view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<view class="close-btn" @click="cancel()">
|
<view class="close-btn" @click="cancel()">
|
||||||
<text class="iconfont icon-close btn"></text>
|
<text class="iconfont icon-close btn"></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import uniPopup from '../uni-popup/uni-popup.vue';
|
import uniPopup from '../uni-popup/uni-popup.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
uniPopup
|
uniPopup
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
newgift: {
|
newgift: {
|
||||||
flag: false,
|
flag: false,
|
||||||
award_list: {
|
award_list: {
|
||||||
point: 0,
|
point: 0,
|
||||||
coupon_list: {}
|
coupon_list: {}
|
||||||
},
|
},
|
||||||
remark: {}
|
remark: {}
|
||||||
},
|
},
|
||||||
bgHight: '940rpx !important',
|
bgHight: '940rpx !important',
|
||||||
bytesCount: null,
|
bytesCount: null,
|
||||||
callback: null
|
};
|
||||||
};
|
},
|
||||||
},
|
filters: {
|
||||||
filters: {
|
int(val) {
|
||||||
int(val) {
|
var str = String(val);
|
||||||
var str = String(val);
|
var arr = str.split('.');
|
||||||
var arr = str.split('.');
|
if (parseInt(arr[1]) > 0) {
|
||||||
if (parseInt(arr[1]) > 0) {
|
return str;
|
||||||
return str;
|
} else {
|
||||||
} else {
|
return arr[0];
|
||||||
return arr[0];
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
computed: {
|
||||||
computed: {
|
introduction() {
|
||||||
introduction() {
|
let bytesCount = 0;
|
||||||
let bytesCount = 0;
|
for (let i = 0, n = this.newgift.remark.length; i < n; i++) {
|
||||||
for (let i = 0, n = this.newgift.remark.length; i < n; i++) {
|
let c = this.newgift.remark.charCodeAt(i);
|
||||||
let c = this.newgift.remark.charCodeAt(i);
|
if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
|
||||||
if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
|
bytesCount += 1;
|
||||||
bytesCount += 1;
|
} else {
|
||||||
} else {
|
bytesCount += 2;
|
||||||
bytesCount += 2;
|
}
|
||||||
}
|
}
|
||||||
}
|
return bytesCount;
|
||||||
return bytesCount;
|
}
|
||||||
}
|
},
|
||||||
},
|
created() {
|
||||||
created() {
|
if (!this.storeToken) return;
|
||||||
if (!this.storeToken) return;
|
this.init();
|
||||||
this.init();
|
},
|
||||||
},
|
methods: {
|
||||||
methods: {
|
init() {
|
||||||
init(callback = null) {
|
this.getHolidayGift();
|
||||||
if (callback) this.callback = callback;
|
},
|
||||||
this.getHolidayGift();
|
// 查询节日有礼设置
|
||||||
},
|
getHolidayGift() {
|
||||||
// 查询节日有礼设置
|
this.$api.sendRequest({
|
||||||
getHolidayGift() {
|
url: '/scenefestival/api/config/config',
|
||||||
this.$api.sendRequest({
|
success: res => {
|
||||||
url: '/scenefestival/api/config/config',
|
if (res.data && res.data[0]) {
|
||||||
success: res => {
|
this.newgift = res.data[0];
|
||||||
if (res.data && res.data[0]) {
|
if (this.newgift.award_list.award_type.length <= 1) {
|
||||||
this.newgift = res.data[0];
|
this.bgHight = '800rpx !important';
|
||||||
if (this.newgift.award_list.award_type.length <= 1) {
|
}
|
||||||
this.bgHight = '800rpx !important';
|
this.getGift();
|
||||||
}
|
}
|
||||||
this.getGift();
|
}
|
||||||
}
|
});
|
||||||
}
|
},
|
||||||
});
|
cancel() {
|
||||||
},
|
this.$refs.nsNewGift.close();
|
||||||
cancel() {
|
},
|
||||||
this.$refs.nsNewGift.close();
|
getGift() {
|
||||||
},
|
if (this.newgift.flag == true) {
|
||||||
getGift() {
|
this.$refs.nsNewGift.open();
|
||||||
if (this.newgift.flag == true) {
|
this.$api.sendRequest({
|
||||||
this.$refs.nsNewGift.open();
|
url: '/scenefestival/api/config/receive',
|
||||||
this.$api.sendRequest({
|
data: {
|
||||||
url: '/scenefestival/api/config/receive',
|
festival_id: this.newgift.festival_id
|
||||||
data: {
|
},
|
||||||
festival_id: this.newgift.festival_id
|
success: res => {}
|
||||||
},
|
});
|
||||||
success: res => {
|
}
|
||||||
if (this.callback) this.callback();
|
},
|
||||||
}
|
closeRewardPopup(type) {
|
||||||
});
|
if (type == 1) {
|
||||||
}
|
this.$util.redirectTo('/pages_tool/member/point_detail', {});
|
||||||
},
|
} else if (type == 2) {
|
||||||
closeRewardPopup(type) {
|
this.$util.redirectTo('/pages_tool/member/balance_detail', {});
|
||||||
if (type == 1) {
|
} else if (type == 3) {
|
||||||
this.$util.redirectTo('/pages_tool/member/point_detail', {});
|
this.$util.redirectTo('/pages_tool/member/coupon', {});
|
||||||
} else if (type == 2) {
|
}
|
||||||
this.$util.redirectTo('/pages_tool/member/balance_detail', {});
|
}
|
||||||
} else if (type == 3) {
|
}
|
||||||
this.$util.redirectTo('/pages_tool/member/coupon', {});
|
};
|
||||||
}
|
</script>
|
||||||
}
|
|
||||||
}
|
<style scoped>
|
||||||
};
|
/deep/ .newgift-content uni-image {
|
||||||
</script>
|
width: 113rpx !important;
|
||||||
|
height: 24rpx !important;
|
||||||
<style scoped>
|
}
|
||||||
/deep/ .newgift-content uni-image {
|
|
||||||
width: 113rpx !important;
|
/deep/ .reward-popup .uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
|
||||||
height: 24rpx !important;
|
max-height: unset !important;
|
||||||
}
|
overflow-y: unset;
|
||||||
|
}
|
||||||
/deep/ .reward-popup .uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
|
|
||||||
max-height: unset !important;
|
.register-box /deep/ .uni-scroll-view {
|
||||||
overflow-y: unset;
|
background: unset !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.register-box /deep/ .uni-scroll-view {
|
.register-box {
|
||||||
background: unset !important;
|
max-height: 300rpx;
|
||||||
}
|
overflow-y: scroll;
|
||||||
|
/* margin-top: 610rpx; */
|
||||||
.register-box {
|
}
|
||||||
max-height: 300rpx;
|
</style>
|
||||||
overflow-y: scroll;
|
|
||||||
/* margin-top: 610rpx; */
|
<style lang="scss">
|
||||||
}
|
.reward-wrap {
|
||||||
</style>
|
width: 85vw;
|
||||||
|
height: auto;
|
||||||
<style lang="scss">
|
|
||||||
.reward-wrap {
|
.newgift-content {
|
||||||
width: 85vw;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
background-size: 100%;
|
||||||
.newgift-content {
|
background-repeat: no-repeat;
|
||||||
width: 100%;
|
padding-bottom: 40rpx;
|
||||||
height: auto;
|
}
|
||||||
background-size: 100%;
|
|
||||||
background-repeat: no-repeat;
|
.content-title-holiday {
|
||||||
padding-bottom: 40rpx;
|
font-size: $font-size-toolbar;
|
||||||
}
|
font-weight: bold;
|
||||||
|
font-family: BDZongYi-A001;
|
||||||
.content-title-holiday {
|
display: flex;
|
||||||
font-size: $font-size-toolbar;
|
align-items: center;
|
||||||
font-weight: bold;
|
justify-content: center;
|
||||||
font-family: BDZongYi-A001;
|
// margin-bottom: 20rpx;
|
||||||
display: flex;
|
padding-top: 320rpx;
|
||||||
align-items: center;
|
line-height: 1;
|
||||||
justify-content: center;
|
|
||||||
// margin-bottom: 20rpx;
|
.birthday-img-all {
|
||||||
padding-top: 320rpx;
|
width: 100rpx;
|
||||||
line-height: 1;
|
height: 20rpx;
|
||||||
|
}
|
||||||
.birthday-img-all {
|
|
||||||
width: 100rpx;
|
&>view {
|
||||||
height: 20rpx;
|
margin: 0 20rpx;
|
||||||
}
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
&>view {
|
}
|
||||||
margin: 0 20rpx;
|
}
|
||||||
color: #fff;
|
|
||||||
font-weight: bold;
|
.content-title-name {
|
||||||
}
|
font-size: $font-size-toolbar;
|
||||||
}
|
font-weight: bold;
|
||||||
|
overflow: hidden;
|
||||||
.content-title-name {
|
text-overflow: ellipsis;
|
||||||
font-size: $font-size-toolbar;
|
display: -webkit-box;
|
||||||
font-weight: bold;
|
-webkit-line-clamp: 2;
|
||||||
overflow: hidden;
|
-webkit-box-orient: vertical;
|
||||||
text-overflow: ellipsis;
|
text-align: center;
|
||||||
display: -webkit-box;
|
color: #fff;
|
||||||
-webkit-line-clamp: 2;
|
margin: 30rpx 0 40rpx;
|
||||||
-webkit-box-orient: vertical;
|
line-height: 1;
|
||||||
text-align: center;
|
}
|
||||||
color: #fff;
|
|
||||||
margin: 30rpx 0 40rpx;
|
.content-title-hint {
|
||||||
line-height: 1;
|
margin: 0 70rpx 40rpx;
|
||||||
}
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
.content-title-hint {
|
display: -webkit-box;
|
||||||
margin: 0 70rpx 40rpx;
|
-webkit-line-clamp: 2;
|
||||||
overflow: hidden;
|
-webkit-box-orient: vertical;
|
||||||
text-overflow: ellipsis;
|
text-align: center;
|
||||||
display: -webkit-box;
|
color: #fff;
|
||||||
-webkit-line-clamp: 2;
|
}
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
text-align: center;
|
.reward-content {
|
||||||
color: #fff;
|
max-height: 300rpx;
|
||||||
}
|
margin: 0 56rpx;
|
||||||
|
}
|
||||||
.reward-content {
|
|
||||||
max-height: 300rpx;
|
.reward-content-two {
|
||||||
margin: 0 56rpx;
|
max-height: 360rpx;
|
||||||
}
|
margin: 0 56rpx;
|
||||||
|
}
|
||||||
.reward-content-two {
|
|
||||||
max-height: 360rpx;
|
.head {
|
||||||
margin: 0 56rpx;
|
color: #fff;
|
||||||
}
|
text-align: center;
|
||||||
|
line-height: 1;
|
||||||
.head {
|
margin: 20rpx 0;
|
||||||
color: #fff;
|
}
|
||||||
text-align: center;
|
|
||||||
line-height: 1;
|
& .content:last-child {
|
||||||
margin: 20rpx 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .content:last-child {
|
.content {
|
||||||
margin-bottom: 0;
|
display: flex;
|
||||||
}
|
align-items: center;
|
||||||
|
padding: 16rpx 26rpx;
|
||||||
.content {
|
background: #fff;
|
||||||
display: flex;
|
border-radius: 10rpx;
|
||||||
align-items: center;
|
margin-bottom: 20rpx;
|
||||||
padding: 16rpx 26rpx;
|
|
||||||
background: #fff;
|
.info {
|
||||||
border-radius: 10rpx;
|
flex: 1;
|
||||||
margin-bottom: 20rpx;
|
}
|
||||||
|
|
||||||
.info {
|
.tip {
|
||||||
flex: 1;
|
color: #fa5b14;
|
||||||
}
|
padding: 10rpx 0 10rpx 20rpx;
|
||||||
|
width: 60rpx;
|
||||||
.tip {
|
line-height: 1.5;
|
||||||
color: #fa5b14;
|
letter-spacing: 2rpx;
|
||||||
padding: 10rpx 0 10rpx 20rpx;
|
border-left: 2rpx dashed #e5e5e5;
|
||||||
width: 60rpx;
|
}
|
||||||
line-height: 1.5;
|
|
||||||
letter-spacing: 2rpx;
|
.num {
|
||||||
border-left: 2rpx dashed #e5e5e5;
|
font-size: 48rpx;
|
||||||
}
|
color: #fa5b14;
|
||||||
|
font-weight: bolder;
|
||||||
.num {
|
line-height: 1;
|
||||||
font-size: 48rpx;
|
overflow: hidden;
|
||||||
color: #fa5b14;
|
text-overflow: ellipsis;
|
||||||
font-weight: bolder;
|
white-space: nowrap;
|
||||||
line-height: 1;
|
max-width: 300rpx;
|
||||||
overflow: hidden;
|
}
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
.type {
|
||||||
max-width: 300rpx;
|
font-size: $font-size-tag;
|
||||||
}
|
margin-left: 10rpx;
|
||||||
|
line-height: 1;
|
||||||
.type {
|
font-weight: normal;
|
||||||
font-size: $font-size-tag;
|
color: #606266;
|
||||||
margin-left: 10rpx;
|
}
|
||||||
line-height: 1;
|
|
||||||
font-weight: normal;
|
.desc {
|
||||||
color: #606266;
|
margin-top: 8rpx;
|
||||||
}
|
color: $color-tip;
|
||||||
|
font-size: $font-size-tag;
|
||||||
.desc {
|
line-height: 1;
|
||||||
margin-top: 8rpx;
|
}
|
||||||
color: $color-tip;
|
}
|
||||||
font-size: $font-size-tag;
|
|
||||||
line-height: 1;
|
.close-btn {
|
||||||
}
|
text-align: center;
|
||||||
}
|
margin-top: 20rpx;
|
||||||
|
z-index: 500;
|
||||||
.close-btn {
|
|
||||||
text-align: center;
|
.btn {
|
||||||
margin-top: 20rpx;
|
/* margin: 0 50rpx;
|
||||||
z-index: 500;
|
background: linear-gradient(90deg,#ff4100,#ff6a00) ;
|
||||||
|
border: none; */
|
||||||
.btn {
|
color: #fff;
|
||||||
color: #fff;
|
font-size: 40rpx;
|
||||||
font-size: 40rpx;
|
// padding: 100px;
|
||||||
border: 4rpx solid #fff;
|
border: 4rpx solid #fff;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
padding: 10rpx;
|
padding: 10rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
width: 40rpx;
|
width: 40rpx;
|
||||||
height: 40rpx;
|
height: 40rpx;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
line-height: 40rpx;
|
line-height: 40rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,933 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="form-wrap form-component">
|
|
||||||
<view v-for="(item, index) in formData" :key="index">
|
|
||||||
<!-- 文本输入框 -->
|
|
||||||
<view v-if="item.controller == 'Text'" class="order-wrap">
|
|
||||||
<view class="order-cell">
|
|
||||||
<view class="name">
|
|
||||||
<text class="tit">{{ item.value.title }}</text>
|
|
||||||
<text class="required">{{ item.value.required ? '*' : '' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="box">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
:placeholder="item.value.placeholder"
|
|
||||||
placeholder-class="placeholder color-tip"
|
|
||||||
v-model="item.val"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 多行文本输入框 -->
|
|
||||||
<view v-if="item.controller == 'Textarea'" class="order-wrap">
|
|
||||||
<view class="order-cell flex-box textarea">
|
|
||||||
<view class="name">
|
|
||||||
<text class="tit">{{ item.value.title }}</text>
|
|
||||||
<text class="required">{{ item.value.required ? '*' : '' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="box">
|
|
||||||
<textarea
|
|
||||||
:placeholder="item.value.placeholder"
|
|
||||||
placeholder-class="placeholder color-tip"
|
|
||||||
v-model="item.val"
|
|
||||||
></textarea>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 下拉选择器 -->
|
|
||||||
<view v-if="item.controller == 'Select'" class="order-wrap">
|
|
||||||
<picker
|
|
||||||
mode="selector"
|
|
||||||
:range="item.value.options"
|
|
||||||
@change="pickerChange($event, index)"
|
|
||||||
>
|
|
||||||
<view class="order-cell">
|
|
||||||
<view class="name">
|
|
||||||
<text class="tit">{{ item.value.title }}</text>
|
|
||||||
<text class="required">{{ item.value.required ? '*' : '' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="box">
|
|
||||||
<text v-if="item.val != ''">{{ item.val }}</text>
|
|
||||||
<text v-else class="color-tip">请选择</text>
|
|
||||||
</view>
|
|
||||||
<text class="iconfont icon-right"></text>
|
|
||||||
</view>
|
|
||||||
</picker>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 复选框 -->
|
|
||||||
<view v-if="item.controller == 'Checkbox'" class="order-wrap">
|
|
||||||
<view class="order-cell">
|
|
||||||
<view class="name">
|
|
||||||
<text class="tit">{{ item.value.title }}</text>
|
|
||||||
<text class="required">{{ item.value.required ? '*' : '' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="box check-group-box">
|
|
||||||
<checkbox-group @change="checkboxChange($event, index)">
|
|
||||||
<label v-for="(v, k) in item.option_lists" :key="k">
|
|
||||||
<checkbox :value="v.value" :checked="v.checked"></checkbox>
|
|
||||||
<view class="checkbox">
|
|
||||||
<text
|
|
||||||
:class="[
|
|
||||||
'iconfont',
|
|
||||||
!v.checked ? 'icon-fuxuankuang2' : '',
|
|
||||||
v.checked ? 'icon-fuxuankuang1 color-base-text' : ''
|
|
||||||
]"
|
|
||||||
></text>
|
|
||||||
{{ v.value }}
|
|
||||||
</view>
|
|
||||||
</label>
|
|
||||||
</checkbox-group>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 单选框 -->
|
|
||||||
<view v-if="item.controller == 'Radio'" class="order-wrap">
|
|
||||||
<view class="order-cell">
|
|
||||||
<view class="name">
|
|
||||||
<text class="tit">{{ item.value.title }}</text>
|
|
||||||
<text class="required">{{ item.value.required ? '*' : '' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="box radio-group-box">
|
|
||||||
<radio-group @change="radioChange($event, index)">
|
|
||||||
<label v-for="(v, k) in item.option_lists" :key="k">
|
|
||||||
<radio :value="v.value" :checked="item.val == v.value"></radio>
|
|
||||||
<view class="radio-box">
|
|
||||||
<text
|
|
||||||
:class="[
|
|
||||||
'iconfont',
|
|
||||||
item.val != v.value ? 'icon-yuan_checkbox' : '',
|
|
||||||
item.val == v.value ? 'icon-yuan_checked color-base-text' : ''
|
|
||||||
]"
|
|
||||||
></text>
|
|
||||||
{{ v.value }}
|
|
||||||
</view>
|
|
||||||
</label>
|
|
||||||
</radio-group>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 图片上传 -->
|
|
||||||
<view v-if="item.controller == 'Img'" class="order-wrap">
|
|
||||||
<view class="order-cell flex-box">
|
|
||||||
<view class="name">
|
|
||||||
<text class="tit">{{ item.value.title }}</text>
|
|
||||||
<text class="required">{{ item.value.required ? '*' : '' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="box img-boxs">
|
|
||||||
<view v-for="(v, k) in item.img_lists" :key="k" class="img-box" @tap="uploadImg(index)">
|
|
||||||
<image :src="$util.img(v)" mode="aspectFill"></image>
|
|
||||||
<text class="iconfont icon-guanbi" @tap.stop="delImg(k, index)"></text>
|
|
||||||
</view>
|
|
||||||
<view class="img-box" @tap="addImg(index)">
|
|
||||||
<text class="iconfont icon-add1"></text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 日期选择器 -->
|
|
||||||
<view v-if="item.controller == 'Date'" class="order-wrap">
|
|
||||||
<view class="order-cell">
|
|
||||||
<view class="name">
|
|
||||||
<text class="tit">{{ item.value.title }}</text>
|
|
||||||
<text class="required">{{ item.value.required ? '*' : '' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="box box-flex">
|
|
||||||
<picker
|
|
||||||
mode="date"
|
|
||||||
:value="item.val"
|
|
||||||
@change="bindDateChange($event, index)"
|
|
||||||
>
|
|
||||||
<view :class="['uni-input', !item.val ? 'color-tip' : '']">
|
|
||||||
{{ item.val ? item.val : item.value.placeholder }}
|
|
||||||
</view>
|
|
||||||
</picker>
|
|
||||||
</view>
|
|
||||||
<text class="iconfont icon-right"></text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 日期范围选择器 -->
|
|
||||||
<view v-if="item.controller == 'Datelimit'" class="order-wrap">
|
|
||||||
<view class="order-cell flex-box">
|
|
||||||
<view class="name">
|
|
||||||
<text class="tit">{{ item.value.title }}</text>
|
|
||||||
<text class="required">{{ item.value.required ? '*' : '' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="box date-boxs">
|
|
||||||
<view class="date-box">
|
|
||||||
<picker
|
|
||||||
mode="date"
|
|
||||||
:value="item.start_date"
|
|
||||||
@change="bindStartDateChange($event, index)"
|
|
||||||
>
|
|
||||||
<view class="picker-box">
|
|
||||||
<view :class="['uni-input', !item.start_date ? 'color-tip' : '']">
|
|
||||||
{{ item.start_date ? item.start_date : item.value.placeholder_start }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</picker>
|
|
||||||
</view>
|
|
||||||
<view class="interval iconfont icon-jian"></view>
|
|
||||||
<view class="date-box">
|
|
||||||
<picker
|
|
||||||
mode="date"
|
|
||||||
:value="item.end_date"
|
|
||||||
@change="bindEndDateChange($event, index)"
|
|
||||||
>
|
|
||||||
<view class="picker-box">
|
|
||||||
<view :class="['uni-input', !item.end_date ? 'color-tip' : '']">
|
|
||||||
{{ item.end_date ? item.end_date : item.value.placeholder_end }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</picker>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 时间选择器 -->
|
|
||||||
<view v-if="item.controller == 'Time'" class="order-wrap">
|
|
||||||
<view class="order-cell">
|
|
||||||
<view class="name">
|
|
||||||
<text class="tit">{{ item.value.title }}</text>
|
|
||||||
<text class="required">{{ item.value.required ? '*' : '' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="box box-flex">
|
|
||||||
<picker
|
|
||||||
mode="time"
|
|
||||||
:value="item.val"
|
|
||||||
@change="bindTimeChange($event, index)"
|
|
||||||
>
|
|
||||||
<view :class="['uni-input', !item.val ? 'color-tip' : '']">
|
|
||||||
{{ item.val ? item.val : item.value.placeholder }}
|
|
||||||
</view>
|
|
||||||
</picker>
|
|
||||||
</view>
|
|
||||||
<text class="iconfont icon-right"></text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 时间范围选择器 -->
|
|
||||||
<view v-if="item.controller == 'Timelimit'" class="order-wrap">
|
|
||||||
<view class="order-cell flex-box">
|
|
||||||
<view class="name">
|
|
||||||
<text class="tit">{{ item.value.title }}</text>
|
|
||||||
<text class="required">{{ item.value.required ? '*' : '' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="box date-boxs">
|
|
||||||
<view class="date-box">
|
|
||||||
<picker
|
|
||||||
mode="time"
|
|
||||||
:value="item.start_time"
|
|
||||||
@change="bindStartTimeChange($event, index)"
|
|
||||||
>
|
|
||||||
<view class="picker-box">
|
|
||||||
<view :class="['uni-input', !item.start_time ? 'color-tip' : '']">
|
|
||||||
{{ item.start_time ? item.start_time : item.value.placeholder_start }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</picker>
|
|
||||||
</view>
|
|
||||||
<view class="interval iconfont icon-jian"></view>
|
|
||||||
<view class="date-box">
|
|
||||||
<picker
|
|
||||||
mode="time"
|
|
||||||
:value="item.end_time"
|
|
||||||
@change="bindEndTimeChange($event, index)"
|
|
||||||
>
|
|
||||||
<view class="picker-box">
|
|
||||||
<view :class="['uni-input', !item.end_time ? 'color-tip' : '']">
|
|
||||||
{{ item.end_time ? item.end_time : item.value.placeholder_end }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</picker>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 城市选择器 -->
|
|
||||||
<view v-if="item.controller == 'City'" class="order-wrap">
|
|
||||||
<view class="order-cell box-flex">
|
|
||||||
<view class="name">
|
|
||||||
<text class="tit">{{ item.value.title }}</text>
|
|
||||||
<text class="required">{{ item.value.required ? '*' : '' }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="box">
|
|
||||||
<pick-regions
|
|
||||||
:defaultRegions="item.default_regions"
|
|
||||||
:selectArr="item.select_arr"
|
|
||||||
@getRegions="handleGetRegions($event, index)"
|
|
||||||
>
|
|
||||||
<view :class="['select-address', !item.val ? 'empty' : '', !item.val ? 'color-tip' : '']">
|
|
||||||
{{ item.val ? item.val : (item.select_arr == '2' ? '请选择省市' : '请选择省市区/县') }}
|
|
||||||
</view>
|
|
||||||
</pick-regions>
|
|
||||||
</view>
|
|
||||||
<text class="iconfont icon-right"></text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import pickRegions from '@/components/pick-regions/pick-regions.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'ns-form',
|
|
||||||
components: {
|
|
||||||
pickRegions
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
data: {
|
|
||||||
type: Array,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
customAttr: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
formData: this.data
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.setFormData();
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
data: {
|
|
||||||
handler() {
|
|
||||||
this.setFormData();
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
setFormData() {
|
|
||||||
this.formData = this.data;
|
|
||||||
this.formData.forEach((item) => {
|
|
||||||
// 初始化默认值
|
|
||||||
if (!item.val) {
|
|
||||||
item.val = item.value.default ? item.value.default : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理选项列表
|
|
||||||
if (item.value.options) {
|
|
||||||
item.option_lists = [];
|
|
||||||
item.value.options.forEach((option, index) => {
|
|
||||||
let optionItem = {};
|
|
||||||
optionItem.value = option;
|
|
||||||
optionItem.checked = false;
|
|
||||||
|
|
||||||
if (item.controller == 'Radio') {
|
|
||||||
if ((!item.val && index == 0) || (item.val && item.val == option)) {
|
|
||||||
optionItem.checked = true;
|
|
||||||
item.val = option;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.controller == 'Checkbox' && item.val) {
|
|
||||||
let valArray = item.val.split(',');
|
|
||||||
optionItem.checked = valArray.indexOf(option) != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
item.option_lists.push(optionItem);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理图片列表
|
|
||||||
if (item.controller == 'Img') {
|
|
||||||
item.img_lists = item.val ? item.val.split(',') : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理日期
|
|
||||||
if (item.controller == 'Date' && !item.val) {
|
|
||||||
if (item.value.is_show_default) {
|
|
||||||
if (item.value.is_current) {
|
|
||||||
item.val = this.getDate();
|
|
||||||
} else {
|
|
||||||
item.val = item.value.default;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item.val = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理日期范围
|
|
||||||
if (item.controller == 'Datelimit') {
|
|
||||||
if (item.val) {
|
|
||||||
let dateArray = item.val.split(' - ');
|
|
||||||
item.start_date = dateArray[0];
|
|
||||||
item.end_date = dateArray[1];
|
|
||||||
} else {
|
|
||||||
item.val = '';
|
|
||||||
|
|
||||||
// 开始日期
|
|
||||||
if (item.value.is_show_default_start) {
|
|
||||||
if (item.value.is_current_start) {
|
|
||||||
item.start_date = this.getDate();
|
|
||||||
} else {
|
|
||||||
item.start_date = item.value.default_start;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item.start_date = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 结束日期
|
|
||||||
if (item.value.is_show_default_end) {
|
|
||||||
if (item.value.is_current_end) {
|
|
||||||
item.end_date = this.getDate();
|
|
||||||
} else {
|
|
||||||
item.end_date = item.value.default_end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item.end_date = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.start_date && item.end_date) {
|
|
||||||
item.val = item.start_date + ' - ' + item.end_date;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理时间
|
|
||||||
if (item.controller == 'Time' && !item.val) {
|
|
||||||
if (item.value.is_show_default) {
|
|
||||||
if (item.value.is_current) {
|
|
||||||
item.val = this.getTime();
|
|
||||||
} else {
|
|
||||||
item.val = item.value.default;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item.val = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理时间范围
|
|
||||||
if (item.controller == 'Timelimit') {
|
|
||||||
if (item.val) {
|
|
||||||
let timeArray = item.val.split(' - ');
|
|
||||||
item.start_time = timeArray[0];
|
|
||||||
item.end_time = timeArray[1];
|
|
||||||
} else {
|
|
||||||
item.val = '';
|
|
||||||
|
|
||||||
// 开始时间
|
|
||||||
if (item.value.is_show_default_start) {
|
|
||||||
if (item.value.is_current_start) {
|
|
||||||
item.start_time = this.getTime();
|
|
||||||
} else {
|
|
||||||
item.start_time = item.value.default_start;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item.start_time = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 结束时间
|
|
||||||
if (item.value.is_show_default_end) {
|
|
||||||
if (item.value.is_current_end) {
|
|
||||||
item.end_time = this.getTime();
|
|
||||||
} else {
|
|
||||||
item.end_time = item.value.default_end;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item.end_time = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.start_time && item.end_time) {
|
|
||||||
item.val = item.start_time + ' - ' + item.end_time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理城市选择
|
|
||||||
if (item.controller == 'City') {
|
|
||||||
item.full_address = '';
|
|
||||||
item.select_arr = item.value.default_type == 1 ? '2' : '3';
|
|
||||||
if (item.val) {
|
|
||||||
item.default_regions = item.val.split('-');
|
|
||||||
} else {
|
|
||||||
item.default_regions = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 表单验证
|
|
||||||
verify() {
|
|
||||||
for (let i = 0; i < this.formData.length; i++) {
|
|
||||||
let item = this.formData[i];
|
|
||||||
|
|
||||||
// 文本验证
|
|
||||||
if (item.controller == 'Text') {
|
|
||||||
if (item.value.required && !item.val) {
|
|
||||||
this.$util.showToast({ title: '请输入' + item.value.title });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.name == 'ID_CARD' && !/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(item.val)) {
|
|
||||||
if (!item.value.required) {
|
|
||||||
this.$util.showToast({ title: '身份证输入不合法' });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (item.val != '') {
|
|
||||||
this.$util.showToast({ title: '身份证输入不合法' });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.name == 'MOBILE' && !this.$util.verifyMobile(item.val)) {
|
|
||||||
if (!item.value.required) {
|
|
||||||
this.$util.showToast({ title: '手机号输入不合法' });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (item.val != '') {
|
|
||||||
this.$util.showToast({ title: '手机号输入不合法' });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 多行文本验证
|
|
||||||
if (item.controller == 'Textarea' && item.value.required && !item.val) {
|
|
||||||
this.$util.showToast({ title: '请输入' + item.value.title });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 下拉选择验证
|
|
||||||
if (item.controller == 'Select' && item.value.required && !item.val) {
|
|
||||||
this.$util.showToast({ title: '请选择' + item.value.title });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 复选框验证
|
|
||||||
if (item.controller == 'Checkbox' && item.value.required && !item.val) {
|
|
||||||
this.$util.showToast({ title: '请至少选择一个' + item.value.title });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 图片上传验证
|
|
||||||
if (item.controller == 'Img' && item.value.required && !item.val) {
|
|
||||||
this.$util.showToast({ title: '请至少上传一张' + item.value.title });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 日期验证
|
|
||||||
if (item.controller == 'Date' && item.value.required && !item.val) {
|
|
||||||
this.$util.showToast({ title: '请选择' + item.value.title });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 日期范围验证
|
|
||||||
if (item.controller == 'Datelimit') {
|
|
||||||
if (item.value.required && !item.val) {
|
|
||||||
this.$util.showToast({ title: '请选择' + item.value.title });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.$util.timeTurnTimeStamp(item.start_date) > this.$util.timeTurnTimeStamp(item.end_date)) {
|
|
||||||
this.$util.showToast({ title: '结束日期不能小于开始日期' });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 时间验证
|
|
||||||
if (item.controller == 'Time' && item.value.required && !item.val) {
|
|
||||||
this.$util.showToast({ title: '请选择' + item.value.title });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 时间范围验证
|
|
||||||
if (item.controller == 'Timelimit') {
|
|
||||||
if (item.value.required && !item.val) {
|
|
||||||
this.$util.showToast({ title: '请选择' + item.value.title });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.start_time >= item.end_time) {
|
|
||||||
this.$util.showToast({ title: '结束时间必须大于开始时间' });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 城市选择验证
|
|
||||||
if (item.controller == 'City' && item.value.required && !item.val) {
|
|
||||||
this.$util.showToast({ title: '请选择' + item.value.title });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.formData;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 下拉选择改变
|
|
||||||
pickerChange(event, index) {
|
|
||||||
this.formData[index].val = this.data[index].value.options[event.detail.value];
|
|
||||||
this.$forceUpdate();
|
|
||||||
},
|
|
||||||
|
|
||||||
// 复选框改变
|
|
||||||
checkboxChange(event, index) {
|
|
||||||
this.formData[index].val = event.detail.value.toString();
|
|
||||||
this.formData[index].option_lists.forEach((option) => {
|
|
||||||
option.checked = event.detail.value.indexOf(option.value) != -1;
|
|
||||||
});
|
|
||||||
this.$forceUpdate();
|
|
||||||
},
|
|
||||||
|
|
||||||
// 单选框改变
|
|
||||||
radioChange(event, index) {
|
|
||||||
this.formData[index].val = event.detail.value;
|
|
||||||
this.$forceUpdate();
|
|
||||||
},
|
|
||||||
|
|
||||||
// 上传图片
|
|
||||||
uploadImg(index) {
|
|
||||||
let self = this;
|
|
||||||
this.$util.upload(Number(this.formData[index].value.max_count), { path: 'evaluateimg' }, function(res) {
|
|
||||||
if (res.length > 0) {
|
|
||||||
res.forEach(function(img) {
|
|
||||||
if (self.formData[index].img_lists.length >= Number(self.formData[index].value.max_count)) {
|
|
||||||
self.$util.showToast({ title: '最多上传' + self.formData[index].value.max_count + '张图片' });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
self.formData[index].img_lists.push(img);
|
|
||||||
});
|
|
||||||
self.formData[index].val = self.formData[index].img_lists.toString();
|
|
||||||
self.$forceUpdate();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 添加图片
|
|
||||||
addImg(index) {
|
|
||||||
let self = this;
|
|
||||||
if (this.formData[index].img_lists.length >= Number(this.formData[index].value.max_count)) {
|
|
||||||
this.$util.showToast({ title: '最多上传' + this.formData[index].value.max_count + '张图片' });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$util.upload(Number(this.formData[index].value.max_count), { path: 'evaluateimg' }, function(res) {
|
|
||||||
if (res.length > 0) {
|
|
||||||
res.forEach(function(img) {
|
|
||||||
self.formData[index].img_lists.push(img);
|
|
||||||
});
|
|
||||||
self.formData[index].val = self.formData[index].img_lists.toString();
|
|
||||||
self.$forceUpdate();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 删除图片
|
|
||||||
delImg(imgIndex, formIndex) {
|
|
||||||
this.formData[formIndex].img_lists.splice(imgIndex, 1);
|
|
||||||
this.formData[formIndex].val = this.formData[formIndex].img_lists.toString();
|
|
||||||
this.$forceUpdate();
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取当前日期
|
|
||||||
getDate() {
|
|
||||||
let date = new Date();
|
|
||||||
let year = date.getFullYear();
|
|
||||||
let month = date.getMonth() + 1;
|
|
||||||
let day = date.getDate();
|
|
||||||
month = month > 9 ? month : '0' + month;
|
|
||||||
day = day > 9 ? day : '0' + day;
|
|
||||||
return `${year}-${month}-${day}`;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取当前时间
|
|
||||||
getTime() {
|
|
||||||
let date = new Date();
|
|
||||||
let hours = date.getHours();
|
|
||||||
let minutes = date.getMinutes();
|
|
||||||
hours = hours > 9 ? hours : '0' + hours;
|
|
||||||
minutes = minutes > 9 ? minutes : '0' + minutes;
|
|
||||||
return `${hours}:${minutes}`;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 日期改变
|
|
||||||
bindDateChange(event, index) {
|
|
||||||
this.formData[index].val = event.detail.value;
|
|
||||||
this.$forceUpdate();
|
|
||||||
},
|
|
||||||
|
|
||||||
// 开始日期改变
|
|
||||||
bindStartDateChange(event, index) {
|
|
||||||
this.$set(this.formData[index], 'start_date', event.detail.value);
|
|
||||||
this.$set(this.formData[index], 'val', this.formData[index].start_date + ' - ' + this.formData[index].end_date);
|
|
||||||
this.$forceUpdate();
|
|
||||||
},
|
|
||||||
|
|
||||||
// 结束日期改变
|
|
||||||
bindEndDateChange(event, index) {
|
|
||||||
this.$set(this.formData[index], 'end_date', event.detail.value);
|
|
||||||
this.$set(this.formData[index], 'val', this.formData[index].start_date + ' - ' + this.formData[index].end_date);
|
|
||||||
this.$forceUpdate();
|
|
||||||
},
|
|
||||||
|
|
||||||
// 时间改变
|
|
||||||
bindTimeChange(event, index) {
|
|
||||||
this.formData[index].val = event.detail.value;
|
|
||||||
this.$forceUpdate();
|
|
||||||
},
|
|
||||||
|
|
||||||
// 开始时间改变
|
|
||||||
bindStartTimeChange(event, index) {
|
|
||||||
this.formData[index].start_time = event.detail.value;
|
|
||||||
this.$forceUpdate();
|
|
||||||
},
|
|
||||||
|
|
||||||
// 结束时间改变
|
|
||||||
bindEndTimeChange(event, index) {
|
|
||||||
this.formData[index].end_time = event.detail.value;
|
|
||||||
this.formData[index].val = this.formData[index].start_time + ' - ' + this.formData[index].end_time;
|
|
||||||
this.$forceUpdate();
|
|
||||||
},
|
|
||||||
|
|
||||||
// 处理地区选择
|
|
||||||
handleGetRegions(regions, index) {
|
|
||||||
this.formData[index].val = '';
|
|
||||||
this.formData[index].val += regions[0] != undefined ? regions[0].label : '';
|
|
||||||
this.formData[index].val += regions[1] != undefined ? '-' + regions[1].label : '';
|
|
||||||
this.formData[index].val += regions[2] != undefined ? '-' + regions[2].label : '';
|
|
||||||
this.$forceUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.order-wrap {
|
|
||||||
padding: 20rpx 0;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.order-cell {
|
|
||||||
align-items: center;
|
|
||||||
background: #fff;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&.textarea {
|
|
||||||
align-items: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.clear-flex {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
.box {
|
|
||||||
margin-top: 16rpx;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
border-bottom: solid 1px #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.align-top {
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
text {
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
width: 160rpx;
|
|
||||||
margin-bottom: 10rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
.tit {
|
|
||||||
text-align: left;
|
|
||||||
font-size: 32rpx;
|
|
||||||
color: #888;
|
|
||||||
|
|
||||||
text {
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.required {
|
|
||||||
color: red;
|
|
||||||
font-size: 28rpx;
|
|
||||||
margin-left: 4rpx;
|
|
||||||
width: 14rpx;
|
|
||||||
text-align: left;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.box {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0 0rpx;
|
|
||||||
line-height: inherit;
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
input {
|
|
||||||
font-size: 28rpx;
|
|
||||||
text-align: left;
|
|
||||||
height: 70rpx;
|
|
||||||
border: solid 2rpx #eee;
|
|
||||||
line-height: 70rpx;
|
|
||||||
padding: 0 16rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
font-size: 28rpx;
|
|
||||||
width: 100%;
|
|
||||||
height: 88rpx;
|
|
||||||
line-height: 44rpx;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
checkbox-group {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
radio-group {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
line-height: 1;
|
|
||||||
margin-right: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.img-boxs {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
.img-box {
|
|
||||||
margin: 10rpx 20rpx 10rpx 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 100rpx;
|
|
||||||
height: 100rpx;
|
|
||||||
border: 1rpx solid #eee;
|
|
||||||
border-radius: 4rpx;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.icon-guanbi {
|
|
||||||
position: absolute;
|
|
||||||
top: -14rpx;
|
|
||||||
right: -14rpx;
|
|
||||||
display: inline-block;
|
|
||||||
width: 28rpx;
|
|
||||||
height: 28rpx;
|
|
||||||
line-height: 28rpx;
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-add1 {
|
|
||||||
font-size: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.box-flex {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.date-boxs {
|
|
||||||
padding: 0 10rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.interval {
|
|
||||||
margin: 0 12rpx;
|
|
||||||
color: #000;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-box {
|
|
||||||
.picker-box {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.radio-group-box {
|
|
||||||
radio {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.radio-box {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
line-height: 1;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
font-size: 32rpx;
|
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.check-group-box {
|
|
||||||
checkbox {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
line-height: 1;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
font-size: 32rpx;
|
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
color: #909399;
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-flex {
|
|
||||||
picker {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-right {
|
|
||||||
line-height: 1;
|
|
||||||
position: unset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,386 +1,369 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="ns-time">
|
<view class="ns-time">
|
||||||
<uni-popup type="bottom" ref="selectTime">
|
<uni-popup type="bottom" ref="selectTime">
|
||||||
<view class="box">
|
<view class="box">
|
||||||
<view class="title">
|
<view class="title">
|
||||||
<block v-if="obj.delivery && obj.delivery.delivery_type == 'local'">选择送达时间</block>
|
<block v-if="obj.delivery && obj.delivery.delivery_type == 'local'">选择送达时间</block>
|
||||||
<block v-if="obj.delivery && obj.delivery.delivery_type == 'store'">选择自提时间</block>
|
<block v-if="obj.delivery && obj.delivery.delivery_type == 'store'">选择自提时间</block>
|
||||||
<text class="iconfont icon-close" @click="close"></text>
|
<text class="iconfont icon-close" @click="close"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="body">
|
<view class="body">
|
||||||
<!-- 左侧日期选择 -->
|
<!-- 左侧日期选择 -->
|
||||||
<scroll-view :scroll-y="true" class="left">
|
<scroll-view :scroll-y="true" class="left">
|
||||||
<view class="item" :class="index == keyJudge ? 'itemDay' : ''" v-for="(item, index) in dayData" :key="index" @click="selectTime('days', index, 'yes')">
|
<view class="item" :class="index == keyJudge ? 'itemDay' : ''" v-for="(item, index) in dayData" :key="index" @click="selectTime('days', index, 'yes')">
|
||||||
<block v-if="item.title">{{ item.title }}</block>
|
<block v-if="item.title">{{ item.title }}</block>
|
||||||
<block v-else>{{ item.month }}</block>
|
<block v-else>{{ item.month }}</block>
|
||||||
<text class="itemtext">{{ item.Day }}</text>
|
<text class="itemtext">{{ item.Day }}</text>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<!-- 右侧时间选择 -->
|
<!-- 右侧时间选择 -->
|
||||||
<scroll-view :scroll-y="true" class="right">
|
<scroll-view :scroll-y="true" class="right">
|
||||||
<view class="item" :class="key == keyJudge && index == keys ? 'itemTime' : ''" v-for="(item, index) in timeData" :key="index" @click="selectTime('time', index, 'yes')">
|
<view class="item" :class="key == keyJudge && index == keys ? 'itemTime' : ''" v-for="(item, index) in timeData" :key="index" @click="selectTime('time', index, 'yes')">
|
||||||
{{ item }}
|
{{ item }}
|
||||||
<text v-if="key == keyJudge && index == keys" class="iconfont icon-yuan_checked color-base-text"></text>
|
<text v-if="key == keyJudge && index == keys" class="iconfont icon-yuan_checked color-base-text"></text>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import uniPopup from '@/components/uni-popup/uni-popup.vue';
|
import uniPopup from '@/components/uni-popup/uni-popup.vue';
|
||||||
export default {
|
export default {
|
||||||
name: "nsSelectTime",
|
name: "nsSelectTime",
|
||||||
components: {
|
components: {
|
||||||
uniPopup
|
uniPopup
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
//选中日期的键值
|
//选中日期的键值
|
||||||
key: 0,
|
key: 0,
|
||||||
//选中时间的键值
|
//选中时间的键值
|
||||||
keys: 0,
|
keys: 0,
|
||||||
//渲染用数据
|
//渲染用数据
|
||||||
obj: {},
|
obj: {},
|
||||||
//左侧渲染时间
|
//左侧渲染时间
|
||||||
dayData: [],
|
dayData: [],
|
||||||
// 右侧渲染数据
|
// 右侧渲染数据
|
||||||
timeData: [],
|
timeData: [],
|
||||||
//判断弹窗打开
|
//判断弹窗打开
|
||||||
judge: false,
|
judge: false,
|
||||||
//判断左侧列表是否为日期选中列表
|
//判断左侧列表是否为日期选中列表
|
||||||
keyJudge: 0,
|
keyJudge: 0,
|
||||||
//当前时间时间戳
|
//当前时间时间戳
|
||||||
dayTime: 0
|
dayTime: 0
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
refresh(){
|
refresh(){
|
||||||
this.key = 0;
|
this.key = 0;
|
||||||
this.keys = 0;
|
this.keys = 0;
|
||||||
this.keyJudge = 0;
|
this.keyJudge = 0;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 弹窗打开
|
* 弹窗打开
|
||||||
*/
|
*/
|
||||||
open(obj, type) {
|
open(obj, type) {
|
||||||
this.dayData = [];
|
this.dayData = [];
|
||||||
this.timeData = [];
|
this.timeData = [];
|
||||||
this.obj = obj;
|
this.obj = obj;
|
||||||
this.toDay(obj.dataTime.time_type, obj.dataTime.time_week);
|
this.toDay(obj.dataTime.time_type, obj.dataTime.time_week);
|
||||||
if (this.judge) {
|
if (this.judge) {
|
||||||
if (type == 'no') {
|
if (type == 'no') {
|
||||||
this.selectTime('', '', type);
|
this.selectTime('', '', type);
|
||||||
} else {
|
} else {
|
||||||
this.$refs.selectTime.open();
|
this.$refs.selectTime.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 时间选择
|
* 时间选择
|
||||||
*/
|
*/
|
||||||
selectTime(type, index, judge) {
|
selectTime(type, index, judge) {
|
||||||
if (type == 'days') {
|
if (type == 'days') {
|
||||||
this.keyJudge = index;
|
this.keyJudge = index;
|
||||||
this.toTime();
|
this.toTime();
|
||||||
} else if (type == 'time') {
|
} else if (type == 'time') {
|
||||||
this.keys = index;
|
this.keys = index;
|
||||||
this.key = this.keyJudge;
|
this.key = this.keyJudge;
|
||||||
let obj = this.dayData[this.key];
|
let obj = this.dayData[this.key];
|
||||||
obj.time = this.timeData[this.keys];
|
obj.time = this.timeData[this.keys];
|
||||||
let time = obj.time.replace('立即配送(','').replace(')','');
|
let time = obj.time.replace('立即配送(','').replace(')','');
|
||||||
let dateTime = new Date();
|
|
||||||
|
var dateTime = new Date();
|
||||||
let format = time.split('-');
|
var format = time.split('-');
|
||||||
let startHours = format[0].split(':');
|
var startHours = format[0].split(':');
|
||||||
let endHours = format[1].split(':');
|
var endHours = format[1].split(':');
|
||||||
|
|
||||||
let timeData = obj.month.split('月');
|
let timeData = obj.month.split('月');
|
||||||
let month = timeData[0];
|
let month = timeData[0];
|
||||||
let date = timeData[1].split('日')[0];
|
let date = timeData[1].split('日')[0];
|
||||||
|
|
||||||
// 开始时间戳
|
// 开始时间戳
|
||||||
dateTime.setHours(startHours[0],startHours[1],0,0);
|
dateTime.setHours(startHours[0],startHours[1],0,0);
|
||||||
obj.start_time = dateTime.getTime()/1000;
|
obj.start_time = dateTime.getTime()/1000;
|
||||||
obj.start_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[0];
|
obj.start_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[0];
|
||||||
|
|
||||||
// 结束时间戳
|
// 结束时间戳
|
||||||
dateTime.setHours(endHours[0],endHours[1],0,0);
|
dateTime.setHours(endHours[0],endHours[1],0,0);
|
||||||
obj.end_time = dateTime.getTime()/1000;
|
obj.end_time = dateTime.getTime()/1000;
|
||||||
obj.end_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[1];
|
obj.end_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[1];
|
||||||
|
|
||||||
this.$emit('selectTime', { data: obj, type: judge });
|
this.$emit('selectTime', { data: obj, type: judge });
|
||||||
this.$refs.selectTime.close();
|
this.$refs.selectTime.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (judge == 'no') {
|
if (judge == 'no') {
|
||||||
this.toTime(judge);
|
this.toTime(judge);
|
||||||
let obj = this.dayData[0];
|
let obj = this.dayData[0];
|
||||||
obj.time = this.timeData[0];
|
obj.time = this.timeData[0];
|
||||||
let dateTime = new Date();
|
this.$emit('selectTime', { data: obj, type: judge });
|
||||||
let format = obj.time.replace('立即配送(','').replace(')','').split('-');
|
}
|
||||||
let startHours = format[0].split(':');
|
this.$forceUpdate();
|
||||||
let endHours = format[1].split(':');
|
},
|
||||||
|
/**
|
||||||
let timeData = obj.month.split('月');
|
* 弹窗关闭
|
||||||
let month = timeData[0];
|
*/
|
||||||
let date = timeData[1].split('日')[0];
|
close() {
|
||||||
|
this.$refs.selectTime.close();
|
||||||
// 开始时间戳
|
},
|
||||||
dateTime.setHours(startHours[0],startHours[1],0,0);
|
/**
|
||||||
obj.start_time = dateTime.getTime()/1000;
|
* 左侧数据处理
|
||||||
obj.start_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[0];
|
*/
|
||||||
// 结束时间戳
|
toDay(type, obj) {
|
||||||
dateTime.setHours(endHours[0],endHours[1],0,0);
|
let today = new Date();
|
||||||
obj.end_time = dateTime.getTime()/1000;
|
if (this.obj.dataTime.advance_day) {
|
||||||
obj.end_date = dateTime.getFullYear() + '-' + month + '-' + date + ' ' + format[1];
|
today = new Date(today.getTime() + (this.obj.dataTime.advance_day * 86400000));
|
||||||
this.$emit('selectTime', { data: obj, type: judge });
|
}
|
||||||
}
|
let nowYear = today.getFullYear(); //当前年
|
||||||
this.$forceUpdate();
|
let nowMonth = today.getMonth() + 1; //当前月
|
||||||
},
|
let nowDate = today.getDate(); //当前日
|
||||||
/**
|
let nowDay = today.getDay(); //当前星期几
|
||||||
* 弹窗关闭
|
let endDay = new Date(nowYear, nowMonth, 0).getDate(); //当月多少天
|
||||||
*/
|
let Hours = today.getHours();
|
||||||
close() {
|
let Minutes = today.getMinutes();
|
||||||
this.$refs.selectTime.close();
|
this.dayTime = this.obj.dataTime.advance_day ? 0 : Number(Hours) * 3600 + Number(Minutes) * 60; //获取到当前时分秒的时间戳
|
||||||
},
|
let judge = false;
|
||||||
/**
|
let num = 1; //记录循环执行过的次数
|
||||||
* 左侧数据处理
|
let mostDay = this.obj.dataTime.most_day ? this.obj.dataTime.most_day + 1 : 1; // 最多可预约天数
|
||||||
*/
|
let startTime = parseInt(today.getTime() / 1000);
|
||||||
toDay(type, obj) {
|
let week = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
||||||
let today = new Date();
|
if (obj.time_week && obj.time_week.length == 7) {
|
||||||
if (this.obj.dataTime.advance_day) {
|
//判断是否七天全有
|
||||||
today = new Date(today.getTime() + (this.obj.dataTime.advance_day * 86400000));
|
judge = true;
|
||||||
}
|
}
|
||||||
let nowYear = today.getFullYear(); //当前年
|
|
||||||
let nowMonth = today.getMonth() + 1; //当前月
|
for (let i = 0; i < mostDay; i++) {
|
||||||
let nowDate = today.getDate(); //当前日
|
let objects = {};
|
||||||
let nowDay = today.getDay(); //当前星期几
|
let dayStr = week[ nowDay ];
|
||||||
let endDay = new Date(nowYear, nowMonth, 0).getDate(); //当月多少天
|
// 判断最大可预约时间
|
||||||
let Hours = today.getHours();
|
if (this.obj.dataTime.most_day > 0 && ((startTime + num * 86400) > (startTime + this.obj.dataTime.most_day * 86400) ) ) {
|
||||||
let Minutes = today.getMinutes();
|
this.judge = true;
|
||||||
this.dayTime = this.obj.dataTime.advance_day ? 0 : Number(Hours) * 3600 + Number(Minutes) * 60; //获取到当前时分秒的时间戳
|
break;
|
||||||
let judge = false;
|
}
|
||||||
let num = 1; //记录循环执行过的次数
|
//判断当天是否能够配送、自提
|
||||||
let mostDay = this.obj.dataTime.most_day ? this.obj.dataTime.most_day + 1 : 1; // 最多可预约天数
|
if (type == 0 || judge || obj.indexOf(nowDay.toString()) != -1) {
|
||||||
let startTime = parseInt(today.getTime() / 1000);
|
let endTime = this.obj.dataTime.delivery_time[ (this.obj.dataTime.delivery_time.length - 1) ].end_time;
|
||||||
let week = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
endTime -= this.obj.dataTime.time_interval * 60;
|
||||||
if (obj.time_week && obj.time_week.length == 7) {
|
switch (num) {
|
||||||
//判断是否七天全有
|
case 1:
|
||||||
judge = true;
|
if (i == 0) {
|
||||||
}
|
if (endTime < this.dayTime) {
|
||||||
|
i = i - 1;
|
||||||
for (let i = 0; i < mostDay; i++) {
|
} else {
|
||||||
let objects = {};
|
objects = {
|
||||||
let dayStr = week[ nowDay ];
|
title: this.obj.dataTime.advance_day == 0 ? '今天' : '',
|
||||||
// 判断最大可预约时间
|
type: 'special',
|
||||||
if (this.obj.dataTime.most_day > 0 && ((startTime + num * 86400) > (startTime + this.obj.dataTime.most_day * 86400) ) ) {
|
month: nowMonth + '月' + nowDate + '日',
|
||||||
this.judge = true;
|
Day: '(' + dayStr + ')'
|
||||||
break;
|
};
|
||||||
}
|
this.dayData.push(objects); //左侧日期数据处理
|
||||||
//判断当天是否能够配送、自提
|
}
|
||||||
if (type == 0 || judge || obj.indexOf(nowDay.toString()) != -1) {
|
}
|
||||||
|
break;
|
||||||
let endTime = this.obj.dataTime.delivery_time[ (this.obj.dataTime.delivery_time.length - 1) ].end_time;
|
case 2:
|
||||||
endTime -= this.obj.dataTime.time_interval * 60;
|
if (i == 0 || i == 1) {
|
||||||
switch (num) {
|
objects = {
|
||||||
case 1:
|
title: this.obj.dataTime.advance_day == 0 ? '明天' : '',
|
||||||
if (i == 0) {
|
month: nowMonth + '月' + nowDate + '日',
|
||||||
if (endTime < this.dayTime) {
|
Day: '(' + dayStr + ')'
|
||||||
i = i - 1;
|
};
|
||||||
} else {
|
this.dayData.push(objects); //左侧日期数据处理
|
||||||
objects = {
|
}
|
||||||
title: this.obj.dataTime.advance_day == 0 ? '今天' : '',
|
break;
|
||||||
type: 'special',
|
default:
|
||||||
month: nowMonth + '月' + nowDate + '日',
|
objects = {
|
||||||
Day: '(' + dayStr + ')'
|
title: '',
|
||||||
};
|
month: nowMonth + '月' + nowDate + '日',
|
||||||
this.dayData.push(objects); //左侧日期数据处理
|
Day: '(' + dayStr + ')'
|
||||||
}
|
};
|
||||||
}
|
this.dayData.push(objects); //左侧日期数据处理
|
||||||
break;
|
}
|
||||||
case 2:
|
} else {
|
||||||
if (i == 0 || i == 1) {
|
i = i - 1;
|
||||||
objects = {
|
}
|
||||||
title: this.obj.dataTime.advance_day == 0 ? '明天' : '',
|
|
||||||
month: nowMonth + '月' + nowDate + '日',
|
if (nowDate != endDay) {
|
||||||
Day: '(' + dayStr + ')'
|
nowDate += 1;
|
||||||
};
|
} else {
|
||||||
this.dayData.push(objects); //左侧日期数据处理
|
if (nowMonth != 12) {
|
||||||
}
|
nowMonth += 1;
|
||||||
break;
|
} else {
|
||||||
default:
|
nowMonth = 1;
|
||||||
objects = {
|
}
|
||||||
title: '',
|
nowDate = 1;
|
||||||
month: nowMonth + '月' + nowDate + '日',
|
}
|
||||||
Day: '(' + dayStr + ')'
|
|
||||||
};
|
if (nowDay != 6) {
|
||||||
this.dayData.push(objects); //左侧日期数据处理
|
nowDay += 1;
|
||||||
}
|
} else {
|
||||||
} else {
|
nowDay = 0;
|
||||||
i = i - 1;
|
}
|
||||||
}
|
num += 1;
|
||||||
|
|
||||||
if (nowDate != endDay) {
|
if (this.obj.dataTime.most_day == 0 && i == 0) {
|
||||||
nowDate += 1;
|
this.judge = true;
|
||||||
} else {
|
}
|
||||||
if (nowMonth != 12) {
|
}
|
||||||
nowMonth += 1;
|
|
||||||
} else {
|
this.toTime(); //处理右侧时间数据
|
||||||
nowMonth = 1;
|
},
|
||||||
}
|
/**
|
||||||
nowDate = 1;
|
* 处理右侧时间数据
|
||||||
}
|
*/
|
||||||
|
toTime(judge) {
|
||||||
if (nowDay != 6) {
|
//并非打开弹窗进入时,所有数据置零
|
||||||
nowDay += 1;
|
if (judge == 'no') {
|
||||||
} else {
|
this.key = 0;
|
||||||
nowDay = 0;
|
this.keys = 0;
|
||||||
}
|
this.keyJudge = 0;
|
||||||
num += 1;
|
}
|
||||||
|
|
||||||
if (this.obj.dataTime.most_day == 0 && i == 0) {
|
let timeData = [];
|
||||||
this.judge = true;
|
|
||||||
}
|
if (!this.obj.dataTime.delivery_time) {
|
||||||
}
|
this.obj.dataTime.delivery_time = [ {start_time: this.obj.dataTime.start_time, end_time: this.obj.dataTime.end_time} ]
|
||||||
this.toTime(); //处理右侧时间数据
|
}
|
||||||
},
|
|
||||||
/**
|
//判断选中是否为当天
|
||||||
* 处理右侧时间数据
|
let remainder = 0;
|
||||||
*/
|
//当天配送自提的话,向后推迟30分钟
|
||||||
toTime(judge) {
|
let newDayTime = JSON.parse(JSON.stringify(this.dayTime));
|
||||||
//并非打开弹窗进入时,所有数据置零
|
// newDayTime = Math.ceil(this.dayTime / 600) * 600 + 1800;
|
||||||
if (judge == 'no') {
|
|
||||||
this.key = 0;
|
//判断选中是否为当天
|
||||||
this.keys = 0;
|
let timeJudage = false;
|
||||||
this.keyJudge = 0;
|
if (this.dayData[this.keyJudge] && this.dayData[this.keyJudge].type && newDayTime > this.obj.dataTime.start_time) timeJudage = true;
|
||||||
}
|
|
||||||
|
let timeInterval = this.obj.dataTime.time_interval ? this.obj.dataTime.time_interval * 60 : 1200;
|
||||||
let timeData = [];
|
|
||||||
|
this.obj.dataTime.delivery_time.forEach(item => {
|
||||||
if (!this.obj.dataTime.delivery_time) {
|
item.end_time = item.end_time ? item.end_time : 86400;
|
||||||
this.obj.dataTime.delivery_time = [ {start_time: this.obj.dataTime.start_time, end_time: this.obj.dataTime.end_time} ]
|
let num = parseInt((parseInt(item.end_time) - parseInt(item.start_time)) / timeInterval);
|
||||||
}
|
let time = timeJudage ? parseInt(newDayTime) : parseInt(item.start_time);
|
||||||
|
for (let i = 0; i < num; i++) {
|
||||||
//判断选中是否为当天
|
if (parseInt(time) + parseInt(timeInterval) > item.end_time) break;
|
||||||
let remainder = 0;
|
if (timeJudage) {
|
||||||
//当天配送自提的话,向后推迟30分钟
|
if (time >= newDayTime) {
|
||||||
let newDayTime = JSON.parse(JSON.stringify(this.dayTime));
|
if (this.obj.dataTime.time_interval) {
|
||||||
// newDayTime = Math.ceil(this.dayTime / 600) * 600 + 1800;
|
if (time <= item.end_time) {
|
||||||
|
let text = '';
|
||||||
//判断选中是否为当天
|
if (this.obj.delivery.delivery_type == 'local' && i == 0) {
|
||||||
let timeJudage = false;
|
text = '立即配送('+ this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval) + ')';
|
||||||
if (this.dayData[this.keyJudge] && this.dayData[this.keyJudge].type && newDayTime > this.obj.dataTime.start_time) timeJudage = true;
|
} else {
|
||||||
|
text = this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval);
|
||||||
let timeInterval = this.obj.dataTime.time_interval ? this.obj.dataTime.time_interval * 60 : 1200;
|
}
|
||||||
|
timeData.push(text);
|
||||||
this.obj.dataTime.delivery_time.forEach(item => {
|
}
|
||||||
item.end_time = item.end_time ? item.end_time : 86400;
|
} else {
|
||||||
let num = parseInt((parseInt(item.end_time) - parseInt(item.start_time)) / timeInterval);
|
timeData.push(this.$util.getTimeStr(time));
|
||||||
let time = timeJudage ? parseInt(newDayTime) : parseInt(item.start_time);
|
}
|
||||||
for (let i = 0; i < num; i++) {
|
}
|
||||||
if (parseInt(time) + parseInt(timeInterval) > item.end_time) break;
|
} else {
|
||||||
if (timeJudage) {
|
if (this.obj.dataTime.time_interval) {
|
||||||
if (time >= newDayTime) {
|
if (time <= item.end_time) timeData.push(this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval));
|
||||||
if (this.obj.dataTime.time_interval) {
|
} else {
|
||||||
if (time <= item.end_time) {
|
timeData.push(this.$util.getTimeStr(time));
|
||||||
let text = '';
|
}
|
||||||
if (this.obj.delivery.delivery_type == 'local' && i == 0) {
|
}
|
||||||
text = '立即配送('+ this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval) + ')';
|
time = parseInt(time) + timeInterval;
|
||||||
} else {
|
}
|
||||||
text = this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval);
|
})
|
||||||
}
|
this.timeData = timeData;
|
||||||
timeData.push(text);
|
this.$forceUpdate();
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
timeData.push(this.$util.getTimeStr(time));
|
};
|
||||||
}
|
</script>
|
||||||
}
|
|
||||||
} else {
|
<style lang="scss" scoped>
|
||||||
if (this.obj.dataTime.time_interval) {
|
.box {
|
||||||
if (time <= item.end_time) timeData.push(this.$util.getTimeStr(time) + '-' + this.$util.getTimeStr(time + timeInterval));
|
height: 728rpx;
|
||||||
} else {
|
.title {
|
||||||
timeData.push(this.$util.getTimeStr(time));
|
padding: 0 30rpx;
|
||||||
}
|
box-sizing: border-box;
|
||||||
}
|
text-align: center;
|
||||||
time = parseInt(time) + timeInterval;
|
font-size: 28rpx;
|
||||||
}
|
font-weight: bold;
|
||||||
})
|
position: relative;
|
||||||
this.timeData = timeData;
|
height: 90rpx;
|
||||||
this.$forceUpdate();
|
line-height: 90rpx;
|
||||||
}
|
border-bottom: 1rpx solid #f7f4f4;
|
||||||
}
|
.icon-close {
|
||||||
};
|
font-size: 26rpx;
|
||||||
</script>
|
color: #909399;
|
||||||
|
position: absolute;
|
||||||
<style lang="scss" scoped>
|
right: 30rpx;
|
||||||
.box {
|
top: 50%;
|
||||||
height: 728rpx;
|
transform: translateY(-50%);
|
||||||
.title {
|
}
|
||||||
padding: 0 30rpx;
|
}
|
||||||
box-sizing: border-box;
|
.body {
|
||||||
text-align: center;
|
width: 100%;
|
||||||
font-size: 28rpx;
|
height: calc(100% - 90rpx);
|
||||||
font-weight: bold;
|
display: flex;
|
||||||
position: relative;
|
align-items: center;
|
||||||
height: 90rpx;
|
.left {
|
||||||
line-height: 90rpx;
|
width: 230rpx;
|
||||||
border-bottom: 1rpx solid #f7f4f4;
|
background: #f8f8f8;
|
||||||
.icon-close {
|
height: 100%;
|
||||||
font-size: 26rpx;
|
.item {
|
||||||
color: #909399;
|
width: 100%;
|
||||||
position: absolute;
|
padding: 16rpx 30rpx;
|
||||||
right: 30rpx;
|
box-sizing: border-box;
|
||||||
top: 50%;
|
text-align: center;
|
||||||
transform: translateY(-50%);
|
font-size: 24rpx;
|
||||||
}
|
display: flex;
|
||||||
}
|
align-items: center;
|
||||||
.body {
|
}
|
||||||
width: 100%;
|
.itemDay {
|
||||||
height: calc(100% - 90rpx);
|
background: #ffffff;
|
||||||
display: flex;
|
}
|
||||||
align-items: center;
|
}
|
||||||
.left {
|
.right {
|
||||||
width: 230rpx;
|
width: calc(100% - 230rpx);
|
||||||
background: #f8f8f8;
|
height: 100%;
|
||||||
height: 100%;
|
padding: 0 30rpx;
|
||||||
.item {
|
box-sizing: border-box;
|
||||||
width: 100%;
|
.item {
|
||||||
padding: 16rpx 30rpx;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
font-size: 24rpx;
|
||||||
text-align: center;
|
border-bottom: 1rpx solid #eeeeee;
|
||||||
font-size: 24rpx;
|
display: flex;
|
||||||
display: flex;
|
align-items: center;
|
||||||
align-items: center;
|
justify-content: space-between;
|
||||||
}
|
height: 72rpx;
|
||||||
.itemDay {
|
.icon-yuan_checked {
|
||||||
background: #ffffff;
|
font-size: 38rpx;
|
||||||
}
|
margin-right: 30rpx;
|
||||||
}
|
}
|
||||||
.right {
|
}
|
||||||
width: calc(100% - 230rpx);
|
.itemTime {
|
||||||
height: 100%;
|
color: var(--main-color);
|
||||||
padding: 0 30rpx;
|
}
|
||||||
box-sizing: border-box;
|
}
|
||||||
.item {
|
}
|
||||||
width: 100%;
|
}
|
||||||
font-size: 24rpx;
|
</style>
|
||||||
border-bottom: 1rpx solid #eeeeee;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
height: 72rpx;
|
|
||||||
.icon-yuan_checked {
|
|
||||||
font-size: 38rpx;
|
|
||||||
margin-right: 30rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.itemTime {
|
|
||||||
color: var(--main-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,259 +1,269 @@
|
|||||||
<template>
|
<template>
|
||||||
<view v-if="isShow">
|
<view v-if="isShow">
|
||||||
<view ref="ani" :animation="animationData" class="message" :style="{ top: top + 'px', left: left + 'px' }" v-if="show">
|
<view ref="ani" :animation="animationData" class="message" :style="{ top: top + 'px', left: left + 'px' }" v-if="show">
|
||||||
<view class="round bg-gradual-orange flex justify-start shadow" style="padding: 3px;">
|
<view class="round bg-gradual-orange flex justify-start shadow" style="padding: 3px;">
|
||||||
<view class="cu-avatar cu-a-sm round" :style="{ backgroundImage: 'url(' + $util.img(penpaiData.img) + ')' }">
|
<view class="cu-avatar cu-a-sm round" :style="{ backgroundImage: 'url(' + $util.img(penpaiData.img) + ')' }">
|
||||||
<!-- #ifdef APP-NVUE -->
|
<!-- #ifdef APP-NVUE -->
|
||||||
<!-- <image :src="penpaiData.img" class="avatarimg"></image> -->
|
<!-- <image :src="penpaiData.img" class="avatarimg"></image> -->
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
<view class="padding-lr-sm flex align-center">
|
<view class="padding-lr-sm flex align-center">
|
||||||
<text class="text-sm">{{ penpaiData.title }}</text>
|
<text class="text-sm">{{ penpaiData.title }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// #ifdef APP-NVUE
|
// #ifdef APP-NVUE
|
||||||
const animation = uni.requireNativePlugin('animation');
|
const animation = uni.requireNativePlugin('animation');
|
||||||
// #endif
|
// #endif
|
||||||
export default {
|
export default {
|
||||||
name: 'pengpai-fadein-out',
|
name: 'pengpai-fadein-out',
|
||||||
props: {
|
props: {
|
||||||
//持续时间
|
//持续时间
|
||||||
duration: {
|
duration: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 3000
|
default: 3000
|
||||||
},
|
},
|
||||||
//停留时间
|
//停留时间
|
||||||
wait: {
|
wait: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 3500
|
default: 3500
|
||||||
},
|
},
|
||||||
//顶部距离px
|
//顶部距离px
|
||||||
top: {
|
top: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 350
|
default: 350
|
||||||
},
|
},
|
||||||
//左边距离px
|
//左边距离px
|
||||||
left: {
|
left: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 10
|
default: 10
|
||||||
},
|
},
|
||||||
//动画半径
|
//动画半径
|
||||||
radius: {
|
radius: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 30
|
default: 30
|
||||||
},
|
},
|
||||||
//数据
|
//数据
|
||||||
info: {
|
info: {
|
||||||
type: [Array, Object],
|
type: [Array, Object],
|
||||||
default: () => {
|
default: () => {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
animationData: {},
|
animationData: {},
|
||||||
animationNumber: {},
|
animationNumber: {},
|
||||||
show: true,
|
show: true,
|
||||||
index: 0,
|
index: 0,
|
||||||
penpaiData: {},
|
penpaiData: {},
|
||||||
timeIndex: 0
|
timeIndex: 0
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed:{
|
computed:{
|
||||||
isShow(){
|
isShow(){
|
||||||
return this.penpaiData && Object.keys(this.penpaiData).length;
|
return this.penpaiData && Object.keys(this.penpaiData).length;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initData();
|
this.initData();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initData() {
|
initData() {
|
||||||
// 初始化执行第一次
|
// 初始化执行第一次
|
||||||
this.penpaiData = this.info[this.index];
|
this.penpaiData = this.info[this.index];
|
||||||
this.donghua();
|
this.donghua();
|
||||||
// 开启时间函数,轮询推值
|
// 开启时间函数,轮询推值
|
||||||
clearInterval(this.timeIndex);
|
clearInterval(this.timeIndex);
|
||||||
this.timeIndex = setInterval(() => {
|
this.timeIndex = setInterval(() => {
|
||||||
if (this.index == this.info.length - 1) {
|
if (this.index == this.info.length - 1) {
|
||||||
this.index = 0;
|
this.index = 0;
|
||||||
} else {
|
} else {
|
||||||
this.index++;
|
this.index++;
|
||||||
}
|
}
|
||||||
this.penpaiData = this.info[this.index];
|
this.penpaiData = this.info[this.index];
|
||||||
// 执行动画
|
// 执行动画
|
||||||
this.donghua();
|
this.donghua();
|
||||||
}, this.duration + this.wait);
|
}, this.duration + this.wait);
|
||||||
},
|
},
|
||||||
donghua() {
|
donghua() {
|
||||||
//进入
|
//进入
|
||||||
// #ifndef APP-NVUE
|
// #ifndef APP-NVUE
|
||||||
this.animationData = uni
|
this.animationData = uni
|
||||||
.createAnimation({
|
.createAnimation({
|
||||||
duration: this.duration / 2,
|
duration: this.duration / 2,
|
||||||
timingFunction: 'ease'
|
timingFunction: 'ease'
|
||||||
})
|
})
|
||||||
.top(this.top - this.radius)
|
.top(this.top - this.radius)
|
||||||
.opacity(0.9)
|
.opacity(0.9)
|
||||||
.step()
|
.step()
|
||||||
.export();
|
.export();
|
||||||
|
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef APP-NVUE
|
// #ifdef APP-NVUE
|
||||||
if (!this.$refs['ani']) return;
|
if (!this.$refs['ani']) return;
|
||||||
animation.transition(this.$refs['ani'].ref, {
|
animation.transition(this.$refs['ani'].ref, {
|
||||||
styles: {
|
styles: {
|
||||||
transform: `translateY(-${this.radius / 2}px)`,
|
transform: `translateY(-${this.radius / 2}px)`,
|
||||||
opacity: 1
|
opacity: 1
|
||||||
},
|
},
|
||||||
duration: this.duration / 2,
|
duration: this.duration / 2,
|
||||||
timingFunction: 'linear',
|
timingFunction: 'linear',
|
||||||
needLayout: false,
|
needLayout: false,
|
||||||
delay: 0
|
delay: 0
|
||||||
});
|
});
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
//停留
|
//停留
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
//消失
|
//消失
|
||||||
// #ifndef APP-NVUE
|
// #ifndef APP-NVUE
|
||||||
this.animationData = uni.createAnimation({
|
this.animationData = uni
|
||||||
duration: this.duration / 2,
|
.createAnimation({
|
||||||
timingFunction: 'ease'
|
duration: this.duration / 2,
|
||||||
}).top(this.top - this.radius * 2).opacity(0).step().export();
|
timingFunction: 'ease'
|
||||||
|
})
|
||||||
// #endif
|
.top(this.top - this.radius * 2)
|
||||||
|
.opacity(0)
|
||||||
// #ifdef APP-NVUE
|
.step()
|
||||||
if (!this.$refs['ani']) return;
|
.export();
|
||||||
animation.transition(this.$refs['ani'].ref, {
|
|
||||||
styles: {
|
// #endif
|
||||||
transform: `translateY(-${this.radius}px)`,
|
|
||||||
opacity: 0
|
// #ifdef APP-NVUE
|
||||||
},
|
if (!this.$refs['ani']) return;
|
||||||
duration: this.duration / 2,
|
animation.transition(this.$refs['ani'].ref, {
|
||||||
timingFunction: 'linear',
|
styles: {
|
||||||
needLayout: false,
|
transform: `translateY(-${this.radius}px)`,
|
||||||
delay: 0
|
opacity: 0
|
||||||
});
|
},
|
||||||
// #endif
|
duration: this.duration / 2,
|
||||||
}, this.wait);
|
timingFunction: 'linear',
|
||||||
|
needLayout: false,
|
||||||
// console.log('this.top', this.top);
|
delay: 0
|
||||||
// console.log('this.radius', this.radius);
|
});
|
||||||
|
// #endif
|
||||||
setTimeout(() => {
|
}, this.wait);
|
||||||
this.animationData = uni.createAnimation({
|
|
||||||
duration: this.duration / 2,
|
// console.log('this.top', this.top);
|
||||||
timingFunction: 'ease'
|
// console.log('this.radius', this.radius);
|
||||||
}).top(this.top).opacity(0).step().export();
|
|
||||||
}, 2800);
|
setTimeout(() => {
|
||||||
},
|
this.animationData = uni
|
||||||
closeTimer() {
|
.createAnimation({
|
||||||
clearInterval(this.timeIndex); //关闭弹幕定时器
|
duration: this.duration / 2,
|
||||||
}
|
timingFunction: 'ease'
|
||||||
}
|
})
|
||||||
};
|
.top(this.top)
|
||||||
</script>
|
.opacity(0)
|
||||||
|
.step()
|
||||||
<style scoped lang="scss">
|
.export();
|
||||||
.message {
|
}, 2800);
|
||||||
position: absolute;
|
},
|
||||||
z-index: 8;
|
closeTimer() {
|
||||||
opacity: 0;
|
clearInterval(this.timeIndex); //关闭弹幕定时器
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.round {
|
};
|
||||||
border-radius: 50px;
|
</script>
|
||||||
}
|
|
||||||
|
<style scoped lang="scss">
|
||||||
.bg-gradual-orange {
|
.message {
|
||||||
background-color: rgba($color: #000, $alpha: 0.4);
|
position: absolute;
|
||||||
color: #fff;
|
z-index: 8;
|
||||||
}
|
opacity: 0;
|
||||||
|
}
|
||||||
.shadow {
|
|
||||||
box-shadow: 40rpx 40rpx 50rpx rgba(217, 109, 26, 0.2);
|
.round {
|
||||||
}
|
border-radius: 50px;
|
||||||
|
}
|
||||||
.flex {
|
|
||||||
/* #ifndef APP-NVUE */
|
.bg-gradual-orange {
|
||||||
display: flex;
|
background-color: rgba($color: #000, $alpha: 0.4);
|
||||||
/* #endif */
|
color: #fff;
|
||||||
flex-direction: row;
|
}
|
||||||
}
|
|
||||||
|
.shadow {
|
||||||
.justify-start {
|
box-shadow: 40rpx 40rpx 50rpx rgba(217, 109, 26, 0.2);
|
||||||
justify-content: flex-start;
|
}
|
||||||
}
|
|
||||||
|
.flex {
|
||||||
.cu-avatar {
|
/* #ifndef APP-NVUE */
|
||||||
/* #ifndef APP-NVUE */
|
display: flex;
|
||||||
font-variant: small-caps;
|
/* #endif */
|
||||||
display: inline-flex;
|
flex-direction: row;
|
||||||
white-space: nowrap;
|
}
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
.justify-start {
|
||||||
vertical-align: middle;
|
justify-content: flex-start;
|
||||||
/* #endif */
|
}
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
.cu-avatar {
|
||||||
text-align: center;
|
/* #ifndef APP-NVUE */
|
||||||
justify-content: center;
|
font-variant: small-caps;
|
||||||
align-items: center;
|
display: inline-flex;
|
||||||
background-color: #ccc;
|
white-space: nowrap;
|
||||||
color: #ffffff;
|
background-size: cover;
|
||||||
position: relative;
|
background-position: center;
|
||||||
width: 300rpx;
|
vertical-align: middle;
|
||||||
height: 300rpx;
|
/* #endif */
|
||||||
font-size: 300rpx;
|
margin: 0;
|
||||||
}
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
/* #ifdef APP-NVUE */
|
justify-content: center;
|
||||||
.avatarimg {
|
align-items: center;
|
||||||
width: 30rpx;
|
background-color: #ccc;
|
||||||
height: 30rpx;
|
color: #ffffff;
|
||||||
border-radius: 50rpx;
|
position: relative;
|
||||||
}
|
width: 300rpx;
|
||||||
|
height: 300rpx;
|
||||||
/* #endif */
|
font-size: 300rpx;
|
||||||
.cu-a-sm {
|
}
|
||||||
width: 60rpx;
|
|
||||||
height: 60rpx;
|
/* #ifdef APP-NVUE */
|
||||||
font-size: 20rpx;
|
.avatarimg {
|
||||||
}
|
width: 30rpx;
|
||||||
|
height: 30rpx;
|
||||||
.padding-lr-sm {
|
border-radius: 50rpx;
|
||||||
padding-left: 20upx;
|
}
|
||||||
padding-right: 20upx;
|
|
||||||
}
|
/* #endif */
|
||||||
|
.cu-a-sm {
|
||||||
.align-center {
|
width: 60rpx;
|
||||||
align-items: center;
|
height: 60rpx;
|
||||||
}
|
font-size: 20rpx;
|
||||||
|
}
|
||||||
.margin-left-xs {
|
|
||||||
margin-left: 10upx;
|
.padding-lr-sm {
|
||||||
}
|
padding-left: 20upx;
|
||||||
|
padding-right: 20upx;
|
||||||
.text-bold {
|
}
|
||||||
font-weight: bold;
|
|
||||||
}
|
.align-center {
|
||||||
|
align-items: center;
|
||||||
.margin-lr-sm {
|
}
|
||||||
margin-left: 20upx;
|
|
||||||
margin-right: 20upx;
|
.margin-left-xs {
|
||||||
}
|
margin-left: 10upx;
|
||||||
|
}
|
||||||
.text-sm {
|
|
||||||
font-size: $font-size-tag;
|
.text-bold {
|
||||||
color: #ffffff;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
.margin-lr-sm {
|
||||||
|
margin-left: 20upx;
|
||||||
|
margin-right: 20upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-sm {
|
||||||
|
font-size: $font-size-tag;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,329 +1,297 @@
|
|||||||
<template>
|
<template>
|
||||||
<view>
|
<view>
|
||||||
<view @touchmove.prevent.stop class="reward-popup" v-if="reward">
|
<view @touchmove.prevent.stop class="reward-popup" v-if="reward">
|
||||||
<uni-popup ref="registerRewardpopup" type="center" :maskClick="false">
|
<uni-popup ref="registerReward" type="center" :maskClick="false">
|
||||||
<view class="reward-wrap">
|
<view class="reward-wrap">
|
||||||
<image :src="$util.img('public/uniapp/register_reward/register_reward_img.png')" mode="widthFix" class="bg-img-head"/>
|
<image :src="$util.img('public/uniapp/register_reward/register_reward_img.png')" mode="widthFix" class="bg-img-head"/>
|
||||||
<image :src="$util.img('public/uniapp/register_reward/register_reward_money.png')" mode="widthFix" class="bg-img-money"/>
|
<image :src="$util.img('public/uniapp/register_reward/register_reward_money.png')" mode="widthFix" class="bg-img-money"/>
|
||||||
<image :src="$util.img('public/uniapp/register_reward/register_reward_head.png')" mode="widthFix" class="bg-img"/>
|
<image :src="$util.img('public/uniapp/register_reward/register_reward_head.png')" mode="widthFix" class="bg-img"/>
|
||||||
<view class="wrap">
|
<view class="wrap">
|
||||||
<view>
|
<view>
|
||||||
<scroll-view scroll-y="true" class="register-box">
|
<scroll-view scroll-y="true" class="register-box">
|
||||||
<view class="reward-content">
|
<view class="reward-content">
|
||||||
<view class="reward-item" v-if="reward.point > 0">
|
<view class="reward-item" v-if="reward.point > 0">
|
||||||
<view class="head">积分奖励</view>
|
<view class="head">积分奖励</view>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<view>
|
<view>
|
||||||
<text class="num">{{ reward.point }}</text>
|
<text class="num">{{ reward.point }}</text>
|
||||||
<text class="type">积分</text>
|
<text class="type">积分</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="desc">用于下单时抵现或兑换商品等</view>
|
<view class="desc">用于下单时抵现或兑换商品等</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="tip" @click="closeRewardPopup('point')">立即查看</view>
|
<view class="tip" @click="closeRewardPopup('point')">立即查看</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="reward-item" v-if="reward.growth > 0">
|
<view class="reward-item" v-if="reward.growth > 0">
|
||||||
<view class="head">成长值</view>
|
<view class="head">成长值</view>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<view>
|
<view>
|
||||||
<text class="num">{{ reward.growth }}</text>
|
<text class="num">{{ reward.growth }}</text>
|
||||||
<text class="type">成长值</text>
|
<text class="type">成长值</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="desc">用于提升会员等级</view>
|
<view class="desc">用于提升会员等级</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="tip" @click="closeRewardPopup('growth')">立即查看</view>
|
<view class="tip" @click="closeRewardPopup('growth')">立即查看</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="reward-item" v-if="reward.balance > 0">
|
<view class="reward-item" v-if="reward.balance > 0">
|
||||||
<view class="head">红包奖励</view>
|
<view class="head">红包奖励</view>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<view>
|
<view>
|
||||||
<text class="num">{{ reward.balance }}</text>
|
<text class="num">{{ reward.balance }}</text>
|
||||||
<text class="type">元</text>
|
<text class="type">元</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="desc">不可提现下单时可用</view>
|
<view class="desc">不可提现下单时可用</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="tip" @click="closeRewardPopup('balance')">立即查看</view>
|
<view class="tip" @click="closeRewardPopup('balance')">立即查看</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="reward-item" v-if="reward.coupon_list.length > 0">
|
<view class="reward-item" v-if="reward.coupon_list.length > 0">
|
||||||
<view class="head">优惠券奖励</view>
|
<view class="head">优惠券奖励</view>
|
||||||
<view class="content" v-for="(item, index) in reward.coupon_list" :key="index">
|
<view class="content" v-for="(item, index) in reward.coupon_list" :key="index">
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<view>
|
<view>
|
||||||
<text class="num coupon-name">{{ item.coupon_name }}</text>
|
<text class="num coupon-name">{{ item.coupon_name }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="desc" v-if="item.at_least > 0">
|
<view class="desc" v-if="item.at_least > 0">
|
||||||
满{{ item.at_least }}{{ item.type == 'discount' ? '打' + item.discount + '折' : '减' + item.money }}
|
满{{ item.at_least }}{{ item.type == 'discount' ? '打' + item.discount + '折' : '减' + item.money }}
|
||||||
</view>
|
</view>
|
||||||
<view class="desc" v-else>
|
<view class="desc" v-else>
|
||||||
无门槛,{{ item.type == 'discount' ? '打' + item.discount + '折' : '减' + item.money }}
|
无门槛,{{ item.type == 'discount' ? '打' + item.discount + '折' : '减' + item.money }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="tip" @click="closeRewardPopup('coupon')">立即查看</view>
|
<view class="tip" @click="closeRewardPopup('coupon')">立即查看</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="close-btn" @click="closeRewardPopup()"><text class="iconfont icon-close"></text></view>
|
<view class="close-btn" @click="closeRewardPopup()"><text class="iconfont icon-close"></text></view>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import uniPopup from '@/components/uni-popup/uni-popup.vue';
|
import uniPopup from '@/components/uni-popup/uni-popup.vue';
|
||||||
|
|
||||||
// 注册奖励弹出层
|
// 注册奖励弹出层
|
||||||
export default {
|
export default {
|
||||||
name: 'register-reward',
|
name: 'register-reward',
|
||||||
components: {
|
components: {
|
||||||
uniPopup
|
uniPopup
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
reward: null,
|
reward: null,
|
||||||
back: '',
|
back: ''
|
||||||
path: '',
|
};
|
||||||
};
|
},
|
||||||
},
|
created() {},
|
||||||
created() {
|
methods: {
|
||||||
let pages = getCurrentPages();
|
open(back) {
|
||||||
let currentPage = pages[pages.length - 1].route;
|
if (back) this.back = back;
|
||||||
this.path = '/'+currentPage;
|
if (this.addonIsExist.memberregister) {
|
||||||
|
this.getRegisterReward();
|
||||||
},
|
} else {
|
||||||
watch: {
|
this.closeRewardPopup();
|
||||||
'canReceiveRegistergift': {
|
}
|
||||||
handler(newValue, oldValue) {
|
},
|
||||||
if (newValue.status && newValue.status != oldValue.status && newValue.path.split('?')[0] == this.path) {
|
cancel() {
|
||||||
this.$store.commit('setCanReceiveRegistergiftInfo',{status:false,path:''});
|
this.$refs.registerReward.close();
|
||||||
// this.$nextTick(()=>{
|
},
|
||||||
this.open()
|
/**
|
||||||
// })
|
* 获取新人礼配置
|
||||||
}
|
*/
|
||||||
},
|
getRegisterReward() {
|
||||||
deep: true
|
this.$api.sendRequest({
|
||||||
}
|
url: '/memberregister/api/Config/Config',
|
||||||
},
|
success: res => {
|
||||||
computed: {
|
if (res.code >= 0) {
|
||||||
canReceiveRegistergift() {
|
let data = res.data;
|
||||||
return this.$store.state.canReceiveRegistergiftInfo;
|
if (data.is_use == 1 && (data.value.point > 0 || data.value.balance > 0 || data
|
||||||
},
|
.value.growth > 0 || data.value.coupon_list.length > 0)) {
|
||||||
},
|
this.reward = data.value;
|
||||||
methods: {
|
this.$nextTick(() => {
|
||||||
open(back) {
|
if(this.$refs.registerReward) this.$refs.registerReward.open();
|
||||||
if (back) this.back = back;
|
});
|
||||||
if (this.addonIsExist.memberregister) {
|
}
|
||||||
this.getRegisterReward();
|
}
|
||||||
} else {
|
this.closeRewardPopup();
|
||||||
this.closeRewardPopup();
|
}
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
cancel() {
|
closeRewardPopup(type) {
|
||||||
this.$refs.registerRewardpopup.close();
|
if (this.$refs.registerReward) this.$refs.registerReward.close();
|
||||||
},
|
switch (type) {
|
||||||
/**
|
case 'point':
|
||||||
* 获取新人礼配置
|
this.$util.redirectTo('/pages_tool/member/point_detail', {});
|
||||||
*/
|
break;
|
||||||
getRegisterReward() {
|
case 'balance':
|
||||||
this.$api.sendRequest({
|
this.$util.redirectTo('/pages_tool/member/balance_detail', {});
|
||||||
url: '/memberregister/api/Config/Config',
|
break;
|
||||||
success: res => {
|
case 'growth':
|
||||||
if (res.code >= 0) {
|
this.$util.redirectTo('/pages_tool/member/level', {});
|
||||||
let data = res.data;
|
break;
|
||||||
if (data.is_use == 1 && (data.value.point > 0 || data.value.balance > 0 || data.value.growth > 0 || data.value.coupon_list.length > 0)) {
|
case 'coupon':
|
||||||
this.reward = data.value;
|
this.$util.redirectTo('/pages_tool/member/coupon', {});
|
||||||
this.$forceUpdate()
|
break;
|
||||||
this.$nextTick(()=>{
|
default:
|
||||||
setTimeout(() => {
|
if (this.back) this.$util.redirectTo(decodeURIComponent(this.back), {}, 'redirectTo');
|
||||||
this.$refs.registerRewardpopup.open();
|
else this.$util.redirectTo('/pages/index/index');
|
||||||
});
|
break;
|
||||||
})
|
}
|
||||||
|
}
|
||||||
} else {
|
}
|
||||||
this.closeRewardPopup();
|
};
|
||||||
}
|
</script>
|
||||||
}else{
|
<style scoped>
|
||||||
this.closeRewardPopup();
|
.register-box /deep/ .uni-scroll-view {
|
||||||
}
|
background: unset !important;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
},
|
.register-box {
|
||||||
closeRewardPopup(type) {
|
max-height: 630rpx;
|
||||||
if (this.$refs.registerRewardpopup) this.$refs.registerRewardpopup.close();
|
overflow-y: scroll;
|
||||||
if(!type) return;
|
}
|
||||||
switch (type) {
|
|
||||||
case 'point':
|
.register-box /deep/.uni-popup__wrapper-box {
|
||||||
this.$util.redirectTo('/pages_tool/member/point_detail', {});
|
overflow: unset !important;
|
||||||
break;
|
}
|
||||||
case 'balance':
|
|
||||||
this.$util.redirectTo('/pages_tool/member/balance_detail', {});
|
.reward-popup /deep/.uni-popup__wrapper {
|
||||||
break;
|
background: none;
|
||||||
case 'growth':
|
}
|
||||||
this.$util.redirectTo('/pages_tool/member/level', {});
|
</style>
|
||||||
break;
|
|
||||||
case 'coupon':
|
<style lang="scss">
|
||||||
this.$util.redirectTo('/pages_tool/member/coupon', {});
|
.uni-popup__wrapper-box {
|
||||||
break;
|
overflow: unset !important;
|
||||||
default:
|
}
|
||||||
this.$util.loginComplete('/pages/index/index','redirectTo');
|
|
||||||
// if (this.back) this.$util.redirectTo(decodeURIComponent(this.back), {}, 'redirectTo');
|
.close-btn {
|
||||||
// else this.$util.redirectTo('/pages/index/index');
|
text-align: center;
|
||||||
break;
|
margin-top: 20rpx;
|
||||||
}
|
|
||||||
}
|
.iconfont {
|
||||||
}
|
color: #fff;
|
||||||
};
|
font-size: 40rpx;
|
||||||
</script>
|
}
|
||||||
<style scoped>
|
}
|
||||||
.register-box /deep/ .uni-scroll-view {
|
|
||||||
background: unset !important;
|
.reward-wrap {
|
||||||
}
|
width: 80vw;
|
||||||
|
height: auto;
|
||||||
.register-box {
|
position: relative;
|
||||||
max-height: 630rpx;
|
// padding-top: 150rpx;
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
&>uni-image,
|
||||||
|
.bg-img {
|
||||||
.register-box /deep/.uni-popup__wrapper-box {
|
width: 100%;
|
||||||
overflow: unset !important;
|
will-change: transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reward-popup /deep/.uni-popup__wrapper {
|
.bg-img-head {
|
||||||
background: none;
|
position: absolute;
|
||||||
}
|
top: -150rpx;
|
||||||
</style>
|
width: 100vw;
|
||||||
|
left: -10vw;
|
||||||
<style lang="scss">
|
}
|
||||||
.uni-popup__wrapper-box {
|
|
||||||
overflow: unset !important;
|
.bg-img-money {
|
||||||
}
|
position: absolute;
|
||||||
|
width: 93vw;
|
||||||
.close-btn {
|
left: -48rpx;
|
||||||
text-align: center;
|
top: 100rpx;
|
||||||
margin-top: 20rpx;
|
z-index: 10;
|
||||||
|
}
|
||||||
.iconfont {
|
|
||||||
color: #fff;
|
.wrap {
|
||||||
font-size: 40rpx;
|
width: calc(100% - 2rpx);
|
||||||
}
|
height: 100%;
|
||||||
}
|
background-color: #ef3030;
|
||||||
|
margin-top: -80rpx;
|
||||||
.reward-wrap {
|
padding-bottom: 30rpx;
|
||||||
width: 80vw;
|
border-bottom-left-radius: 10rpx;
|
||||||
height: auto;
|
border-bottom-right-radius: 10rpx;
|
||||||
position: relative;
|
|
||||||
// padding-top: 150rpx;
|
&>view {
|
||||||
|
position: relative;
|
||||||
&>uni-image,
|
}
|
||||||
.bg-img {
|
}
|
||||||
width: 100%;
|
|
||||||
will-change: transform;
|
.reward-content {
|
||||||
}
|
margin: 0 50rpx 0 50rpx;
|
||||||
|
}
|
||||||
.bg-img-head {
|
|
||||||
position: absolute;
|
.reward-item {
|
||||||
top: -150rpx;
|
.head {
|
||||||
width: 100vw;
|
color: #fff;
|
||||||
left: -10vw;
|
text-align: center;
|
||||||
}
|
line-height: 1;
|
||||||
|
margin: 20rpx 0;
|
||||||
.bg-img-money {
|
}
|
||||||
position: absolute;
|
|
||||||
width: 93vw;
|
.content {
|
||||||
left: -48rpx;
|
display: flex;
|
||||||
top: 100rpx;
|
padding: 16rpx 26rpx;
|
||||||
z-index: 10;
|
background: #fff;
|
||||||
}
|
border-radius: 10rpx;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
.wrap {
|
|
||||||
width: calc(100% - 2rpx);
|
.info {
|
||||||
height: 100%;
|
flex: 1;
|
||||||
background-color: #ef3030;
|
}
|
||||||
margin-top: -80rpx;
|
|
||||||
padding-bottom: 30rpx;
|
.tip {
|
||||||
border-bottom-left-radius: 10rpx;
|
color: #ff222d;
|
||||||
border-bottom-right-radius: 10rpx;
|
padding: 10rpx 0 10rpx 30rpx;
|
||||||
|
width: 70rpx;
|
||||||
&>view {
|
line-height: 1.5;
|
||||||
position: relative;
|
letter-spacing: 2rpx;
|
||||||
}
|
border-left: 2rpx dashed #e5e5e5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reward-content {
|
.num {
|
||||||
margin: 0 50rpx 0 50rpx;
|
font-size: 52rpx;
|
||||||
}
|
color: #ff222d;
|
||||||
|
font-weight: bolder;
|
||||||
.reward-item {
|
line-height: 1;
|
||||||
.head {
|
}
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
.coupon-name {
|
||||||
line-height: 1;
|
font-size: 38rpx;
|
||||||
margin: 20rpx 0;
|
}
|
||||||
}
|
|
||||||
|
.type {
|
||||||
.content {
|
font-size: $font-size-base;
|
||||||
display: flex;
|
margin-left: 10rpx;
|
||||||
padding: 16rpx 26rpx;
|
line-height: 1;
|
||||||
background: #fff;
|
}
|
||||||
border-radius: 10rpx;
|
|
||||||
margin-bottom: 10rpx;
|
.desc {
|
||||||
|
margin-top: 8rpx;
|
||||||
.info {
|
color: $color-tip;
|
||||||
flex: 1;
|
font-size: $font-size-tag;
|
||||||
}
|
line-height: 1;
|
||||||
|
}
|
||||||
.tip {
|
}
|
||||||
color: #ff222d;
|
}
|
||||||
padding: 10rpx 0 10rpx 30rpx;
|
|
||||||
width: 70rpx;
|
.btn {
|
||||||
line-height: 1.5;
|
position: absolute;
|
||||||
letter-spacing: 2rpx;
|
width: calc(100% - 100rpx);
|
||||||
border-left: 2rpx dashed #e5e5e5;
|
bottom: 40rpx;
|
||||||
}
|
left: 50rpx;
|
||||||
|
|
||||||
.num {
|
.btn-img {
|
||||||
font-size: 52rpx;
|
width: 100%;
|
||||||
color: #ff222d;
|
}
|
||||||
font-weight: bolder;
|
}
|
||||||
line-height: 1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.coupon-name {
|
|
||||||
font-size: 38rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.type {
|
|
||||||
font-size: $font-size-base;
|
|
||||||
margin-left: 10rpx;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.desc {
|
|
||||||
margin-top: 8rpx;
|
|
||||||
color: $color-tip;
|
|
||||||
font-size: $font-size-tag;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
position: absolute;
|
|
||||||
width: calc(100% - 100rpx);
|
|
||||||
bottom: 40rpx;
|
|
||||||
left: 50rpx;
|
|
||||||
|
|
||||||
.btn-img {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1,91 +1,95 @@
|
|||||||
<template>
|
<template>
|
||||||
<view>
|
<view>
|
||||||
<view :id="elId" :class="{ border: showBorder }" :style="{ 'border-left': showBorder ? '1px ' + borderColor + ' solid' : 'none' }" class="uni-grid">
|
<view :id="elId" :class="{ border: showBorder }" :style="{ 'border-left': showBorder ? '1px ' + borderColor + ' solid' : 'none' }" class="uni-grid">
|
||||||
<slot />
|
<slot />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'UniGrid',
|
name: 'UniGrid',
|
||||||
props: {
|
props: {
|
||||||
// 每列显示个数
|
// 每列显示个数
|
||||||
column: {
|
column: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 3
|
default: 3
|
||||||
},
|
},
|
||||||
// 是否显示边框
|
// 是否显示边框
|
||||||
showBorder: {
|
showBorder: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
// 是否显示边框
|
// 是否显示边框
|
||||||
borderColor: {
|
borderColor: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '#e5e5e5'
|
default: '#e5e5e5'
|
||||||
},
|
},
|
||||||
// 全局标记水平方向移动距离 ,起点为中心,负数为左移动,正数为右移动
|
// 全局标记水平方向移动距离 ,起点为中心,负数为左移动,正数为右移动
|
||||||
hor: {
|
hor: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
// 全局标记垂直方向移动距离 ,起点为中心,负数为上移动,正数为下移动
|
// 全局标记垂直方向移动距离 ,起点为中心,负数为上移动,正数为下移动
|
||||||
ver: {
|
ver: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
// 是否正方形显示,默认为 true
|
// 是否正方形显示,默认为 true
|
||||||
square: {
|
square: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
highlight: {
|
highlight: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
provide() {
|
provide() {
|
||||||
return {
|
return {
|
||||||
grid: this
|
grid: this
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`;
|
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`;
|
||||||
return {
|
return {
|
||||||
index: 0,
|
index: 0,
|
||||||
elId
|
elId
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.index = 0;
|
this.index = 0;
|
||||||
this.childrens = [];
|
this.childrens = [];
|
||||||
this.pIndex = this.pIndex ? this.pIndex++ : 0;
|
this.pIndex = this.pIndex ? this.pIndex++ : 0;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
change(e) {
|
change(e) {
|
||||||
this.$emit('change', e);
|
this.$emit('change', e);
|
||||||
},
|
},
|
||||||
_getSize(fn) {
|
_getSize(fn) {
|
||||||
uni.createSelectorQuery().in(this).select(`#${this.elId}`).boundingClientRect().exec(ret => {
|
uni.createSelectorQuery()
|
||||||
if (!ret[0]) {
|
.in(this)
|
||||||
setTimeout(this._getSize(fn));
|
.select(`#${this.elId}`)
|
||||||
return;
|
.boundingClientRect()
|
||||||
}
|
.exec(ret => {
|
||||||
let width = (parseInt(ret[0].width / this.column) - 1) * 2 + 'rpx';
|
if (!ret[0]) {
|
||||||
typeof fn === 'function' && fn(width);
|
setTimeout(this._getSize(fn));
|
||||||
});
|
return;
|
||||||
}
|
}
|
||||||
}
|
let width = (parseInt(ret[0].width / this.column) - 1) * 2 + 'rpx';
|
||||||
};
|
typeof fn === 'function' && fn(width);
|
||||||
</script>
|
});
|
||||||
|
}
|
||||||
<style>
|
}
|
||||||
|
};
|
||||||
.uni-grid {
|
</script>
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
<style>
|
||||||
box-sizing: border-box;
|
|
||||||
border-left: 2rpx #e5e5e5 solid;
|
.uni-grid {
|
||||||
}
|
display: flex;
|
||||||
</style>
|
flex-wrap: wrap;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-left: 2rpx #e5e5e5 solid;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,263 +1,261 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="uni-numbox" :class="{ small: size == 'small' }">
|
<view class="uni-numbox" :class="{ small: size == 'small' }">
|
||||||
<button type="default" class="decrease" :class="{ disabled: inputValue <= min || disabled, small: size == 'small' }" @click="_calcValue('minus')">-</button>
|
<button type="default" class="decrease" :class="{ disabled: inputValue <= min || disabled, small: size == 'small' }" @click="_calcValue('minus')">-</button>
|
||||||
<!-- <view
|
<!-- <view
|
||||||
class="uni-numbox__minus"
|
class="uni-numbox__minus"
|
||||||
> -->
|
> -->
|
||||||
<!-- :style="'background-image:url(' + $util.img('public/uniapp/jian.png') + ')'" -->
|
<!-- :style="'background-image:url(' + $util.img('public/uniapp/jian.png') + ')'" -->
|
||||||
<!-- </view> -->
|
<!-- </view> -->
|
||||||
<!-- <input :disabled="disabled || inputDisabled" class="uni-input uni-numbox__value" type="number" @input="_onInput" @blur="_onInput" :class="{ small: size == 'small' }" v-model="inputValue"/> -->
|
<!-- <input :disabled="disabled || inputDisabled" class="uni-input uni-numbox__value" type="number" @input="_onInput" @blur="_onInput" :class="{ small: size == 'small' }" v-model="inputValue"/> -->
|
||||||
<input :disabled="disabled || inputDisabled" class="uni-input uni-numbox__value" type="number" @blur="_onInput" :class="{ small: size == 'small' }" v-model="inputValue" />
|
<input :disabled="disabled || inputDisabled" class="uni-input uni-numbox__value" type="number" @blur="_onInput" :class="{ small: size == 'small' }" v-model="inputValue" />
|
||||||
<button type="default" class="increase" :class="{ disabled: inputValue >= max || disabled, small: size == 'small' }" @click="_calcValue('plus')">+</button>
|
<button type="default" class="increase" :class="{ disabled: inputValue >= max || disabled, small: size == 'small' }" @click="_calcValue('plus')">+</button>
|
||||||
<!-- <view
|
<!-- <view
|
||||||
class="uni-numbox__plus" @click="_calcValue('plus')"
|
class="uni-numbox__plus" @click="_calcValue('plus')"
|
||||||
:style="'background-image:url(' + $util.img('public/uniapp/jia.png') + ')'"
|
:style="'background-image:url(' + $util.img('public/uniapp/jia.png') + ')'"
|
||||||
>
|
>
|
||||||
</view> -->
|
</view> -->
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'UniNumberBox',
|
name: 'UniNumberBox',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: 1
|
default: 1
|
||||||
},
|
},
|
||||||
min: {
|
min: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
max: {
|
max: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 100
|
default: 100
|
||||||
},
|
},
|
||||||
step: {
|
step: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 1
|
default: 1
|
||||||
},
|
},
|
||||||
disabled: {
|
disabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
inputDisabled: {
|
inputDisabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'default'
|
default: 'default'
|
||||||
},
|
},
|
||||||
index: {
|
index: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: -1
|
default: -1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
inputValue: 0,
|
inputValue: 0,
|
||||||
initialValue: 0, // 初始值,防止第一次触发变化
|
initialValue: 0, // 初始值,防止第一次触发变化
|
||||||
initialIndex: 0, // 初始索引,防止第一次触发变化
|
initialIndex: 0, // 初始索引,防止第一次触发变化
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value(val) {
|
value(val) {
|
||||||
this.inputValue = +val;
|
this.inputValue = +val;
|
||||||
},
|
},
|
||||||
inputValue(newVal, oldVal, params) {
|
inputValue(newVal, oldVal, params) {
|
||||||
// 与初始值相同,不允许操作
|
// 与初始值相同,不允许操作
|
||||||
if (+newVal != 0 && +newVal == this.initialValue) return;
|
if (+newVal != 0 && +newVal == this.initialValue) return;
|
||||||
|
|
||||||
// 索引不同,不允许操作
|
// 索引不同,不允许操作
|
||||||
if (this.initialIndex != this.index) return;
|
if (this.initialIndex != this.index) return;
|
||||||
|
|
||||||
if (+newVal !== +oldVal) {
|
if (+newVal !== +oldVal) {
|
||||||
this.$emit('change', newVal, params);
|
this.$emit('change', newVal, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initialValue = +this.value;
|
this.initialValue = +this.value;
|
||||||
this.inputValue = +this.value;
|
this.inputValue = +this.value;
|
||||||
this.initialIndex = this.index;
|
this.initialIndex = this.index;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
_calcValue(type) {
|
_calcValue(type) {
|
||||||
if (this.disabled) {
|
if (this.disabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const scale = this._getDecimalScale();
|
const scale = this._getDecimalScale();
|
||||||
let value = this.inputValue * scale;
|
let value = this.inputValue * scale;
|
||||||
let step = this.step * scale;
|
let step = this.step * scale;
|
||||||
if (type === 'minus') {
|
if (type === 'minus') {
|
||||||
value -= step;
|
value -= step;
|
||||||
} else if (type === 'plus') {
|
} else if (type === 'plus') {
|
||||||
value += step;
|
value += step;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value < this.min && type === 'minus') {
|
if (value < this.min && type === 'minus') {
|
||||||
this.$emit('limit', {
|
this.$emit('limit', {
|
||||||
value: this.inputValue,
|
value: this.inputValue,
|
||||||
type
|
type
|
||||||
}, this.index);
|
}, this.index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value > this.max && type === 'plus') {
|
if (value > this.max && type === 'plus') {
|
||||||
this.$emit('limit', {
|
this.$emit('limit', {
|
||||||
value: this.inputValue,
|
value: this.inputValue,
|
||||||
type
|
type
|
||||||
}, this.index);
|
}, this.index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.inputValue = value / scale;
|
this.inputValue = value / scale;
|
||||||
this.$emit('change', this.inputValue);
|
},
|
||||||
},
|
_getDecimalScale() {
|
||||||
_getDecimalScale() {
|
let scale = 1;
|
||||||
let scale = 1;
|
// 浮点型
|
||||||
// 浮点型
|
if (~~this.step !== this.step) {
|
||||||
if (~~this.step !== this.step) {
|
scale = Math.pow(10, (this.step + '').split('.')[1].length);
|
||||||
scale = Math.pow(10, (this.step + '').split('.')[1].length);
|
}
|
||||||
}
|
return scale;
|
||||||
return scale;
|
},
|
||||||
},
|
_onInput(event) {
|
||||||
_onInput(event) {
|
setTimeout(() => {
|
||||||
setTimeout(() => {
|
let value = event.detail.value;
|
||||||
let value = event.detail.value;
|
// if (!/(^[1-9]\d*$)/.test(value)) value = this.min;
|
||||||
// if (!/(^[1-9]\d*$)/.test(value)) value = this.min;
|
// if (!value) {
|
||||||
// if (!value) {
|
// this.inputValue = 0;
|
||||||
// this.inputValue = 0;
|
// return;
|
||||||
// return;
|
// }
|
||||||
// }
|
value = +value;
|
||||||
value = +value;
|
|
||||||
|
if (value > this.max) {
|
||||||
if (value > this.max) {
|
value = this.max;
|
||||||
value = this.max;
|
this.$util.showToast({
|
||||||
this.$util.showToast({
|
title: '商品库存不足'
|
||||||
title: '商品库存不足'
|
});
|
||||||
});
|
} else if (value < this.min) {
|
||||||
} else if (value < this.min) {
|
this.$util.showToast({
|
||||||
this.$util.showToast({
|
title: '商品最少购买' + this.min + '件'
|
||||||
title: '商品最少购买' + this.min + '件'
|
});
|
||||||
});
|
value = this.min;
|
||||||
value = this.min;
|
}
|
||||||
}
|
// 如果没有最小购买,同时也删除了输入框的内容,默认赋值为1
|
||||||
// 如果没有最小购买,同时也删除了输入框的内容,默认赋值为1
|
if (!value) value = 1;
|
||||||
if (!value) value = 1;
|
|
||||||
|
this.inputValue = value;
|
||||||
this.inputValue = value;
|
this.$forceUpdate();
|
||||||
this.$forceUpdate();
|
}, 0);
|
||||||
this.$emit('change', value);
|
}
|
||||||
}, 0);
|
}
|
||||||
}
|
};
|
||||||
}
|
</script>
|
||||||
};
|
<style lang="scss">
|
||||||
</script>
|
.uni-numbox {
|
||||||
<style lang="scss">
|
display: inline-flex;
|
||||||
.uni-numbox {
|
flex-direction: row;
|
||||||
display: inline-flex;
|
justify-content: flex-start;
|
||||||
flex-direction: row;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
height: 70rpx;
|
||||||
align-items: center;
|
position: relative;
|
||||||
height: 70rpx;
|
}
|
||||||
position: relative;
|
|
||||||
}
|
.uni-numbox.small {
|
||||||
|
height: 44rpx;
|
||||||
.uni-numbox.small {
|
}
|
||||||
height: 44rpx;
|
|
||||||
}
|
.uni-numbox:after {
|
||||||
|
content: '';
|
||||||
.uni-numbox:after {
|
position: absolute;
|
||||||
content: '';
|
transform-origin: center;
|
||||||
position: absolute;
|
box-sizing: border-box;
|
||||||
transform-origin: center;
|
pointer-events: none;
|
||||||
box-sizing: border-box;
|
top: -50%;
|
||||||
pointer-events: none;
|
left: -50%;
|
||||||
top: -50%;
|
right: -50%;
|
||||||
left: -50%;
|
bottom: -50%;
|
||||||
right: -50%;
|
border-radius: 12rpx;
|
||||||
bottom: -50%;
|
transform: scale(0.5);
|
||||||
border-radius: 12rpx;
|
}
|
||||||
transform: scale(0.5);
|
|
||||||
}
|
.uni-numbox__minus,
|
||||||
|
.uni-numbox__plus {
|
||||||
.uni-numbox__minus,
|
width: 40rpx;
|
||||||
.uni-numbox__plus {
|
height: 40rpx;
|
||||||
width: 40rpx;
|
border-radius: 50%;
|
||||||
height: 40rpx;
|
background-size: 100% 100%;
|
||||||
border-radius: 50%;
|
background-position: center;
|
||||||
background-size: 100% 100%;
|
}
|
||||||
background-position: center;
|
|
||||||
}
|
.uni-numbox__value {
|
||||||
|
position: relative;
|
||||||
.uni-numbox__value {
|
background-color: $color-bg;
|
||||||
position: relative;
|
width: 80rpx;
|
||||||
background-color: $color-bg;
|
height: 40rpx;
|
||||||
width: 80rpx;
|
text-align: center;
|
||||||
height: 40rpx;
|
border: 1px solid $color-line;
|
||||||
text-align: center;
|
display: inline-block;
|
||||||
border: 1px solid $color-line;
|
line-height: 36rpx;
|
||||||
display: inline-block;
|
font-weight: bold;
|
||||||
line-height: 36rpx;
|
margin: 0;
|
||||||
font-weight: bold;
|
padding: 0;
|
||||||
margin: 0;
|
vertical-align: top;
|
||||||
padding: 0;
|
min-height: initial;
|
||||||
vertical-align: top;
|
border-left: none;
|
||||||
min-height: initial;
|
border-right: none;
|
||||||
border-left: none;
|
}
|
||||||
border-right: none;
|
|
||||||
}
|
.uni-numbox__value.small {
|
||||||
|
width: 60rpx;
|
||||||
.uni-numbox__value.small {
|
font-size: $font-size-tag;
|
||||||
width: 60rpx;
|
}
|
||||||
font-size: $font-size-tag;
|
|
||||||
}
|
.uni-numbox__value:after {
|
||||||
|
content: '';
|
||||||
.uni-numbox__value:after {
|
position: absolute;
|
||||||
content: '';
|
transform-origin: center;
|
||||||
position: absolute;
|
box-sizing: border-box;
|
||||||
transform-origin: center;
|
pointer-events: none;
|
||||||
box-sizing: border-box;
|
top: -50%;
|
||||||
pointer-events: none;
|
left: -50%;
|
||||||
top: -50%;
|
right: -50%;
|
||||||
left: -50%;
|
bottom: -50%;
|
||||||
right: -50%;
|
border-top-width: 0;
|
||||||
bottom: -50%;
|
border-bottom-width: 0;
|
||||||
border-top-width: 0;
|
transform: scale(0.5);
|
||||||
border-bottom-width: 0;
|
}
|
||||||
transform: scale(0.5);
|
|
||||||
}
|
.uni-numbox--disabled {
|
||||||
|
color: silver;
|
||||||
.uni-numbox--disabled {
|
}
|
||||||
color: silver;
|
|
||||||
}
|
.uni-numbox button {
|
||||||
|
width: 40rpx;
|
||||||
.uni-numbox button {
|
height: 40rpx;
|
||||||
width: 40rpx;
|
display: inline-block;
|
||||||
height: 40rpx;
|
box-sizing: content-box;
|
||||||
display: inline-block;
|
border: 1px solid $color-line;
|
||||||
box-sizing: content-box;
|
padding: 0;
|
||||||
border: 1px solid $color-line;
|
margin: 0;
|
||||||
padding: 0;
|
border-radius: 0;
|
||||||
margin: 0;
|
background-color: #fff;
|
||||||
border-radius: 0;
|
font-weight: bold;
|
||||||
background-color: #fff;
|
|
||||||
font-weight: bold;
|
&.disabled {
|
||||||
|
color: $color-line;
|
||||||
&.disabled {
|
background-color: #f8f8f8 !important;
|
||||||
color: $color-line;
|
}
|
||||||
background-color: #f8f8f8 !important;
|
|
||||||
}
|
&.decrease {
|
||||||
|
font-size: 44rpx;
|
||||||
&.decrease {
|
line-height: 32rpx;
|
||||||
font-size: 44rpx;
|
}
|
||||||
line-height: 32rpx;
|
|
||||||
}
|
&.increase {
|
||||||
|
font-size: $font-size-toolbar;
|
||||||
&.increase {
|
line-height: 36rpx;
|
||||||
font-size: $font-size-toolbar;
|
}
|
||||||
line-height: 36rpx;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1,243 +1,244 @@
|
|||||||
<template>
|
<template>
|
||||||
<view v-if="showPopup" class="uni-popup" :class="customClass" :style="{'top': top}">
|
<view v-if="showPopup" class="uni-popup" :class="customClass" :style="{'top': top}">
|
||||||
<view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" ></view>
|
<view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" ></view>
|
||||||
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup safe-area" @click="close(true)" v-if="isIphoneX">
|
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup safe-area" @click="close(true)" v-if="isIphoneX">
|
||||||
<view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear">
|
<view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear">
|
||||||
<slot />
|
<slot />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup" @click="close(true)" v-else>
|
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup" @click="close(true)" v-else>
|
||||||
<view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear">
|
<view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear">
|
||||||
<slot />
|
<slot />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'UniPopup',
|
name: 'UniPopup',
|
||||||
props: {
|
props: {
|
||||||
// 开启动画
|
// 开启动画
|
||||||
animation: {
|
animation: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
|
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'center'
|
default: 'center'
|
||||||
},
|
},
|
||||||
// 是否开启自定义
|
// 是否开启自定义
|
||||||
custom: {
|
custom: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
maskClick: {
|
// maskClick
|
||||||
type: Boolean,
|
maskClick: {
|
||||||
default: true
|
type: Boolean,
|
||||||
},
|
default: true
|
||||||
show: {
|
},
|
||||||
type: Boolean,
|
show: {
|
||||||
default: true
|
type: Boolean,
|
||||||
},
|
default: true
|
||||||
top: {
|
},
|
||||||
type: String,
|
top: {
|
||||||
default: '0'
|
type: String,
|
||||||
},
|
default: '0'
|
||||||
customClass: {
|
},
|
||||||
type: String,
|
customClass: {
|
||||||
default: ''
|
type: String,
|
||||||
}
|
default: ''
|
||||||
},
|
}
|
||||||
data() {
|
},
|
||||||
return {
|
data() {
|
||||||
ani: '',
|
return {
|
||||||
showPopup: false,
|
ani: '',
|
||||||
callback: null,
|
showPopup: false,
|
||||||
isIphoneX: false
|
callback: null,
|
||||||
};
|
isIphoneX: false
|
||||||
},
|
};
|
||||||
watch: {
|
},
|
||||||
show(newValue) {
|
watch: {
|
||||||
if (newValue) {
|
show(newValue) {
|
||||||
this.open();
|
if (newValue) {
|
||||||
} else {
|
this.open();
|
||||||
this.close();
|
} else {
|
||||||
}
|
this.close();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
created() {
|
},
|
||||||
this.isIphoneX = this.$util.uniappIsIPhoneX();
|
created() {
|
||||||
},
|
this.isIphoneX = this.$util.uniappIsIPhoneX();
|
||||||
methods: {
|
},
|
||||||
clear() {},
|
methods: {
|
||||||
open(callback) {
|
clear() {},
|
||||||
if (callback) this.callback = callback;
|
open(callback) {
|
||||||
|
if (callback) this.callback = callback;
|
||||||
this.$emit('change', {
|
|
||||||
show: true
|
this.$emit('change', {
|
||||||
});
|
show: true
|
||||||
this.showPopup = true;
|
});
|
||||||
this.$nextTick(() => {
|
this.showPopup = true;
|
||||||
setTimeout(() => {
|
this.$nextTick(() => {
|
||||||
this.ani = 'uni-' + this.type;
|
setTimeout(() => {
|
||||||
}, 30);
|
this.ani = 'uni-' + this.type;
|
||||||
});
|
}, 30);
|
||||||
},
|
});
|
||||||
close(type, callback) {
|
},
|
||||||
if (!this.maskClick && type) return;
|
close(type, callback) {
|
||||||
this.$emit('change', {
|
if (!this.maskClick && type) return;
|
||||||
show: false
|
this.$emit('change', {
|
||||||
});
|
show: false
|
||||||
this.ani = '';
|
});
|
||||||
this.$nextTick(() => {
|
this.ani = '';
|
||||||
setTimeout(() => {
|
this.$nextTick(() => {
|
||||||
this.showPopup = false;
|
setTimeout(() => {
|
||||||
}, 300);
|
this.showPopup = false;
|
||||||
});
|
}, 300);
|
||||||
|
});
|
||||||
if (callback) callback();
|
|
||||||
|
if (callback) callback();
|
||||||
if (this.callback) this.callback.call(this);
|
|
||||||
}
|
if (this.callback) this.callback.call(this);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
};
|
||||||
<style>
|
</script>
|
||||||
.uni-popup {
|
<style>
|
||||||
position: fixed;
|
.uni-popup {
|
||||||
top: 0;
|
position: fixed;
|
||||||
bottom: 0;
|
top: 0;
|
||||||
left: 0;
|
bottom: 0;
|
||||||
right: 0;
|
left: 0;
|
||||||
z-index: 999;
|
right: 0;
|
||||||
overflow: hidden;
|
z-index: 999;
|
||||||
}
|
overflow: hidden;
|
||||||
|
}
|
||||||
.uni-popup__mask {
|
|
||||||
position: absolute;
|
.uni-popup__mask {
|
||||||
top: 0;
|
position: absolute;
|
||||||
bottom: 0;
|
top: 0;
|
||||||
left: 0;
|
bottom: 0;
|
||||||
right: 0;
|
left: 0;
|
||||||
z-index: 998;
|
right: 0;
|
||||||
background: rgba(0, 0, 0, 0.4);
|
z-index: 998;
|
||||||
opacity: 0;
|
background: rgba(0, 0, 0, 0.4);
|
||||||
}
|
opacity: 0;
|
||||||
|
}
|
||||||
.uni-popup__mask.ani {
|
|
||||||
transition: all 0.3s;
|
.uni-popup__mask.ani {
|
||||||
}
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
.uni-popup__mask.uni-bottom,
|
|
||||||
.uni-popup__mask.uni-center,
|
.uni-popup__mask.uni-bottom,
|
||||||
.uni-popup__mask.uni-right,
|
.uni-popup__mask.uni-center,
|
||||||
.uni-popup__mask.uni-left,
|
.uni-popup__mask.uni-right,
|
||||||
.uni-popup__mask.uni-top {
|
.uni-popup__mask.uni-left,
|
||||||
opacity: 1;
|
.uni-popup__mask.uni-top {
|
||||||
}
|
opacity: 1;
|
||||||
|
}
|
||||||
.uni-popup__wrapper {
|
|
||||||
position: absolute;
|
.uni-popup__wrapper {
|
||||||
z-index: 999;
|
position: absolute;
|
||||||
box-sizing: border-box;
|
z-index: 999;
|
||||||
//background: #ffffff;
|
box-sizing: border-box;
|
||||||
}
|
//background: #ffffff;
|
||||||
|
}
|
||||||
.uni-popup__wrapper.ani {
|
|
||||||
transition: all 0.3s;
|
.uni-popup__wrapper.ani {
|
||||||
}
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
.uni-popup__wrapper.top {
|
|
||||||
top: 0;
|
.uni-popup__wrapper.top {
|
||||||
left: 0;
|
top: 0;
|
||||||
width: 100%;
|
left: 0;
|
||||||
transform: translateY(-100%);
|
width: 100%;
|
||||||
}
|
transform: translateY(-100%);
|
||||||
|
}
|
||||||
.uni-popup__wrapper.bottom {
|
|
||||||
bottom: 0;
|
.uni-popup__wrapper.bottom {
|
||||||
left: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
left: 0;
|
||||||
transform: translateY(100%);
|
width: 100%;
|
||||||
background: #ffffff;
|
transform: translateY(100%);
|
||||||
}
|
background: #ffffff;
|
||||||
|
}
|
||||||
.uni-popup__wrapper.right {
|
|
||||||
bottom: 0;
|
.uni-popup__wrapper.right {
|
||||||
left: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
left: 0;
|
||||||
transform: translateX(100%);
|
width: 100%;
|
||||||
}
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
.uni-popup__wrapper.left {
|
|
||||||
bottom: 0;
|
.uni-popup__wrapper.left {
|
||||||
left: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
left: 0;
|
||||||
transform: translateX(-100%);
|
width: 100%;
|
||||||
}
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
.uni-popup__wrapper.center {
|
|
||||||
width: 100%;
|
.uni-popup__wrapper.center {
|
||||||
height: 100%;
|
width: 100%;
|
||||||
display: flex;
|
height: 100%;
|
||||||
justify-content: center;
|
display: flex;
|
||||||
align-items: center;
|
justify-content: center;
|
||||||
transform: scale(1.2);
|
align-items: center;
|
||||||
opacity: 0;
|
transform: scale(1.2);
|
||||||
}
|
opacity: 0;
|
||||||
|
}
|
||||||
.uni-popup__wrapper-box {
|
|
||||||
position: relative;
|
.uni-popup__wrapper-box {
|
||||||
box-sizing: border-box;
|
position: relative;
|
||||||
border-radius: 10rpx;
|
box-sizing: border-box;
|
||||||
}
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
|
|
||||||
background: #fff;
|
.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
|
||||||
}
|
background: #fff;
|
||||||
|
}
|
||||||
.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
|
|
||||||
position: relative;
|
.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
|
||||||
max-width: 80%;
|
position: relative;
|
||||||
max-height: 80%;
|
max-width: 80%;
|
||||||
overflow-y: scroll;
|
max-height: 80%;
|
||||||
}
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
.uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box,
|
|
||||||
.uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box {
|
.uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box,
|
||||||
width: 100%;
|
.uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box {
|
||||||
max-height: 500px;
|
width: 100%;
|
||||||
overflow-y: scroll;
|
max-height: 500px;
|
||||||
}
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
.uni-popup__wrapper.uni-bottom,
|
|
||||||
.uni-popup__wrapper.uni-top {
|
.uni-popup__wrapper.uni-bottom,
|
||||||
transform: translateY(0);
|
.uni-popup__wrapper.uni-top {
|
||||||
}
|
transform: translateY(0);
|
||||||
|
}
|
||||||
.uni-popup__wrapper.uni-left,
|
|
||||||
.uni-popup__wrapper.uni-right {
|
.uni-popup__wrapper.uni-left,
|
||||||
transform: translateX(0);
|
.uni-popup__wrapper.uni-right {
|
||||||
}
|
transform: translateX(0);
|
||||||
|
}
|
||||||
.uni-popup__wrapper.uni-center {
|
|
||||||
transform: scale(1);
|
.uni-popup__wrapper.uni-center {
|
||||||
opacity: 1;
|
transform: scale(1);
|
||||||
}
|
opacity: 1;
|
||||||
|
}
|
||||||
/* isIphoneX系列手机底部安全距离 */
|
|
||||||
.bottom.safe-area {
|
/* isIphoneX系列手机底部安全距离 */
|
||||||
padding-bottom: constant(safe-area-inset-bottom);
|
.bottom.safe-area {
|
||||||
padding-bottom: env(safe-area-inset-bottom);
|
padding-bottom: constant(safe-area-inset-bottom);
|
||||||
}
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
}
|
||||||
.left.safe-area {
|
|
||||||
padding-bottom: 68rpx;
|
.left.safe-area {
|
||||||
}
|
padding-bottom: 68rpx;
|
||||||
|
}
|
||||||
.right.safe-area {
|
|
||||||
padding-bottom: 68rpx;
|
.right.safe-area {
|
||||||
}
|
padding-bottom: 68rpx;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,158 +1,158 @@
|
|||||||
<template>
|
<template>
|
||||||
<view
|
<view
|
||||||
v-if="text"
|
v-if="text"
|
||||||
:class="[
|
:class="[
|
||||||
disabled === true || disabled === 'true' ? 'uni-tag--disabled' : '',
|
disabled === true || disabled === 'true' ? 'uni-tag--disabled' : '',
|
||||||
inverted === true || inverted === 'true' ? 'uni-tag--inverted' : '',
|
inverted === true || inverted === 'true' ? 'uni-tag--inverted' : '',
|
||||||
circle === true || circle === 'true' ? 'uni-tag--circle' : '',
|
circle === true || circle === 'true' ? 'uni-tag--circle' : '',
|
||||||
mark === true || mark === 'true' ? 'uni-tag--mark' : '',
|
mark === true || mark === 'true' ? 'uni-tag--mark' : '',
|
||||||
'uni-tag--' + size,
|
'uni-tag--' + size,
|
||||||
'uni-tag--' + type
|
'uni-tag--' + type
|
||||||
]"
|
]"
|
||||||
class="uni-tag"
|
class="uni-tag"
|
||||||
@click="onClick()"
|
@click="onClick()"
|
||||||
>
|
>
|
||||||
{{ text }}
|
{{ text }}
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'UniTag',
|
name: 'UniTag',
|
||||||
props: {
|
props: {
|
||||||
type: {
|
type: {
|
||||||
// 标签类型default、primary、success、warning、danger、royal
|
// 标签类型default、primary、success、warning、danger、royal
|
||||||
type: String,
|
type: String,
|
||||||
default: 'default'
|
default: 'default'
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
// 标签大小 normal, small
|
// 标签大小 normal, small
|
||||||
type: String,
|
type: String,
|
||||||
default: 'normal'
|
default: 'normal'
|
||||||
},
|
},
|
||||||
// 标签内容
|
// 标签内容
|
||||||
text: {
|
text: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
disabled: {
|
disabled: {
|
||||||
// 是否为禁用状态
|
// 是否为禁用状态
|
||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: false
|
defalut: false
|
||||||
},
|
},
|
||||||
inverted: {
|
inverted: {
|
||||||
// 是否为空心
|
// 是否为空心
|
||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: false
|
defalut: false
|
||||||
},
|
},
|
||||||
circle: {
|
circle: {
|
||||||
// 是否为圆角样式
|
// 是否为圆角样式
|
||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: false
|
defalut: false
|
||||||
},
|
},
|
||||||
mark: {
|
mark: {
|
||||||
// 是否为标记样式
|
// 是否为标记样式
|
||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: false
|
defalut: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onClick() {
|
onClick() {
|
||||||
if (this.disabled === true || this.disabled === 'true') {
|
if (this.disabled === true || this.disabled === 'true') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$emit('click');
|
this.$emit('click');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
.uni-tag {
|
.uni-tag {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 0 32rpx;
|
padding: 0 32rpx;
|
||||||
height: 60rpx;
|
height: 60rpx;
|
||||||
line-height: calc(60rpx - 2px);
|
line-height: calc(60rpx - 2px);
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: #333;
|
color: #333;
|
||||||
border-radius: 6rpx;
|
border-radius: 6rpx;
|
||||||
background-color: #f8f8f8;
|
background-color: #f8f8f8;
|
||||||
border: 1px solid #f8f8f8;
|
border: 1px solid #f8f8f8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--circle {
|
.uni-tag--circle {
|
||||||
border-radius: 30rpx;
|
border-radius: 30rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--mark {
|
.uni-tag--mark {
|
||||||
border-radius: 0 30rpx 30rpx 0;
|
border-radius: 0 30rpx 30rpx 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--disabled {
|
.uni-tag--disabled {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--small {
|
.uni-tag--small {
|
||||||
height: 40rpx;
|
height: 40rpx;
|
||||||
padding: 0 16rpx;
|
padding: 0 16rpx;
|
||||||
line-height: calc(40rpx - 2px);
|
line-height: calc(40rpx - 2px);
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--primary {
|
.uni-tag--primary {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #007aff;
|
background-color: #007aff;
|
||||||
border: 1px solid #007aff;
|
border: 1px solid #007aff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--primary.uni-tag--inverted {
|
.uni-tag--primary.uni-tag--inverted {
|
||||||
color: #007aff;
|
color: #007aff;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid #007aff;
|
border: 1px solid #007aff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--success {
|
.uni-tag--success {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #4cd964;
|
background-color: #4cd964;
|
||||||
border: 1px solid #4cd964;
|
border: 1px solid #4cd964;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--success.uni-tag--inverted {
|
.uni-tag--success.uni-tag--inverted {
|
||||||
color: #4cd964;
|
color: #4cd964;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid #4cd964;
|
border: 1px solid #4cd964;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--warning {
|
.uni-tag--warning {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #f0ad4e;
|
background-color: #f0ad4e;
|
||||||
border: 1px solid #f0ad4e;
|
border: 1px solid #f0ad4e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--warning.uni-tag--inverted {
|
.uni-tag--warning.uni-tag--inverted {
|
||||||
color: #f0ad4e;
|
color: #f0ad4e;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid #f0ad4e;
|
border: 1px solid #f0ad4e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--error {
|
.uni-tag--error {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #dd524d;
|
background-color: #dd524d;
|
||||||
border: 1px solid #dd524d;
|
border: 1px solid #dd524d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--error.uni-tag--inverted {
|
.uni-tag--error.uni-tag--inverted {
|
||||||
color: #dd524d;
|
color: #dd524d;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid #dd524d;
|
border: 1px solid #dd524d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-tag--inverted {
|
.uni-tag--inverted {
|
||||||
color: #333;
|
color: #333;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid #f8f8f8;
|
border: 1px solid #f8f8f8;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,218 +0,0 @@
|
|||||||
<template>
|
|
||||||
<text
|
|
||||||
class="uv-count-num"
|
|
||||||
:style="textStyle"
|
|
||||||
>
|
|
||||||
{{ displayValue }}
|
|
||||||
</text>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'uv-count-to',
|
|
||||||
props: {
|
|
||||||
startVal: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
endVal: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
duration: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 2000
|
|
||||||
},
|
|
||||||
autoplay: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
decimals: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
useEasing: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
decimal: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: '.'
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
type: String,
|
|
||||||
default: '#606266'
|
|
||||||
},
|
|
||||||
fontSize: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 22
|
|
||||||
},
|
|
||||||
bold: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
separator: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
localStartVal: this.startVal,
|
|
||||||
displayValue: this.formatNumber(this.startVal),
|
|
||||||
printVal: null,
|
|
||||||
paused: false,
|
|
||||||
localDuration: Number(this.duration),
|
|
||||||
startTime: null,
|
|
||||||
timestamp: null,
|
|
||||||
remaining: null,
|
|
||||||
rAF: null,
|
|
||||||
lastTime: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
countDown() {
|
|
||||||
return this.startVal > this.endVal
|
|
||||||
},
|
|
||||||
textStyle() {
|
|
||||||
return {
|
|
||||||
fontSize: this.fontSize + 'px',
|
|
||||||
fontWeight: this.bold ? 'bold' : 'normal',
|
|
||||||
color: this.color
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
startVal() {
|
|
||||||
if (this.autoplay) {
|
|
||||||
this.start()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
endVal() {
|
|
||||||
console.log(123)
|
|
||||||
if (this.autoplay) {
|
|
||||||
this.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
if (this.autoplay) {
|
|
||||||
this.start()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
easingFn(t, b, c, d) {
|
|
||||||
return c * (1 - Math.pow(2, -10 * t / d)) * 1024 / 1023 + b
|
|
||||||
},
|
|
||||||
requestAnimationFrame(callback) {
|
|
||||||
const currTime = new Date().getTime()
|
|
||||||
const timeToCall = Math.max(0, 16 - (currTime - this.lastTime))
|
|
||||||
const id = setTimeout(() => {
|
|
||||||
callback(currTime + timeToCall)
|
|
||||||
}, timeToCall)
|
|
||||||
this.lastTime = currTime + timeToCall
|
|
||||||
return id
|
|
||||||
},
|
|
||||||
cancelAnimationFrame(id) {
|
|
||||||
clearTimeout(id)
|
|
||||||
},
|
|
||||||
start() {
|
|
||||||
this.localStartVal = this.startVal
|
|
||||||
this.startTime = null
|
|
||||||
this.localDuration = this.duration
|
|
||||||
this.paused = false
|
|
||||||
this.rAF = this.requestAnimationFrame(this.count)
|
|
||||||
},
|
|
||||||
restart() {
|
|
||||||
if (this.paused) {
|
|
||||||
this.resume()
|
|
||||||
this.paused = false
|
|
||||||
} else {
|
|
||||||
this.stop()
|
|
||||||
this.paused = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
stop() {
|
|
||||||
this.cancelAnimationFrame(this.rAF)
|
|
||||||
this.paused = true
|
|
||||||
},
|
|
||||||
resume() {
|
|
||||||
if (this.remaining) {
|
|
||||||
this.startTime = 0
|
|
||||||
this.localDuration = this.remaining
|
|
||||||
this.localStartVal = this.printVal
|
|
||||||
this.requestAnimationFrame(this.count)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
reset() {
|
|
||||||
this.startTime = null
|
|
||||||
this.cancelAnimationFrame(this.rAF)
|
|
||||||
this.displayValue = this.formatNumber(this.startVal)
|
|
||||||
},
|
|
||||||
count(timestamp) {
|
|
||||||
if (!this.startTime) this.startTime = timestamp
|
|
||||||
this.timestamp = timestamp
|
|
||||||
const progress = timestamp - this.startTime
|
|
||||||
this.remaining = this.localDuration - progress
|
|
||||||
|
|
||||||
if (this.useEasing) {
|
|
||||||
if (this.countDown) {
|
|
||||||
this.printVal = this.localStartVal - this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration)
|
|
||||||
} else {
|
|
||||||
this.printVal = this.easingFn(progress, this.localStartVal, this.endVal - this.localStartVal, this.localDuration)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.countDown) {
|
|
||||||
this.printVal = this.localStartVal - (this.localStartVal - this.endVal) * (progress / this.localDuration)
|
|
||||||
} else {
|
|
||||||
this.printVal = this.localStartVal + (this.endVal - this.localStartVal) * (progress / this.localDuration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.countDown) {
|
|
||||||
this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal
|
|
||||||
} else {
|
|
||||||
this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal
|
|
||||||
}
|
|
||||||
|
|
||||||
this.displayValue = this.formatNumber(this.printVal) || 0
|
|
||||||
|
|
||||||
if (progress < this.localDuration) {
|
|
||||||
this.rAF = this.requestAnimationFrame(this.count)
|
|
||||||
} else {
|
|
||||||
this.$emit('end')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isNumber(val) {
|
|
||||||
return !isNaN(parseFloat(val))
|
|
||||||
},
|
|
||||||
formatNumber(num) {
|
|
||||||
num = Number(num)
|
|
||||||
num = num.toFixed(Number(this.decimals))
|
|
||||||
num += ''
|
|
||||||
const x = num.split('.')
|
|
||||||
let x1 = x[0]
|
|
||||||
const x2 = x.length > 1 ? this.decimal + x[1] : ''
|
|
||||||
const rgx = /(\d+)(\d{3})/
|
|
||||||
|
|
||||||
if (this.separator && !this.isNumber(this.separator)) {
|
|
||||||
while (rgx.test(x1)) {
|
|
||||||
x1 = x1.replace(rgx, '$1' + this.separator + '$2')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return x1 + x2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
destroyed() {
|
|
||||||
this.cancelAnimationFrame(this.rAF)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.uv-count-num {
|
|
||||||
display: inline-flex;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
# 企业微信联系客服组件更新日志
|
|
||||||
|
|
||||||
## v2.0.0 - 集成全局Store配置
|
|
||||||
|
|
||||||
### 新增功能
|
|
||||||
- ✅ 企业微信配置集成到全局Store
|
|
||||||
- ✅ 从 `/api/config/init` 统一获取配置
|
|
||||||
- ✅ 支持props覆盖全局配置
|
|
||||||
- ✅ 优化配置获取逻辑
|
|
||||||
|
|
||||||
### 变更内容
|
|
||||||
1. **Store集成**:
|
|
||||||
- 在 `store/index.js` 中添加 `wxworkConfig` 状态
|
|
||||||
- 添加 `setWxworkConfig` mutation
|
|
||||||
- 在 `init` action 中从 `/api/config/init` 获取企业微信配置
|
|
||||||
|
|
||||||
2. **组件优化**:
|
|
||||||
- `wxwork-contact.vue` 组件现在优先从全局Store获取配置
|
|
||||||
- 支持通过props覆盖全局配置
|
|
||||||
- 移除单独的API调用,使用统一配置
|
|
||||||
|
|
||||||
3. **页面集成**:
|
|
||||||
- `pages/contact/contact.vue` 页面简化配置获取逻辑
|
|
||||||
- 直接使用全局Store中的企业微信配置
|
|
||||||
|
|
||||||
### 配置格式
|
|
||||||
后端 `/api/config/init` 需要返回以下格式的企业微信配置:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"code": 0,
|
|
||||||
"data": {
|
|
||||||
// ... 其他配置 ...
|
|
||||||
"wxwork": {
|
|
||||||
"corp_id": "企业ID",
|
|
||||||
"agent_id": "应用ID",
|
|
||||||
"contact_id": "客服ID",
|
|
||||||
"contact_url": "活码链接",
|
|
||||||
"timestamp": "时间戳",
|
|
||||||
"nonceStr": "随机字符串",
|
|
||||||
"signature": "签名",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 使用方式
|
|
||||||
```vue
|
|
||||||
<!-- 使用全局配置 -->
|
|
||||||
<wxwork-contact btn-text="联系企业客服"></wxwork-contact>
|
|
||||||
|
|
||||||
<!-- 覆盖全局配置 -->
|
|
||||||
<wxwork-contact
|
|
||||||
:corp-id="customCorpId"
|
|
||||||
:contact-url="customContactUrl"
|
|
||||||
btn-text="自定义客服"></wxwork-contact>
|
|
||||||
```
|
|
||||||
|
|
||||||
## v1.0.0 - 初始版本
|
|
||||||
|
|
||||||
### 功能
|
|
||||||
- 企业微信JS-SDK封装
|
|
||||||
- 基础联系客服组件
|
|
||||||
- 支持小程序和H5环境
|
|
||||||
- 活码跳转和SDK两种方式
|
|
||||||
@@ -1,484 +0,0 @@
|
|||||||
# 企业微信联系客服组件
|
|
||||||
|
|
||||||
## 功能说明
|
|
||||||
|
|
||||||
这个组件实现了在小程序中点击"联系客服"后,自动跳转到企业微信添加对应销售的功能。
|
|
||||||
|
|
||||||
## 关键前提条件
|
|
||||||
|
|
||||||
### ⚠️ 重要提醒
|
|
||||||
微信小程序与企业微信互通有严格的平台限制和权限要求,使用前请确保满足以下所有条件:
|
|
||||||
|
|
||||||
### 1. 微信小程序环境要求
|
|
||||||
- **平台限制**:功能仅在微信小程序环境中可用
|
|
||||||
- **基础库版本**:需要微信小程序基础库 2.3.0 及以上版本
|
|
||||||
- **用户环境**:用户需要在微信中打开小程序
|
|
||||||
|
|
||||||
### 2. 企业微信配置要求
|
|
||||||
- **企业认证**:企业微信账号必须完成企业认证
|
|
||||||
- **客户联系功能**:需要开通企业微信"客户联系"功能
|
|
||||||
- **应用权限**:企业微信应用需要有客户联系相关权限
|
|
||||||
|
|
||||||
### 3. 互通配置要求
|
|
||||||
- **关联配置**:小程序必须与企业微信进行关联配置
|
|
||||||
- **权限申请**:需要在微信开放平台和企业微信后台分别申请相应权限
|
|
||||||
- **域名白名单**:相关域名需要在小程序和企业微信后台都配置白名单
|
|
||||||
|
|
||||||
### 4. 跳转权限要求
|
|
||||||
- **小程序AppID**:需要在企业微信中配置允许跳转的小程序AppID
|
|
||||||
- **企业微信AppID**:需要在微信开放平台配置关联的企业微信AppID
|
|
||||||
- **业务域授权**:需要配置业务域授权,允许跨平台跳转
|
|
||||||
|
|
||||||
### 5. 开发调试要求
|
|
||||||
- **测试环境**:需要在测试环境中验证跳转功能
|
|
||||||
- **权限验证**:确保所有必要的API权限已申请并生效
|
|
||||||
- **兼容性测试**:在不同微信版本中进行兼容性测试
|
|
||||||
|
|
||||||
### 6. 具体配置要求
|
|
||||||
|
|
||||||
| 条件 | 说明 |
|
|
||||||
|------|------|
|
|
||||||
| **小程序与企业微信绑定** | 在企业微信管理后台 → 「应用管理」→「小程序」中关联你的微信小程序AppID |
|
|
||||||
| **配置可信域名** | 如果涉及网页跳转或回调,需在企业微信后台配置业务域名 |
|
|
||||||
| **使用企业微信服务商 or 自建应用** | 若需高级功能(如获取客户详情),需有企业微信管理员权限或通过服务商代开发 |
|
|
||||||
|
|
||||||
## 使用方法
|
|
||||||
|
|
||||||
### 1. 基础用法
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<wxwork-contact
|
|
||||||
:corp-id="corpId"
|
|
||||||
:agent-id="agentId"
|
|
||||||
:timestamp="timestamp"
|
|
||||||
:nonce-str="nonceStr"
|
|
||||||
:signature="signature"
|
|
||||||
:contact-id="contactId"
|
|
||||||
:contact-url="contactUrl"
|
|
||||||
btn-text="添加企业微信客服">
|
|
||||||
</wxwork-contact>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 组件架构
|
|
||||||
|
|
||||||
### 分层设计
|
|
||||||
```
|
|
||||||
调用方 (页面组件)
|
|
||||||
↓ 传递配置参数
|
|
||||||
wxwork-contact 组件
|
|
||||||
↓ 调用SDK
|
|
||||||
wxwork-jssdk.js
|
|
||||||
↓ 调用企业微信API
|
|
||||||
企业微信服务
|
|
||||||
```
|
|
||||||
|
|
||||||
### 组件设计原则
|
|
||||||
|
|
||||||
- **独立性**:组件不直接依赖全局Store,所有配置通过props传递
|
|
||||||
- **职责分离**:组件只负责UI展示和企业微信SDK调用,配置管理由调用方负责
|
|
||||||
- **灵活配置**:支持调用者覆盖任何配置参数
|
|
||||||
|
|
||||||
## 版本信息
|
|
||||||
|
|
||||||
### v3.0.0 - 统一客服服务重构版本
|
|
||||||
- 创建 `CustomerService` 统一客服处理服务
|
|
||||||
- 重构 `ns-contact.vue` 和 `hover-nav.vue` 消除重复代码
|
|
||||||
- 提供统一的客服处理接口和平台适配
|
|
||||||
- 完善错误处理和降级机制
|
|
||||||
- 支持所有客服类型的统一调用
|
|
||||||
|
|
||||||
### v2.0.0 - Store集成版本
|
|
||||||
- 企业微信配置集成到全局Store
|
|
||||||
- 从 `/api/config/init` 统一获取配置
|
|
||||||
- 组件完全独立,通过props接收配置
|
|
||||||
- 支持全局配置和局部覆盖
|
|
||||||
|
|
||||||
### v1.0.0 - 初始版本
|
|
||||||
- 基础企业微信联系功能
|
|
||||||
- 支持活码跳转和JS-SDK两种方式
|
|
||||||
|
|
||||||
### 2. 属性说明
|
|
||||||
|
|
||||||
| 属性 | 类型 | 默认值 | 说明 |
|
|
||||||
|------|------|--------|------|
|
|
||||||
| btnText | String | '添加企业微信客服' | 按钮文字 |
|
|
||||||
| corpId | String | - | 企业ID(必需) |
|
|
||||||
| agentId | String | '' | 应用ID |
|
|
||||||
| timestamp | String | '' | 时间戳 |
|
|
||||||
| nonceStr | String | '' | 随机字符串 |
|
|
||||||
| signature | String | '' | 签名 |
|
|
||||||
| contactId | String | '' | 客服ID或活码配置ID |
|
|
||||||
| contactUrl | String | '' | 活码链接 |
|
|
||||||
| showConfirm | Boolean | true | 是否显示确认弹窗 |
|
|
||||||
|
|
||||||
### 3. 在联系页面中使用
|
|
||||||
|
|
||||||
在 `pages/contact/contact.vue` 中已集成使用示例:
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<wxwork-contact
|
|
||||||
v-if="wxworkConfig && wxworkConfig.enabled"
|
|
||||||
:corp-id="wxworkConfig.corpId"
|
|
||||||
:agent-id="wxworkConfig.agentId"
|
|
||||||
:timestamp="wxworkConfig.timestamp"
|
|
||||||
:nonce-str="wxworkConfig.nonceStr"
|
|
||||||
:signature="wxworkConfig.signature"
|
|
||||||
:contact-id="wxworkConfig.contactId"
|
|
||||||
:contact-url="wxworkConfig.contactUrl"
|
|
||||||
btn-text="企业微信客服"
|
|
||||||
:show-confirm="false">
|
|
||||||
</wxwork-contact>
|
|
||||||
```
|
|
||||||
|
|
||||||
## 配置说明
|
|
||||||
|
|
||||||
### 后端接口需求
|
|
||||||
|
|
||||||
企业微信配置已集成到 `/api/config/init` 接口中,返回以下格式的数据:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"code": 0,
|
|
||||||
"data": {
|
|
||||||
// ... 其他配置 ...
|
|
||||||
"wxwork": {
|
|
||||||
"corp_id": "企业ID",
|
|
||||||
"agent_id": "应用ID",
|
|
||||||
"contact_id": "客服ID",
|
|
||||||
"contact_url": "活码链接",
|
|
||||||
"timestamp": "时间戳",
|
|
||||||
"nonceStr": "随机字符串",
|
|
||||||
"signature": "签名",
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 全局Store集成
|
|
||||||
|
|
||||||
企业微信配置通过以下方式集成到全局状态管理:
|
|
||||||
|
|
||||||
1. **Store状态**:在 `store/index.js` 中添加 `wxworkConfig` 状态
|
|
||||||
2. **配置获取**:在 `init` action 中从 `/api/config/init` 获取企业微信配置
|
|
||||||
3. **状态更新**:使用 `setWxworkConfig` mutation 更新配置
|
|
||||||
4. **持久化**:配置自动保存到本地存储
|
|
||||||
|
|
||||||
### 企业微信配置步骤
|
|
||||||
|
|
||||||
1. **获取企业微信活码**:
|
|
||||||
- 登录企业微信管理后台
|
|
||||||
- 进入"客户联系" -> "配置" -> "联系我"
|
|
||||||
- 创建活码,获取配置ID或直接获取活码链接
|
|
||||||
|
|
||||||
2. **配置参数**:
|
|
||||||
- `corp_id`: 企业ID(在企业微信后台获取)
|
|
||||||
- `agent_id`: 企业微信应用ID
|
|
||||||
- `contact_id`: 客服的用户ID
|
|
||||||
- `contact_url`: 企业微信活码链接(推荐使用活码链接)
|
|
||||||
- `timestamp`: 生成签名的时间戳
|
|
||||||
- `nonceStr`: 生成签名的随机字符串
|
|
||||||
- `signature`: JS-SDK签名
|
|
||||||
|
|
||||||
## 典型业务流程示例
|
|
||||||
|
|
||||||
### 目标
|
|
||||||
用户在小程序中点击"联系客服",自动添加对应的企业微信销售。
|
|
||||||
|
|
||||||
### 步骤
|
|
||||||
1. **后端调用企业微信 API** 创建「联系我」二维码(可带场景值,如 user_id=123)。
|
|
||||||
2. **前端在小程序中展示该二维码(或生成跳转链接)**。
|
|
||||||
3. **用户长按识别 → 打开企业微信 → 添加客服**。
|
|
||||||
4. **企业微信收到添加事件 → 通过 API 获取 external_userid → 关联到原小程序用户**。
|
|
||||||
|
|
||||||
## 实现原理
|
|
||||||
|
|
||||||
### 方案1:企业微信活码跳转(推荐)
|
|
||||||
- 使用企业微信活码链接
|
|
||||||
- 通过 `uni.navigateToMiniProgram` 跳转到企业微信小程序
|
|
||||||
- 直接添加对应的销售为联系人
|
|
||||||
|
|
||||||
### 方案2:JS-SDK方式
|
|
||||||
- 使用企业微信JS-SDK
|
|
||||||
- 调用 `openUserProfile` 接口打开用户资料
|
|
||||||
- 用户手动添加联系人
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
### 功能限制
|
|
||||||
1. **小程序环境**:需要在微信小程序环境中使用
|
|
||||||
2. **权限配置**:确保小程序有跳转企业微信的权限
|
|
||||||
3. **降级处理**:当企业微信不可用时,会降级到原有客服方式
|
|
||||||
4. **用户体验**:建议添加确认弹窗,避免误操作
|
|
||||||
|
|
||||||
### 前提条件验证
|
|
||||||
5. **权限检查**:使用前需要验证所有必需权限是否生效
|
|
||||||
6. **配置完整性**:确保所有配置参数都已正确设置
|
|
||||||
7. **网络环境**:确保用户网络环境允许访问企业微信服务
|
|
||||||
8. **版本兼容**:检查微信版本和企业微信版本兼容性
|
|
||||||
|
|
||||||
### 调试建议
|
|
||||||
9. **错误监控**:添加适当的错误日志和用户反馈机制
|
|
||||||
10. **性能优化**:避免频繁的SDK初始化和配置获取
|
|
||||||
11. **安全考虑**:敏感配置信息应在服务端处理,前端不暴露
|
|
||||||
|
|
||||||
## 兼容性
|
|
||||||
|
|
||||||
- 微信小程序:✅ 支持
|
|
||||||
- H5环境:✅ 支持跳转活码链接
|
|
||||||
- 其他平台:降级处理
|
|
||||||
|
|
||||||
## 文件结构
|
|
||||||
|
|
||||||
```
|
|
||||||
components/wxwork-contact/
|
|
||||||
├── wxwork-contact.vue # 主组件
|
|
||||||
└── README.md # 说明文档
|
|
||||||
|
|
||||||
components/ns-contact/
|
|
||||||
└── ns-contact.vue # 统一客服组件(重构后)
|
|
||||||
|
|
||||||
components/hover-nav/
|
|
||||||
└── hover-nav.vue # 悬浮导航组件(重构后)
|
|
||||||
|
|
||||||
common/js/
|
|
||||||
├── wxwork-jssdk.js # 企业微信JS-SDK封装
|
|
||||||
└── customer-service.js # 客服统一处理服务(新增)
|
|
||||||
|
|
||||||
store/
|
|
||||||
└── index.js # 全局Store,包含wxworkConfig状态管理
|
|
||||||
|
|
||||||
pages/contact/
|
|
||||||
└── contact.vue # 联系页面,集成企业微信功能
|
|
||||||
```
|
|
||||||
|
|
||||||
## 系统梳理与优化 (v3.1.0)
|
|
||||||
|
|
||||||
### 🔧 已修复的问题
|
|
||||||
|
|
||||||
#### 1. **App.vue 配置恢复**
|
|
||||||
- ✅ 修复了企业微信配置 (`wxworkConfig`) 在应用启动时的恢复
|
|
||||||
- ✅ 确保所有配置都能正确从本地存储恢复到Store
|
|
||||||
|
|
||||||
#### 2. **客服服务参数传递**
|
|
||||||
- ✅ 修复了 `openCustomerServiceChat` 参数传递错误
|
|
||||||
- ✅ 正确传递 `sendMessageTitle`、`sendMessagePath`、`sendMessageImg`
|
|
||||||
|
|
||||||
#### 3. **组件配置访问**
|
|
||||||
- ✅ 在 `ns-contact.vue` 和 `hover-nav.vue` 中添加 computed 属性
|
|
||||||
- ✅ 确保能够正确访问 `servicerConfig`
|
|
||||||
|
|
||||||
#### 4. **企业微信服务优化**
|
|
||||||
- ✅ 改进参数传递,支持自定义消息参数
|
|
||||||
- ✅ 统一处理函数调用方式
|
|
||||||
|
|
||||||
### 🛡️ 新增功能
|
|
||||||
|
|
||||||
#### 1. **配置验证机制**
|
|
||||||
```javascript
|
|
||||||
const validation = this.customerService.validateConfig();
|
|
||||||
if (!validation.isValid) {
|
|
||||||
// 处理配置错误
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. **错误处理增强**
|
|
||||||
- ✅ 添加配置错误弹窗
|
|
||||||
- ✅ 改进错误日志记录
|
|
||||||
- ✅ 警告信息提示
|
|
||||||
|
|
||||||
#### 3. **类型安全**
|
|
||||||
- ✅ 完善参数类型检查
|
|
||||||
- ✅ 空值和异常情况处理
|
|
||||||
|
|
||||||
### 📋 当前系统状态
|
|
||||||
|
|
||||||
| 组件 | 状态 | 功能完整性 |
|
|
||||||
|------|------|-----------|
|
|
||||||
| **customer-service.js** | ✅ 完成 | 统一客服处理服务 |
|
|
||||||
| **ns-contact.vue** | ✅ 修复 | 支持所有客服类型 |
|
|
||||||
| **hover-nav.vue** | ✅ 修复 | 集成统一客服服务 |
|
|
||||||
| **App.vue** | ✅ 修复 | 配置完整恢复 |
|
|
||||||
| **contact.vue** | ⚠️ 待优化 | 仍使用原始方式 |
|
|
||||||
|
|
||||||
### 🔄 待优化项
|
|
||||||
|
|
||||||
#### 1. **contact.vue 页面重构**
|
|
||||||
- 建议集成统一客服服务
|
|
||||||
- 添加企业微信客服按钮
|
|
||||||
- 统一UI交互体验
|
|
||||||
|
|
||||||
#### 2. **加载状态反馈**
|
|
||||||
- 客服功能调用时的loading状态
|
|
||||||
- 网络请求的进度指示
|
|
||||||
|
|
||||||
#### 3. **用户体验优化**
|
|
||||||
- 客服按钮的点击反馈
|
|
||||||
- 错误状态的友好提示
|
|
||||||
|
|
||||||
### 🧪 测试建议
|
|
||||||
|
|
||||||
1. **配置验证测试**:
|
|
||||||
- 测试各种配置缺失情况
|
|
||||||
- 验证错误提示准确性
|
|
||||||
|
|
||||||
2. **平台兼容测试**:
|
|
||||||
- 微信小程序客服功能
|
|
||||||
- H5环境跳转
|
|
||||||
- 支付宝小程序客服
|
|
||||||
|
|
||||||
3. **企业微信功能测试**:
|
|
||||||
- 活码链接跳转
|
|
||||||
- 降级处理机制
|
|
||||||
- 参数传递正确性
|
|
||||||
|
|
||||||
### 📖 使用最佳实践
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// 推荐使用方式
|
|
||||||
const customerService = createCustomerService(this);
|
|
||||||
|
|
||||||
// 带配置验证的调用
|
|
||||||
if (customerService.isConfigAvailable()) {
|
|
||||||
customerService.handleCustomerClick({
|
|
||||||
sendMessageTitle: '商品咨询',
|
|
||||||
sendMessagePath: '/pages/goods/detail',
|
|
||||||
sendMessageImg: 'product-image.jpg'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 重构说明 (v3.0.0)
|
|
||||||
|
|
||||||
### 统一客服处理服务
|
|
||||||
|
|
||||||
为了解决代码重复问题,我们创建了 `CustomerService` 类来统一处理所有客服逻辑:
|
|
||||||
|
|
||||||
#### 主要改进
|
|
||||||
1. **代码复用**:消除 `ns-contact.vue` 和 `hover-nav.vue` 中的重复代码
|
|
||||||
2. **统一接口**:提供一致的客服处理API
|
|
||||||
3. **平台适配**:自动处理不同平台的客服配置
|
|
||||||
4. **类型安全**:完善的错误处理和降级机制
|
|
||||||
|
|
||||||
#### 使用方式
|
|
||||||
|
|
||||||
**1. 在组件中导入**
|
|
||||||
```javascript
|
|
||||||
import { createCustomerService } from '@/common/js/customer-service.js';
|
|
||||||
```
|
|
||||||
|
|
||||||
**2. 初始化服务**
|
|
||||||
```javascript
|
|
||||||
created() {
|
|
||||||
this.customerService = createCustomerService(this);
|
|
||||||
this.buttonConfig = this.customerService.getButtonConfig();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**3. 处理客服点击**
|
|
||||||
```javascript
|
|
||||||
methods: {
|
|
||||||
contactServicer() {
|
|
||||||
this.customerService.handleCustomerClick({
|
|
||||||
niushop: this.niushop,
|
|
||||||
sendMessageTitle: this.sendMessageTitle,
|
|
||||||
sendMessagePath: this.sendMessagePath,
|
|
||||||
sendMessageImg: this.sendMessageImg
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 核心方法
|
|
||||||
|
|
||||||
| 方法名 | 用途 | 参数 |
|
|
||||||
|--------|------|------|
|
|
||||||
| `handleCustomerClick(options)` | 统一处理客服点击 | 客服配置选项 |
|
|
||||||
| `getButtonConfig()` | 获取按钮配置 | - |
|
|
||||||
| `getServiceType()` | 获取客服类型 | - |
|
|
||||||
| `openWxworkService()` | 打开企业微信客服 | 是否使用原方式 |
|
|
||||||
|
|
||||||
#### 支持的客服类型
|
|
||||||
|
|
||||||
- `wxwork` - 企业微信客服
|
|
||||||
- `third` - 第三方客服
|
|
||||||
- `niushop` - 牛商客服
|
|
||||||
- `weapp` - 微信小程序客服
|
|
||||||
- `aliapp` - 支付宝小程序客服
|
|
||||||
- `none` - 无客服(显示提示)
|
|
||||||
|
|
||||||
## 常见问题 (FAQ)
|
|
||||||
|
|
||||||
### Q: contact_id 是小程序ID吗?
|
|
||||||
A: 不是的。`contact_id` 是**企业微信中客服人员的用户ID**,具体说明如下:
|
|
||||||
|
|
||||||
- **定义**:企业微信系统内部分配给客服人员的唯一标识符
|
|
||||||
- **获取方式**:通过企业微信管理后台的"客户联系" → "配置" → "联系我"功能创建活码时获得
|
|
||||||
- **用途**:用于指定具体客服人员,当用户点击"联系客服"时,系统通过这个ID知道应该添加哪个企业微信客服人员
|
|
||||||
|
|
||||||
### Q: contact_id 和小程序ID的区别?
|
|
||||||
A: 两者的作用完全不同:
|
|
||||||
|
|
||||||
| 字段 | 用途 | 获取方式 |
|
|
||||||
|------|------|----------|
|
|
||||||
| **contact_id** | 指定具体的企业微信客服人员 | 企业微信管理后台获取 |
|
|
||||||
| **小程序AppID** | 识别整个微信小程序应用 | 微信开放平台获取 |
|
|
||||||
|
|
||||||
在业务流程中:
|
|
||||||
1. 用户在小程序中点击"联系客服"
|
|
||||||
2. 系统使用 `contact_id` 打开对应的企业微信客服人员资料
|
|
||||||
3. 用户添加该企业微信客服为联系人
|
|
||||||
|
|
||||||
所以 `contact_id` 是企业微信客服的ID,不是小程序的ID。
|
|
||||||
|
|
||||||
### Q: wxwork_contact_url 从哪里来?
|
|
||||||
A: `wxwork_contact_url` 应该来自全局Store中的 `wxworkConfig`,而不是 `servicerConfig`:
|
|
||||||
|
|
||||||
**正确的配置来源**:
|
|
||||||
- ✅ `this.$store.state.wxworkConfig.contact_url` - 企业微信配置
|
|
||||||
- ❌ `this.config.wxwork_contact_url` - 错误的配置路径
|
|
||||||
|
|
||||||
**配置获取流程**:
|
|
||||||
1. **后端接口**:`/api/config/init` 返回 `wxwork_config` 数据
|
|
||||||
2. **Store存储**:`setWxworkConfig` 将配置保存到 `wxworkConfig` 状态
|
|
||||||
3. **组件使用**:通过 `this.$store.state.wxworkConfig.contact_url` 访问
|
|
||||||
|
|
||||||
**代码修正示例**:
|
|
||||||
```javascript
|
|
||||||
// 错误 ❌
|
|
||||||
if (this.config.wxwork_contact_url) { ... }
|
|
||||||
|
|
||||||
// 正确 ✅
|
|
||||||
const wxworkConfig = this.$store.state?.wxworkConfig;
|
|
||||||
if (wxworkConfig?.contact_url) { ... }
|
|
||||||
```
|
|
||||||
|
|
||||||
**字段对应关系**:
|
|
||||||
| 后端字段 | Store字段 | 组件使用 |
|
|
||||||
|---------|----------|----------|
|
|
||||||
| `contact_url` | `contact_url` | `wxworkConfig.contact_url` |
|
|
||||||
|
|
||||||
### Q: navigateToMiniProgram 中的企业微信小程序AppID 是指我的业务小程序ID吗?
|
|
||||||
A: 不是的!`appId: 'wxeb490c6f9b154ef9'` 是**企业微信官方小程序的AppID**,不是你的业务小程序ID。
|
|
||||||
|
|
||||||
**两者的区别**:
|
|
||||||
|
|
||||||
| 小程序类型 | AppID示例 | 用途 | 所有者 |
|
|
||||||
|-----------|----------|------|--------|
|
|
||||||
| **企业微信官方小程序** | `wxeb490c6f9b154ef9` | 展示企业联系人详情页面 | 腾讯企业微信团队 |
|
|
||||||
| **你的业务小程序** | 你的AppID | 你的业务功能(电商、服务等) | 你的企业/组织 |
|
|
||||||
|
|
||||||
**业务流程**:
|
|
||||||
```
|
|
||||||
用户小程序 (你的业务)
|
|
||||||
↓ 点击"联系客服"
|
|
||||||
navigateToMiniProgram 跳转到
|
|
||||||
企业微信官方小程序 (wxeb490c6f9b154ef9)
|
|
||||||
↓ 展示联系人详情
|
|
||||||
用户添加客服人员到企业微信
|
|
||||||
```
|
|
||||||
|
|
||||||
**关键点**:
|
|
||||||
- 这个AppID是企业微信官方小程序,通常是固定值
|
|
||||||
- 用于跳转到企业微信环境展示联系人详情
|
|
||||||
- 不需要替换成你自己的小程序AppID |
|
|
||||||
@@ -1,301 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="wxwork-contact-wrap">
|
|
||||||
<slot></slot>
|
|
||||||
<button
|
|
||||||
type="default"
|
|
||||||
hover-class="none"
|
|
||||||
class="contact-button"
|
|
||||||
@click="addWxWorkContact">
|
|
||||||
<text class="btn-text">{{ btnText }}</text>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<!-- 确认弹窗 -->
|
|
||||||
<uni-popup ref="confirmPopup" type="center">
|
|
||||||
<view class="confirm-popup">
|
|
||||||
<view class="popup-header">
|
|
||||||
<text>添加企业微信客服</text>
|
|
||||||
</view>
|
|
||||||
<view class="popup-body">
|
|
||||||
<text>点击确定后将跳转至企业微信,添加专业客服为您服务</text>
|
|
||||||
</view>
|
|
||||||
<view class="popup-footer">
|
|
||||||
<button class="cancel-btn" @click="closePopup">取消</button>
|
|
||||||
<button class="confirm-btn" @click="confirmAdd">确定</button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uni-popup>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { WxWork } from '@/common/js/wxwork-jssdk.js';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'wxwork-contact',
|
|
||||||
props: {
|
|
||||||
// 按钮文字
|
|
||||||
btnText: {
|
|
||||||
type: String,
|
|
||||||
default: '添加企业微信客服'
|
|
||||||
},
|
|
||||||
// 企业ID(必需)
|
|
||||||
corpId: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
// 应用ID
|
|
||||||
agentId: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 时间戳
|
|
||||||
timestamp: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 随机字符串
|
|
||||||
nonceStr: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 签名
|
|
||||||
signature: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 客服ID或活码配置ID
|
|
||||||
contactId: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 活码链接
|
|
||||||
contactUrl: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// 是否显示确认弹窗
|
|
||||||
showConfirm: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
wxWorkSDK: null
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.initWxWork();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/**
|
|
||||||
* 初始化企业微信SDK
|
|
||||||
*/
|
|
||||||
initWxWork() {
|
|
||||||
try {
|
|
||||||
if (this.corpId) {
|
|
||||||
this.wxWorkSDK = new WxWork();
|
|
||||||
const initResult = this.wxWorkSDK.init({
|
|
||||||
corpId: this.corpId,
|
|
||||||
agentId: this.agentId,
|
|
||||||
timestamp: this.timestamp,
|
|
||||||
nonceStr: this.nonceStr,
|
|
||||||
signature: this.signature,
|
|
||||||
jsApiList: ['openUserProfile', 'openEnterpriseChat']
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!initResult) {
|
|
||||||
console.error('企业微信SDK初始化失败');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('初始化企业微信SDK失败:', error);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 点击添加企业微信客服
|
|
||||||
*/
|
|
||||||
addWxWorkContact() {
|
|
||||||
if (this.showConfirm) {
|
|
||||||
this.$refs.confirmPopup.open();
|
|
||||||
} else {
|
|
||||||
this.confirmAdd();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 确认添加
|
|
||||||
*/
|
|
||||||
confirmAdd() {
|
|
||||||
this.closePopup();
|
|
||||||
|
|
||||||
// 直接使用props传递的配置
|
|
||||||
const contactUrl = this.contactUrl;
|
|
||||||
const contactId = this.contactId;
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
if (contactUrl) {
|
|
||||||
// 方案1:直接跳转到企业微信活码
|
|
||||||
this.jumpToWxWorkContact(contactUrl);
|
|
||||||
} else if (contactId) {
|
|
||||||
// 方案2:使用SDK打开用户资料
|
|
||||||
this.openUserProfile(contactId);
|
|
||||||
} else {
|
|
||||||
this.showError('未配置企业微信客服信息');
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef H5
|
|
||||||
if (contactUrl) {
|
|
||||||
// H5环境直接跳转
|
|
||||||
window.location.href = contactUrl;
|
|
||||||
} else {
|
|
||||||
this.showError('未配置企业微信客服信息');
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 跳转到企业微信客服
|
|
||||||
*/
|
|
||||||
jumpToWxWorkContact(contactUrl) {
|
|
||||||
uni.navigateToMiniProgram({
|
|
||||||
appId: 'wxeb490c6f9b154ef9', // 企业微信小程序AppID
|
|
||||||
path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(contactUrl)}`,
|
|
||||||
success: () => {
|
|
||||||
console.log('跳转企业微信成功');
|
|
||||||
this.$util.showToast({
|
|
||||||
title: '跳转成功',
|
|
||||||
icon: 'success'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.error('跳转企业微信失败:', err);
|
|
||||||
this.showError('跳转失败,请检查企业微信配置');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开用户资料
|
|
||||||
*/
|
|
||||||
openUserProfile(contactId) {
|
|
||||||
if (!this.wxWorkSDK) {
|
|
||||||
this.showError('企业微信SDK未初始化');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.wxWorkSDK.addContact({
|
|
||||||
userId: contactId
|
|
||||||
}, (res) => {
|
|
||||||
console.log('打开用户资料成功:', res);
|
|
||||||
}, (err) => {
|
|
||||||
console.error('打开用户资料失败:', err);
|
|
||||||
this.showError('打开用户资料失败');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示错误提示
|
|
||||||
*/
|
|
||||||
showError(message) {
|
|
||||||
uni.showModal({
|
|
||||||
title: '提示',
|
|
||||||
content: message,
|
|
||||||
showCancel: false
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关闭弹窗
|
|
||||||
*/
|
|
||||||
closePopup() {
|
|
||||||
this.$refs.confirmPopup.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.wxwork-contact-wrap {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.contact-button {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(135deg, #1e7dd8 0%, #1482e0 100%);
|
|
||||||
color: #fff;
|
|
||||||
border: none;
|
|
||||||
border-radius: 8rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.btn-text {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.confirm-popup {
|
|
||||||
width: 600rpx;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 16rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.popup-header {
|
|
||||||
padding: 40rpx 30rpx 20rpx;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #333;
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-body {
|
|
||||||
padding: 30rpx;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #666;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-footer {
|
|
||||||
display: flex;
|
|
||||||
border-top: 1px solid #f0f0f0;
|
|
||||||
|
|
||||||
button {
|
|
||||||
flex: 1;
|
|
||||||
height: 88rpx;
|
|
||||||
line-height: 88rpx;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 30rpx;
|
|
||||||
border: none;
|
|
||||||
border-radius: 0;
|
|
||||||
|
|
||||||
&.cancel-btn {
|
|
||||||
background: #fff;
|
|
||||||
color: #999;
|
|
||||||
border-right: 1px solid #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.confirm-btn {
|
|
||||||
background: #1e7dd8;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -11,7 +11,7 @@ export const lang = {
|
|||||||
home:'首页',
|
home:'首页',
|
||||||
cart:'购物车',
|
cart:'购物车',
|
||||||
leave:'立即留言',
|
leave:'立即留言',
|
||||||
make:'立即咨询',
|
make:'立即支付',
|
||||||
|
|
||||||
send:'配送',
|
send:'配送',
|
||||||
express:'快递发货',
|
express:'快递发货',
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
export const lang = {
|
export const lang = {
|
||||||
//title为每个页面的标题
|
//title为每个页面的标题
|
||||||
title: '编辑收货地址',
|
title: '编辑收货地址',
|
||||||
consignee: '姓名',
|
consignee: '姓名',
|
||||||
consigneePlaceholder: '收货人姓名',
|
consigneePlaceholder: '收货人姓名',
|
||||||
mobile: '手机',
|
mobile: '手机',
|
||||||
mobilePlaceholder: '收货人手机号',
|
mobilePlaceholder: '收货人手机号',
|
||||||
telephone: '电话',
|
telephone: '电话',
|
||||||
telephonePlaceholder: '收货人固定电话(选填)',
|
telephonePlaceholder: '收货人固定电话(选填)',
|
||||||
receivingCity: '地区',
|
receivingCity: '地区',
|
||||||
address: '详细地址',
|
address: '详细地址',
|
||||||
house:'门牌号',
|
addressPlaceholder: '小区、街道、写字楼',
|
||||||
housePlaceholder:'请输入楼层门牌号',
|
save: '保存'
|
||||||
addressPlaceholder: '小区、街道、写字楼',
|
}
|
||||||
save: '保存'
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,51 +1,51 @@
|
|||||||
export const lang = {
|
export const lang = {
|
||||||
//title为每个页面的标题
|
//title为每个页面的标题
|
||||||
title: '会员中心',
|
title: '会员中心',
|
||||||
login: '立即登录',
|
login: '登录/注册',
|
||||||
loginTpis: '点击登录 享受更多精彩信息',
|
loginTpis: '点击登录 享受更多精彩信息',
|
||||||
memberLevel: '会员等级',
|
memberLevel: '会员等级',
|
||||||
moreAuthority: '更多权限',
|
moreAuthority: '更多权限',
|
||||||
allOrders: '全部订单',
|
allOrders: '全部订单',
|
||||||
seeAllOrders: '查看全部订单',
|
seeAllOrders: '查看全部订单',
|
||||||
waitPay: '待付款',
|
waitPay: '待付款',
|
||||||
readyDelivery: '待发货',
|
readyDelivery: '待发货',
|
||||||
waitDelivery: '待收货',
|
waitDelivery: '待收货',
|
||||||
refunding: '退款',
|
refunding: '退款',
|
||||||
// 会员中心入口
|
// 会员中心入口
|
||||||
sign: '签到',
|
sign: '签到',
|
||||||
personInfo: '个人资料',
|
personInfo: '个人资料',
|
||||||
receivingAddress: '收货地址',
|
receivingAddress: '收货地址',
|
||||||
accountList: '账户列表',
|
accountList: '账户列表',
|
||||||
couponList: '优惠券',
|
couponList: '优惠券',
|
||||||
mySpellList: '我的拼单',
|
mySpellList: '我的拼单',
|
||||||
myBargain: '我的砍价',
|
myBargain: '我的砍价',
|
||||||
virtualCode: '虚拟码',
|
virtualCode: '虚拟码',
|
||||||
winningRecord: '我的礼品',
|
winningRecord: '我的礼品',
|
||||||
myCollection: '我的关注',
|
myCollection: '我的关注',
|
||||||
myTracks: '我的足迹',
|
myTracks: '我的足迹',
|
||||||
pintuanOrder: '拼团订单',
|
pintuanOrder: '拼团订单',
|
||||||
yushouOrder: '预售订单',
|
yushouOrder: '预售订单',
|
||||||
verification: '核销台',
|
verification: '核销台',
|
||||||
message: '我的消息',
|
message: '我的消息',
|
||||||
exchangeOrder: '积分兑换',
|
exchangeOrder: '积分兑换',
|
||||||
|
|
||||||
waitpay:'待付款',
|
waitpay:'待付款',
|
||||||
waitsend:'待发货',
|
waitsend:'待发货',
|
||||||
waitconfirm:'待收货',
|
waitconfirm:'待收货',
|
||||||
activist:'售后',
|
activist:'售后',
|
||||||
completed:'已完成',
|
completed:'已完成',
|
||||||
|
|
||||||
// 推广中心
|
// 推广中心
|
||||||
balance: '余额',
|
balance: '余额',
|
||||||
point: '积分',
|
point: '积分',
|
||||||
coupon: '优惠券',
|
coupon: '优惠券',
|
||||||
memberRecommend: '邀请有礼',
|
memberRecommend: '邀请有礼',
|
||||||
myPresale: '我的预售',
|
myPresale: '我的预售',
|
||||||
myGiftcard: '我的礼品卡',
|
myGiftcard: '我的礼品卡',
|
||||||
myDivideticket: '我的瓜分券',
|
myDivideticket: '我的瓜分券',
|
||||||
myRebate:'拼团返利',
|
myRebate:'拼团返利',
|
||||||
myHongbao:'我的红包列表',
|
myHongbao:'我的红包列表',
|
||||||
myBlindBox:'我的盲盒',
|
myBlindBox:'我的盲盒',
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
export const lang = {
|
export const lang = {
|
||||||
//title为每个页面的标题
|
//title为每个页面的标题
|
||||||
title: '订单列表',
|
title: '订单列表',
|
||||||
emptyTips: '暂无相关订单',
|
emptyTips: '暂无相关订单',
|
||||||
all: '全部',
|
all: '全部',
|
||||||
waitPay: '待付款',
|
waitPay: '待付款',
|
||||||
readyDelivery: '待发货',
|
readyDelivery: '待发货',
|
||||||
waitDelivery: '待收货',
|
waitDelivery: '待收货',
|
||||||
waitEvaluate: '待评价',
|
waitEvaluate: '待评价',
|
||||||
waitUse: '待使用',
|
waitUse: '待使用',
|
||||||
update: "释放刷新",
|
update: "释放刷新",
|
||||||
updateIng: "加载中...",
|
updateIng: "加载中..."
|
||||||
toLogin: "去登录"
|
}
|
||||||
}
|
|
||||||
|
|||||||
145
main.js
145
main.js
@@ -1,70 +1,77 @@
|
|||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
import './common/js/pc'
|
import './common/js/pc'
|
||||||
// #endif
|
// #endif
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import App from './App'
|
import App from './App'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import Util from './common/js/util.js'
|
import Util from './common/js/util.js'
|
||||||
import Http from './common/js/http.js'
|
import Http from './common/js/http.js'
|
||||||
import Lang from './common/js/lang.js'
|
import Lang from './common/js/lang.js'
|
||||||
import Config from './common/js/config.js'
|
import Config from './common/js/config.js'
|
||||||
import EventBus from './common/js/event-bus.js'
|
import EventBus from './common/js/event-bus.js'
|
||||||
import DomEventBridge from './common/js/dom-event-bridge.js'
|
import DomEventBridge from './common/js/dom-event-bridge.js'
|
||||||
import globalConfig from './common/js/golbalConfig.js';
|
import globalConfig from './common/js/golbalConfig.js';
|
||||||
import {
|
import {
|
||||||
uniStorage
|
uniStorage
|
||||||
} from './common/js/storage.js'
|
} from './common/js/storage.js'
|
||||||
|
|
||||||
Vue.prototype.$store = store //挂在vue
|
Vue.prototype.$store = store //挂在vue
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
Vue.prototype.$util = Util;
|
Vue.prototype.$util = Util;
|
||||||
Vue.prototype.$api = Http;
|
Vue.prototype.$api = Http;
|
||||||
|
|
||||||
Vue.prototype.$langConfig = Lang; //语言包对象
|
Vue.prototype.$langConfig = Lang; //语言包对象
|
||||||
Vue.prototype.$lang = Lang.lang; //解析语言包
|
Vue.prototype.$lang = Lang.lang; //解析语言包
|
||||||
|
|
||||||
Vue.prototype.$config = Config;
|
Vue.prototype.$config = Config;
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
// #ifdef H5
|
EventBus.setDomBridge(DomEventBridge)
|
||||||
EventBus.setDomBridge(DomEventBridge)
|
// #endif
|
||||||
// #endif
|
Vue.prototype.$eventBus = EventBus;
|
||||||
Vue.prototype.$eventBus = EventBus;
|
|
||||||
|
Vue.mixin(globalConfig);
|
||||||
Vue.mixin(globalConfig);
|
|
||||||
|
App.mpType = 'app';
|
||||||
App.mpType = 'app';
|
|
||||||
|
// 重写存储,增加前缀
|
||||||
// 重写存储,增加前缀
|
uniStorage();
|
||||||
Util.rewriteUniStorageMethod();
|
|
||||||
|
//常用组件
|
||||||
//常用组件
|
import loadingCover from '@/components/loading-cover/loading-cover.vue';
|
||||||
import loadingCover from '@/components/loading-cover/loading-cover.vue';
|
Vue.component('loading-cover', loadingCover);
|
||||||
Vue.component('loading-cover', loadingCover);
|
|
||||||
|
import nsEmpty from '@/components/ns-empty/ns-empty.vue';
|
||||||
import nsMpHtml from '@/components/ns-mp-html/ns-mp-html.vue';
|
Vue.component('ns-empty', nsEmpty);
|
||||||
Vue.component('ns-mp-html', nsMpHtml);
|
|
||||||
|
import MescrollUni from "@/components/mescroll/my-list-mescroll.vue";
|
||||||
import nsEmpty from '@/components/ns-empty/ns-empty.vue';
|
Vue.component("mescroll-uni", MescrollUni); //上拉加载,下拉刷新组件
|
||||||
Vue.component('ns-empty', nsEmpty);
|
|
||||||
|
import MescrollBody from "@/components/mescroll/mescroll-body.vue"
|
||||||
import MescrollUni from "@/components/mescroll/my-list-mescroll.vue";
|
Vue.component('mescroll-body', MescrollBody);
|
||||||
Vue.component("mescroll-uni", MescrollUni); //上拉加载,下拉刷新组件
|
|
||||||
|
import NsLogin from "@/components/ns-login/ns-login.vue"
|
||||||
import MescrollBody from "@/components/mescroll/mescroll-body.vue"
|
Vue.component('ns-login', NsLogin);
|
||||||
Vue.component('mescroll-body', MescrollBody);
|
|
||||||
|
import PrivacyPopup from '@/components/wx-privacy-popup/privacy-popup.vue';
|
||||||
import NsLogin from "@/components/ns-login/ns-login.vue"
|
Vue.component('privacy-popup', PrivacyPopup)
|
||||||
Vue.component('ns-login', NsLogin);
|
|
||||||
|
// ========== 新增:注册diy系列组件 ==========
|
||||||
import PrivacyPopup from '@/components/wx-privacy-popup/privacy-popup.vue';
|
import DiyBottomNav from '@/components/diy-components/diy-bottom-nav.vue'
|
||||||
Vue.component('privacy-popup', PrivacyPopup)
|
import DiyGroup from '@/components/diy-components/diy-group.vue'
|
||||||
|
import DiyCategory from '@/components/diy-components/diy-category.vue'
|
||||||
const app = new Vue({
|
import DiyIcon from '@/components/diy-components/diy-icon.vue' // 补充diy-icon
|
||||||
...App,
|
|
||||||
store
|
Vue.component('diy-bottom-nav', DiyBottomNav) // 修正拼写错误
|
||||||
})
|
Vue.component('diy-group', DiyGroup)
|
||||||
|
Vue.component('diy-category', DiyCategory)
|
||||||
|
Vue.component('diy-icon', DiyIcon) // 注册diy-icon
|
||||||
|
// ========== 新增结束 ==========
|
||||||
|
const app = new Vue({
|
||||||
|
...App,
|
||||||
|
store
|
||||||
|
})
|
||||||
|
|
||||||
app.$mount()
|
app.$mount()
|
||||||
@@ -54,18 +54,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/* 快应用特有相关 */
|
|
||||||
"quickapp" : {},
|
|
||||||
/* 小程序特有相关 */
|
/* 小程序特有相关 */
|
||||||
"mp-weixin" : {
|
"mp-weixin" : {
|
||||||
"appid" : "wx29215aa1bd97bbd6",
|
"appid" : "wxa8f94045d9c2fc10",
|
||||||
"setting" : {
|
"setting" : {
|
||||||
"urlCheck" : false,
|
"urlCheck" : false,
|
||||||
"postcss" : false,
|
"postcss" : false,
|
||||||
"es6" : true,
|
"es6" : true,
|
||||||
"minified" : true,
|
"minified" : true
|
||||||
"codeSigning" : true,
|
|
||||||
"uglifyFileName" : true
|
|
||||||
},
|
},
|
||||||
"usingComponents" : true,
|
"usingComponents" : true,
|
||||||
"permission" : {
|
"permission" : {
|
||||||
@@ -110,7 +106,7 @@
|
|||||||
},
|
},
|
||||||
"optimization" : {
|
"optimization" : {
|
||||||
"treeShaking" : {
|
"treeShaking" : {
|
||||||
"enable" : true
|
"enable" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"domain" : " ",
|
"domain" : " ",
|
||||||
@@ -128,5 +124,12 @@
|
|||||||
"uniStatistics" : {
|
"uniStatistics" : {
|
||||||
"version" : "2"
|
"version" : "2"
|
||||||
},
|
},
|
||||||
"sassImplementationName" : "node-sass"
|
"sassImplementationName" : "node-sass",
|
||||||
|
/** 快应用配置 **/
|
||||||
|
"quickapp-webview" : {
|
||||||
|
"package" : "com.jieganfsj.fivegshop",
|
||||||
|
"minPlatformVersion" : 1070,
|
||||||
|
"versionName" : "1.0.0",
|
||||||
|
"versionCode" : 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
4
node_modules/jweixin-module/README.md
generated
vendored
4
node_modules/jweixin-module/README.md
generated
vendored
@@ -19,8 +19,8 @@ https://unpkg.com/jweixin-module/out/index.js
|
|||||||
## 使用
|
## 使用
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var wx = require('jweixin-module')
|
var jweixin = require('jweixin-module')
|
||||||
wx.ready(function(){
|
jweixin.ready(function(){
|
||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|||||||
80
node_modules/jweixin-module/package.json
generated
vendored
80
node_modules/jweixin-module/package.json
generated
vendored
@@ -1,60 +1,26 @@
|
|||||||
{
|
{
|
||||||
"_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",
|
"name": "jweixin-module",
|
||||||
"escapedName": "jweixin-module",
|
"version": "1.6.0",
|
||||||
"rawSpec": "",
|
"description": "微信JS-SDK",
|
||||||
"saveSpec": null,
|
"main": "lib/index.js",
|
||||||
"fetchSpec": "latest"
|
"scripts": {},
|
||||||
},
|
"repository": {
|
||||||
"_requiredBy": [
|
"type": "git",
|
||||||
"#USER",
|
"url": "git+https://github.com/zhetengbiji/jweixin-module.git"
|
||||||
"/"
|
},
|
||||||
],
|
"keywords": [
|
||||||
"_resolved": "https://registry.npmjs.org/jweixin-module/-/jweixin-module-1.4.1.tgz",
|
"wxjssdk",
|
||||||
"_shasum": "1fc8fa42622243f6c35651d272cd587debf56cd1",
|
"weixin",
|
||||||
"_spec": "jweixin-module",
|
"jweixin",
|
||||||
"_where": "E:\\demo\\niushop_uniapp",
|
"wechat",
|
||||||
"author": {
|
"jssdk",
|
||||||
"name": "Shengqiang Guo"
|
"wx"
|
||||||
},
|
],
|
||||||
"bugs": {
|
"author": "Shengqiang Guo",
|
||||||
"url": "https://github.com/zhetengbiji/jweixin-module/issues"
|
"license": "ISC",
|
||||||
},
|
"bugs": {
|
||||||
"bundleDependencies": false,
|
"url": "https://github.com/zhetengbiji/jweixin-module/issues"
|
||||||
"deprecated": false,
|
},
|
||||||
"description": "微信JS-SDK",
|
"homepage": "https://github.com/zhetengbiji/jweixin-module#readme",
|
||||||
"devDependencies": {
|
"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"
|
|
||||||
}
|
}
|
||||||
|
|||||||
28
package-lock.json
generated
28
package-lock.json
generated
@@ -1,13 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "uniappsaas",
|
"name": "frontend",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
|
"dependencies": {
|
||||||
|
"@dcloudio/uni-quickapp-webview": "^2.0.2-4080420251103001",
|
||||||
|
"jweixin-module": "^1.6.0"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"terser-webpack-plugin": "^5.3.10"
|
"terser-webpack-plugin": "^5.3.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@dcloudio/uni-quickapp-webview": {
|
||||||
|
"version": "2.0.2-4080420251103001",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@dcloudio/uni-quickapp-webview/-/uni-quickapp-webview-2.0.2-4080420251103001.tgz",
|
||||||
|
"integrity": "sha512-dxDDk/37OoUZ6PmXhXS/9C8Y5tYRalU6FIXT5OlPf1co2VuLF0OrdqAmINJDWs1dBQgN7e6Hw+bkeK9+4SzLxQ==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/@jridgewell/gen-mapping": {
|
"node_modules/@jridgewell/gen-mapping": {
|
||||||
"version": "0.3.5",
|
"version": "0.3.5",
|
||||||
"resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
|
"resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
|
||||||
@@ -619,6 +629,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/jweixin-module": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/jweixin-module/-/jweixin-module-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/loader-runner": {
|
"node_modules/loader-runner": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://repo.huaweicloud.com/repository/npm/loader-runner/-/loader-runner-4.3.0.tgz",
|
"resolved": "https://repo.huaweicloud.com/repository/npm/loader-runner/-/loader-runner-4.3.0.tgz",
|
||||||
@@ -984,6 +1000,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@dcloudio/uni-quickapp-webview": {
|
||||||
|
"version": "2.0.2-4080420251103001",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@dcloudio/uni-quickapp-webview/-/uni-quickapp-webview-2.0.2-4080420251103001.tgz",
|
||||||
|
"integrity": "sha512-dxDDk/37OoUZ6PmXhXS/9C8Y5tYRalU6FIXT5OlPf1co2VuLF0OrdqAmINJDWs1dBQgN7e6Hw+bkeK9+4SzLxQ=="
|
||||||
|
},
|
||||||
"@jridgewell/gen-mapping": {
|
"@jridgewell/gen-mapping": {
|
||||||
"version": "0.3.5",
|
"version": "0.3.5",
|
||||||
"resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
|
"resolved": "https://repo.huaweicloud.com/repository/npm/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
|
||||||
@@ -1456,6 +1477,11 @@
|
|||||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"jweixin-module": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/jweixin-module/-/jweixin-module-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w=="
|
||||||
|
},
|
||||||
"loader-runner": {
|
"loader-runner": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://repo.huaweicloud.com/repository/npm/loader-runner/-/loader-runner-4.3.0.tgz",
|
"resolved": "https://repo.huaweicloud.com/repository/npm/loader-runner/-/loader-runner-4.3.0.tgz",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"terser-webpack-plugin": "^5.3.10"
|
"terser-webpack-plugin": "^5.3.10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@dcloudio/uni-quickapp-webview": "^2.0.2-4080420251103001",
|
||||||
"jweixin-module": "^1.6.0"
|
"jweixin-module": "^1.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
214
pages.json
214
pages.json
@@ -3,7 +3,7 @@
|
|||||||
{
|
{
|
||||||
"path": "pages/index/index",
|
"path": "pages/index/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationStyle": "custom",
|
// "navigationStyle": "custom",
|
||||||
"enablePullDownRefresh": true
|
"enablePullDownRefresh": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -28,17 +28,15 @@
|
|||||||
"path": "pages/goods/category",
|
"path": "pages/goods/category",
|
||||||
"style": {
|
"style": {
|
||||||
"disableScroll": true,
|
"disableScroll": true,
|
||||||
"navigationStyle": "custom",
|
|
||||||
"navigationBarTitleText": "商品分类",
|
"navigationBarTitleText": "商品分类",
|
||||||
"enablePullDownRefresh": true
|
"enablePullDownRefresh": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 商品详情、限时折扣、预售
|
// 商品详情
|
||||||
{
|
{
|
||||||
"path": "pages/goods/detail",
|
"path": "pages/goods/detail",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationStyle": "custom",
|
|
||||||
"navigationBarTitleText": "商品详情"
|
"navigationBarTitleText": "商品详情"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -56,7 +54,6 @@
|
|||||||
{
|
{
|
||||||
"path": "pages/member/index",
|
"path": "pages/member/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationStyle": "custom",
|
|
||||||
"enablePullDownRefresh": true
|
"enablePullDownRefresh": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -115,55 +112,6 @@
|
|||||||
//******************营销活动模块(26)******************
|
//******************营销活动模块(26)******************
|
||||||
"root": "pages_promotion",
|
"root": "pages_promotion",
|
||||||
"pages": [
|
"pages": [
|
||||||
//----------组合套餐模块(2)----------
|
|
||||||
{
|
|
||||||
"path": "bundling/detail",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "bundling/payment",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//----------砍价模块(5)----------
|
|
||||||
{
|
|
||||||
"path": "bargain/list",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "bargain/detail",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"path": "bargain/my_bargain",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "bargain/payment",
|
|
||||||
"style": {
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
//----------积分模块(2)----------
|
//----------积分模块(2)----------
|
||||||
{
|
{
|
||||||
@@ -762,21 +710,11 @@
|
|||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//******************聊天(4)******************
|
|
||||||
{
|
|
||||||
"path": "chat/room",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"softinputMode": "adjustResize"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//******************支付模块(2)******************
|
//******************支付模块(2)******************
|
||||||
{
|
{
|
||||||
"path": "pay/index",
|
"path": "pay/index",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -784,7 +722,7 @@
|
|||||||
{
|
{
|
||||||
"path": "pay/wx_pay",
|
"path": "pay/wx_pay",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -792,7 +730,7 @@
|
|||||||
{
|
{
|
||||||
"path": "pay/result",
|
"path": "pay/result",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -800,15 +738,7 @@
|
|||||||
{
|
{
|
||||||
"path": "pay/cashier",
|
"path": "pay/cashier",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pay/offlinepay",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -816,7 +746,7 @@
|
|||||||
{
|
{
|
||||||
"path": "storeclose/storeclose",
|
"path": "storeclose/storeclose",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -825,7 +755,7 @@
|
|||||||
{
|
{
|
||||||
"path": "order/logistics",
|
"path": "order/logistics",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -833,7 +763,7 @@
|
|||||||
{
|
{
|
||||||
"path": "order/evaluate",
|
"path": "order/evaluate",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -841,7 +771,7 @@
|
|||||||
{
|
{
|
||||||
"path": "order/refund",
|
"path": "order/refund",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -849,7 +779,7 @@
|
|||||||
{
|
{
|
||||||
"path": "order/refund_goods_select",
|
"path": "order/refund_goods_select",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -857,7 +787,7 @@
|
|||||||
{
|
{
|
||||||
"path": "order/refund_type_select",
|
"path": "order/refund_type_select",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -865,7 +795,7 @@
|
|||||||
{
|
{
|
||||||
"path": "order/refund_batch",
|
"path": "order/refund_batch",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -873,7 +803,7 @@
|
|||||||
{
|
{
|
||||||
"path": "order/refund_detail",
|
"path": "order/refund_detail",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
@@ -881,130 +811,38 @@
|
|||||||
{
|
{
|
||||||
"path": "order/activist",
|
"path": "order/activist",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom",
|
"navigationStyle": "custom",
|
||||||
// #endif
|
// #endif
|
||||||
"navigationBarTitleText": "退款"
|
"navigationBarTitleText": "退款"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "order/detail_virtual",
|
||||||
|
"style": {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
},
|
||||||
//******************登录模块(3)******************
|
//******************登录模块(3)******************
|
||||||
{
|
|
||||||
"path": "login/index",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "登录"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "login/aggrement",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "协议"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "login/login",
|
"path": "login/login",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom",
|
"navigationStyle": "custom",
|
||||||
// #endif
|
// #endif
|
||||||
"navigationBarTitleText": "登录"
|
"navigationBarTitleText": "登录"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "login/register",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "注册"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "form/form",
|
"path": "form/form",
|
||||||
"style": {
|
"style": {
|
||||||
// #ifdef H5
|
// #ifdef APP-PLUS
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "store/list",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "门店列表"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "store/detail",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "门店详情"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "store/store_payment",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "门店付款"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "store/payment_qrcode",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "付款码"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//******************核销模块(4)******************
|
|
||||||
{
|
|
||||||
"path": "verification/index",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "核销台"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "verification/list",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "核销列表"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "verification/detail",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "核销详情"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "weapp/order_shipping",
|
|
||||||
"style": {
|
|
||||||
// #ifdef H5
|
|
||||||
"navigationStyle": "custom",
|
|
||||||
// #endif
|
|
||||||
"navigationBarTitleText": "小程序发货"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//******************AI客服******************
|
//******************AI客服******************
|
||||||
{
|
{
|
||||||
"path": "ai-chat/index",
|
"path": "ai-chat/index",
|
||||||
@@ -1041,7 +879,7 @@
|
|||||||
"text": ""
|
"text": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pagePath": "pages/goods/cart",
|
"pagePath": "pages/contact/contact",
|
||||||
"text": ""
|
"text": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view class="container">
|
|
||||||
<web-view src="https://dify.aigc-quickapp.com/chatbot/ILbr8HHEgpBW2ggp"></web-view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
onLoad() {
|
|
||||||
console.log('Dify 聊天页已加载')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.container {
|
|
||||||
width: 100%;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -14,13 +14,13 @@
|
|||||||
<view class="dite-button" @click="officialAccountsOpen">关注公众号</view>
|
<view class="dite-button" @click="officialAccountsOpen">关注公众号</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="page-header" v-if="diyData.global && diyData.global.navBarSwitch" :style="{ backgroundImage: bgImg }">
|
<!-- <view class="page-header" v-if="diyData.global && diyData.global.navBarSwitch" :style="{ backgroundImage: bgImg }">
|
||||||
<ns-navbar :title-color="textNavColor" :data="diyData.global" :scrollTop="scrollTop" :isBack="false"/>
|
<ns-navbar :title-color="textNavColor" :data="diyData.global" :scrollTop="scrollTop" :isBack="false"/>
|
||||||
</view>
|
</view> -->
|
||||||
|
|
||||||
<diy-index-page v-if="topIndexValue" ref="indexPage" :value="topIndexValue" :bgUrl="bgUrl" :scrollTop="scrollTop" :diyGlobal="diyData.global" class="diy-index-page">
|
<diy-index-page v-if="topIndexValue" ref="indexPage" :value="topIndexValue" :bgUrl="bgUrl" :scrollTop="scrollTop" :diyGlobal="diyData.global" class="diy-index-page">
|
||||||
<template v-slot:components>
|
<template v-slot:components>
|
||||||
<diy-group ref="diyGroup" v-if="diyData.value" :refresh="refresh" :diyData="diyData" :scrollTop="scrollTop" :haveTopCategory="true" :followOfficialAccount="followOfficialAccount"/>
|
<diy-group ref="diyGroup" v-if="diyData.value" :diyData="diyData" :scrollTop="scrollTop" :haveTopCategory="true" :followOfficialAccount="followOfficialAccount"/>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:default>
|
<template v-slot:default>
|
||||||
<ns-copyright v-show="isShowCopyRight"/>
|
<ns-copyright v-show="isShowCopyRight"/>
|
||||||
@@ -94,27 +94,26 @@
|
|||||||
<!-- 选择门店弹出框,定位当前位置,展示最近的一个门店 -->
|
<!-- 选择门店弹出框,定位当前位置,展示最近的一个门店 -->
|
||||||
<view @touchmove.prevent.stop class="choose-store">
|
<view @touchmove.prevent.stop class="choose-store">
|
||||||
<uni-popup ref="chooseStorePopup" type="center" :maskClick="false" class="choose-store">
|
<uni-popup ref="chooseStorePopup" type="center" :maskClick="false" class="choose-store">
|
||||||
<view class="choose-store-popup" v-if="currentStore">
|
<view class="choose-store-popup">
|
||||||
<view class="head-wrap">请确认门店</view>
|
<view class="head-wrap" @click="closeChooseStorePopup">请确认门店</view>
|
||||||
<view class="position-wrap">
|
<view class="position-wrap">
|
||||||
<text class="iconfont icon-dizhi"></text>
|
<text class="iconfont icon-dizhi"></text>
|
||||||
<text class="address">{{ currentPosition || currentStore.show_address }}</text>
|
<text class="address">{{ currentPosition }}</text>
|
||||||
<view class="reposition" @click="reGetLocation" v-if="globalStoreConfig && globalStoreConfig.is_allow_change == 1">
|
<view class="reposition" @click="reposition" v-if="globalStoreConfig && globalStoreConfig.is_allow_change == 1">
|
||||||
<text class="iconfont icon-dingwei"></text>
|
<text class="iconfont icon-dingwei"></text>
|
||||||
<text>重新定位</text>
|
<text>重新定位</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="store-wrap" v-if="currentStore">
|
<view class="store-wrap" v-if="nearestStore">
|
||||||
<text class="tag">当前门店</text>
|
<text class="tag">当前门店</text>
|
||||||
<view class="store-name">{{ currentStore.store_name }}</view>
|
<view class="store-name">{{ nearestStore.store_name }}</view>
|
||||||
<view class="store-close-desc" v-if="currentStore.status == 0 && currentStore.close_desc">{{ currentStore.close_desc }}</view>
|
<view class="address">{{ nearestStore.show_address }}</view>
|
||||||
<view class="address">{{ currentStore.show_address }}</view>
|
<view class="distance" v-if="nearestStore.distance">
|
||||||
<view class="distance" v-if="currentStore.distance">
|
|
||||||
<text class="iconfont icon-dizhi"></text>
|
<text class="iconfont icon-dizhi"></text>
|
||||||
<text>{{ currentStore.distance > 1 ? currentStore.distance + 'km' : currentStore.distance * 1000 + 'm' }}</text>
|
<text>{{ nearestStore.distance > 1 ? nearestStore.distance + 'km' : nearestStore.distance * 1000 + 'm' }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<button type="primary" @click="closeChooseStorePopup">确认进入</button>
|
<button type="primary" @click="enterStore">确认进入</button>
|
||||||
<view class="other-store" @click="chooseOtherStore" v-if="globalStoreConfig && globalStoreConfig.is_allow_change == 1">
|
<view class="other-store" @click="chooseOtherStore" v-if="globalStoreConfig && globalStoreConfig.is_allow_change == 1">
|
||||||
<text>选择其他门店</text>
|
<text>选择其他门店</text>
|
||||||
<text class="iconfont icon-right"></text>
|
<text class="iconfont icon-right"></text>
|
||||||
@@ -122,34 +121,12 @@
|
|||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</view>
|
</view>
|
||||||
<!-- 连锁门店未开启定位或定位失败弹框 -->
|
<hover-nav></hover-nav>
|
||||||
<view @touchmove.prevent.stop class="chain-stores">
|
|
||||||
<uni-popup ref="getLocationFailRef" type="bottom" :maskClick="false" class="choose-store">
|
|
||||||
<view class="chain-store-popup">
|
|
||||||
<view class="title">获取位置失败</view>
|
|
||||||
<view class="body">
|
|
||||||
<view class="center">
|
|
||||||
<view class="image">
|
|
||||||
<image width="341rpx" :src="$util.img('public/uniapp/index/no_location_tips.png')" mode="aspectFit"/>
|
|
||||||
</view>
|
|
||||||
<view class="text-top">系统暂时定位不到您的位置</view>
|
|
||||||
<view class="text-bottom" v-if="mapConfig.wap_is_open == 1">请确认定位服务已经打开或者您可手动选择附近的门店以便我们提供更精确的服务</view>
|
|
||||||
<view class="text-bottom" v-else>请手动选择附近的门店以便我们提供更精确的服务</view>
|
|
||||||
<view class="footer">
|
|
||||||
<button :type="mapConfig.wap_is_open == 1?'default':'primary'" @click="chooseStore">选择门店</button>
|
|
||||||
<button v-if="mapConfig.wap_is_open == 1" type="primary" class="btn-right" @click="openSetting">开启定位</button>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uni-popup>
|
|
||||||
</view>
|
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<!-- 小程序隐私协议 -->
|
<!-- 小程序隐私协议 -->
|
||||||
<privacy-popup ref="privacyPopup"></privacy-popup>
|
<privacy-popup ref="privacyPopup"></privacy-popup>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<to-top v-if="showTop" @toTop="scrollToTopNative()"></to-top>
|
<to-top v-if="showTop" @toTop="scrollToTopNative()"></to-top>
|
||||||
<ns-login ref="login"></ns-login>
|
<ns-login ref="login"></ns-login>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -159,8 +136,8 @@
|
|||||||
import nsNavbar from '@/components/ns-navbar/ns-navbar.vue';
|
import nsNavbar from '@/components/ns-navbar/ns-navbar.vue';
|
||||||
import diyJs from '@/common/js/diy.js';
|
import diyJs from '@/common/js/diy.js';
|
||||||
import indexJs from './public/js/index.js';
|
import indexJs from './public/js/index.js';
|
||||||
import toTop from '@/components/toTop/toTop.vue';
|
import toTop from '@/components/toTop/toTop.vue';
|
||||||
import scroll from '@/common/js/scroll-view.js';
|
import scroll from '@/common/js/scroll-view.js';
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -169,31 +146,8 @@
|
|||||||
nsNavbar,
|
nsNavbar,
|
||||||
toTop
|
toTop
|
||||||
},
|
},
|
||||||
mixins: [diyJs, scroll, indexJs],
|
mixins: [diyJs, scroll, indexJs]
|
||||||
methods: {
|
|
||||||
// 新增:电话按钮点击事件-弹出对话框
|
|
||||||
openCallDialog() {
|
|
||||||
uni.showModal({
|
|
||||||
title: "拨打?【仅为模拟】", // 弹窗标题
|
|
||||||
content: "", // 弹窗内容(可留空)
|
|
||||||
confirmText: "确定", // 确定按钮文字
|
|
||||||
cancelText: "取消", // 取消按钮文字
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
// 点击“确定”后的操作(比如实际拨号)
|
|
||||||
uni.makePhoneCall({
|
|
||||||
phoneNumber: "13800138000" // 替换为实际要拨打的号码
|
|
||||||
});
|
|
||||||
} else if (res.cancel) {
|
|
||||||
// 点击“取消”后的操作(可留空)
|
|
||||||
console.log('用户取消拨打');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@@ -273,14 +227,6 @@
|
|||||||
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
|
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
|
||||||
max-height: unset !important;
|
max-height: unset !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .chain-stores .uni-popup__mask{
|
|
||||||
backdrop-filter: blur(10rpx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/deep/ .chain-stores .uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box, .uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box{
|
|
||||||
max-height: 100vh !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/deep/ .mescroll-totop {
|
/deep/ .mescroll-totop {
|
||||||
right: 24rpx!important;
|
right: 24rpx!important;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user