Compare commits
283 Commits
custom/272
...
tmp/tmp-01
| Author | SHA1 | Date | |
|---|---|---|---|
| a2616c9757 | |||
| fb47da8095 | |||
| 37958cbe39 | |||
| 9f53f147ee | |||
| 2342a14f2e | |||
| 36b0c22e47 | |||
| 4a52b9c229 | |||
| 9ec90a906f | |||
| e125a5f39c | |||
| 8c0ec46dd8 | |||
| b65ec35d3c | |||
| d113d6125b | |||
| 2f24661cd9 | |||
| 50908a274b | |||
| 9e68562de5 | |||
| 8e5561c2a7 | |||
| 8d5c543a4f | |||
| cf411407dd | |||
| 86e4be302b | |||
| 2fd06796e1 | |||
| 60c51e551a | |||
| d0d3ac47c6 | |||
| af677f6565 | |||
| f889efeb16 | |||
| d026bb6180 | |||
| 82b856f5d9 | |||
| 7f33b6948a | |||
| 3489b89a0b | |||
| dc4f2769f9 | |||
| 5cf87e4d56 | |||
| c9ca63cff5 | |||
| a6072f4895 | |||
| 38947ddc62 | |||
| cfe83ada38 | |||
| 1e9e0ffea8 | |||
| 28acdfb621 | |||
| ad9f1c495b | |||
| 7c2a7468e7 | |||
| b2051dcf92 | |||
| e3c86de84a | |||
| 6e0eb5d4f3 | |||
| 9d186ff094 | |||
| 8611ec4dc3 | |||
| 89bfd94a07 | |||
| 5cf8b7b467 | |||
| 2cc0162435 | |||
| d8e75a0c9e | |||
| 8af3c0ccb9 | |||
| d8b78168a8 | |||
| 7675e8e04d | |||
| 88d05048a6 | |||
| 28a92c0635 | |||
| b5a47b8b4e | |||
| 4f99e8b5f2 | |||
| 87fc49146c | |||
| 826fcfb024 | |||
| 7174d87b79 | |||
| 4bc747cd9c | |||
| e046868665 | |||
| 19c3ec4f9f | |||
| ffbc15929d | |||
| 524280d816 | |||
| 6e736e0733 | |||
| 4891566793 | |||
| b02f5fbc21 | |||
| 4f5a300afa | |||
| aae6e76797 | |||
| 3162d6a9f2 | |||
| 8010ac45a6 | |||
| baebba4cef | |||
| 1be7155fe8 | |||
| 611c0b930b | |||
| ec1903519d | |||
| b1953a020d | |||
| 3ce26322e0 | |||
| 588ec60948 | |||
| 962ea124fa | |||
| 0ca0fe3b0d | |||
| cef2b6e02e | |||
| e018f9a8b9 | |||
| def8a6cf6f | |||
| 857f295923 | |||
| 50ee885b74 | |||
| 410f248510 | |||
| ba5fcfaab1 | |||
| 5a46bb8d69 | |||
| e33ad16d10 | |||
| d8ba7ace0f | |||
| 875072bb68 | |||
| 0912b9b031 | |||
| 7ffe4acc0f | |||
| 4bcf0cbd2d | |||
| fdf85dfec7 | |||
| 1d62b37060 | |||
| 4ad93ceace | |||
| 294856d9ef | |||
| ba2c7d6d64 | |||
| ec9e76fda7 | |||
| 5dba8071e4 | |||
| 19a53ef414 | |||
| e943b11c8f | |||
| e9db54980e | |||
| 3ddcc665b8 | |||
| a981c02baf | |||
| 1c3f759b35 | |||
| bb58866192 | |||
| 069b3c2c07 | |||
| c6fd13956a | |||
| a489e24988 | |||
| 6897fc631b | |||
| 6d23a64aef | |||
| f34533b0c7 | |||
| 72c74f44f0 | |||
| 7f3d9c0f10 | |||
| 37f95e7267 | |||
| d3c630e860 | |||
| c5b57cedeb | |||
| bf24746a7c | |||
| 5ff2925ba1 | |||
| 3dc81e7f53 | |||
| 0417c5c5ed | |||
| db26a85c8b | |||
| 54c39259a7 | |||
| 15361211b1 | |||
| e301ddc6ec | |||
| a560ad4a5d | |||
| 7f7a18803f | |||
| 42563d7184 | |||
| 14a903f42a | |||
| c9f8614927 | |||
| fe9303bf4c | |||
| e4dfd0ae11 | |||
| 7037d0b083 | |||
| e8a79bd245 | |||
| 047cf765da | |||
| 3a30b0817d | |||
| a464a8731f | |||
| 7599a80943 | |||
| 992a01cc76 | |||
| dd09c66215 | |||
| e2b89c348f | |||
| 475edc93a6 | |||
| cb86cba389 | |||
| 0dc4dec616 | |||
| 2a5214df11 | |||
| 09e410df00 | |||
|
|
75dfe80bde | ||
|
|
2a1f33323c | ||
|
|
b441c46993 | ||
| 38ade75046 | |||
| 1e51abd7cd | |||
| 0939449aa7 | |||
| 29b5cfda6f | |||
| ceca4e5956 | |||
| aa9d2e64d2 | |||
| e8ccb87266 | |||
| 153c84266a | |||
| 7ae7a1d3bd | |||
| 1ebb94e9e2 | |||
| 9b53540f91 | |||
| 2a36fa2b60 | |||
| 2223636184 | |||
| 6144dc72b8 | |||
| 47e1c2372d | |||
| 5b9bef9214 | |||
| 08880a15df | |||
| e40e6e73b2 | |||
| dd4176998b | |||
| 2896817435 | |||
| dc956761a0 | |||
| 36fd0621fd | |||
| 1e6cd55f0a | |||
| f7fcf7fb27 | |||
| 28359f2f16 | |||
| b3cc86d088 | |||
| c6a8bc04f2 | |||
| 0ed0789528 | |||
| 16d1a3a945 | |||
| 82df9ddbac | |||
| 392a8e2952 | |||
| db7a8d7202 | |||
| bb87f4b1d2 | |||
| fe039ed126 | |||
| 03c1a8d71a | |||
| e8fb35b310 | |||
| 286fcc2142 | |||
| 2280ff68fa | |||
| 9e0cab7ec4 | |||
| a31c004508 | |||
| ee8c24cdf8 | |||
| b043601a77 | |||
| e20968aee2 | |||
| 8ceeca33b4 | |||
| 02e9cfa313 | |||
| 3f894bcb20 | |||
| 8d5d6e3da8 | |||
| ce1ea6eadf | |||
| 191c803f66 | |||
| 4e1448d2c4 | |||
| ce26a9be5f | |||
| 8b01d8f8ec | |||
| 6ab2834fdc | |||
| 85816e416c | |||
| bf8e177c30 | |||
| 57111a00c2 | |||
| aa7c7cbe60 | |||
| d012c7fff7 | |||
| 128d75b921 | |||
| 7e0d61c7e5 | |||
| 26af083839 | |||
| 68bc853dff | |||
| 13166132c7 | |||
| f87c7d963e | |||
| 6f6899deaa | |||
| 7f54666629 | |||
| 5747b256c6 | |||
| 09b285016c | |||
| 72c12a79fd | |||
| 84f4ad83c2 | |||
| 1512c60109 | |||
| 5b41dee46c | |||
| 9ed337b59a | |||
| 8fedeafe63 | |||
| 31336f9a80 | |||
| 2f7c9bf0af | |||
| f8257361b5 | |||
| ec05534ff1 | |||
| 4f9c353e9a | |||
| 52b5f5b006 | |||
| 5a8663eb48 | |||
| 8108802204 | |||
| 6fe3bceb4b | |||
| ee4fbb277c | |||
| 6718010ceb | |||
| faf1f6d3d8 | |||
| 2d98a32efc | |||
| 7fde30063b | |||
| 10465b7cf2 | |||
| c7e9b497ae | |||
| de63cd4c6a | |||
| 2f230d3b2c | |||
| 6f01b3c1c6 | |||
| b10fcf02d4 | |||
| 6956841c8b | |||
| 90820ade30 | |||
| 8df59abd03 | |||
| d1b9e528f8 | |||
| 618babf5bf | |||
| 9a63b5ff4e | |||
| d7b07c974d | |||
| 6358102cae | |||
| 6023b5b65e | |||
| b96b5f0bc3 | |||
| 35aadc7014 | |||
| 4bdbfff7d4 | |||
| 5d34f00b3e | |||
| 548aeed7b7 | |||
| ce13661826 | |||
| d9f0d1987e | |||
| afd002fad3 | |||
| 531dc347f7 | |||
| 405f37a3f6 | |||
| 73f9cb8820 | |||
| b1ebb38c06 | |||
| 60a0e5133e | |||
| 8ef6975ee1 | |||
| be51b30fb4 | |||
| b24f77be1a | |||
| 311efe1ecd | |||
| db8fb25da8 | |||
| 9415f397d2 | |||
| 4da852944e | |||
| f3bb6a1782 | |||
| 2a0489d4b2 | |||
| ca74d4f8e5 | |||
| d9c9599cb2 | |||
| 142a97d65c | |||
| b945583857 | |||
| 88debacf8c | |||
| 9d12b02463 | |||
| 23e81114e9 | |||
| 08583aa8aa | |||
| 5e536afeae |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
|||||||
/.hbuilderx
|
/.hbuilderx
|
||||||
/.idea
|
/.idea
|
||||||
/node_modules
|
/node_modules
|
||||||
|
/iconfont-preview.html
|
||||||
|
|||||||
59
.local.config.js
Normal file
59
.local.config.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
// 本地调试配置示例文件
|
||||||
|
// 复制此文件并重命名为 local.config.js 以使用自定义本地配置
|
||||||
|
|
||||||
|
const localDevConfig = ({
|
||||||
|
'460': { // 制氧设备平台
|
||||||
|
uniacid: 460,
|
||||||
|
domain: 'https://xcx30.5g-quickapp.com/',
|
||||||
|
},
|
||||||
|
'576-xcx30.5g': { // 活性石灰装备
|
||||||
|
uniacid: 576,
|
||||||
|
domain: 'https://xcx30.5g-quickapp.com/',
|
||||||
|
},
|
||||||
|
'2285': { // 数码喷墨墨水
|
||||||
|
uniacid: 2285,
|
||||||
|
domain: 'https://xcx.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
'2811': { // POCT检测分析平台
|
||||||
|
uniacid: 2811,
|
||||||
|
domain: 'https://xcx6.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
'2724': { // 生物菌肥
|
||||||
|
uniacid: 2724,
|
||||||
|
domain: 'https://xcx.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
'2505': { // 煤矿钻机
|
||||||
|
uniacid: 2505,
|
||||||
|
domain: 'https://xcx.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
'2777': { // 养老服务
|
||||||
|
uniacid: 2777,
|
||||||
|
domain: 'https://xcx.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
'1': { // 开发平台
|
||||||
|
uniacid: 1,
|
||||||
|
domain: 'https://dev.aigc-quickapp.com',
|
||||||
|
},
|
||||||
|
'1-test': { // 测试平台
|
||||||
|
uniacid: 1,
|
||||||
|
domain: 'https://test.aigc-quickapp.com',
|
||||||
|
},
|
||||||
|
'local-2': { // 测试平台
|
||||||
|
uniacid: 2,
|
||||||
|
domain: 'http://localhost:8050/',
|
||||||
|
},
|
||||||
|
'100': {
|
||||||
|
uniacid: 100,
|
||||||
|
domain: 'https://5g.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
'1': {
|
||||||
|
uniacid: 1,
|
||||||
|
domain: 'https://5g.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
'115': {
|
||||||
|
uniacid: 115,
|
||||||
|
domain: 'https://5g.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
})['2811']; // 选择要使用的环境配置
|
||||||
|
|
||||||
|
export default localDevConfig;
|
||||||
@@ -6,10 +6,34 @@ const localDevConfig = ({
|
|||||||
uniacid: 460,
|
uniacid: 460,
|
||||||
domain: 'https://xcx30.5g-quickapp.com/',
|
domain: 'https://xcx30.5g-quickapp.com/',
|
||||||
},
|
},
|
||||||
|
'576-xcx30.5g': { // 活性石灰装备
|
||||||
|
uniacid: 576,
|
||||||
|
domain: 'https://xcx30.5g-quickapp.com/',
|
||||||
|
},
|
||||||
'2285': { // 数码喷墨墨水
|
'2285': { // 数码喷墨墨水
|
||||||
uniacid: 2285,
|
uniacid: 2285,
|
||||||
domain: 'https://xcx.aigc-quickapp.com/',
|
domain: 'https://xcx.aigc-quickapp.com/',
|
||||||
},
|
},
|
||||||
|
'2811': { // POCT检测分析平台
|
||||||
|
uniacid: 2811,
|
||||||
|
domain: 'https://xcx6.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
'2812': { // IVD数商模式
|
||||||
|
uniacid: 2812,
|
||||||
|
domain: 'https://xcx6.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
'2724': { // 生物菌肥
|
||||||
|
uniacid: 2724,
|
||||||
|
domain: 'https://xcx.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
'2505': { // 煤矿钻机
|
||||||
|
uniacid: 2505,
|
||||||
|
domain: 'https://xcx.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
|
'2777': { // 养老服务
|
||||||
|
uniacid: 2777,
|
||||||
|
domain: 'https://xcx.aigc-quickapp.com/',
|
||||||
|
},
|
||||||
'1': { // 开发平台
|
'1': { // 开发平台
|
||||||
uniacid: 1,
|
uniacid: 1,
|
||||||
domain: 'https://dev.aigc-quickapp.com',
|
domain: 'https://dev.aigc-quickapp.com',
|
||||||
@@ -18,6 +42,14 @@ const localDevConfig = ({
|
|||||||
uniacid: 1,
|
uniacid: 1,
|
||||||
domain: 'https://test.aigc-quickapp.com',
|
domain: 'https://test.aigc-quickapp.com',
|
||||||
},
|
},
|
||||||
})['2285']; // 选择要使用的环境配置
|
'local-2': { // 测试平台
|
||||||
|
uniacid: 2,
|
||||||
|
domain: 'http://localhost:8050/',
|
||||||
|
},
|
||||||
|
'local-2-dev': { // 本地开发测试平台
|
||||||
|
uniacid: 2,
|
||||||
|
domain: 'http://localhost:8050/',
|
||||||
|
},
|
||||||
|
})['2812']; // 选择要使用的环境配置
|
||||||
|
|
||||||
export default localDevConfig;
|
export default localDevConfig;
|
||||||
10
App.vue
10
App.vue
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [auth],
|
mixins: [auth],
|
||||||
onLaunch: function(options) {
|
onLaunch: async function(options) {
|
||||||
// 方式:支持快应用,从url中query部分获取uniacid,或useragent中获取uniacid
|
// 方式:支持快应用,从url中query部分获取uniacid,或useragent中获取uniacid
|
||||||
if(options.query.uniacid){
|
if(options.query.uniacid){
|
||||||
uni.setStorageSync('uniacid', options.query.uniacid);
|
uni.setStorageSync('uniacid', options.query.uniacid);
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
if (uni.getSystemInfoSync().platform == 'ios') {
|
if (this.$util.getDeviceInfo().platform == 'ios') {
|
||||||
uni.setStorageSync('initUrl', location.href);
|
uni.setStorageSync('initUrl', location.href);
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
@@ -61,7 +61,8 @@
|
|||||||
|
|
||||||
// 主题风格
|
// 主题风格
|
||||||
if (uni.getStorageSync('themeStyle')) {
|
if (uni.getStorageSync('themeStyle')) {
|
||||||
this.$store.commit('setThemeStyle', configExternal.loadThemeSync(uni.getStorageSync('themeStyle')));
|
const themeData = await configExternal.loadTheme(uni.getStorageSync('themeStyle'));
|
||||||
|
this.$store.commit('setThemeStyle', themeData);
|
||||||
this.$store.dispatch('themeColorSet');
|
this.$store.dispatch('themeColorSet');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +266,6 @@
|
|||||||
imgUrl: this.$util.img(share_data.imgUrl)
|
imgUrl: this.$util.img(share_data.imgUrl)
|
||||||
},
|
},
|
||||||
res => {
|
res => {
|
||||||
console.log(res);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -313,7 +313,7 @@
|
|||||||
@import './common/css/iconfont.css';
|
@import './common/css/iconfont.css';
|
||||||
@import './common/css/icondiy.css'; // 自定义图标库
|
@import './common/css/icondiy.css'; // 自定义图标库
|
||||||
@import './common/css/icon/extend.css'; // 扩展图标库
|
@import './common/css/icon/extend.css'; // 扩展图标库
|
||||||
page{
|
page {
|
||||||
background: #f4f6fa;
|
background: #f4f6fa;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -123,7 +123,7 @@ image {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.choose-store {
|
.choose-store {
|
||||||
/deep/ .uni-popup__wrapper{
|
::v-deep .uni-popup__wrapper{
|
||||||
background: none!important;
|
background: none!important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -870,13 +870,13 @@
|
|||||||
// 海报
|
// 海报
|
||||||
// .uni-popup__wrapper-box
|
// .uni-popup__wrapper-box
|
||||||
.poster-layer {
|
.poster-layer {
|
||||||
/deep/ .uni-popup__wrapper.center {
|
::v-deep .uni-popup__wrapper.center {
|
||||||
width: 100vw!important;
|
width: 100vw!important;
|
||||||
height: 100vh!important;
|
height: 100vh!important;
|
||||||
background: none!important;
|
background: none!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
|
::v-deep .uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
|
||||||
max-width: 100vw!important;
|
max-width: 100vw!important;
|
||||||
max-height: 100vh!important;
|
max-height: 100vh!important;
|
||||||
background: none!important;
|
background: none!important;
|
||||||
|
|||||||
@@ -559,7 +559,7 @@ scroll-view ::-webkit-scrollbar {
|
|||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/::-webkit-scrollbar {
|
::v-deep ::-webkit-scrollbar {
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
@@ -609,7 +609,7 @@ scroll-view ::-webkit-scrollbar {
|
|||||||
font-weight: 500!important;
|
font-weight: 500!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .reward-popup .uni-popup__wrapper-box {
|
::v-deep .reward-popup .uni-popup__wrapper-box {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
max-width: unset !important;
|
max-width: unset !important;
|
||||||
max-height: unset !important;
|
max-height: unset !important;
|
||||||
@@ -618,7 +618,7 @@ scroll-view ::-webkit-scrollbar {
|
|||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
// 下拉加载动画【页面】
|
// 下拉加载动画【页面】
|
||||||
/deep/ body uni-page-refresh div{
|
::v-deep body uni-page-refresh div{
|
||||||
width: 14rpx !important;
|
width: 14rpx !important;
|
||||||
height: 14rpx !important;
|
height: 14rpx !important;
|
||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
@@ -626,7 +626,7 @@ scroll-view ::-webkit-scrollbar {
|
|||||||
clip: rect(-152rpx, 90rpx, 90rpx, -30rpx) !important;
|
clip: rect(-152rpx, 90rpx, 90rpx, -30rpx) !important;
|
||||||
animation:.6s backgroundChange linear infinite;
|
animation:.6s backgroundChange linear infinite;
|
||||||
}
|
}
|
||||||
/deep/ body uni-page-refresh div::after{
|
::v-deep body uni-page-refresh div::after{
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -22rpx;
|
left: -22rpx;
|
||||||
@@ -636,7 +636,7 @@ scroll-view ::-webkit-scrollbar {
|
|||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
animation:.5s backgroundChange linear infinite;
|
animation:.5s backgroundChange linear infinite;
|
||||||
}
|
}
|
||||||
/deep/ body uni-page-refresh div::before{
|
::v-deep body uni-page-refresh div::before{
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: -22rpx;
|
right: -22rpx;
|
||||||
@@ -646,15 +646,15 @@ scroll-view ::-webkit-scrollbar {
|
|||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
animation:.7s backgroundChange linear infinite;
|
animation:.7s backgroundChange linear infinite;
|
||||||
}
|
}
|
||||||
/deep/ body uni-page-refresh > div > div{
|
::v-deep body uni-page-refresh > div > div{
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下拉加载动画【scroll-view】
|
// 下拉加载动画【scroll-view】
|
||||||
/deep/ body .uni-scroll-view-refresher{
|
::v-deep body .uni-scroll-view-refresher{
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
/deep/ body .uni-scroll-view-refresher div{
|
::v-deep body .uni-scroll-view-refresher div{
|
||||||
left: 50%;
|
left: 50%;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
@@ -666,7 +666,7 @@ scroll-view ::-webkit-scrollbar {
|
|||||||
clip: rect(-152rpx, 90rpx, 90rpx, -30rpx) !important;
|
clip: rect(-152rpx, 90rpx, 90rpx, -30rpx) !important;
|
||||||
animation:.6s backgroundChange linear infinite;
|
animation:.6s backgroundChange linear infinite;
|
||||||
}
|
}
|
||||||
/deep/ body .uni-scroll-view-refresher div::after{
|
::v-deep body .uni-scroll-view-refresher div::after{
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -22rpx;
|
left: -22rpx;
|
||||||
@@ -676,7 +676,7 @@ scroll-view ::-webkit-scrollbar {
|
|||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
animation:.5s backgroundChange linear infinite;
|
animation:.5s backgroundChange linear infinite;
|
||||||
}
|
}
|
||||||
/deep/ body .uni-scroll-view-refresher div::before{
|
::v-deep body .uni-scroll-view-refresher div::before{
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: -22rpx;
|
right: -22rpx;
|
||||||
@@ -686,7 +686,7 @@ scroll-view ::-webkit-scrollbar {
|
|||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
animation:.7s backgroundChange linear infinite;
|
animation:.7s backgroundChange linear infinite;
|
||||||
}
|
}
|
||||||
/deep/ body .uni-scroll-view-refresher > div > div{
|
::v-deep body .uni-scroll-view-refresher > div > div{
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
@keyframes backgroundChange {
|
@keyframes backgroundChange {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// 修复图片垂直对齐问题,解决两张图片上下有空白缝隙问题
|
// 修复图片垂直对齐问题,解决两张图片上下有空白缝隙问题
|
||||||
/deep/ ._img {
|
::v-deep ._img {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
@@ -377,7 +377,7 @@ view {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .goods-form {
|
::v-deep .goods-form {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -1354,7 +1354,7 @@ view {
|
|||||||
border-bottom: 2rpx solid #F4F4F6;
|
border-bottom: 2rpx solid #F4F4F6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .form-wrap {
|
::v-deep .form-wrap {
|
||||||
margin: 0 24rpx;
|
margin: 0 24rpx;
|
||||||
|
|
||||||
.icon-right {
|
.icon-right {
|
||||||
|
|||||||
@@ -5,6 +5,17 @@ import store from '@/store/index.js'
|
|||||||
let currentConversationId = null;
|
let currentConversationId = null;
|
||||||
const CONVERSATION_KEY = 'ai_conversation_id';
|
const CONVERSATION_KEY = 'ai_conversation_id';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取域名配置参数(避免重复代码)
|
||||||
|
*/
|
||||||
|
function getDomainParams() {
|
||||||
|
return {
|
||||||
|
imgDomain: Config.imgDomain,
|
||||||
|
h5Domain: Config.h5Domain,
|
||||||
|
baseUrl: Config.baseUrl
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化时从本地读取会话ID
|
// 初始化时从本地读取会话ID
|
||||||
try {
|
try {
|
||||||
const saved = uni.getStorageSync(CONVERSATION_KEY);
|
const saved = uni.getStorageSync(CONVERSATION_KEY);
|
||||||
@@ -16,12 +27,19 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
/**
|
||||||
|
* 获取uniacid
|
||||||
|
* @returns {number} uniacid
|
||||||
|
*/
|
||||||
|
getUniacid() {
|
||||||
|
return uni.getStorageSync('uniacid') || Config.uniacid; // 从缓存中获取uniacid,或使用默认uniacid
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送普通消息(blocking 模式)
|
* 发送普通消息(blocking 模式)
|
||||||
*/
|
*/
|
||||||
async sendMessage(message, options = {}) {
|
async sendMessage(message, options = {}) {
|
||||||
try {
|
try {
|
||||||
const aiConfig = store.getters.globalAIKefuConfig;
|
|
||||||
const params = {
|
const params = {
|
||||||
url: '/api/kefu/chat',
|
url: '/api/kefu/chat',
|
||||||
data: {
|
data: {
|
||||||
@@ -31,16 +49,14 @@ export default {
|
|||||||
query: message,
|
query: message,
|
||||||
response_mode: 'blocking', // 强制 blocking
|
response_mode: 'blocking', // 强制 blocking
|
||||||
user: store.state.memberInfo?.id || 'anonymous',
|
user: store.state.memberInfo?.id || 'anonymous',
|
||||||
conversation_id: this.getConversationId() || ''
|
conversation_id: this.getConversationId() || '',
|
||||||
|
...getDomainParams()
|
||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('Sending blocking request to:', params.url);
|
|
||||||
console.log('Request data:', params.data);
|
|
||||||
|
|
||||||
const response = await http.sendRequest({
|
const response = await http.sendRequest({
|
||||||
...params,
|
...params,
|
||||||
async: false
|
async: false
|
||||||
@@ -52,7 +68,14 @@ export default {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Dify API请求失败:', error);
|
console.error('[AI Service] Dify API请求失败,详细错误:', error);
|
||||||
|
console.error('[AI Service] 错误堆栈:', error.stack);
|
||||||
|
// 打印更多信息帮助调试
|
||||||
|
console.error('[AI Service] store 状态:', {
|
||||||
|
memberInfo: store.state.memberInfo,
|
||||||
|
uniacid: this.getUniacid(),
|
||||||
|
token: store.state.token
|
||||||
|
});
|
||||||
throw new Error('AI服务暂时不可用,请稍后重试');
|
throw new Error('AI服务暂时不可用,请稍后重试');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -60,55 +83,106 @@ export default {
|
|||||||
/**
|
/**
|
||||||
* 流式消息入口(自动适配平台)
|
* 流式消息入口(自动适配平台)
|
||||||
*/
|
*/
|
||||||
async sendStreamMessage(message, onChunk, onComplete) {
|
async sendStreamMessage(message, onChunk, onComplete) {
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
// 微信小程序:降级为普通请求 + 前端打字模拟
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
const match = Config.baseUrl.match(/^(?:https?:\/\/|wss?:\/\/)([^\/\s:]+)/);
|
||||||
const result = await this.sendMessage(message);
|
const domain = match ? match[1] : '';
|
||||||
const content = result.content || '';
|
const wssUrl = `wss://${domain}/ws/aikefu`;
|
||||||
const conversationId = result.conversationId || '';
|
const socketTask = wx.connectSocket({
|
||||||
|
url: wssUrl,
|
||||||
|
header: {}
|
||||||
|
});
|
||||||
|
|
||||||
// 保存会话ID(确保连续对话)
|
let content = '';
|
||||||
if (conversationId) {
|
let conversationId = '';
|
||||||
this.setConversationId(conversationId);
|
let isAuthenticated = false;
|
||||||
}
|
|
||||||
|
|
||||||
// 模拟打字效果
|
socketTask.onOpen(() => {
|
||||||
let index = 0;
|
socketTask.send({
|
||||||
const chunkSize = 2; // 每次显示2个字符
|
data: JSON.stringify({
|
||||||
return new Promise((resolve) => {
|
action: 'auth',
|
||||||
const timer = setInterval(() => {
|
uniacid: this.getUniacid(),
|
||||||
if (index < content.length) {
|
token: store.state.token || 'test_token',
|
||||||
const chunk = content.substring(index, index + chunkSize);
|
user_id: store.state.memberInfo?.id || 'anonymous'
|
||||||
index += chunkSize;
|
})
|
||||||
if (onChunk) onChunk(chunk);
|
});
|
||||||
} else {
|
});
|
||||||
clearInterval(timer);
|
|
||||||
if (onComplete) {
|
socketTask.onMessage((res) => {
|
||||||
onComplete({
|
try {
|
||||||
content: content,
|
const data = JSON.parse(res.data);
|
||||||
conversation_id: conversationId
|
|
||||||
});
|
if (data.type === 'auth_success') {
|
||||||
}
|
isAuthenticated = true;
|
||||||
resolve({ content, conversation_id: conversationId });
|
socketTask.send({
|
||||||
}
|
data: JSON.stringify({
|
||||||
}, 80); // 打字速度:80ms/次
|
action: 'chat',
|
||||||
});
|
uniacid: this.getUniacid(),
|
||||||
} catch (error) {
|
query: message,
|
||||||
console.error('小程序流式消息降级失败:', error);
|
user_id: store.state.memberInfo?.id || 'anonymous',
|
||||||
if (onComplete) {
|
conversation_id: this.getConversationId() || '',
|
||||||
onComplete({ error: error.message || '发送失败' });
|
...getDomainParams()
|
||||||
}
|
})
|
||||||
throw error;
|
});
|
||||||
}
|
} else if (data.type === 'auth_failed') {
|
||||||
|
const errorMsg = '认证失败,请重新登录';
|
||||||
|
console.error(errorMsg, data);
|
||||||
|
reject(new Error(errorMsg));
|
||||||
|
if (onComplete) onComplete({ error: errorMsg });
|
||||||
|
socketTask.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理流式消息块
|
||||||
|
else if (data.event === 'message') {
|
||||||
|
const text = data.answer || data.content || data.text || '';
|
||||||
|
content += text;
|
||||||
|
if (onChunk) onChunk(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理流结束
|
||||||
|
else if (data.event === 'message_end') {
|
||||||
|
conversationId = data.conversation_id || '';
|
||||||
|
if (conversationId) {
|
||||||
|
this.setConversationId(conversationId);
|
||||||
|
}
|
||||||
|
if (onComplete) {
|
||||||
|
onComplete({ content, conversation_id: conversationId });
|
||||||
|
}
|
||||||
|
resolve({ content, conversation_id: conversationId });
|
||||||
|
socketTask.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可选:处理 done
|
||||||
|
else if (data.type === 'done') {
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.error('WebSocket 消息解析失败:', e, '原始数据:', res.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socketTask.onError((err) => {
|
||||||
|
const errorMsg = 'WebSocket 连接失败';
|
||||||
|
console.error(errorMsg, err);
|
||||||
|
reject(new Error(errorMsg));
|
||||||
|
if (onComplete) onComplete({ error: errorMsg });
|
||||||
|
});
|
||||||
|
|
||||||
|
socketTask.onClose(() => {
|
||||||
|
});
|
||||||
|
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
if (!isAuthenticated || content === '') {
|
||||||
|
console.warn('WebSocket 超时,强制关闭');
|
||||||
|
socketTask.close();
|
||||||
|
reject(new Error('AI服务响应超时'));
|
||||||
|
if (onComplete) onComplete({ error: 'AI服务响应超时' });
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
});
|
||||||
// #endif
|
// #endif
|
||||||
|
},
|
||||||
// #ifdef H5
|
|
||||||
// H5:使用真实流式(EventSource / Fetch)
|
|
||||||
return this.sendHttpStream(message, onChunk, onComplete);
|
|
||||||
// #endif
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP 流式请求(仅 H5 使用)
|
* HTTP 流式请求(仅 H5 使用)
|
||||||
*/
|
*/
|
||||||
@@ -123,20 +197,19 @@ export default {
|
|||||||
'Accept': 'text/event-stream',
|
'Accept': 'text/event-stream',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
uniacid: store.state.uniacid || '1',
|
uniacid: this.getUniacid(),
|
||||||
|
token: store.state.token || 'test_token',
|
||||||
inputs: {},
|
inputs: {},
|
||||||
query: message,
|
query: message,
|
||||||
response_mode: 'streaming',
|
response_mode: 'streaming',
|
||||||
user_id: store.state.memberInfo?.id || 'anonymous',
|
user_id: store.state.memberInfo?.id || 'anonymous',
|
||||||
conversation_id: this.getConversationId() || ''
|
conversation_id: this.getConversationId() || '',
|
||||||
|
...getDomainParams()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok || !response.body) {
|
||||||
throw new Error(`HTTP ${response.status}`);
|
throw new Error('无效响应');
|
||||||
}
|
|
||||||
if (!response.body) {
|
|
||||||
throw new Error('响应体不可用');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const reader = response.body.getReader();
|
const reader = response.body.getReader();
|
||||||
@@ -145,50 +218,64 @@ export default {
|
|||||||
let content = '';
|
let content = '';
|
||||||
let conversationId = '';
|
let conversationId = '';
|
||||||
|
|
||||||
function processBuffer(buf, callback) {
|
while (true) {
|
||||||
const lines = buf.split('\n');
|
const { done, value } = await reader.read();
|
||||||
buf = lines.pop() || '';
|
if (done) break;
|
||||||
|
|
||||||
|
buffer += decoder.decode(value, { stream: true });
|
||||||
|
|
||||||
|
// 按行分割,保留不完整的最后一行
|
||||||
|
const lines = buffer.split('\n');
|
||||||
|
buffer = lines.pop() || ''; // 未完成的行留到下次
|
||||||
|
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
const trimmed = line.trim();
|
const trimmed = line.trim();
|
||||||
if (trimmed.startsWith('data:')) {
|
if (trimmed.startsWith('data:')) {
|
||||||
const jsonStr = trimmed.slice(5).trim();
|
try {
|
||||||
if (jsonStr) {
|
const jsonStr = trimmed.slice(5).trim();
|
||||||
try {
|
if (jsonStr && jsonStr !== '[DONE]') {
|
||||||
const data = JSON.parse(jsonStr);
|
const data = JSON.parse(jsonStr);
|
||||||
if (data.event === 'message') {
|
if (data.event === 'message') {
|
||||||
const text = data.answer || data.text || '';
|
const text = data.answer || data.text || '';
|
||||||
content += text;
|
content += text;
|
||||||
callback(text);
|
if (onChunk) onChunk(text);
|
||||||
}
|
}
|
||||||
if (data.conversation_id) {
|
if (data.conversation_id) {
|
||||||
conversationId = data.conversation_id;
|
conversationId = data.conversation_id;
|
||||||
}
|
}
|
||||||
if (data.event === 'message_end') {
|
if (data.event === 'message_end') {
|
||||||
// 可选:提前完成
|
// 可提前结束
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
console.warn('解析流数据失败:', e);
|
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('解析失败:', e, line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
// 处理最后残留的 buffer(如果有)
|
||||||
const { done, value } = await reader.read();
|
if (buffer.trim().startsWith('data:')) {
|
||||||
if (done) break;
|
try {
|
||||||
buffer += decoder.decode(value, { stream: true });
|
const jsonStr = buffer.trim().slice(5);
|
||||||
buffer = processBuffer(buffer, (chunk) => {
|
if (jsonStr) {
|
||||||
if (onChunk) onChunk(chunk);
|
const data = JSON.parse(jsonStr);
|
||||||
});
|
if (data.event === 'message') {
|
||||||
|
const text = data.answer || '';
|
||||||
|
content += text;
|
||||||
|
if (onChunk) onChunk(text);
|
||||||
|
}
|
||||||
|
if (data.conversation_id) {
|
||||||
|
conversationId = data.conversation_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('最后 buffer 解析失败:', e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onComplete) {
|
if (onComplete) {
|
||||||
onComplete({
|
onComplete({ content, conversation_id: conversationId });
|
||||||
content,
|
|
||||||
conversation_id: conversationId
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return { content, conversation_id: conversationId };
|
return { content, conversation_id: conversationId };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -196,11 +283,6 @@ export default {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
// 理论上不会执行到这里,但防止 fallback
|
|
||||||
return this.sendStreamMessage(message, onChunk, onComplete);
|
|
||||||
// #endif
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -256,17 +338,19 @@ export default {
|
|||||||
* 生成新会话(如需)
|
* 生成新会话(如需)
|
||||||
*/
|
*/
|
||||||
async generateConversationId() {
|
async generateConversationId() {
|
||||||
const params = {
|
const params = {
|
||||||
url: '/api/kefu/createConversation',
|
url: '/api/kefu/createConversation',
|
||||||
data: {
|
data: {
|
||||||
uniacid: store.state.uniacid,
|
uniacid: this.getUniacid(),
|
||||||
user_id: store.state.memberInfo?.id || 'anonymous',
|
token: store.state.token || 'test_token',
|
||||||
member_id: store.state.memberInfo?.id || '',
|
user_id: store.state.memberInfo?.id || 'anonymous',
|
||||||
},
|
member_id: store.state.memberInfo?.id || 'anonymous',
|
||||||
header: {
|
...getDomainParams()
|
||||||
'Content-Type': 'application/json'
|
},
|
||||||
}
|
header: {
|
||||||
};
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
};
|
||||||
const response = await http.sendRequest({
|
const response = await http.sendRequest({
|
||||||
...params,
|
...params,
|
||||||
async: false
|
async: false
|
||||||
@@ -305,7 +389,10 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const response = await http.sendRequest({
|
const response = await http.sendRequest({
|
||||||
url: '/api/kefu/clear-conversation',
|
url: '/api/kefu/clear-conversation',
|
||||||
data: { conversation_id: conversationId },
|
data: {
|
||||||
|
conversation_id: conversationId,
|
||||||
|
...getDomainParams()
|
||||||
|
},
|
||||||
async: false
|
async: false
|
||||||
});
|
});
|
||||||
return response.success;
|
return response.success;
|
||||||
@@ -324,13 +411,14 @@ export default {
|
|||||||
throw new Error('会话ID(conversation_id)是必填参数');
|
throw new Error('会话ID(conversation_id)是必填参数');
|
||||||
}
|
}
|
||||||
const requestData = {
|
const requestData = {
|
||||||
uniacid: params.uniacid || store.state.uniacid || '1',
|
uniacid: params.uniacid || this.getUniacid(),
|
||||||
conversation_id: params.conversation_id,
|
conversation_id: params.conversation_id,
|
||||||
user_id: params.user_id || store.state.memberInfo?.id || 'anonymous',
|
user_id: params.user_id || store.state.memberInfo?.id || 'anonymous',
|
||||||
limit: params.limit || 20,
|
limit: params.limit || 20,
|
||||||
offset: params.offset || 0,
|
offset: params.offset || 0,
|
||||||
member_id: params.member_id || store.state.memberInfo?.id || '',
|
member_id: params.member_id || store.state.memberInfo?.id || 'anonymous',
|
||||||
token: params.token || ''
|
token: params.token || '',
|
||||||
|
...getDomainParams()
|
||||||
};
|
};
|
||||||
const response = await http.sendRequest({
|
const response = await http.sendRequest({
|
||||||
url: '/api/kefu/getHistory',
|
url: '/api/kefu/getHistory',
|
||||||
@@ -369,13 +457,17 @@ export default {
|
|||||||
if (window.currentEventSource) {
|
if (window.currentEventSource) {
|
||||||
window.currentEventSource.close();
|
window.currentEventSource.close();
|
||||||
}
|
}
|
||||||
const params = new URLSearchParams({
|
const paramsObj = {
|
||||||
uniacid: store.state.uniacid || '1',
|
uniacid: this.getUniacid(),
|
||||||
user_id: store.state.memberInfo?.id || '123456',
|
user_id: store.state.memberInfo?.id || 'anonymous',
|
||||||
|
member_id: store.state.memberInfo?.id || 'anonymous',
|
||||||
|
token: store.state.token || 'test_token',
|
||||||
query: message,
|
query: message,
|
||||||
conversation_id: conversationId || '',
|
conversation_id: conversationId || '',
|
||||||
stream: 'true'
|
stream: 'true',
|
||||||
});
|
...getDomainParams()
|
||||||
|
};
|
||||||
|
const params = new URLSearchParams(paramsObj);
|
||||||
const url = `${Config.baseUrl}/api/kefu/chat?${params.toString()}`;
|
const url = `${Config.baseUrl}/api/kefu/chat?${params.toString()}`;
|
||||||
try {
|
try {
|
||||||
const eventSource = new EventSource(url);
|
const eventSource = new EventSource(url);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const langConfig = {
|
|||||||
// 主题配置
|
// 主题配置
|
||||||
export const themeConfig = {
|
export const themeConfig = {
|
||||||
// 主题列表
|
// 主题列表
|
||||||
themeList: ['default', 'red', 'green', 'blue'],
|
themeList: ['default', 'red', 'green', 'blue', 'pink', 'gold', 'purple', 'yellow', 'black'],
|
||||||
// 默认主题
|
// 默认主题
|
||||||
defaultTheme: 'default'
|
defaultTheme: 'default'
|
||||||
};
|
};
|
||||||
@@ -98,28 +98,6 @@ class ConfigExternal {
|
|||||||
return this.loadPromises[key];
|
return this.loadPromises[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载主题配置(同步方式)
|
|
||||||
* @param {string} theme - 主题名称
|
|
||||||
* @returns {object} - 主题配置
|
|
||||||
*/
|
|
||||||
loadThemeSync(theme = themeConfig.defaultTheme) {
|
|
||||||
if (this.loadedConfigs[`theme_${theme}`]) {
|
|
||||||
return this.loadedConfigs[`theme_${theme}`];
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 动态加载主题配置
|
|
||||||
const themeData = require(`@/common/js/style_color.js`)['default'][theme];
|
|
||||||
console.log('sync themeData => ', themeData);
|
|
||||||
this.loadedConfigs[`theme_${theme}`] = themeData;
|
|
||||||
return themeData;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`加载主题 ${theme} 失败:`, error);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载主题配置(异步方式)
|
* 加载主题配置(异步方式)
|
||||||
* @param {string} theme - 主题名称
|
* @param {string} theme - 主题名称
|
||||||
@@ -138,7 +116,7 @@ class ConfigExternal {
|
|||||||
try {
|
try {
|
||||||
// 动态加载主题配置
|
// 动态加载主题配置
|
||||||
const themeData = require(`@/common/js/style_color.js`)['default'][theme];
|
const themeData = require(`@/common/js/style_color.js`)['default'][theme];
|
||||||
console.log('async themeData => ', themeData);
|
// console.log('async themeData => ', themeData);
|
||||||
this.loadedConfigs[`theme_${theme}`] = themeData;
|
this.loadedConfigs[`theme_${theme}`] = themeData;
|
||||||
resolve(themeData);
|
resolve(themeData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ try {
|
|||||||
// 默认域名, 自定义发行时可以修改
|
// 默认域名, 自定义发行时可以修改
|
||||||
let defaultDomain = '';
|
let defaultDomain = '';
|
||||||
|
|
||||||
|
// #ifdef H5_XCX_5G_QUICKAPP_COM
|
||||||
|
defaultDomain = 'https://xcx20.5g-quickapp.com';
|
||||||
|
// #endif
|
||||||
|
|
||||||
// #ifdef H5_XCX_AIGC_QUICKAPP_COM
|
// #ifdef H5_XCX_AIGC_QUICKAPP_COM
|
||||||
defaultDomain = 'https://xcx.aigc-quickapp.com/';
|
defaultDomain = 'https://xcx.aigc-quickapp.com/';
|
||||||
// #endif
|
// #endif
|
||||||
@@ -43,19 +47,20 @@ let localDevConfig = { uniacid: 0, domain: defaultDomain };
|
|||||||
|
|
||||||
// #ifndef PRODUCTION
|
// #ifndef PRODUCTION
|
||||||
// 尝试动态加载本地配置文件
|
// 尝试动态加载本地配置文件
|
||||||
try {
|
if (process?.env?.NODE_ENV === 'development') {
|
||||||
// 尝试从项目根目录加载本地配置文件
|
try {
|
||||||
// 使用相对路径的方式,确保在不同平台下都能正确解析
|
// 尝试从项目根目录加载本地配置文件
|
||||||
let customConfig = require('@/.local.config.js').default;
|
// 使用相对路径的方式,确保在不同平台下都能正确解析
|
||||||
if (customConfig) {
|
let customConfig = require('@/.local.config.js').default;
|
||||||
localDevConfig = customConfig;
|
if (customConfig) {
|
||||||
|
localDevConfig = customConfig;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// 如果本地配置文件不存在或加载失败,保持使用默认配置
|
||||||
|
// 只在开发模式下输出提示信息
|
||||||
|
// #ifdef WEB
|
||||||
|
// #endif
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
// 如果本地配置文件不存在或加载失败,保持使用默认配置
|
|
||||||
// 只在开发模式下输出提示信息
|
|
||||||
// #ifdef WEB
|
|
||||||
console.log('本地配置文件 .local.config.js 不存在,使用默认配置');
|
|
||||||
// #endif
|
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
* 客服统一处理服务
|
* 客服统一处理服务
|
||||||
* 整合各种客服方式,提供统一的调用接口
|
* 整合各种客服方式,提供统一的调用接口
|
||||||
*/
|
*/
|
||||||
|
import IMAGE_CONFIG from './image-config.js';
|
||||||
|
|
||||||
export class CustomerService {
|
export class CustomerService {
|
||||||
constructor(vueInstance, externalConfig = null) {
|
constructor(vueInstance, externalConfig = null) {
|
||||||
this.vm = vueInstance;
|
this.vm = vueInstance;
|
||||||
@@ -28,28 +30,28 @@ export class CustomerService {
|
|||||||
return this.latestPlatformConfig;
|
return this.latestPlatformConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优先级:外部传入的最新配置 > vuex配置 > 空对象
|
// 优先级:外部传入 > vuex store > 空对象
|
||||||
const servicerConfig = this.externalConfig || this.vm.$store.state.servicerConfig || {};
|
const servicerConfig = this.externalConfig || this.vm.$store.state.servicerConfig || {};
|
||||||
console.log(`【实时客服配置】`, servicerConfig);
|
|
||||||
|
|
||||||
let platformConfig = null;
|
let platformConfig = null;
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
platformConfig = servicerConfig.h5 ? (typeof servicerConfig.h5 === 'object' ? servicerConfig.h5 : null) : null;
|
platformConfig = servicerConfig.h5 && typeof servicerConfig.h5 === 'object' ? servicerConfig.h5 : null;
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
platformConfig = servicerConfig.weapp ? (typeof servicerConfig.weapp === 'object' ? servicerConfig.weapp : null) : null;
|
platformConfig = servicerConfig.weapp && typeof servicerConfig.weapp === 'object' ? servicerConfig.weapp : null;
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef MP-ALIPAY
|
// #ifdef MP-ALIPAY
|
||||||
platformConfig = servicerConfig.aliapp ? (typeof servicerConfig.aliapp === 'object' ? servicerConfig.aliapp : null) : null;
|
platformConfig = servicerConfig.aliapp && typeof servicerConfig.aliapp === 'object' ? servicerConfig.aliapp : null;
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef PC
|
// #ifdef PC
|
||||||
platformConfig = servicerConfig.pc ? (typeof servicerConfig.pc === 'object' ? servicerConfig.pc : null) : null;
|
platformConfig = servicerConfig.pc && typeof servicerConfig.pc === 'object' ? servicerConfig.pc : null;
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// 处理空数组情况(你的配置中pc/aliapp是空数组,转为null)
|
// 防止空数组被当作有效配置
|
||||||
if (Array.isArray(platformConfig)) {
|
if (Array.isArray(platformConfig)) {
|
||||||
platformConfig = null;
|
platformConfig = null;
|
||||||
}
|
}
|
||||||
@@ -75,6 +77,15 @@ export class CustomerService {
|
|||||||
return config && typeof config === 'object' && config.type;
|
return config && typeof config === 'object' && config.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否有有效的客服配置(用于判断是否显示客服按钮)
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
hasValidKefuConfig() {
|
||||||
|
const config = this.getPlatformConfig();
|
||||||
|
return config && typeof config === 'object' && config.type && config.type !== 'none';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证客服配置完整性
|
* 验证客服配置完整性
|
||||||
* @returns {Object} 验证结果
|
* @returns {Object} 验证结果
|
||||||
@@ -89,32 +100,18 @@ export class CustomerService {
|
|||||||
warnings: []
|
warnings: []
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!config) {
|
if (!config || !config.type) {
|
||||||
result.isValid = false;
|
|
||||||
result.errors.push('客服配置不存在');
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.type === 'aikefu') {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.type) {
|
|
||||||
result.isValid = false;
|
result.isValid = false;
|
||||||
result.errors.push('客服类型未配置');
|
result.errors.push('客服类型未配置');
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.type === 'wxwork') {
|
if (config.type === 'wxwork') {
|
||||||
if (!wxworkConfig) {
|
if (!wxworkConfig || !wxworkConfig.enable) {
|
||||||
result.isValid = false;
|
result.warnings.push('企业微信未启用');
|
||||||
result.errors.push('企业微信配置不存在');
|
}
|
||||||
} else {
|
if (!wxworkConfig.contact_url) {
|
||||||
if (!wxworkConfig.enable) {
|
result.warnings.push('企业微信活码链接未配置');
|
||||||
result.warnings.push('企业微信功能未启用');
|
|
||||||
}
|
|
||||||
if (!wxworkConfig.contact_url) {
|
|
||||||
result.warnings.push('企业微信活码链接未配置,将使用原有客服方式');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,40 +119,39 @@ export class CustomerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 跳转到Dify客服页面
|
* 跳转到 AI 客服页面(Dify)
|
||||||
*/
|
*/
|
||||||
openDifyService() {
|
openDifyService() {
|
||||||
try {
|
try {
|
||||||
if (this.vm.setAiUnreadCount) {
|
// 清除未读数(如果存在)
|
||||||
|
if (typeof this.vm.setAiUnreadCount === 'function') {
|
||||||
this.vm.setAiUnreadCount(0);
|
this.vm.setAiUnreadCount(0);
|
||||||
}
|
}
|
||||||
// 强制跳转,忽略框架层的封装
|
|
||||||
uni.redirectTo({
|
// ✅ 修正路径:必须与 pages.json 中注册的路径一致
|
||||||
url: '/pages_tool/ai-chat/index',
|
const aiChatUrl = '/pages_tool/ai-chat/index';
|
||||||
|
|
||||||
|
// ✅ 使用 navigateTo 保留返回栈(体验更好)
|
||||||
|
uni.navigateTo({
|
||||||
|
url: aiChatUrl,
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
// 兜底:使用window.location跳转(H5)
|
console.error('跳转 AI 客服失败:', err);
|
||||||
|
// H5 兜底
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
window.location.href = '/pages_tool/ai-chat/index';
|
window.location.href = aiChatUrl;
|
||||||
// #endif
|
// #endif
|
||||||
console.error('跳转Dify客服失败:', err);
|
uni.showToast({ title: '打开客服失败', icon: 'none' });
|
||||||
uni.showToast({
|
|
||||||
title: '跳转客服失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('跳转Dify客服异常:', e);
|
console.error('跳转 AI 客服异常:', e);
|
||||||
uni.showToast({
|
uni.showToast({ title: '打开客服失败', icon: 'none' });
|
||||||
title: '跳转客服失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理客服点击事件
|
* 处理客服点击事件(统一入口)
|
||||||
* @param {Object} options 选项参数
|
* @param {Object} options 选项参数(用于消息卡片等)
|
||||||
*/
|
*/
|
||||||
handleCustomerClick(options = {}) {
|
handleCustomerClick(options = {}) {
|
||||||
const validation = this.validateConfig();
|
const validation = this.validateConfig();
|
||||||
@@ -170,6 +166,7 @@ export class CustomerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const config = this.getPlatformConfig();
|
const config = this.getPlatformConfig();
|
||||||
|
|
||||||
const { niushop = {}, sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options;
|
const { niushop = {}, sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options;
|
||||||
|
|
||||||
if (config.type === 'none') {
|
if (config.type === 'none') {
|
||||||
@@ -177,7 +174,7 @@ export class CustomerService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 核心分支:根据最新的type处理
|
// 核心路由:根据 type 决定行为
|
||||||
switch (config.type) {
|
switch (config.type) {
|
||||||
case 'aikefu':
|
case 'aikefu':
|
||||||
this.openDifyService();
|
this.openDifyService();
|
||||||
@@ -188,6 +185,9 @@ export class CustomerService {
|
|||||||
case 'third':
|
case 'third':
|
||||||
this.openThirdService(config);
|
this.openThirdService(config);
|
||||||
break;
|
break;
|
||||||
|
case 'miniprogram':
|
||||||
|
this.openThirdService(config);
|
||||||
|
break;
|
||||||
case 'niushop':
|
case 'niushop':
|
||||||
this.openNiushopService(niushop);
|
this.openNiushopService(niushop);
|
||||||
break;
|
break;
|
||||||
@@ -198,36 +198,40 @@ export class CustomerService {
|
|||||||
this.openAliappService(config);
|
this.openAliappService(config);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
console.error('【未知客服类型】', config.type);
|
||||||
this.makePhoneCall();
|
this.makePhoneCall();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// ================== 各类型客服实现 ==================
|
||||||
* 打开企业微信客服
|
|
||||||
* @param {boolean} useOriginalService 是否使用原有客服方式
|
|
||||||
* @param {Object} servicerConfig 客服配置
|
|
||||||
* @param {Object} options 选项参数
|
|
||||||
*/
|
|
||||||
openWxworkService(useOriginalService = false, servicerConfig = null, options = {}) {
|
openWxworkService(useOriginalService = false, servicerConfig = null, options = {}) {
|
||||||
const config = servicerConfig || this.getPlatformConfig();
|
const config = servicerConfig || this.getPlatformConfig();
|
||||||
const wxworkConfig = this.getWxworkConfig();
|
const wxworkConfig = this.getWxworkConfig();
|
||||||
const { sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options;
|
const { sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options;
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
if (wxworkConfig?.enable && wxworkConfig?.contact_url && !useOriginalService) {
|
if (!useOriginalService && wxworkConfig?.enable && wxworkConfig?.contact_url) {
|
||||||
wx.navigateToMiniProgram({
|
wx.navigateToMiniProgram({
|
||||||
appId: 'wxeb490c6f9b154ef9',
|
appId: 'wxeb490c6f9b154ef9',
|
||||||
path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(wxworkConfig.contact_url)}`,
|
path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(wxworkConfig.contact_url)}`,
|
||||||
success: () => console.log('跳转企业微信成功'),
|
success: () => {},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
console.error('跳转企业微信失败:', err);
|
console.error('跳转企业微信失败:', err);
|
||||||
this.fallbackToOriginalService();
|
this.fallbackToOriginalService();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// 检查是否有企业微信配置
|
||||||
|
if (!config.wxwork_url && !config.corpid) {
|
||||||
|
console.error('企业微信配置不完整,缺少 wxwork_url 或 corpid');
|
||||||
|
uni.showToast({ title: '企业微信配置不完整', icon: 'none' });
|
||||||
|
this.fallbackToPhoneCall();
|
||||||
|
return;
|
||||||
|
}
|
||||||
wx.openCustomerServiceChat({
|
wx.openCustomerServiceChat({
|
||||||
extInfo: { url: config.wxwork_url },
|
extInfo: { url: config.wxwork_url || '' },
|
||||||
corpId: config.corpid,
|
corpId: config.corpid || '',
|
||||||
showMessageCard: true,
|
showMessageCard: true,
|
||||||
sendMessageTitle,
|
sendMessageTitle,
|
||||||
sendMessagePath,
|
sendMessagePath,
|
||||||
@@ -237,120 +241,120 @@ export class CustomerService {
|
|||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
if (wxworkConfig?.enable && wxworkConfig?.contact_url) {
|
if (!useOriginalService && wxworkConfig?.enable && wxworkConfig?.contact_url) {
|
||||||
window.location.href = wxworkConfig.contact_url;
|
window.location.href = wxworkConfig.contact_url;
|
||||||
} else if (config.wxwork_url) {
|
} else if (config.wxwork_url) {
|
||||||
location.href = config.wxwork_url;
|
window.location.href = config.wxwork_url;
|
||||||
} else {
|
} else {
|
||||||
this.fallbackToPhoneCall();
|
this.fallbackToPhoneCall();
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开第三方客服
|
|
||||||
* @param {Object} config 客服配置
|
|
||||||
*/
|
|
||||||
openThirdService(config) {
|
openThirdService(config) {
|
||||||
|
|
||||||
|
// 支持多种可能的字段名
|
||||||
|
const miniAppId = config.mini_app_id || config.miniAppId || config.appid || config.appId || config.app_id;
|
||||||
|
const miniAppPath = config.mini_app_path || config.miniAppPath || config.path || config.page_path || '';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 优先处理第三方微信小程序客服
|
||||||
|
if (miniAppId) {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
wx.navigateToMiniProgram({
|
||||||
|
appId: miniAppId,
|
||||||
|
path: miniAppPath,
|
||||||
|
success: () => {
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('【跳转第三方小程序失败】', err);
|
||||||
|
uni.showToast({ title: '跳转失败,请稍后重试', icon: 'none' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
uni.showToast({ title: '第三方小程序客服仅在微信小程序中可用', icon: 'none' });
|
||||||
|
// #endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理第三方链接客服
|
||||||
if (config.third_url) {
|
if (config.third_url) {
|
||||||
|
// #ifdef H5
|
||||||
window.location.href = config.third_url;
|
window.location.href = config.third_url;
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
uni.setClipboardData({
|
||||||
|
data: config.third_url,
|
||||||
|
success: () => {
|
||||||
|
uni.showToast({ title: '链接已复制,请在浏览器打开', icon: 'none' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
} else {
|
} else {
|
||||||
|
console.error('【第三方客服配置不完整】缺少 mini_app_id 或 third_url');
|
||||||
this.fallbackToPhoneCall();
|
this.fallbackToPhoneCall();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开牛商客服
|
|
||||||
* @param {Object} niushop 牛商参数
|
|
||||||
*/
|
|
||||||
openNiushopService(niushop) {
|
openNiushopService(niushop) {
|
||||||
if (Object.keys(niushop).length > 0) {
|
if (Object.keys(niushop).length > 0 && this.vm.$util?.redirectTo) {
|
||||||
this.vm.$util.redirectTo('/pages_tool/chat/room', niushop);
|
this.vm.$util.redirectTo('/pages_tool/chat/room', niushop);
|
||||||
} else {
|
} else {
|
||||||
this.makePhoneCall();
|
this.makePhoneCall();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开微信小程序客服
|
|
||||||
* @param {Object} config 客服配置
|
|
||||||
* @param {Object} options 选项参数
|
|
||||||
*/
|
|
||||||
openWeappService(config, options = {}) {
|
openWeappService(config, options = {}) {
|
||||||
if (!this.shouldUseCustomService(config)) {
|
// 如果 useOfficial 为 true 或 undefined,则使用原生系统客服(由 button open-type="contact" 触发)
|
||||||
console.log('使用官方微信小程序客服');
|
// 此方法仅用于自定义跳转(如 useOfficial: false)
|
||||||
|
if (config.useOfficial !== false) {
|
||||||
|
// 不做任何事,应由 <button open-type="contact"> 触发
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('使用自定义微信小程序客服');
|
|
||||||
this.handleCustomWeappService(config, options);
|
this.handleCustomWeappService(config, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理自定义微信小程序客服
|
|
||||||
* @param {Object} config 客服配置
|
|
||||||
* @param {Object} options 选项参数
|
|
||||||
*/
|
|
||||||
handleCustomWeappService(config, options = {}) {
|
handleCustomWeappService(config, options = {}) {
|
||||||
const { sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options;
|
|
||||||
|
|
||||||
if (config.customServiceUrl) {
|
if (config.customServiceUrl) {
|
||||||
let url = config.customServiceUrl;
|
let url = config.customServiceUrl;
|
||||||
const params = [];
|
const params = [];
|
||||||
|
const { sendMessageTitle, sendMessagePath, sendMessageImg } = options;
|
||||||
if (sendMessageTitle) params.push(`title=${encodeURIComponent(sendMessageTitle)}`);
|
if (sendMessageTitle) params.push(`title=${encodeURIComponent(sendMessageTitle)}`);
|
||||||
if (sendMessagePath) params.push(`path=${encodeURIComponent(sendMessagePath)}`);
|
if (sendMessagePath) params.push(`path=${encodeURIComponent(sendMessagePath)}`);
|
||||||
if (sendMessageImg) params.push(`img=${encodeURIComponent(sendMessageImg)}`);
|
if (sendMessageImg) params.push(`img=${encodeURIComponent(sendMessageImg)}`);
|
||||||
|
|
||||||
if (params.length > 0) {
|
if (params.length > 0) {
|
||||||
url += (url.includes('?') ? '&' : '?') + params.join('&');
|
url += (url.includes('?') ? '&' : '?') + params.join('&');
|
||||||
}
|
}
|
||||||
|
uni.navigateTo({ url });
|
||||||
uni.navigateTo({
|
|
||||||
url: url,
|
|
||||||
fail: (err) => {
|
|
||||||
console.error('跳转自定义客服页面失败:', err);
|
|
||||||
this.tryThirdPartyService(config, options);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tryThirdPartyService(config, options);
|
this.tryThirdPartyService(config, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 尝试使用第三方客服
|
|
||||||
* @param {Object} config 客服配置
|
|
||||||
* @param {Object} options 选项参数
|
|
||||||
*/
|
|
||||||
tryThirdPartyService(config, options = {}) {
|
tryThirdPartyService(config, options = {}) {
|
||||||
if (config.thirdPartyServiceUrl) {
|
// 支持第三方微信小程序客服
|
||||||
// #ifdef H5
|
if (config.thirdPartyMiniAppId || config.mini_app_id) {
|
||||||
window.open(config.thirdPartyServiceUrl, '_blank');
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
if (config.thirdPartyMiniAppId) {
|
wx.navigateToMiniProgram({
|
||||||
wx.navigateToMiniProgram({
|
appId: config.thirdPartyMiniAppId || config.mini_app_id,
|
||||||
appId: config.thirdPartyMiniAppId,
|
path: config.thirdPartyMiniAppPath || config.mini_app_path || ''
|
||||||
path: config.thirdPartyMiniAppPath || '',
|
});
|
||||||
fail: (err) => {
|
// #endif
|
||||||
console.error('跳转第三方小程序失败:', err);
|
return;
|
||||||
this.fallbackToPhoneCall();
|
}
|
||||||
}
|
|
||||||
});
|
// 支持第三方链接客服
|
||||||
} else {
|
if (config.thirdPartyServiceUrl || config.third_url) {
|
||||||
uni.setClipboardData({
|
const serviceUrl = config.thirdPartyServiceUrl || config.third_url;
|
||||||
data: config.thirdPartyServiceUrl,
|
// #ifdef H5
|
||||||
success: () => {
|
window.open(serviceUrl, '_blank');
|
||||||
uni.showModal({
|
// #endif
|
||||||
title: '客服链接已复制',
|
// #ifdef MP-WEIXIN
|
||||||
content: '客服链接已复制到剪贴板,请在浏览器中粘贴访问',
|
uni.setClipboardData({ data: serviceUrl });
|
||||||
showCancel: false
|
uni.showToast({ title: '客服链接已复制', icon: 'none' });
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// #endif
|
// #endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -358,103 +362,55 @@ export class CustomerService {
|
|||||||
this.fallbackToPhoneCall();
|
this.fallbackToPhoneCall();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 降级到电话客服
|
|
||||||
*/
|
|
||||||
fallbackToPhoneCall() {
|
|
||||||
uni.showModal({
|
|
||||||
title: '联系客服',
|
|
||||||
content: '在线客服暂时不可用,是否拨打电话联系客服?',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
this.makePhoneCall();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开支付宝小程序客服
|
|
||||||
* @param {Object} config 客服配置
|
|
||||||
*/
|
|
||||||
openAliappService(config) {
|
openAliappService(config) {
|
||||||
console.log('支付宝小程序客服', config);
|
if (config.type === 'aikefu') {
|
||||||
switch (config.type) {
|
this.openDifyService();
|
||||||
case 'aikefu':
|
} else if (config.type === 'third') {
|
||||||
this.openDifyService();
|
this.openThirdService(config);
|
||||||
break;
|
} else {
|
||||||
case 'third':
|
// 支付宝原生客服由 button open-type="contact" 触发,此处不处理
|
||||||
this.openThirdService(config);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log('使用支付宝官方客服');
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// ================== 辅助方法 ==================
|
||||||
* 拨打电话
|
|
||||||
*/
|
|
||||||
makePhoneCall() {
|
makePhoneCall() {
|
||||||
this.vm.$api.sendRequest({
|
this.vm.$api.sendRequest({
|
||||||
url: '/api/site/shopcontact',
|
url: '/api/site/shopcontact',
|
||||||
success: res => {
|
success: res => {
|
||||||
if (res.code === 0 && res.data?.mobile) {
|
if (res.code === 0 && res.data?.mobile) {
|
||||||
uni.makePhoneCall({
|
uni.makePhoneCall({ phoneNumber: res.data.mobile });
|
||||||
phoneNumber: res.data.mobile
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
uni.showToast({
|
uni.showToast({ title: '暂无客服电话', icon: 'none' });
|
||||||
title: '暂无客服电话',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fail: () => {
|
fail: () => {
|
||||||
uni.showToast({
|
uni.showToast({ title: '获取客服电话失败', icon: 'none' });
|
||||||
title: '获取客服电话失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示无客服弹窗
|
|
||||||
*/
|
|
||||||
showNoServicePopup() {
|
showNoServicePopup() {
|
||||||
const siteInfo = this.vm.$store.state.siteInfo || {};
|
const siteInfo = this.vm.$store.state.siteInfo || {};
|
||||||
const message = siteInfo?.site_tel
|
const message = siteInfo?.site_tel
|
||||||
? `请联系客服,客服电话是${siteInfo.site_tel}`
|
? `请联系客服,客服电话是 ${siteInfo.site_tel}`
|
||||||
: '抱歉,商家暂无客服,请线下联系';
|
: '抱歉,商家暂无客服,请线下联系';
|
||||||
|
uni.showModal({ title: '联系客服', content: message, showCancel: false });
|
||||||
uni.showModal({
|
|
||||||
title: '联系客服',
|
|
||||||
content: message,
|
|
||||||
showCancel: false
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示配置错误弹窗
|
|
||||||
* @param {Array} errors 错误列表
|
|
||||||
*/
|
|
||||||
showConfigErrorPopup(errors) {
|
showConfigErrorPopup(errors) {
|
||||||
const message = errors.join('\n');
|
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '配置错误',
|
title: '客服配置错误',
|
||||||
content: `客服配置有误:\n${message}`,
|
content: `配置有误:\n${errors.join('\n')}`,
|
||||||
showCancel: false
|
showCancel: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 降级处理:使用原有客服方式
|
|
||||||
*/
|
|
||||||
fallbackToOriginalService() {
|
fallbackToOriginalService() {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: '无法直接添加企业微信客服,是否使用其他方式联系客服?',
|
content: '无法直接添加企业微信,是否使用其他方式联系客服?',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm) {
|
if (res.confirm) {
|
||||||
this.openWxworkService(true);
|
this.openWxworkService(true);
|
||||||
@@ -463,9 +419,19 @@ export class CustomerService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fallbackToPhoneCall() {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '在线客服不可用,是否拨打电话联系客服?',
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) this.makePhoneCall();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取客服按钮配置
|
* 获取按钮配置(用于 template 中 v-if / open-type 判断)
|
||||||
* @returns {Object} 按钮配置
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
getButtonConfig() {
|
getButtonConfig() {
|
||||||
const config = this.getPlatformConfig();
|
const config = this.getPlatformConfig();
|
||||||
@@ -473,11 +439,10 @@ export class CustomerService {
|
|||||||
|
|
||||||
let openType = '';
|
let openType = '';
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
if (config.type === 'weapp') {
|
if (config.type === 'weapp' && config.useOfficial !== false) {
|
||||||
openType = config.useOfficial !== false ? 'contact' : '';
|
openType = 'contact';
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef MP-ALIPAY
|
// #ifdef MP-ALIPAY
|
||||||
if (config.type === 'aliapp') openType = 'contact';
|
if (config.type === 'aliapp') openType = 'contact';
|
||||||
// #endif
|
// #endif
|
||||||
@@ -486,25 +451,234 @@ export class CustomerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否应该使用自定义客服处理
|
* 获取客服按钮图标
|
||||||
* @param {Object} config 客服配置
|
* @returns {String} 图标URL
|
||||||
* @returns {boolean} 是否使用自定义客服
|
|
||||||
*/
|
*/
|
||||||
shouldUseCustomService(config) {
|
getKefuButtonIcon() {
|
||||||
// #ifdef MP-WEIXIN
|
const shopInfo = this.vm.shopInfo || {};
|
||||||
if (config?.type === 'weapp') {
|
const config = this.getPlatformConfig();
|
||||||
return config.useOfficial === false;
|
|
||||||
|
// 优先使用指定的智能客服头像
|
||||||
|
if (config?.type === 'aikefu' || config?.type === 'wxwork' || config?.type === 'qyweixin') {
|
||||||
|
return this.vm.$util.img(IMAGE_CONFIG.aiAvatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shopInfo.kefuimg || this.vm.$util?.getDefaultImage()?.kefu || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为微信官方客服
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
isWeappOfficialKefu() {
|
||||||
|
const config = this.getPlatformConfig();
|
||||||
|
return config?.type === 'weapp';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为智能客服
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
isAIKefu() {
|
||||||
|
const config = this.getPlatformConfig();
|
||||||
|
return config?.type === 'aikefu';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为企业微信客服
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
isWxworkKefu() {
|
||||||
|
const config = this.getPlatformConfig();
|
||||||
|
return config?.type === 'wxwork' || config?.type === 'qyweixin';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为第三方客服
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
isThirdKefu() {
|
||||||
|
const config = this.getPlatformConfig();
|
||||||
|
return config?.type === 'third';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否需要同时显示小程序系统客服
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
shouldShowExtraWeappSystemKefu() {
|
||||||
|
const config = this.getPlatformConfig();
|
||||||
|
return (config?.show_system_service === true || config?.show_system_service === '1') && config?.type !== 'weapp';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算容器高度
|
||||||
|
* @param {Boolean} isLanguageSwitchEnabled 是否启用语言切换
|
||||||
|
* @param {Boolean} showWeappSystemKefu 是否显示小程序系统客服
|
||||||
|
* @param {Boolean} fixBtnShow 是否显示按钮
|
||||||
|
* @returns {String} 高度值(px)
|
||||||
|
*/
|
||||||
|
getContainerHeight(isLanguageSwitchEnabled, showWeappSystemKefu, fixBtnShow) {
|
||||||
|
if (!fixBtnShow) return '160px';
|
||||||
|
|
||||||
|
let buttonCount = 1;
|
||||||
|
if (isLanguageSwitchEnabled) buttonCount++;
|
||||||
|
if (showWeappSystemKefu) buttonCount++;
|
||||||
|
|
||||||
|
const totalRpx = 94 * buttonCount - 14;
|
||||||
|
const pxValue = Math.round(totalRpx * 0.5);
|
||||||
|
|
||||||
|
return `${pxValue}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取未读消息数量
|
||||||
|
* @returns {Number}
|
||||||
|
*/
|
||||||
|
getUnreadCount() {
|
||||||
|
return this.vm.$store?.state?.aiUnreadCount || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拨打电话联系客服
|
||||||
|
* @param {String} phoneNumber 电话号码
|
||||||
|
*/
|
||||||
|
makePhoneCallByNumber(phoneNumber) {
|
||||||
|
if (phoneNumber) {
|
||||||
|
uni.makePhoneCall({ phoneNumber });
|
||||||
|
} else {
|
||||||
|
this.makePhoneCall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开 AI 智能助手
|
||||||
|
*/
|
||||||
|
openAIChat() {
|
||||||
|
try {
|
||||||
|
if (typeof this.vm.setAiUnreadCount === 'function') {
|
||||||
|
this.vm.setAiUnreadCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const aiChatUrl = '/pages_tool/ai-chat/index';
|
||||||
|
|
||||||
|
uni.navigateTo({
|
||||||
|
url: aiChatUrl,
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('跳转 AI 客服失败:', err);
|
||||||
|
// #ifdef H5
|
||||||
|
window.location.href = aiChatUrl;
|
||||||
|
// #endif
|
||||||
|
uni.showToast({ title: '打开客服失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error('跳转 AI 客服异常:', e);
|
||||||
|
uni.showToast({ title: '打开客服失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开客服选择对话框(预留方法)
|
||||||
|
*/
|
||||||
|
openCustomerSelectPopupDialog() {
|
||||||
|
uni.showToast({ title: '客服选择功能开发中', icon: 'none' });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开客服选择弹出层(ActionSheet)
|
||||||
|
* @param {Array} kefuList 客服列表
|
||||||
|
*/
|
||||||
|
openKefuSelectPopup(kefuList) {
|
||||||
|
const kefuNames = kefuList.map(item => item.name);
|
||||||
|
uni.showActionSheet({
|
||||||
|
itemList: kefuNames,
|
||||||
|
success: (res) => {
|
||||||
|
const selectedKefu = kefuList[res.tapIndex];
|
||||||
|
const cs = createCustomerService(this.vm, selectedKefu);
|
||||||
|
|
||||||
|
if (selectedKefu.isOfficial) {
|
||||||
|
uni.openCustomerServiceConversation({
|
||||||
|
sessionFrom: 'weapp',
|
||||||
|
showMessageCard: true
|
||||||
|
});
|
||||||
|
} else if (selectedKefu.id === 'qyweixin-kefu') {
|
||||||
|
if (uni.getSystemInfoSync().platform === 'wechat') {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages_tool/qyweixin-kefu/index'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const qyweixinUrl = this.vm.shopInfo?.qyweixinUrl;
|
||||||
|
if (qyweixinUrl) {
|
||||||
|
window.location.href = qyweixinUrl;
|
||||||
|
} else {
|
||||||
|
uni.showToast({ title: '企业微信客服未配置', icon: 'none' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cs.handleCustomerClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 核心方法:统一客服入口(带验证和配置检查)
|
||||||
|
* @param {Object} options 选项参数
|
||||||
|
*/
|
||||||
|
handleUnifiedKefuClick(options = {}) {
|
||||||
|
const validation = this.validateConfig();
|
||||||
|
|
||||||
|
if (!validation.isValid) {
|
||||||
|
console.error('客服配置无效:', validation.errors);
|
||||||
|
uni.showToast({ title: '客服暂不可用', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validation.warnings.length > 0) {
|
||||||
|
console.warn('客服配置警告:', validation.warnings);
|
||||||
|
}
|
||||||
|
|
||||||
|
const platformConfig = this.getPlatformConfig();
|
||||||
|
|
||||||
|
// 检查企业微信配置
|
||||||
|
if (platformConfig.type === 'wxwork') {
|
||||||
|
const wxworkConfig = this.getWxworkConfig();
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
if (!wxworkConfig?.enable || !wxworkConfig?.contact_url) {
|
||||||
|
console.warn('企业微信配置不完整,使用原生客服');
|
||||||
|
uni.showToast({ title: '企业微信配置不完整', icon: 'none' });
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
if (!wxworkConfig?.contact_url && !platformConfig.wxwork_url) {
|
||||||
|
console.error('企业微信链接未配置');
|
||||||
|
uni.showToast({ title: '企业微信链接未配置', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接调用统一处理方法,由 CustomerService 内部根据配置路由
|
||||||
|
try {
|
||||||
|
this.handleCustomerClick({
|
||||||
|
sendMessageTitle: options.sendMessageTitle || '来自悬浮按钮的咨询',
|
||||||
|
sendMessagePath: options.sendMessagePath || '/pages/index/index'
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('客服处理失败:', error);
|
||||||
|
uni.showToast({ title: '打开客服失败', icon: 'none' });
|
||||||
}
|
}
|
||||||
// #endif
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建客服服务实例
|
* 创建客服服务实例
|
||||||
* @param {Object} vueInstance Vue实例
|
* @param {Object} vueInstance Vue 实例(通常是 this)
|
||||||
* @param {Object} externalConfig 外部最新配置
|
* @param {Object} externalConfig 可选:外部传入的最新配置(如从 DIY 数据中提取)
|
||||||
* @returns {CustomerService} 客服服务实例
|
* @returns {CustomerService}
|
||||||
*/
|
*/
|
||||||
export function createCustomerService(vueInstance, externalConfig = null) {
|
export function createCustomerService(vueInstance, externalConfig = null) {
|
||||||
return new CustomerService(vueInstance, externalConfig);
|
return new CustomerService(vueInstance, externalConfig);
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import WxMap 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';
|
||||||
|
import util from '@/common/js/util.js';
|
||||||
|
|
||||||
|
let systemInfo = util.getDeviceInfo();
|
||||||
|
|
||||||
let systemInfo = uni.getSystemInfoSync();
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -198,7 +200,6 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
play(){
|
play(){
|
||||||
console.log(123)
|
|
||||||
},
|
},
|
||||||
async init() {
|
async init() {
|
||||||
|
|
||||||
@@ -607,10 +608,10 @@ export default {
|
|||||||
},
|
},
|
||||||
// 分享给好友
|
// 分享给好友
|
||||||
onShareAppMessage() {
|
onShareAppMessage() {
|
||||||
return this.mpShareData.appMessage;
|
return this.mpShareData?.appMessage;
|
||||||
},
|
},
|
||||||
// 分享到朋友圈
|
// 分享到朋友圈
|
||||||
onShareTimeline() {
|
onShareTimeline() {
|
||||||
return this.mpShareData.timeLine;
|
return this.mpShareData?.timeLine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
// 是否是英文环境
|
// 是否是英文环境
|
||||||
isEnEnv() {
|
isEnEnv() {
|
||||||
return uni.getStorageSync('lang') === 'en-us';
|
return this.$langConfig.getCurrentLocale() === 'en-us';
|
||||||
},
|
},
|
||||||
themeStyle() {
|
themeStyle() {
|
||||||
return this.$store.state.themeStyle;
|
return this.$store.state.themeStyle;
|
||||||
@@ -65,10 +65,18 @@ export default {
|
|||||||
componentRefresh() {
|
componentRefresh() {
|
||||||
return this.$store.state.componentRefresh;
|
return this.$store.state.componentRefresh;
|
||||||
},
|
},
|
||||||
|
// AI客服配置
|
||||||
|
globalAIKefuConfig() {
|
||||||
|
return this.$store.state.globalAIKefuConfig;
|
||||||
|
},
|
||||||
// 客服配置
|
// 客服配置
|
||||||
servicerConfig() {
|
servicerConfig() {
|
||||||
return this.$store.state.servicerConfig;
|
return this.$store.state.servicerConfig;
|
||||||
},
|
},
|
||||||
|
// 企业微信配置
|
||||||
|
wxworkConfig() {
|
||||||
|
return this.$store.state.wxworkConfig;
|
||||||
|
},
|
||||||
diySeckillInterval() {
|
diySeckillInterval() {
|
||||||
return this.$store.state.diySeckillInterval;
|
return this.$store.state.diySeckillInterval;
|
||||||
},
|
},
|
||||||
@@ -145,7 +153,7 @@ export default {
|
|||||||
if (isJump && route != 'pages/index/index') {
|
if (isJump && route != 'pages/index/index') {
|
||||||
uni.setStorageSync('manual_change_store', true); // 手动切换门店
|
uni.setStorageSync('manual_change_store', true); // 手动切换门店
|
||||||
this.$store.dispatch('getCartNumber'); //重新获取购物车数据
|
this.$store.dispatch('getCartNumber'); //重新获取购物车数据
|
||||||
this.$util.redirectTo('/pages/index/index');
|
this.$util.redirectTo(this.$util.INDEX_PAGE_URL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -164,7 +164,6 @@ export default {
|
|||||||
|
|
||||||
// 商品详情
|
// 商品详情
|
||||||
if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = (this.goodsSkuDetail.goods_content);
|
if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = (this.goodsSkuDetail.goods_content);
|
||||||
console.log(this.goodsSkuDetail.goods_content)
|
|
||||||
// if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = htmlParser(this.goodsSkuDetail.goods_content);
|
// if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = htmlParser(this.goodsSkuDetail.goods_content);
|
||||||
|
|
||||||
//商品服务
|
//商品服务
|
||||||
@@ -240,7 +239,7 @@ export default {
|
|||||||
},
|
},
|
||||||
goHome() {
|
goHome() {
|
||||||
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
||||||
this.$util.redirectTo('/pages/index/index');
|
this.$util.redirectTo(this.$util.INDEX_PAGE_URL);
|
||||||
},
|
},
|
||||||
goCart() {
|
goCart() {
|
||||||
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
||||||
|
|||||||
@@ -316,11 +316,9 @@ function replaceVideo(html){
|
|||||||
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
15
common/js/image-config.js
Normal file
15
common/js/image-config.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* 图片配置文件
|
||||||
|
* 将大图片上传到服务器后,请在此处配置网络URL
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 替换为你上传后的实际图片URL
|
||||||
|
const IMAGE_CONFIG = {
|
||||||
|
// AI客服头像
|
||||||
|
aiAvatar: 'public/static/img/s-agent.jpg',
|
||||||
|
|
||||||
|
// 用户默认头像
|
||||||
|
userAvatar: 'public/static/img/s-user.jpg'
|
||||||
|
};
|
||||||
|
|
||||||
|
export default IMAGE_CONFIG;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { langConfig } from './config-external.js';
|
import { langConfig } from './config-external.js';
|
||||||
|
|
||||||
var locale = uni.getStorageSync('lang') || "zh-cn"; //设置语言
|
|
||||||
// 缓存已加载的语言包
|
// 缓存已加载的语言包
|
||||||
var loadedLangPacks = {};
|
const loadedLangPacks = {};
|
||||||
|
|
||||||
// 处理页面目录映射
|
// 处理页面目录映射
|
||||||
function processRoutePath(route) {
|
function processRoutePath(route) {
|
||||||
@@ -54,25 +54,40 @@ function loadLangPackSync(lang, path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCurrentLocale() {
|
||||||
|
return uni.getStorageSync('lang') || "zh-cn";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
langList: langConfig.langList,
|
langList: langConfig.langList,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得当前本地语言
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getCurrentLocale,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 解析多语言
|
* * 解析多语言
|
||||||
* @param {Object} field
|
* @param {Object} field
|
||||||
*/
|
*/
|
||||||
lang(field) {
|
lang(field) {
|
||||||
let _this = getCurrentPages()[getCurrentPages().length - 1];
|
let _page = getCurrentPages()[getCurrentPages().length - 1];
|
||||||
if (!_this) return;
|
if (!_page) return;
|
||||||
|
|
||||||
|
const locale = getCurrentLocale(); // 获得当前本地语言
|
||||||
|
|
||||||
|
let value = ''; // 存放解析后的语言值
|
||||||
|
let langPath = ''; // 存放当前页面语言包路径
|
||||||
|
|
||||||
var value = '';
|
|
||||||
try {
|
try {
|
||||||
//公共语言包(同步加载)
|
//公共语言包(同步加载)
|
||||||
var lang = loadLangPackSync(locale, 'common');
|
var lang = loadLangPackSync(locale, 'common');
|
||||||
|
|
||||||
//当前页面语言包(同步加载)
|
//当前页面语言包(同步加载)
|
||||||
let route = _this.route;
|
let route = _page.route;
|
||||||
let langPath = processRoutePath(route);
|
langPath = processRoutePath(route);
|
||||||
// console.log(`当前页面语言包路径: ${langPath}`);
|
|
||||||
|
|
||||||
// 加载当前页面语言包
|
// 加载当前页面语言包
|
||||||
let currentPageLang = loadLangPackSync(locale, langPath);
|
let currentPageLang = loadLangPackSync(locale, langPath);
|
||||||
@@ -100,7 +115,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('解析语言包失败:', e);
|
console.error('解析语言包失败:', e, { langPath, field, locale });
|
||||||
value = field;
|
value = field;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +128,10 @@ export default {
|
|||||||
if (value == undefined || (value == 'title' && field == 'title')) value = ''; // field
|
if (value == undefined || (value == 'title' && field == 'title')) value = ''; // field
|
||||||
|
|
||||||
// 多语言调试,注释后可以关闭控制台输出
|
// 多语言调试,注释后可以关闭控制台输出
|
||||||
// console.log(`字段: ${field}, 值: ${value}`)
|
if (field == value) {
|
||||||
|
console.warn(`警告: 字段 ${field} 在语言包 ${langPath} 中未找到对应值,使用默认值 ${field} 当前语言: ${locale}`);
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@@ -122,14 +140,18 @@ export default {
|
|||||||
* @param {String} url 切换后跳转的页面url
|
* @param {String} url 切换后跳转的页面url
|
||||||
*/
|
*/
|
||||||
change(value, url = '/pages_tool/member/index') {
|
change(value, url = '/pages_tool/member/index') {
|
||||||
let _this = getCurrentPages()[getCurrentPages().length - 1];
|
let _page = getCurrentPages()[getCurrentPages().length - 1];
|
||||||
if (!_this) return;
|
if (!_page) return;
|
||||||
|
|
||||||
uni.setStorageSync("lang", value);
|
uni.setStorageSync("lang", value);
|
||||||
locale = uni.getStorageSync('lang') || "zh-cn"; //设置语言
|
const locale = getCurrentLocale();
|
||||||
|
|
||||||
// 清空已加载的语言包缓存
|
// 清空已加载的语言包缓存
|
||||||
loadedLangPacks = {};
|
for (let key in loadedLangPacks) {
|
||||||
|
if (!key.startsWith(locale)) {
|
||||||
|
delete loadedLangPacks[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.refresh();
|
this.refresh();
|
||||||
|
|
||||||
@@ -139,9 +161,10 @@ export default {
|
|||||||
},
|
},
|
||||||
//刷新标题、tabbar
|
//刷新标题、tabbar
|
||||||
refresh() {
|
refresh() {
|
||||||
let _this = getCurrentPages()[getCurrentPages().length - 1];
|
let _page = getCurrentPages()[getCurrentPages().length - 1];
|
||||||
if (!_this) return;
|
if (!_page) return;
|
||||||
locale = uni.getStorageSync('lang') || "zh-cn"; //设置语言
|
|
||||||
|
const locale = getCurrentLocale();
|
||||||
|
|
||||||
this.title(this.lang("title"));
|
this.title(this.lang("title"));
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import util from '@/common/js/util.js'
|
||||||
import TransformCoordinate from './transformCoordinate.js'
|
import TransformCoordinate from './transformCoordinate.js'
|
||||||
|
|
||||||
function openMapByDefault(latitude, longitude, name) {
|
function openMapByDefault(latitude, longitude, name) {
|
||||||
@@ -85,18 +86,16 @@ 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) {
|
let platform = util.getDeviceInfo().platform;
|
||||||
|
switch (platform) {
|
||||||
case 'android':
|
case '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上')
|
|
||||||
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('运行在开发者工具上')
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { EventSafety } from './event-safety'
|
import { EventSafety } from '@/common/js/event-safety.js'
|
||||||
|
import util from '@/common/js/util.js'
|
||||||
|
|
||||||
export class NavigationHelper {
|
export class NavigationHelper {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -42,7 +43,6 @@ export class NavigationHelper {
|
|||||||
|
|
||||||
query.select('.uni-page-head').boundingClientRect((rect) => {
|
query.select('.uni-page-head').boundingClientRect((rect) => {
|
||||||
if (rect && rect.height > 0) {
|
if (rect && rect.height > 0) {
|
||||||
console.log('直接查询导航栏高度成功:', rect.height)
|
|
||||||
resolve(rect.height)
|
resolve(rect.height)
|
||||||
} else {
|
} else {
|
||||||
console.warn('未找到 uni-page-head 元素或高度为0')
|
console.warn('未找到 uni-page-head 元素或高度为0')
|
||||||
@@ -59,11 +59,10 @@ export class NavigationHelper {
|
|||||||
// 微信小程序精确计算
|
// 微信小程序精确计算
|
||||||
try {
|
try {
|
||||||
const menuButtonInfo = wx.getMenuButtonBoundingClientRect()
|
const menuButtonInfo = wx.getMenuButtonBoundingClientRect()
|
||||||
const systemInfo = uni.getSystemInfoSync()
|
let systemInfo = util.getDeviceInfo();
|
||||||
|
|
||||||
const height = menuButtonInfo.bottom +
|
const height = menuButtonInfo.bottom +
|
||||||
(menuButtonInfo.top - systemInfo.statusBarHeight)
|
(menuButtonInfo.top - systemInfo.statusBarHeight)
|
||||||
console.log('微信小程序导航栏高度:', height)
|
|
||||||
resolve(height)
|
resolve(height)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('微信小程序高度计算失败:', error)
|
console.error('微信小程序高度计算失败:', error)
|
||||||
@@ -119,7 +118,7 @@ export class NavigationHelper {
|
|||||||
// 获取状态栏高度
|
// 获取状态栏高度
|
||||||
getStatusBarHeight() {
|
getStatusBarHeight() {
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
const systemInfo = uni.getSystemInfoSync()
|
let systemInfo = util.getDeviceInfo();
|
||||||
return systemInfo.statusBarHeight || 20
|
return systemInfo.statusBarHeight || 20
|
||||||
// #endif
|
// #endif
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
@@ -138,7 +137,7 @@ export class NavigationHelper {
|
|||||||
// 获取安全区域
|
// 获取安全区域
|
||||||
getSafeAreaInsets() {
|
getSafeAreaInsets() {
|
||||||
try {
|
try {
|
||||||
const systemInfo = uni.getSystemInfoSync()
|
let systemInfo = util.getDeviceInfo();
|
||||||
return systemInfo.safeArea || {
|
return systemInfo.safeArea || {
|
||||||
top: 0,
|
top: 0,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
@@ -173,7 +172,6 @@ export class NavigationHelper {
|
|||||||
|
|
||||||
// 处理服务请求
|
// 处理服务请求
|
||||||
async handleServiceRequest(event, component) {
|
async handleServiceRequest(event, component) {
|
||||||
console.log('处理导航相关服务请求:', event.type)
|
|
||||||
|
|
||||||
// 安全检查事件目标
|
// 安全检查事件目标
|
||||||
if (this.shouldProcessNavigationRequest(event)) {
|
if (this.shouldProcessNavigationRequest(event)) {
|
||||||
@@ -277,7 +275,6 @@ export class NavigationHelper {
|
|||||||
// 清理缓存
|
// 清理缓存
|
||||||
clearCache() {
|
clearCache() {
|
||||||
this.navigationCache.clear()
|
this.navigationCache.clear()
|
||||||
console.log('导航缓存已清理')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
100
common/js/share.js
Normal file
100
common/js/share.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
// 文件分享工具函数
|
||||||
|
export default {
|
||||||
|
/**
|
||||||
|
* 生成文件预览链接
|
||||||
|
* @param {Object} file - 文件对象,包含 name 和 url 属性
|
||||||
|
* @returns {string} - 生成的文件预览链接
|
||||||
|
*/
|
||||||
|
generateFilePreviewUrl(file) {
|
||||||
|
// 推断文件类型
|
||||||
|
let fileType = '';
|
||||||
|
if (file.name) {
|
||||||
|
const ext = file.name.split('.').pop().toLowerCase();
|
||||||
|
if (['pdf'].includes(ext)) {
|
||||||
|
fileType = 'pdf';
|
||||||
|
} else if (['doc', 'docx'].includes(ext)) {
|
||||||
|
fileType = 'word';
|
||||||
|
} else if (['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv'].includes(ext)) {
|
||||||
|
fileType = 'video';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建文件预览链接
|
||||||
|
const previewUrl = `/pages_tool/file-preview/file-preview?fileName=${encodeURIComponent(file.name)}&fileUrl=${encodeURIComponent(file.url || '')}&fileType=${encodeURIComponent(fileType)}`;
|
||||||
|
return previewUrl;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分享文件
|
||||||
|
* @param {Object} file - 文件对象,包含 name 和 url 属性
|
||||||
|
* @param {string} title - 分享标题,默认使用文件名
|
||||||
|
* @param {string} desc - 分享描述,默认使用固定文案
|
||||||
|
*/
|
||||||
|
shareFile(file, title = file.name, desc = '查看企业文件:' + file.name) {
|
||||||
|
// 生成文件预览链接
|
||||||
|
const filePreviewUrl = this.generateFilePreviewUrl(file);
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
// H5 平台分享
|
||||||
|
if (navigator.share) {
|
||||||
|
// 使用 Web Share API
|
||||||
|
navigator.share({
|
||||||
|
title: title,
|
||||||
|
text: desc,
|
||||||
|
url: filePreviewUrl
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('分享失败:', err);
|
||||||
|
uni.showToast({ title: '分享失败', icon: 'none' });
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 不支持 Web Share API 的浏览器
|
||||||
|
uni.setClipboardData({
|
||||||
|
data: filePreviewUrl,
|
||||||
|
success: () => {
|
||||||
|
uni.showToast({ title: '链接已复制,请粘贴分享', icon: 'success' });
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
uni.showToast({ title: '复制失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
// 微信小程序分享
|
||||||
|
uni.showActionSheet({
|
||||||
|
itemList: ['发送给朋友', '分享到朋友圈'],
|
||||||
|
success: (res) => {
|
||||||
|
if (res.tapIndex === 0) {
|
||||||
|
// 发送给朋友
|
||||||
|
uni.shareAppMessage({
|
||||||
|
title: title,
|
||||||
|
path: filePreviewUrl,
|
||||||
|
success: () => {
|
||||||
|
uni.showToast({ title: '分享成功', icon: 'success' });
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
uni.showToast({ title: '分享失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (res.tapIndex === 1) {
|
||||||
|
// 分享到朋友圈
|
||||||
|
uni.shareTimeline({
|
||||||
|
title: desc,
|
||||||
|
path: filePreviewUrl,
|
||||||
|
success: () => {
|
||||||
|
uni.showToast({ title: '分享成功', icon: 'success' });
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
uni.showToast({ title: '分享失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
// 用户取消分享
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -21,53 +21,35 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
// 判断是否已连接
|
// 判断是否已连接
|
||||||
checkOpenSocket() {
|
checkOpenSocket() {
|
||||||
console.log('判断是否已连接');
|
|
||||||
// alert('判断是否已连接')
|
|
||||||
let self = this;
|
let self = this;
|
||||||
uni.sendSocketMessage({
|
uni.sendSocketMessage({
|
||||||
data: 'ping',
|
data: 'ping',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
console.log('连接成功,检查');
|
|
||||||
// alert('连接成功,检查')
|
|
||||||
// self.getChatList();
|
|
||||||
},
|
},
|
||||||
fail: (err) => { // 未连接打开websocket连接
|
fail: (err) => { // 未连接打开websocket连接
|
||||||
console.log('连接失败');
|
|
||||||
// alert('连接失败')
|
|
||||||
self.openConnection();
|
self.openConnection();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
openConnection() { // 打开连接
|
openConnection() { // 打开连接
|
||||||
console.log('打开连接');
|
|
||||||
// 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);
|
|
||||||
// alert('连接成功 connectSocket=', res);
|
|
||||||
},
|
},
|
||||||
fail(err) {
|
fail(err) {
|
||||||
console.log('连接失败 connectSocket=', err);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// uni.onSocketOpen((res) => {
|
|
||||||
// console.log('连接成功', res);
|
|
||||||
// });
|
|
||||||
this.onSocketMessage(); // 打开成功监听服务器返回的消息
|
this.onSocketMessage(); // 打开成功监听服务器返回的消息
|
||||||
},
|
},
|
||||||
// 打开成功监听服务器返回的消息
|
// 打开成功监听服务器返回的消息
|
||||||
onSocketMessage() { // 消息
|
onSocketMessage() { // 消息
|
||||||
console.log("开始监听");
|
|
||||||
|
|
||||||
let that = this;
|
let that = this;
|
||||||
this.pingInterval = config.pingInterval;
|
this.pingInterval = config.pingInterval;
|
||||||
this.timeoutObj = null;
|
this.timeoutObj = null;
|
||||||
uni.onSocketMessage((res) => { //type:init,connect,close,string,order,goods
|
uni.onSocketMessage((res) => { //type:init,connect,close,string,order,goods
|
||||||
let msg = JSON.parse(res.data);
|
let msg = JSON.parse(res.data);
|
||||||
console.log("监听该服务器消息", res);
|
|
||||||
if (msg.type == 'close') {
|
if (msg.type == 'close') {
|
||||||
clearInterval(that.timeoutObj);
|
clearInterval(that.timeoutObj);
|
||||||
that.timeoutObj = null;
|
that.timeoutObj = null;
|
||||||
@@ -141,22 +123,18 @@ export default {
|
|||||||
},
|
},
|
||||||
// 检测心跳reset
|
// 检测心跳reset
|
||||||
reset() {
|
reset() {
|
||||||
console.log("检测心跳");
|
|
||||||
clearInterval(this.timeoutObj);
|
clearInterval(this.timeoutObj);
|
||||||
this.start(); // 启动心跳
|
this.start(); // 启动心跳
|
||||||
},
|
},
|
||||||
// 启动心跳 start
|
// 启动心跳 start
|
||||||
start() {
|
start() {
|
||||||
console.log("启动心跳");
|
|
||||||
let self = this;
|
let self = this;
|
||||||
this.timeoutObj = setInterval(function () {
|
this.timeoutObj = setInterval(function () {
|
||||||
uni.sendSocketMessage({
|
uni.sendSocketMessage({
|
||||||
data: 'ping',
|
data: 'ping',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
console.log('连接中....');
|
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
console.log('连接失败重新连接....');
|
|
||||||
self.openConnection();
|
self.openConnection();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* 颜色配置
|
||||||
|
* 包含默认颜色和其他颜色
|
||||||
|
* 特别注意:
|
||||||
|
* 1. 分组不会被计算成Key,分组下的属性会被计算成Key
|
||||||
|
* 2. 分组下的属性如果有相同的Key,会被覆盖
|
||||||
|
* 3. 例如:hoverNav,hoverNav_bg_color和hoverNav_text_color, 不会生成hoverNav_hoverNav_bg_color和hoverNav_hoverNav_text_color
|
||||||
|
* 问题原因:历史遗留
|
||||||
|
*/
|
||||||
export default {
|
export default {
|
||||||
'default': {
|
'default': {
|
||||||
//红色
|
//红色
|
||||||
@@ -11,7 +20,7 @@ export default {
|
|||||||
main_color_shallow: '#FFF4F4',//淡背景
|
main_color_shallow: '#FFF4F4',//淡背景
|
||||||
price_color: 'rgb(252,82,39)',//价格颜色
|
price_color: 'rgb(252,82,39)',//价格颜色
|
||||||
btn_text_color: '#FFFFFF',//按钮文字颜色
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||||
goods_detail: {
|
...{
|
||||||
goods_price: 'rgb(252,82,39,1)',//价格
|
goods_price: 'rgb(252,82,39,1)',//价格
|
||||||
promotion_tag: '#FF4646',
|
promotion_tag: '#FF4646',
|
||||||
goods_card_bg: '#201A18',//会员卡背景
|
goods_card_bg: '#201A18',//会员卡背景
|
||||||
@@ -22,35 +31,39 @@ export default {
|
|||||||
goods_btn_color: '#FF4646',//按钮颜色
|
goods_btn_color: '#FF4646',//按钮颜色
|
||||||
goods_btn_color_shallow: '#F7B500',//副按钮颜色
|
goods_btn_color_shallow: '#F7B500',//副按钮颜色
|
||||||
},
|
},
|
||||||
pintuan: {
|
...{
|
||||||
pintuan_label_bg: '#F7B500',
|
pintuan_label_bg: '#F7B500',
|
||||||
pintuan_label_color: '#FFFFFF',
|
pintuan_label_color: '#FFFFFF',
|
||||||
pintuan_color: '#FA6400',
|
pintuan_color: '#FA6400',
|
||||||
pintuan_promotion_color: '#FA3A1D',//活动背景
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||||
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||||
},
|
},
|
||||||
super_member: {
|
...{
|
||||||
super_member_start_bg: '#7c7878',
|
super_member_start_bg: '#7c7878',
|
||||||
super_member_end_bg: '#201a18',
|
super_member_end_bg: '#201a18',
|
||||||
super_member_start_text_color: '#FFDBA6',
|
super_member_start_text_color: '#FFDBA6',
|
||||||
super_member_end_text_color: '#FFEBCA',
|
super_member_end_text_color: '#FFEBCA',
|
||||||
},
|
},
|
||||||
bargain: {
|
...{
|
||||||
bargain_promotion_color: '#F0353E',//活动背景
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||||
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
seckill: {
|
...{
|
||||||
seckill_promotion_color: '#F83530',//活动背景
|
seckill_promotion_color: '#F83530',//活动背景
|
||||||
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
giftcard: {
|
...{
|
||||||
giftcard_promotion_color: '#FF3369',//活动背景
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||||
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
groupby: {
|
...{
|
||||||
groupby_promotion_color: '#E64136',//活动背景
|
groupby_promotion_color: '#E64136',//活动背景
|
||||||
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
|
...{
|
||||||
|
hover_nav_bg_color: '#FFFC', //背景色: 红色 '#c6251b', 白色: '#FFFC'
|
||||||
|
hover_nav_text_color: '#000' // 文字颜色: 白色 '#FFFFFF', 黑色: '#000'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'green': {
|
'green': {
|
||||||
name: 'green',
|
name: 'green',
|
||||||
@@ -63,7 +76,7 @@ export default {
|
|||||||
main_color_shallow: '#F0FFF5',//淡背景
|
main_color_shallow: '#F0FFF5',//淡背景
|
||||||
price_color: 'rgba(252,82,39,1)',//价格颜色
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||||
btn_text_color: '#FFFFFF',//按钮文字颜色
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||||
goods_detail: {
|
...{
|
||||||
goods_price: 'rgba(252,82,39,1)',//价格
|
goods_price: 'rgba(252,82,39,1)',//价格
|
||||||
promotion_tag: '#19C650',
|
promotion_tag: '#19C650',
|
||||||
goods_card_bg: '#201A18',//会员卡背景
|
goods_card_bg: '#201A18',//会员卡背景
|
||||||
@@ -74,35 +87,39 @@ export default {
|
|||||||
goods_btn_color: '#19C650',//按钮颜色
|
goods_btn_color: '#19C650',//按钮颜色
|
||||||
goods_btn_color_shallow: '#FA6400',//副按钮颜色
|
goods_btn_color_shallow: '#FA6400',//副按钮颜色
|
||||||
},
|
},
|
||||||
pintuan: {
|
...{
|
||||||
pintuan_label_bg: '#F7B500',
|
pintuan_label_bg: '#F7B500',
|
||||||
pintuan_label_color: '#FFFFFF',
|
pintuan_label_color: '#FFFFFF',
|
||||||
pintuan_color: '#FA6400',
|
pintuan_color: '#FA6400',
|
||||||
pintuan_promotion_color: '#FA3A1D',//活动背景
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||||
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||||
},
|
},
|
||||||
super_member: {
|
...{
|
||||||
super_member_start_bg: '#7c7878',
|
super_member_start_bg: '#7c7878',
|
||||||
super_member_end_bg: '#201a18',
|
super_member_end_bg: '#201a18',
|
||||||
super_member_start_text_color: '#FFDBA6',
|
super_member_start_text_color: '#FFDBA6',
|
||||||
super_member_end_text_color: '#FFEBCA',
|
super_member_end_text_color: '#FFEBCA',
|
||||||
},
|
},
|
||||||
bargain: {
|
...{
|
||||||
bargain_promotion_color: '#F0353E',//活动背景
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||||
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
seckill: {
|
...{
|
||||||
seckill_promotion_color: '#F83530',//活动背景
|
seckill_promotion_color: '#F83530',//活动背景
|
||||||
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
giftcard: {
|
...{
|
||||||
giftcard_promotion_color: '#FF3369',//活动背景
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||||
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
groupby: {
|
...{
|
||||||
groupby_promotion_color: '#E64136',//活动背景
|
groupby_promotion_color: '#E64136',//活动背景
|
||||||
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
|
...{
|
||||||
|
hover_nav_bg_color: '#19C650',//背景色
|
||||||
|
hover_nav_text_color: '#FFFFFF'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'blue': {
|
'blue': {
|
||||||
name: 'blue',
|
name: 'blue',
|
||||||
@@ -115,7 +132,7 @@ export default {
|
|||||||
main_color_shallow: '#E2F3FF',
|
main_color_shallow: '#E2F3FF',
|
||||||
price_color: 'rgba(252,82,39,1)',//价格颜色
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||||
btn_text_color: '#FFFFFF',//按钮文字颜色
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||||
goods_detail: {
|
...{
|
||||||
goods_price: 'rgba(252,82,39,1)',//价格
|
goods_price: 'rgba(252,82,39,1)',//价格
|
||||||
promotion_tag: '#36ABFF',
|
promotion_tag: '#36ABFF',
|
||||||
goods_card_bg: '#201A18',//会员卡背景
|
goods_card_bg: '#201A18',//会员卡背景
|
||||||
@@ -126,35 +143,39 @@ export default {
|
|||||||
goods_btn_color: '#36ABFF',//按钮颜色
|
goods_btn_color: '#36ABFF',//按钮颜色
|
||||||
goods_btn_color_shallow: '#FA6400',//副按钮颜色
|
goods_btn_color_shallow: '#FA6400',//副按钮颜色
|
||||||
},
|
},
|
||||||
pintuan: {
|
...{
|
||||||
pintuan_label_bg: '#F7B500',
|
pintuan_label_bg: '#F7B500',
|
||||||
pintuan_label_color: '#FFFFFF',
|
pintuan_label_color: '#FFFFFF',
|
||||||
pintuan_color: '#FA6400',
|
pintuan_color: '#FA6400',
|
||||||
pintuan_promotion_color: '#FA3A1D',//活动背景
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||||
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||||
},
|
},
|
||||||
super_member: {
|
...{
|
||||||
super_member_start_bg: '#7c7878',
|
super_member_start_bg: '#7c7878',
|
||||||
super_member_end_bg: '#201a18',
|
super_member_end_bg: '#201a18',
|
||||||
super_member_start_text_color: '#FFDBA6',
|
super_member_start_text_color: '#FFDBA6',
|
||||||
super_member_end_text_color: '#FFEBCA',
|
super_member_end_text_color: '#FFEBCA',
|
||||||
},
|
},
|
||||||
bargain: {
|
...{
|
||||||
bargain_promotion_color: '#F0353E',//活动背景
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||||
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
seckill: {
|
...{
|
||||||
seckill_promotion_color: '#F83530',//活动背景
|
seckill_promotion_color: '#F83530',//活动背景
|
||||||
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
giftcard: {
|
...{
|
||||||
giftcard_promotion_color: '#FF3369',//活动背景
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||||
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
groupby: {
|
...{
|
||||||
groupby_promotion_color: '#E64136',//活动背景
|
groupby_promotion_color: '#E64136',//活动背景
|
||||||
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
|
...{
|
||||||
|
hover_nav_bg_color: '#36ABFF',//背景色
|
||||||
|
hover_nav_text_color: '#FFFFFF'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'pink': {
|
'pink': {
|
||||||
name: 'pink',
|
name: 'pink',
|
||||||
@@ -167,7 +188,7 @@ export default {
|
|||||||
main_color_shallow: '#FFF5F8',//淡背景
|
main_color_shallow: '#FFF5F8',//淡背景
|
||||||
price_color: 'rgba(252,82,39,1)',//价格颜色
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||||
btn_text_color: '#FFFFFF',//按钮文字颜色
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||||
goods_detail: {
|
...{
|
||||||
goods_price: 'rgba(252,82,39,1)',//价格
|
goods_price: 'rgba(252,82,39,1)',//价格
|
||||||
promotion_tag: '#FF407E',
|
promotion_tag: '#FF407E',
|
||||||
goods_card_bg: '#201A18',//会员卡背景
|
goods_card_bg: '#201A18',//会员卡背景
|
||||||
@@ -178,35 +199,39 @@ export default {
|
|||||||
goods_btn_color: '#FF407E',//按钮颜色
|
goods_btn_color: '#FF407E',//按钮颜色
|
||||||
goods_btn_color_shallow: '#F7B500',//副按钮颜色
|
goods_btn_color_shallow: '#F7B500',//副按钮颜色
|
||||||
},
|
},
|
||||||
pintuan: {
|
...{
|
||||||
pintuan_label_bg: '#F7B500',
|
pintuan_label_bg: '#F7B500',
|
||||||
pintuan_label_color: '#FFFFFF',
|
pintuan_label_color: '#FFFFFF',
|
||||||
pintuan_color: '#FA6400',
|
pintuan_color: '#FA6400',
|
||||||
pintuan_promotion_color: '#FA3A1D',//活动背景
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||||
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||||
},
|
},
|
||||||
super_member: {
|
...{
|
||||||
super_member_start_bg: '#7c7878',
|
super_member_start_bg: '#7c7878',
|
||||||
super_member_end_bg: '#201a18',
|
super_member_end_bg: '#201a18',
|
||||||
super_member_start_text_color: '#FFDBA6',
|
super_member_start_text_color: '#FFDBA6',
|
||||||
super_member_end_text_color: '#FFEBCA',
|
super_member_end_text_color: '#FFEBCA',
|
||||||
},
|
},
|
||||||
bargain: {
|
...{
|
||||||
bargain_promotion_color: '#F0353E',//活动背景
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||||
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
seckill: {
|
...{
|
||||||
seckill_promotion_color: '#F83530',//活动背景
|
seckill_promotion_color: '#F83530',//活动背景
|
||||||
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
giftcard: {
|
...{
|
||||||
giftcard_promotion_color: '#FF3369',//活动背景
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||||
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
groupby: {
|
...{
|
||||||
groupby_promotion_color: '#E64136',//活动背景
|
groupby_promotion_color: '#E64136',//活动背景
|
||||||
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
|
...{
|
||||||
|
hover_nav_bg_color: '#FF407E',//背景色
|
||||||
|
hover_nav_text_color: '#FFFFFF'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'gold': {
|
'gold': {
|
||||||
name: 'gold',
|
name: 'gold',
|
||||||
@@ -219,7 +244,7 @@ export default {
|
|||||||
main_color_shallow: '#FFFAF1',//淡背景
|
main_color_shallow: '#FFFAF1',//淡背景
|
||||||
price_color: 'rgba(252,82,39,1)',//价格颜色
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||||
btn_text_color: '#FFFFFF',//按钮文字颜色
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||||
goods_detail: {
|
...{
|
||||||
goods_price: 'rgba(252,82,39,1)',//价格
|
goods_price: 'rgba(252,82,39,1)',//价格
|
||||||
promotion_tag: '#CFAF70',
|
promotion_tag: '#CFAF70',
|
||||||
goods_card_bg: '#201A18',//会员卡背景
|
goods_card_bg: '#201A18',//会员卡背景
|
||||||
@@ -230,35 +255,39 @@ export default {
|
|||||||
goods_btn_color: '#CFAF70',//按钮颜色
|
goods_btn_color: '#CFAF70',//按钮颜色
|
||||||
goods_btn_color_shallow: '#444444',//副按钮颜色
|
goods_btn_color_shallow: '#444444',//副按钮颜色
|
||||||
},
|
},
|
||||||
pintuan: {
|
...{
|
||||||
pintuan_label_bg: '#F7B500',
|
pintuan_label_bg: '#F7B500',
|
||||||
pintuan_label_color: '#FFFFFF',
|
pintuan_label_color: '#FFFFFF',
|
||||||
pintuan_color: '#FA6400',
|
pintuan_color: '#FA6400',
|
||||||
pintuan_promotion_color: '#FA3A1D',//活动背景
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||||
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||||
},
|
},
|
||||||
super_member: {
|
...{
|
||||||
super_member_start_bg: '#7c7878',
|
super_member_start_bg: '#7c7878',
|
||||||
super_member_end_bg: '#201a18',
|
super_member_end_bg: '#201a18',
|
||||||
super_member_start_text_color: '#FFDBA6',
|
super_member_start_text_color: '#FFDBA6',
|
||||||
super_member_end_text_color: '#FFEBCA',
|
super_member_end_text_color: '#FFEBCA',
|
||||||
},
|
},
|
||||||
bargain: {
|
...{
|
||||||
bargain_promotion_color: '#F0353E',//活动背景
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||||
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
seckill: {
|
...{
|
||||||
seckill_promotion_color: '#F83530',//活动背景
|
seckill_promotion_color: '#F83530',//活动背景
|
||||||
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
giftcard: {
|
...{
|
||||||
giftcard_promotion_color: '#FF3369',//活动背景
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||||
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
groupby: {
|
...{
|
||||||
groupby_promotion_color: '#E64136',//活动背景
|
groupby_promotion_color: '#E64136',//活动背景
|
||||||
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
|
...{
|
||||||
|
hover_nav_bg_color: '#CFAF70',//背景色
|
||||||
|
hover_nav_text_color: '#FFFFFF'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'purple': {
|
'purple': {
|
||||||
name: 'purple',
|
name: 'purple',
|
||||||
@@ -271,7 +300,7 @@ export default {
|
|||||||
main_color_shallow: '#F8F3FF',//淡背景
|
main_color_shallow: '#F8F3FF',//淡背景
|
||||||
price_color: 'rgba(252,82,39,1)',//价格颜色
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||||
btn_text_color: '#FFFFFF',//按钮文字颜色
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||||
goods_detail: {
|
...{
|
||||||
goods_price: 'rgba(252,82,39,1)',//价格
|
goods_price: 'rgba(252,82,39,1)',//价格
|
||||||
promotion_tag: '#A253FF',
|
promotion_tag: '#A253FF',
|
||||||
goods_card_bg: '#201A18',//会员卡背景
|
goods_card_bg: '#201A18',//会员卡背景
|
||||||
@@ -282,35 +311,39 @@ export default {
|
|||||||
goods_btn_color: '#A253FF',//按钮颜色
|
goods_btn_color: '#A253FF',//按钮颜色
|
||||||
goods_btn_color_shallow: '#222222',//副按钮颜色
|
goods_btn_color_shallow: '#222222',//副按钮颜色
|
||||||
},
|
},
|
||||||
pintuan: {
|
...{
|
||||||
pintuan_label_bg: '#F7B500',
|
pintuan_label_bg: '#F7B500',
|
||||||
pintuan_label_color: '#FFFFFF',
|
pintuan_label_color: '#FFFFFF',
|
||||||
pintuan_color: '#FA6400',
|
pintuan_color: '#FA6400',
|
||||||
pintuan_promotion_color: '#FA3A1D',//活动背景
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||||
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||||
},
|
},
|
||||||
super_member: {
|
...{
|
||||||
super_member_start_bg: '#7c7878',
|
super_member_start_bg: '#7c7878',
|
||||||
super_member_end_bg: '#201a18',
|
super_member_end_bg: '#201a18',
|
||||||
super_member_start_text_color: '#FFDBA6',
|
super_member_start_text_color: '#FFDBA6',
|
||||||
super_member_end_text_color: '#FFEBCA',
|
super_member_end_text_color: '#FFEBCA',
|
||||||
},
|
},
|
||||||
bargain: {
|
...{
|
||||||
bargain_promotion_color: '#F0353E',//活动背景
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||||
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
seckill: {
|
...{
|
||||||
seckill_promotion_color: '#F83530',//活动背景
|
seckill_promotion_color: '#F83530',//活动背景
|
||||||
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
giftcard: {
|
...{
|
||||||
giftcard_promotion_color: '#FF3369',//活动背景
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||||
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
groupby: {
|
...{
|
||||||
groupby_promotion_color: '#E64136',//活动背景
|
groupby_promotion_color: '#E64136',//活动背景
|
||||||
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
|
...{
|
||||||
|
hover_nav_bg_color: '#A253FF',//背景色
|
||||||
|
hover_nav_text_color: '#FFFFFF'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'yellow': {
|
'yellow': {
|
||||||
name: 'yellow',
|
name: 'yellow',
|
||||||
@@ -323,7 +356,7 @@ export default {
|
|||||||
main_color_shallow: '#FFFBEF',//淡背景
|
main_color_shallow: '#FFFBEF',//淡背景
|
||||||
price_color: 'rgba(252,82,39,1)',//价格颜色
|
price_color: 'rgba(252,82,39,1)',//价格颜色
|
||||||
btn_text_color: '#303133',//按钮文字颜色
|
btn_text_color: '#303133',//按钮文字颜色
|
||||||
goods_detail: {
|
...{
|
||||||
goods_price: 'rgba(252,82,39,1)',//价格
|
goods_price: 'rgba(252,82,39,1)',//价格
|
||||||
promotion_tag: '#FFD009',
|
promotion_tag: '#FFD009',
|
||||||
goods_card_bg: '#201A18',//会员卡背景
|
goods_card_bg: '#201A18',//会员卡背景
|
||||||
@@ -334,35 +367,39 @@ export default {
|
|||||||
goods_btn_color: '#FFD009',//按钮颜色
|
goods_btn_color: '#FFD009',//按钮颜色
|
||||||
goods_btn_color_shallow: '#1D262E',//副按钮颜色
|
goods_btn_color_shallow: '#1D262E',//副按钮颜色
|
||||||
},
|
},
|
||||||
pintuan: {
|
...{
|
||||||
pintuan_label_bg: '#F7B500',
|
pintuan_label_bg: '#F7B500',
|
||||||
pintuan_label_color: '#FFFFFF',
|
pintuan_label_color: '#FFFFFF',
|
||||||
pintuan_color: '#FA6400',
|
pintuan_color: '#FA6400',
|
||||||
pintuan_promotion_color: '#FA3A1D',//活动背景
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||||
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||||
},
|
},
|
||||||
super_member: {
|
...{
|
||||||
super_member_start_bg: '#7c7878',
|
super_member_start_bg: '#7c7878',
|
||||||
super_member_end_bg: '#201a18',
|
super_member_end_bg: '#201a18',
|
||||||
super_member_start_text_color: '#FFDBA6',
|
super_member_start_text_color: '#FFDBA6',
|
||||||
super_member_end_text_color: '#FFEBCA',
|
super_member_end_text_color: '#FFEBCA',
|
||||||
},
|
},
|
||||||
bargain: {
|
...{
|
||||||
bargain_promotion_color: '#F0353E',//活动背景
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||||
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
seckill: {
|
...{
|
||||||
seckill_promotion_color: '#F83530',//活动背景
|
seckill_promotion_color: '#F83530',//活动背景
|
||||||
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
giftcard: {
|
...{
|
||||||
giftcard_promotion_color: '#FF3369',//活动背景
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||||
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
groupby: {
|
...{
|
||||||
groupby_promotion_color: '#E64136',//活动背景
|
groupby_promotion_color: '#E64136',//活动背景
|
||||||
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
|
...{
|
||||||
|
hover_nav_bg_color: '#FFD009',//背景色
|
||||||
|
hover_nav_text_color: '#303133'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'black': {
|
'black': {
|
||||||
name: 'black',
|
name: 'black',
|
||||||
@@ -375,7 +412,7 @@ export default {
|
|||||||
main_color_shallow: '#efefef',//淡背景
|
main_color_shallow: '#efefef',//淡背景
|
||||||
price_color: 'rgba(255,0,0,1)',//价格颜色
|
price_color: 'rgba(255,0,0,1)',//价格颜色
|
||||||
btn_text_color: '#FFFFFF',//按钮文字颜色
|
btn_text_color: '#FFFFFF',//按钮文字颜色
|
||||||
goods_detail: {
|
...{
|
||||||
goods_price: 'rgba(255,0,0,1)',//价格
|
goods_price: 'rgba(255,0,0,1)',//价格
|
||||||
promotion_tag: '#222222',
|
promotion_tag: '#222222',
|
||||||
goods_card_bg: '#201A18',//会员卡背景
|
goods_card_bg: '#201A18',//会员卡背景
|
||||||
@@ -386,34 +423,38 @@ export default {
|
|||||||
goods_btn_color: '#222222',//按钮颜色
|
goods_btn_color: '#222222',//按钮颜色
|
||||||
goods_btn_color_shallow: '#FA8B00',//副按钮颜色
|
goods_btn_color_shallow: '#FA8B00',//副按钮颜色
|
||||||
},
|
},
|
||||||
pintuan: {
|
...{
|
||||||
pintuan_label_bg: '#F7B500',
|
pintuan_label_bg: '#F7B500',
|
||||||
pintuan_label_color: '#FFFFFF',
|
pintuan_label_color: '#FFFFFF',
|
||||||
pintuan_color: '#FA6400',
|
pintuan_color: '#FA6400',
|
||||||
pintuan_promotion_color: '#FA3A1D',//活动背景
|
pintuan_promotion_color: '#FA3A1D',//活动背景
|
||||||
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
pintuan_promotion_aux_color: '#FD9A01',//活动背景辅色
|
||||||
},
|
},
|
||||||
super_member: {
|
...{
|
||||||
super_member_start_bg: '#fadcb5',
|
super_member_start_bg: '#fadcb5',
|
||||||
super_member_end_bg: '#f6bd74',
|
super_member_end_bg: '#f6bd74',
|
||||||
super_member_start_text_color: '#ab6126',
|
super_member_start_text_color: '#ab6126',
|
||||||
super_member_end_text_color: '#d19336',
|
super_member_end_text_color: '#d19336',
|
||||||
},
|
},
|
||||||
bargain: {
|
...{
|
||||||
bargain_promotion_color: '#F0353E',//活动背景
|
bargain_promotion_color: '#F0353E',//活动背景
|
||||||
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
bargain_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
seckill: {
|
...{
|
||||||
seckill_promotion_color: '#F83530',//活动背景
|
seckill_promotion_color: '#F83530',//活动背景
|
||||||
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
seckill_promotion_aux_color: '#FD9A01',//活动辅色
|
||||||
},
|
},
|
||||||
giftcard: {
|
...{
|
||||||
giftcard_promotion_color: '#FF3369',//活动背景
|
giftcard_promotion_color: '#FF3369',//活动背景
|
||||||
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
giftcard_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
groupby: {
|
...{
|
||||||
groupby_promotion_color: '#E64136',//活动背景
|
groupby_promotion_color: '#E64136',//活动背景
|
||||||
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
groupby_promotion_aux_color: '#F7B500',//活动辅色
|
||||||
},
|
},
|
||||||
|
...{
|
||||||
|
hover_nav_bg_color: '#222222',//背景色
|
||||||
|
hover_nav_text_color: '#FFFFFF'
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
147
common/js/uniapp.utils.js
Normal file
147
common/js/uniapp.utils.js
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/**
|
||||||
|
* 将常用的Uniapp提供的函数,存放到这里,按需引用
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示错误信息
|
||||||
|
* @param {Exception} err
|
||||||
|
* @param {Boolean} useModal
|
||||||
|
*/
|
||||||
|
const showError = (err, useModal = false) => {
|
||||||
|
const content = err?.message || err?.errMsg || err?.toString();
|
||||||
|
if (!useModal) {
|
||||||
|
uni.showToast({
|
||||||
|
title: content,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 3000
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.showModal({
|
||||||
|
title: '错误提示',
|
||||||
|
content,
|
||||||
|
showCancel: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打电话
|
||||||
|
* @param {string} mobile 电话号码
|
||||||
|
*/
|
||||||
|
export const makePhoneCall = (mobile) => {
|
||||||
|
try {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: `${mobile}`,
|
||||||
|
success(e) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
showError(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拷贝文本(返回 Promise)
|
||||||
|
* @param {*} text
|
||||||
|
* @param {*} options
|
||||||
|
* @returns {Promise} 返回 Promise,成功时 resolve,失败时 reject
|
||||||
|
*/
|
||||||
|
export const copyTextAsync = (text, { copySuccess = '', copyFailed = '' } = {}) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// 输入验证
|
||||||
|
if (!text && text !== '') {
|
||||||
|
const error = new Error('复制文本不能为空');
|
||||||
|
showError(error);
|
||||||
|
reject(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 超时监测
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
let error = new Error('复制操作长时间无响应,请检查相关权限及配置是否正确');
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
error = new Error([
|
||||||
|
'复制操作长时间无响应!',
|
||||||
|
'原因:',
|
||||||
|
'1.微信平台->用户隐私保护指引->"剪贴板"功能未添加或审核未通过;',
|
||||||
|
'2.微信平台对剪贴板API调用频率有限制'
|
||||||
|
].join('\r\n'));
|
||||||
|
// #endif
|
||||||
|
showError(error, true);
|
||||||
|
reject(error);
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
try {
|
||||||
|
uni.setClipboardData({
|
||||||
|
data: `${text}`,
|
||||||
|
success: (res) => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (copySuccess) {
|
||||||
|
uni.showToast({
|
||||||
|
title: copySuccess,
|
||||||
|
icon: 'success',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
showError(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(res);
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
try {
|
||||||
|
uni.showToast({
|
||||||
|
title: err.message || err.errMsg || copyFailed || '复制失败',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
showError(e);
|
||||||
|
}
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
showError(err);
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拷贝文本(回调形式,兼容旧代码)
|
||||||
|
* @param {*} text
|
||||||
|
* @param {*} options
|
||||||
|
* @param {Function} callback 回调函数,接收 (success, error) 参数
|
||||||
|
*/
|
||||||
|
export const copyText = (text, options = {}, callback) => {
|
||||||
|
copyTextAsync(text, options)
|
||||||
|
.then(res => {
|
||||||
|
if (callback) callback(true, null);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
if (callback) callback(false, err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开定位
|
||||||
|
* @param {Object} options
|
||||||
|
*/
|
||||||
|
export const openLocation = ({ latitude, longitude, name } = {}) => {
|
||||||
|
try {
|
||||||
|
uni.openLocation({
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
name,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
showError(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,15 +7,20 @@ import {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 首页路径
|
// 关于页面路径,使用常量导出
|
||||||
export const INDEX_PAGE_URL = '/pages/index/index';
|
export const INDEX_PAGE_URL = '/pages/index/index';
|
||||||
|
export const CATEGORY_PAGE_URL = '/pages_goods/category';
|
||||||
|
export const CONTACT_PAGE_URL = '/pages_tool/contact/contact';
|
||||||
|
export const MEMBER_PAGE_URL = '/pages_tool/member/index';
|
||||||
|
export const LOGIN_PAGE_URL = '/pages_tool/login/login';
|
||||||
|
export const AI_CHAT_PAGE_URL = '/pages_tool/ai-chat/index';
|
||||||
|
|
||||||
// 当前最新的tabBar.list (参见pages.json 中的tabBar.list 配置)
|
// 当前最新的tabBar.list (参见pages.json 中的tabBar.list 配置)
|
||||||
export const systemTabBarList = [
|
export const systemTabBarList = [
|
||||||
INDEX_PAGE_URL,
|
INDEX_PAGE_URL,
|
||||||
'/pages_goods/category',
|
CATEGORY_PAGE_URL,
|
||||||
'/pages_tool/contact/contact',
|
CONTACT_PAGE_URL,
|
||||||
'/pages_tool/member/index'
|
MEMBER_PAGE_URL
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,10 +37,28 @@ export const adaptSubpackageUrl = (url) => {
|
|||||||
*/
|
*/
|
||||||
// 定义前缀映射表
|
// 定义前缀映射表
|
||||||
const urlPrefixMap = {
|
const urlPrefixMap = {
|
||||||
|
'/pages/promotion/': '/pages_promotion/',
|
||||||
|
'/pages/order/': '/pages_order/',
|
||||||
'/pages/goods/': '/pages_goods/',
|
'/pages/goods/': '/pages_goods/',
|
||||||
|
|
||||||
'/pages/contact/': '/pages_tool/contact/',
|
'/pages/contact/': '/pages_tool/contact/',
|
||||||
'/pages/member/': '/pages_tool/member/',
|
'/pages/member/': '/pages_tool/member/',
|
||||||
'/pages/vr': '/pages_tool/vr/'
|
'/pages/login/': '/pages_tool/login/',
|
||||||
|
'/pages/agreement/': '/pages_tool/agreement/',
|
||||||
|
'/pages/article/': '/pages_tool/article/',
|
||||||
|
'/pages/cases/': '/pages_tool/cases/',
|
||||||
|
'/pages/contact/': '/pages_tool/contact/',
|
||||||
|
'/pages/files/': '/pages_tool/files/',
|
||||||
|
'/pages/form/': '/pages_tool/form/',
|
||||||
|
'/pages/help/': '/pages_tool/help/',
|
||||||
|
'/pages/notice/': '/pages_tool/notice/',
|
||||||
|
'/pages/pay/': '/pages_tool/pay/',
|
||||||
|
'/pages/recharge/': '/pages_tool/recharge/',
|
||||||
|
'/pages/seal/': '/pages_tool/seal/',
|
||||||
|
'/pages/storeclose/': '/pages_tool/storeclose/',
|
||||||
|
'/pages/vr/': '/pages_tool/vr/',
|
||||||
|
'/pages/weapp/': '/pages_tool/weapp/',
|
||||||
|
'/pages/webview/': '/pages_tool/webview/',
|
||||||
};
|
};
|
||||||
|
|
||||||
// 构建正则表达式
|
// 构建正则表达式
|
||||||
@@ -61,20 +84,55 @@ export const adaptSubpackageUrl = (url) => {
|
|||||||
return replacePrefix(url);
|
return replacePrefix(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查tabBar是否激活
|
||||||
|
* @param {string} linkUrl 链接路径 /pages/goods/category
|
||||||
|
* @param {string} currentPageRoute 当前页面路径 /pages_goods/category
|
||||||
|
* @returns {boolean} 是否激活
|
||||||
|
*/
|
||||||
|
export const checkTabBarActive = (linkUrl, currentPageRoute) => {
|
||||||
|
const linkUrlParts = adaptSubpackageUrl(linkUrl).split('/');
|
||||||
|
const currentPageRouteParts = currentPageRoute.split('/');
|
||||||
|
|
||||||
|
// console.log('diy-bottom-nav verify:', { linkUrlParts, currentPageRouteParts});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 二级页面
|
||||||
|
if (linkUrlParts[2] === currentPageRouteParts[2]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 一级页面,限定只能是goods相关
|
||||||
|
if (linkUrlParts[1] === currentPageRouteParts[1] && linkUrlParts[1] === 'pages_goods') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('diy-bottom-nav verify error:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
/** 导出页面URL常量 */
|
||||||
|
MEMBER_PAGE_URL,
|
||||||
|
CATEGORY_PAGE_URL,
|
||||||
|
CONTACT_PAGE_URL,
|
||||||
|
INDEX_PAGE_URL,
|
||||||
|
LOGIN_PAGE_URL,
|
||||||
|
AI_CHAT_PAGE_URL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页面跳转
|
* 页面跳转
|
||||||
* @param {string} to 跳转链接 /pages/idnex/index
|
* @param {string} to 跳转链接 /pages/idnex/index
|
||||||
* @param {Object} param 参数 {key : value, ...}
|
* @param {Object} param 参数 {key : value, ...}, 默认{}
|
||||||
* @param {string} mode 模式
|
* @param {string} mode 模式 navigateTo、redirectTo、reLaunch、tabbar, 默认navigateTo
|
||||||
*/
|
*/
|
||||||
redirectTo(to, param, mode) {
|
redirectTo(to, param = {}, mode = 'navigateTo') {
|
||||||
let url = to;
|
let url = to;
|
||||||
|
|
||||||
// 替换url中的前缀
|
// 替换url中的前缀
|
||||||
console.log('redirectTo', to, param, mode);
|
|
||||||
url = adaptSubpackageUrl(url);
|
url = adaptSubpackageUrl(url);
|
||||||
console.log('adaptSubpackageUrl', url);
|
|
||||||
|
|
||||||
if (param != undefined) {
|
if (param != undefined) {
|
||||||
Object.keys(param).forEach(function (key) {
|
Object.keys(param).forEach(function (key) {
|
||||||
@@ -91,7 +149,7 @@ export default {
|
|||||||
const tabBarUrl = systemTabBarList[i];
|
const tabBarUrl = systemTabBarList[i];
|
||||||
if (url.indexOf(tabBarUrl) == 0) {
|
if (url.indexOf(tabBarUrl) == 0) {
|
||||||
// 首页特殊处理,采用switchTab, 其他页面采用redirectTo, 不能返回,不能退回
|
// 首页特殊处理,采用switchTab, 其他页面采用redirectTo, 不能返回,不能退回
|
||||||
(tabBarUrl == INDEX_PAGE_URL ? uni.switchTab : uni.redirectTo)({url});
|
(tabBarUrl == INDEX_PAGE_URL ? uni.switchTab : uni.redirectTo)({ url });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,26 +157,25 @@ export default {
|
|||||||
// 如果url不包含tabBarList中的路径,根据mode判断跳转方式
|
// 如果url不包含tabBarList中的路径,根据mode判断跳转方式
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 'tabbar':
|
case 'tabbar':
|
||||||
// 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
|
// 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。重置页面栈,仅保留 tabBar 页面
|
||||||
uni.switchTab({
|
uni.switchTab({
|
||||||
url
|
url
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'redirectTo':
|
case 'redirectTo':
|
||||||
// 关闭当前页面,跳转到应用内的某个页面。
|
// 关闭当前页面,跳转到应用内的某个页面。替换栈顶页面,长度不变(上限10层)
|
||||||
uni.redirectTo({
|
uni.redirectTo({
|
||||||
url
|
url
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'reLaunch':
|
case 'reLaunch':
|
||||||
// 关闭所有页面,打开到应用内的某个页面。
|
// 关闭所有页面,打开到应用内的某个页面。清空栈后打开新页面,长度=1
|
||||||
uni.reLaunch({
|
uni.reLaunch({
|
||||||
url
|
url
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// 保留当前页面,跳转到应用内的某个页面
|
// 保留当前页面,跳转到应用内的某个页面,新增页面到栈顶,长度+1(上限10层)
|
||||||
console.log('保留当前页面,跳转到应用内的某个页面', url);
|
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url
|
url
|
||||||
});
|
});
|
||||||
@@ -130,8 +187,6 @@ export default {
|
|||||||
* @param {Object} params 参数,针对商品、相册里面的图片区分大中小,size: big、mid、small
|
* @param {Object} params 参数,针对商品、相册里面的图片区分大中小,size: big、mid、small
|
||||||
*/
|
*/
|
||||||
img(img_path, params) {
|
img(img_path, params) {
|
||||||
|
|
||||||
|
|
||||||
var path = "";
|
var path = "";
|
||||||
if (img_path != undefined && img_path != "") {
|
if (img_path != undefined && img_path != "") {
|
||||||
if (img_path.split(',').length > 1) {
|
if (img_path.split(',').length > 1) {
|
||||||
@@ -155,6 +210,8 @@ export default {
|
|||||||
// console.log(img_path)
|
// console.log(img_path)
|
||||||
path = img_path;
|
path = img_path;
|
||||||
}
|
}
|
||||||
|
// 修复:去除 URL 中的双斜杠,避免微信 downloadFile 域名匹配失败
|
||||||
|
path = path.replace(/([^:]\/)\/+/g, "$1");
|
||||||
}
|
}
|
||||||
|
|
||||||
// path += '?t=' + parseInt(new Date().getTime() / 1000);
|
// path += '?t=' + parseInt(new Date().getTime() / 1000);
|
||||||
@@ -491,7 +548,7 @@ export default {
|
|||||||
* 检测苹果X以上的手机
|
* 检测苹果X以上的手机
|
||||||
*/
|
*/
|
||||||
isIPhoneX() {
|
isIPhoneX() {
|
||||||
let res = uni.getSystemInfoSync();
|
let res = this.getDeviceInfo();
|
||||||
if (res.model.search('iPhone X') != -1) {
|
if (res.model.search('iPhone X') != -1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -499,13 +556,33 @@ export default {
|
|||||||
},
|
},
|
||||||
//判断安卓还是iOS
|
//判断安卓还是iOS
|
||||||
isAndroid() {
|
isAndroid() {
|
||||||
let platform = uni.getSystemInfoSync().platform
|
let platform = this.getDeviceInfo().platform;
|
||||||
if (platform == 'ios') {
|
if (platform == 'ios') {
|
||||||
return false;
|
return false;
|
||||||
} else if (platform == 'android') {
|
} else if (platform == 'android') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 获取设备信息(包含降级处理)
|
||||||
|
*/
|
||||||
|
getDeviceInfo() {
|
||||||
|
try {
|
||||||
|
return uni.getDeviceInfo();
|
||||||
|
} catch (e) {
|
||||||
|
return uni.getSystemInfoSync();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 获取窗口信息(包含降级处理)
|
||||||
|
*/
|
||||||
|
getWindowInfo() {
|
||||||
|
try {
|
||||||
|
return uni.getWindowInfo();
|
||||||
|
} catch (e) {
|
||||||
|
return uni.getSystemInfoSync();
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 深度拷贝对象
|
* 深度拷贝对象
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
@@ -527,6 +604,31 @@ export default {
|
|||||||
}
|
}
|
||||||
return cloneObj
|
return cloneObj
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开微信企业客服
|
||||||
|
* @param {Function} fallbackFunc 降级处理函数
|
||||||
|
*/
|
||||||
|
openWxWorkServiceChat(fallbackFunc) {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
let wxworkConfig = store.state?.wxworkConfig
|
||||||
|
if (wxworkConfig?.enable && wxworkConfig?.contact_url) {
|
||||||
|
// 直接使用活码链接跳转
|
||||||
|
wx.navigateToMiniProgram({
|
||||||
|
appId: 'wxeb490c6f9b154ef9', // 是企业微信官方小程序的AppID(固定值, 由腾讯企业微信团队维护, 不需要修改,用于展示"添加企业微信联系人"的官方页面)
|
||||||
|
path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(wxworkConfig?.contact_url)}`,
|
||||||
|
success: () => {
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
fallbackFunc && fallbackFunc();
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义模板的跳转链接
|
* 自定义模板的跳转链接
|
||||||
* @param {Object} link
|
* @param {Object} link
|
||||||
@@ -549,7 +651,6 @@ export default {
|
|||||||
|
|
||||||
} else if (link.appid) {
|
} else if (link.appid) {
|
||||||
// 跳转其他小程序
|
// 跳转其他小程序
|
||||||
|
|
||||||
uni.navigateToMiniProgram({
|
uni.navigateToMiniProgram({
|
||||||
appId: link.appid,
|
appId: link.appid,
|
||||||
path: link.page
|
path: link.page
|
||||||
@@ -557,7 +658,6 @@ export default {
|
|||||||
|
|
||||||
} else if (link.name == 'MOBILE' && !link.wap_url) {
|
} else if (link.name == 'MOBILE' && !link.wap_url) {
|
||||||
// 拨打电话
|
// 拨打电话
|
||||||
|
|
||||||
uni.makePhoneCall({
|
uni.makePhoneCall({
|
||||||
phoneNumber: link.mobile,
|
phoneNumber: link.mobile,
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
@@ -590,16 +690,19 @@ export default {
|
|||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
wx.openCustomerServiceChat({
|
this.openWxWorkServiceChat(() => {
|
||||||
extInfo: {
|
wx.openCustomerServiceChat({
|
||||||
url: config.wxwork_url
|
extInfo: {
|
||||||
},
|
url: config.wxwork_url
|
||||||
corpId: config.corpid,
|
},
|
||||||
showMessageCard: true,
|
corpId: config.corpid,
|
||||||
sendMessageTitle: 'this.sendMessageTitle',
|
showMessageCard: true,
|
||||||
sendMessagePath: 'this.sendMessagePath',
|
sendMessageTitle: 'this.sendMessageTitle',
|
||||||
sendMessageImg: 'this.sendMessageImg'
|
sendMessagePath: 'this.sendMessagePath',
|
||||||
|
sendMessageImg: 'this.sendMessageImg'
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// #endif
|
// #endif
|
||||||
break;
|
break;
|
||||||
case 'third':
|
case 'third':
|
||||||
@@ -650,7 +753,7 @@ export default {
|
|||||||
*/
|
*/
|
||||||
uniappIsIPhoneX() {
|
uniappIsIPhoneX() {
|
||||||
let isIphoneX = false;
|
let isIphoneX = false;
|
||||||
let systemInfo = uni.getSystemInfoSync();
|
let systemInfo = this.getDeviceInfo();
|
||||||
// #ifdef MP
|
// #ifdef MP
|
||||||
if (systemInfo.model.search('iPhone X') != -1 || systemInfo.model.search('iPhone 11') != -1 || systemInfo.model.search('iPhone 12') != -1 || systemInfo.model.search('iPhone 13') != -1) {
|
if (systemInfo.model.search('iPhone X') != -1 || systemInfo.model.search('iPhone 11') != -1 || systemInfo.model.search('iPhone 12') != -1 || systemInfo.model.search('iPhone 13') != -1) {
|
||||||
isIphoneX = true;
|
isIphoneX = true;
|
||||||
@@ -677,7 +780,7 @@ export default {
|
|||||||
*/
|
*/
|
||||||
uniappIsIPhone11() {
|
uniappIsIPhone11() {
|
||||||
let isIphone11 = false;
|
let isIphone11 = false;
|
||||||
let systemInfo = uni.getSystemInfoSync();
|
let systemInfo = this.getDeviceInfo();
|
||||||
// #ifdef MP
|
// #ifdef MP
|
||||||
if (systemInfo.model.search('iPhone 11') != -1) {
|
if (systemInfo.model.search('iPhone 11') != -1) {
|
||||||
isIphone11 = true;
|
isIphone11 = true;
|
||||||
@@ -688,7 +791,7 @@ export default {
|
|||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
//判断该浏览器是否为safaria浏览器
|
//判断该浏览器是否为safaria浏览器
|
||||||
isSafari() {
|
isSafari() {
|
||||||
let res = uni.getSystemInfoSync();
|
let res = this.getDeviceInfo();
|
||||||
var ua = navigator.userAgent.toLowerCase();
|
var ua = navigator.userAgent.toLowerCase();
|
||||||
if (ua.indexOf('applewebkit') > -1 && ua.indexOf('mobile') > -1 && ua.indexOf('safari') > -1 &&
|
if (ua.indexOf('applewebkit') > -1 && ua.indexOf('mobile') > -1 && ua.indexOf('safari') > -1 &&
|
||||||
ua.indexOf('linux') === -1 && ua.indexOf('android') === -1 && ua.indexOf('chrome') === -1 &&
|
ua.indexOf('linux') === -1 && ua.indexOf('android') === -1 && ua.indexOf('chrome') === -1 &&
|
||||||
@@ -727,13 +830,22 @@ export default {
|
|||||||
let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
|
let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
|
||||||
return routes.length ? routes[routes.length - 1].route : '';
|
return routes.length ? routes[routes.length - 1].route : '';
|
||||||
},
|
},
|
||||||
goBack(backUrl = '/pages/index/index') {
|
goBack(backUrl = INDEX_PAGE_URL) {
|
||||||
if (getCurrentPages().length == 1) {
|
if (getCurrentPages().length == 1) {
|
||||||
this.redirectTo(backUrl);
|
this.redirectTo(backUrl);
|
||||||
} else {
|
} else {
|
||||||
uni.navigateBack();
|
uni.navigateBack();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 隐藏“返回首页/小房子”按钮
|
||||||
|
* 这个函数,用到页面show, onshow 的生命周期时
|
||||||
|
*/
|
||||||
|
hideHomeButton() {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
wx.hideHomeButton();
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param val 转化时间字符串 (转化时分秒)
|
* @param val 转化时间字符串 (转化时分秒)
|
||||||
@@ -789,12 +901,11 @@ export default {
|
|||||||
},
|
},
|
||||||
success: res => {
|
success: res => {
|
||||||
if (res.code >= 0) {
|
if (res.code >= 0) {
|
||||||
uni.removeStorage({
|
uni.removeStorage({
|
||||||
key: 'source_member',
|
key: 'source_member',
|
||||||
success: res => {
|
success: res => {
|
||||||
console.log('删除成功', res)
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -818,27 +929,23 @@ export default {
|
|||||||
success: res => {
|
success: res => {
|
||||||
if (res.data.length) {
|
if (res.data.length) {
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
uni.requestSubscribeMessage({
|
uni.requestSubscribeMessage({
|
||||||
tmplIds: res.data,
|
tmplIds: res.data,
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
console.log("res", res)
|
},
|
||||||
},
|
fail: (res) => {
|
||||||
fail: (res) => {
|
}
|
||||||
console.log('fail', res)
|
})
|
||||||
}
|
|
||||||
})
|
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef MP-ALIPAY
|
// #ifdef MP-ALIPAY
|
||||||
my.requestSubscribeMessage({
|
my.requestSubscribeMessage({
|
||||||
entityIds: res.data,
|
entityIds: res.data,
|
||||||
success: res => {
|
success: res => {
|
||||||
console.log("res", res)
|
},
|
||||||
},
|
fail: res => {
|
||||||
fail: res => {
|
}
|
||||||
console.log('fail', res)
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1083,5 +1190,73 @@ export default {
|
|||||||
verifyMobile(mobile) {
|
verifyMobile(mobile) {
|
||||||
var parse = /^\d{11}$/.test(mobile);
|
var parse = /^\d{11}$/.test(mobile);
|
||||||
return parse;
|
return parse;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 判断是否为快应用环境
|
||||||
|
* @returns {boolean} 是否为快应用
|
||||||
|
*/
|
||||||
|
isQuickApp() {
|
||||||
|
// #ifndef QUICKAPP-WEBVIEW
|
||||||
|
let _isQuickApp = false;
|
||||||
|
try {
|
||||||
|
const ua = navigator?.userAgent?.toLowerCase();
|
||||||
|
_isQuickApp = ua.indexOf('quickapp') !== -1;
|
||||||
|
|
||||||
|
if (!_isQuickApp) {
|
||||||
|
// 特殊说明由于网站是嵌入到快应用的Webview组件中<web>,UA中不会包含quickapp字符串,
|
||||||
|
// 但是会包含uniacid参数,所以这里通过uniacid参数来判断是否为快应用环境
|
||||||
|
_isQuickApp = ua.indexOf('uniacid=') !== -1;
|
||||||
|
}
|
||||||
|
} catch (e) { }
|
||||||
|
|
||||||
|
if (!_isQuickApp) {
|
||||||
|
const systemInfo = this.getDeviceInfo();
|
||||||
|
_isQuickApp = systemInfo?.platform === 'quickapp' || process?.env?.UNI_PLATFORM === 'quickapp';
|
||||||
|
}
|
||||||
|
return _isQuickApp;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 判断是否为华为快应用环境
|
||||||
|
* @returns {boolean} 是否为华为快应用
|
||||||
|
*/
|
||||||
|
isHuaweiQuickApp() {
|
||||||
|
if (!this.isQuickApp()) return false;
|
||||||
|
|
||||||
|
// #ifndef QUICKAPP-WEBVIEW-HUAWEI
|
||||||
|
const systemInfo = this.getDeviceInfo();
|
||||||
|
return systemInfo.brand === 'HUAWEI' || systemInfo.manufacturer === 'HUAWEI' ||
|
||||||
|
(typeof qh !== 'undefined' && qh.platform === 'huawei');
|
||||||
|
// #endif
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 蛇形命名转驼峰命名
|
||||||
|
* @param {string} str 蛇形命名字符串
|
||||||
|
* @returns {string} 驼峰命名字符串
|
||||||
|
*/
|
||||||
|
snakeToCamel(str) {
|
||||||
|
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 蛇形命名转驼峰命名(递归处理对象中的所有属性名)
|
||||||
|
* @param {Object} obj 包含蛇形命名字符串属性的对象
|
||||||
|
* @returns {Object} 驼峰命名字符串属性的对象
|
||||||
|
*/
|
||||||
|
snakeToCamelForObj(obj) {
|
||||||
|
if (typeof obj !== 'object' || obj === null) return obj;
|
||||||
|
if (Array.isArray(obj)) return obj.map(this.snakeToCamelForObj.bind(this));
|
||||||
|
const newObj = {};
|
||||||
|
for (const key in obj) {
|
||||||
|
if (Object.hasOwnProperty.call(obj, key)) {
|
||||||
|
const newKey = this.snakeToCamel(key);
|
||||||
|
newObj[newKey] = this.snakeToCamelForObj(obj[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newObj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,6 @@ let Weixin = function () {
|
|||||||
typeof callback == 'function' && callback(res);
|
typeof callback == 'function' && callback(res);
|
||||||
},
|
},
|
||||||
fail: (res) => {
|
fail: (res) => {
|
||||||
console.log('获取收货地址 fail',res);
|
|
||||||
alert(JSON.stringify(res))
|
alert(JSON.stringify(res))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
38
common/mixin/image-longpress.js
Normal file
38
common/mixin/image-longpress.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* 微信小程序图片长按识别二维码 mixin
|
||||||
|
* 自动为页面中的所有 image 组件添加 show-menu-by-longpress 属性
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 需要排除的图片类名(不需要长按识别的)
|
||||||
|
excludeImageClass: ['no-longpress', 'swiper-image', 'banner-image']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.addLongpressToImages()
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 为页面中的所有 image 添加长按识别支持
|
||||||
|
*/
|
||||||
|
addLongpressToImages() {
|
||||||
|
// 获取当前页面所有 image 组件
|
||||||
|
const images = document.querySelectorAll && document.querySelectorAll('image')
|
||||||
|
if (images) {
|
||||||
|
images.forEach(img => {
|
||||||
|
// 检查是否需要排除
|
||||||
|
const className = img.className || ''
|
||||||
|
const shouldExclude = this.excludeImageClass.some(cls => className.includes(cls))
|
||||||
|
if (!shouldExclude) {
|
||||||
|
img.setAttribute('show-menu-by-longpress', 'true')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
143
components-diy/css/common-channel.scss
Normal file
143
components-diy/css/common-channel.scss
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
// 公共微信视频号样式
|
||||||
|
|
||||||
|
// CSS 变量
|
||||||
|
:root {
|
||||||
|
// 尺寸变量
|
||||||
|
--channel-play-btn-size: 80rpx;
|
||||||
|
--channel-play-btn-small-size: 60rpx;
|
||||||
|
--channel-play-btn-icon-size: 40rpx;
|
||||||
|
--channel-play-btn-icon-small-size: 30rpx;
|
||||||
|
--channel-border-radius: 12rpx;
|
||||||
|
--channel-stats-padding: 10rpx;
|
||||||
|
--channel-info-wrap-padding: 10rpx 0;
|
||||||
|
|
||||||
|
// 字体变量
|
||||||
|
--channel-name-font-size: 28rpx;
|
||||||
|
--video-title-font-size: 28rpx;
|
||||||
|
--video-title-small-font-size: 24rpx;
|
||||||
|
--video-stats-font-size: 24rpx;
|
||||||
|
--channel-stats-font-size: 20rpx;
|
||||||
|
|
||||||
|
// 颜色变量
|
||||||
|
--channel-name-color: #333;
|
||||||
|
--video-title-color: #333;
|
||||||
|
--video-title-small-color: #666;
|
||||||
|
--video-stats-color: #999;
|
||||||
|
--channel-stats-color: #fff;
|
||||||
|
--channel-border-color: #f0f0f0;
|
||||||
|
--channel-play-btn-bg: rgba(0, 0, 0, 0.4);
|
||||||
|
--channel-stats-bg: linear-gradient(transparent, rgba(0, 0, 0, 0.6));
|
||||||
|
|
||||||
|
// 间距变量
|
||||||
|
--channel-name-margin-bottom: 4rpx;
|
||||||
|
--video-title-margin-bottom: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 响应式设计
|
||||||
|
@media (max-width: 375px) {
|
||||||
|
:root {
|
||||||
|
--channel-play-btn-size: 70rpx;
|
||||||
|
--channel-play-btn-small-size: 50rpx;
|
||||||
|
--channel-play-btn-icon-size: 35rpx;
|
||||||
|
--channel-play-btn-icon-small-size: 25rpx;
|
||||||
|
--channel-name-font-size: 24rpx;
|
||||||
|
--video-title-font-size: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 750px) {
|
||||||
|
:root {
|
||||||
|
--channel-play-btn-size: 90rpx;
|
||||||
|
--channel-play-btn-small-size: 70rpx;
|
||||||
|
--channel-play-btn-icon-size: 45rpx;
|
||||||
|
--channel-play-btn-icon-small-size: 35rpx;
|
||||||
|
--channel-name-font-size: 32rpx;
|
||||||
|
--video-title-font-size: 32rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 播放按钮样式
|
||||||
|
.channel-play-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: var(--channel-play-btn-size);
|
||||||
|
height: var(--channel-play-btn-size);
|
||||||
|
background-color: var(--channel-play-btn-bg);
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
.play-icon {
|
||||||
|
width: var(--channel-play-btn-icon-size);
|
||||||
|
height: var(--channel-play-btn-icon-size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 小尺寸播放按钮(用于列表)
|
||||||
|
.channel-play-btn.small {
|
||||||
|
width: var(--channel-play-btn-small-size);
|
||||||
|
height: var(--channel-play-btn-small-size);
|
||||||
|
|
||||||
|
.play-icon {
|
||||||
|
width: var(--channel-play-btn-icon-small-size);
|
||||||
|
height: var(--channel-play-btn-icon-small-size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 视频统计信息
|
||||||
|
.channel-stats {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: var(--channel-stats-bg);
|
||||||
|
padding: var(--channel-stats-padding);
|
||||||
|
color: var(--channel-stats-color);
|
||||||
|
font-size: var(--channel-stats-font-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 视频信息容器
|
||||||
|
.channel-info-wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
padding: var(--channel-info-wrap-padding);
|
||||||
|
|
||||||
|
.channel-name {
|
||||||
|
margin-bottom: var(--channel-name-margin-bottom);
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: var(--channel-name-font-size);
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--channel-name-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-title {
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: var(--video-title-small-font-size);
|
||||||
|
color: var(--video-title-small-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 视频标题
|
||||||
|
.video-title {
|
||||||
|
font-size: var(--video-title-font-size);
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--video-title-color);
|
||||||
|
margin-bottom: var(--video-title-margin-bottom);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 视频统计信息(非绝对定位版本)
|
||||||
|
.video-stats {
|
||||||
|
font-size: var(--video-stats-font-size);
|
||||||
|
color: var(--video-stats-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3,16 +3,16 @@
|
|||||||
<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">
|
||||||
<!-- 自动垂直滚动 -->
|
<!-- 自动垂直滚动 -->
|
||||||
<swiper class="auto-scroll-swiper" :style="swiperStyle" :vertical="swiperConfig.vertical !== false"
|
<swiper class="auto-scroll-swiper" :style="[swiperStyle]" :vertical="swiperConfig.vertical !== false"
|
||||||
:autoplay="swiperConfig.autoplay !== false" :circular="swiperConfig.circular !== false"
|
:autoplay="swiperConfig.autoplay !== false" :circular="swiperConfig.circular !== false"
|
||||||
:interval="swiperConfig.interval || 3000" :duration="swiperConfig.duration || 500"
|
:interval="swiperConfig.interval || 3000" :duration="swiperConfig.duration || 500"
|
||||||
:display-multiple-items="safeDisplayMultipleItems">
|
:display-multiple-items="safeDisplayMultipleItems">
|
||||||
<swiper-item v-for="(item, index) in list" :key="index" @click="toDetail(item)">
|
<swiper-item v-for="(item, index) in list" :key="index" @tap.stop="toDetail(item)">
|
||||||
<view class="swiper-item-content">
|
<view class="swiper-item-content">
|
||||||
<view :class="['item', value.ornament.type]" :style="itemCss">
|
<view :class="['item', value.ornament.type]" :style="itemCss">
|
||||||
<view class="article-img">
|
<view class="article-img">
|
||||||
<image class="cover-img" :src="$util.img(item.cover_img)" mode="widthFix"
|
<image class="cover-img" :src="$util.img(item.cover_img)" mode="widthFix"
|
||||||
@error="imgError(index)" />
|
@error="imgError(index)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-wrap">
|
<view class="info-wrap">
|
||||||
<text class="title">{{ item.article_title }}</text>
|
<text class="title">{{ item.article_title }}</text>
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
<view class="time" :style="{ color: value.timecolor }">
|
<view class="time" :style="{ color: value.timecolor }">
|
||||||
{{ audiotime }}
|
{{ audiotime }}
|
||||||
</view>
|
</view>
|
||||||
<view @click="play()" class="start" :class="status ? 'iconj icon-07zanting' : 'iconj icon-bofang'"
|
<view @tap.stop="play()" class="start" :class="status ? 'iconj icon-07zanting' : 'iconj icon-bofang'"
|
||||||
style="padding-top: 18rpx"></view>
|
style="padding-top: 18rpx"></view>
|
||||||
</view>
|
</view>
|
||||||
<view class="fui-audio style3" :style="{ background: value.background }" v-else>
|
<view class="fui-audio style3" :style="{ background: value.background }" v-else>
|
||||||
<!-- <audio src="/static/audio/bgm.mp3" controls loop></audio> -->
|
<!-- <audio src="/static/audio/bgm.mp3" controls loop></audio> -->
|
||||||
<view class="img">
|
<view class="img">
|
||||||
<image :src="$util.img(value.imageUrl)"></image>
|
<image :src="$util.img(value.imageUrl)" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="name" :style="{ color: value.textcolor }">{{ value.text }}</view>
|
<view class="name" :style="{ color: value.textcolor }">{{ value.text }}</view>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<!-- {{audios[value.id].audiotime}} -->
|
<!-- {{audios[value.id].audiotime}} -->
|
||||||
{{ audiotime }}
|
{{ audiotime }}
|
||||||
</view>
|
</view>
|
||||||
<view @click="play()" class="start" :class="status ? 'iconj icon-07zanting' : 'iconj icon-bofang'"></view>
|
<view @tap.stop="play()" class="start" :class="status ? 'iconj icon-07zanting' : 'iconj icon-bofang'"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -98,9 +98,7 @@ export default {
|
|||||||
uni.setStorageSync('audio_list', audio_list)
|
uni.setStorageSync('audio_list', audio_list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(uni.getStorageSync('audio_list'))
|
|
||||||
var n = this;
|
var n = this;
|
||||||
// console.log(a)
|
|
||||||
a.onPlay(function () {
|
a.onPlay(function () {
|
||||||
var e = setInterval(function () {
|
var e = setInterval(function () {
|
||||||
var i = a.currentTime / a.duration * 100 + "%", s = Math.floor(Math.ceil(a.currentTime) / 60), o = (Math.ceil(a.currentTime) % 60 / 100).toFixed(2).slice(-2), r = Math.ceil(a.currentTime);
|
var i = a.currentTime / a.duration * 100 + "%", s = Math.floor(Math.ceil(a.currentTime) / 60), o = (Math.ceil(a.currentTime) % 60 / 100).toFixed(2).slice(-2), r = Math.ceil(a.currentTime);
|
||||||
@@ -113,13 +111,12 @@ export default {
|
|||||||
|
|
||||||
var s = n.$util.img(n.value.audioUrl), o = n.audios[n.value.id].seconds || 0, r = 0, u = 1;
|
var s = n.$util.img(n.value.audioUrl), o = n.audios[n.value.id].seconds || 0, r = 0, u = 1;
|
||||||
0 == u && a.onEnded(function (e) {
|
0 == u && a.onEnded(function (e) {
|
||||||
c[t].status = !1, n.status = !1, c[t].seconds = 0, console.log(c), n.audios = c;
|
c[t].status = !1, n.status = !1, c[t].seconds = 0, n.audios = c;
|
||||||
});
|
});
|
||||||
var c = n.audios;
|
var c = n.audios;
|
||||||
c[t] || (c[t] = {}), a.paused && 0 == o ? (a.src = s, a.play(), 1 == u && (a.loop = !0),
|
c[t] || (c[t] = {}), a.paused && 0 == o ? (a.src = s, a.play(), 1 == u && (a.loop = !0),
|
||||||
c[t].status = !0, n.status = !0, n.pauseOther(t)) : a.paused && o > 0 ? (a.play(), 0 == r ? a.seek(o) : a.seek(0),
|
c[t].status = !0, n.status = !0, n.pauseOther(t)) : a.paused && o > 0 ? (a.play(), 0 == r ? a.seek(o) : a.seek(0),
|
||||||
c[t].status = !0, n.status = !0, n.pauseOther(t)) : (a.pause(), c[t].status = !1, n.status = !1), n.audios = c;
|
c[t].status = !0, n.status = !0, n.pauseOther(t)) : (a.pause(), c[t].status = !1, n.status = !1), n.audios = c;
|
||||||
console.log(n.audios)
|
|
||||||
},
|
},
|
||||||
pauseOther: function (e) {
|
pauseOther: function (e) {
|
||||||
var t = this;
|
var t = this;
|
||||||
@@ -190,18 +187,14 @@ export default {
|
|||||||
var u = s + ":" + o, c = that.audios;
|
var u = s + ":" + o, c = that.audios;
|
||||||
c[t].audiowidth = i, c[t].Time = e, c[t].audiotime = u, c[t].seconds = r
|
c[t].audiowidth = i, c[t].Time = e, c[t].audiotime = u, c[t].seconds = r
|
||||||
that.audios = c
|
that.audios = c
|
||||||
// console.log(c)
|
|
||||||
console.log(that.audios[that.value.id].audiotime)
|
|
||||||
that.audiotime = that.audios[that.value.id].audiotime
|
that.audiotime = that.audios[that.value.id].audiotime
|
||||||
that.audiowidth = that.audios[that.value.id].audiowidth
|
that.audiowidth = that.audios[that.value.id].audiowidth
|
||||||
console.log(i)
|
|
||||||
that.lyg = i
|
that.lyg = i
|
||||||
}, 1e3);
|
}, 1e3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
this.audioContext.onEnded(() => {
|
this.audioContext.onEnded(() => {
|
||||||
console.log('播放结束');
|
|
||||||
this.status = 0
|
this.status = 0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,12 @@
|
|||||||
:style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }">
|
:style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }">
|
||||||
{{ value.titleStyle.leftText }}
|
{{ value.titleStyle.leftText }}
|
||||||
</view>
|
</view>
|
||||||
<image v-else class="left-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix"></image>
|
<image v-else class="left-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix" show-menu-by-longpress></image>
|
||||||
<view class="head-content" v-if="value.titleStyle.style == 'style-1'"
|
<view class="head-content" v-if="value.titleStyle.style == 'style-1'"
|
||||||
:style="{ color: value.titleStyle.textColor }">低至0元免费拿</view>
|
:style="{ color: value.titleStyle.textColor }">低至0元免费拿</view>
|
||||||
<view class="head-right"
|
<view class="head-right"
|
||||||
:style="{ fontSize: value.titleStyle.moreFontSize * 2 + 'rpx', color: value.titleStyle.moreColor }"
|
:style="{ fontSize: value.titleStyle.moreFontSize * 2 + 'rpx', color: value.titleStyle.moreColor }"
|
||||||
@click="$util.redirectTo('/pages_promotion/bargain/list')">
|
@tap.stop="$util.redirectTo('/pages_promotion/bargain/list')">
|
||||||
<text>{{ value.titleStyle.more }}</text>
|
<text>{{ value.titleStyle.more }}</text>
|
||||||
<text class="iconfont icon-right"></text>
|
<text class="iconfont icon-right"></text>
|
||||||
</view>
|
</view>
|
||||||
@@ -23,12 +23,12 @@
|
|||||||
|
|
||||||
<!-- 商品列表 -->
|
<!-- 商品列表 -->
|
||||||
<template v-if="value.template == 'row1-of1'">
|
<template v-if="value.template == 'row1-of1'">
|
||||||
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)"
|
<view class="item" v-for="(item, index) in list" :key="index" @tap.stop="toDetail(item)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" />
|
@error="imageError(index)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="content"
|
<view class="content"
|
||||||
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.btnStyle.control">
|
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.btnStyle.control">
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<view class="bg">
|
<view class="bg">
|
||||||
<view class="curr" :style="{ width: progress(item) * 2 + 'rpx' }">
|
<view class="curr" :style="{ width: progress(item) * 2 + 'rpx' }">
|
||||||
<image class="progress-bar" mode="widthFix"
|
<image class="progress-bar" mode="widthFix"
|
||||||
:src="$util.img('public/uniapp/bargain/progress_bar_01.png')" />
|
:src="$util.img('public/uniapp/bargain/progress_bar_01.png')" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="num" v-if="item.is_bargaining">
|
<view class="num" v-if="item.is_bargaining">
|
||||||
@@ -84,12 +84,12 @@
|
|||||||
|
|
||||||
<template v-if="value.template == 'horizontal-slide'">
|
<template v-if="value.template == 'horizontal-slide'">
|
||||||
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
|
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
|
||||||
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)"
|
<view class="item" v-for="(item, index) in list" :key="index" @tap.stop="toDetail(item)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" :lazy-load="true" />
|
@error="imageError(index)" :lazy-load="true" show-menu-by-longpress/>
|
||||||
<image class="bg"
|
<image class="bg"
|
||||||
v-if="value.saleStyle.control && value.template == 'horizontal-slide' && value.style != 'style-2'"
|
v-if="value.saleStyle.control && value.template == 'horizontal-slide' && value.style != 'style-2'"
|
||||||
:src="$util.img('public/uniapp/bargain/bg.png')" mode="widthFix" />
|
:src="$util.img('public/uniapp/bargain/bg.png')" mode="widthFix" />
|
||||||
@@ -130,11 +130,11 @@
|
|||||||
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
||||||
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
||||||
<view class="item" v-for="(item, dataIndex) in list[pageIndex]" :key="dataIndex"
|
<view class="item" v-for="(item, dataIndex) in list[pageIndex]" :key="dataIndex"
|
||||||
@click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
@tap.stop="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(dataIndex)" :lazy-load="true" />
|
@error="imageError(dataIndex)" :lazy-load="true" show-menu-by-longpress/>
|
||||||
<image class="bg"
|
<image class="bg"
|
||||||
v-if="value.saleStyle.control && value.template == 'horizontal-slide' && value.style != 'style-2'"
|
v-if="value.saleStyle.control && value.template == 'horizontal-slide' && value.style != 'style-2'"
|
||||||
:src="$util.img('public/uniapp/bargain/bg.png')" mode="widthFix" />
|
:src="$util.img('public/uniapp/bargain/bg.png')" mode="widthFix" />
|
||||||
@@ -365,7 +365,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
/deep/.uni-scroll-view ::-webkit-scrollbar {
|
::v-deep .uni-scroll-view ::-webkit-scrollbar {
|
||||||
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -374,7 +374,7 @@ export default {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/::-webkit-scrollbar {
|
::v-deep ::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<view data-component-name="diy-bottom-nav" v-if="tabBarList && tabBarList.list">
|
<view data-component-name="diy-bottom-nav" v-if="tabBarList && tabBarList.list">
|
||||||
<view class="tab-bar" :style="{ backgroundColor: tabBarList.backgroundColor }">
|
<view class="tab-bar" :style="{ backgroundColor: tabBarList.backgroundColor }">
|
||||||
<view class="tabbar-border"></view>
|
<view class="tabbar-border"></view>
|
||||||
<view class="item" v-for="(item, index) in tabBarList.list" :key="item.id" @click="redirectTo(item.link)">
|
<view class="item" v-for="(item, index) in tabBarList.list" :key="item.id" @tap.stop="redirectTo(item.link)">
|
||||||
<view class="bd">
|
<view class="bd">
|
||||||
<block v-if="item.link.wap_url == '/pages_goods/cart'">
|
<block v-if="item.link.wap_url == '/pages_goods/cart'">
|
||||||
<view class="icon" v-if="tabBarList.type == 1 || tabBarList.type == 2"
|
<view class="icon" v-if="tabBarList.type == 1 || tabBarList.type == 2"
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { adaptSubpackageUrl } from '@/common/js/util.js'
|
import { adaptSubpackageUrl, checkTabBarActive } from '@/common/js/util.js'
|
||||||
import DiyMinx from './minx.js'
|
import DiyMinx from './minx.js'
|
||||||
// 底部导航栏
|
// 底部导航栏
|
||||||
export default {
|
export default {
|
||||||
@@ -145,27 +145,16 @@ export default {
|
|||||||
let linkUrl = link.wap_url;
|
let linkUrl = link.wap_url;
|
||||||
|
|
||||||
// 首页特殊处理
|
// 首页特殊处理
|
||||||
if (linkUrl === '/pages/index/index' && this.name === 'DIY_VIEW_INDEX') {
|
if (linkUrl === this.$util.INDEX_PAGE_URL && this.name === 'DIY_VIEW_INDEX') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('diy-bottom-nav verify:', { likkUrl: adaptSubpackageUrl(linkUrl), currentPageRoute: currentPageRoute});
|
|
||||||
|
|
||||||
// 精确匹配当前路径
|
// 精确匹配当前路径
|
||||||
if (adaptSubpackageUrl(linkUrl) === currentPageRoute) {
|
if (adaptSubpackageUrl(linkUrl) === currentPageRoute) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 同属于一个子包的路径,也认为是匹配的
|
return checkTabBarActive(linkUrl, currentPageRoute);
|
||||||
try {
|
|
||||||
if (adaptSubpackageUrl(linkUrl).split('/')[1] === currentPageRoute.split('/')[1]) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('diy-bottom-nav verify error:', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<view data-component-name="diy-category-item" class="item-wrap" :class="type">
|
<view data-component-name="diy-category-item" class="item-wrap" :class="type">
|
||||||
<block v-if="type == 'category' && category.child_list && category.child_list.length">
|
<block v-if="type == 'category' && category.child_list && category.child_list.length">
|
||||||
<view class="category-adv" v-if="category.image_adv" @click="diyRedirectTo(category.link_url)">
|
<view class="category-adv" v-if="category.image_adv" @tap.stop="diyRedirectTo(category.link_url)">
|
||||||
<image :src="$util.img(category.image_adv)" mode="widthFix" />
|
<image :src="$util.img(category.image_adv)" mode="widthFix" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<block v-if="value.level == 2">
|
<block v-if="value.level == 2">
|
||||||
<view class="category-title">{{ category.category_name }}</view>
|
<view class="category-title">{{ category.category_name }}</view>
|
||||||
<view class="category-list">
|
<view class="category-list">
|
||||||
<view class="category-item" v-for="(one, oneIndex) in category.child_list" :key="oneIndex"
|
<view class="category-item" v-for="(one, oneIndex) in category.child_list" :key="oneIndex"
|
||||||
@click="$util.redirectTo('/pages_goods/list', { category_id: one.category_id })">
|
@tap.stop="$util.redirectTo('/pages_goods/list', { category_id: one.category_id })">
|
||||||
<view class="img-box">
|
<view class="img-box">
|
||||||
<image :src="$util.img(one.image)" mode="widthFix" />
|
<image :src="$util.img(one.image)" mode="widthFix" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
<view class="name">{{ one.category_name }}</view>
|
<view class="name">{{ one.category_name }}</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -23,9 +23,9 @@
|
|||||||
<view class="category-title">{{ one.category_name }}</view>
|
<view class="category-title">{{ one.category_name }}</view>
|
||||||
<view class="category-list">
|
<view class="category-list">
|
||||||
<view class="category-item" v-for="(two, twoIndex) in one.child_list" :key="twoIndex"
|
<view class="category-item" v-for="(two, twoIndex) in one.child_list" :key="twoIndex"
|
||||||
@click="$util.redirectTo('/pages_goods/list', { category_id: two.category_id })">
|
@tap.stop="$util.redirectTo('/pages_goods/list', { category_id: two.category_id })">
|
||||||
<view class="img-box">
|
<view class="img-box">
|
||||||
<image :src="$util.img(two.image)" mode="widthFix" :lazy-load="true" />
|
<image :src="$util.img(two.image)" mode="widthFix" :lazy-load="true" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
<view class="name">{{ two.category_name }}</view>
|
<view class="name">{{ two.category_name }}</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -44,22 +44,22 @@
|
|||||||
:class="{ 'screen-category-4': value.template == 4 }" :scroll-with-animation="true"
|
:class="{ 'screen-category-4': value.template == 4 }" :scroll-with-animation="true"
|
||||||
:scroll-into-view="scrollIntoView">
|
:scroll-into-view="scrollIntoView">
|
||||||
<view class="item" id="category-2--1" :class="{ selected: categoryId == -1 }"
|
<view class="item" id="category-2--1" :class="{ selected: categoryId == -1 }"
|
||||||
@click="selectCategory(-1)">全部</view>
|
@tap.stop="selectCategory(-1)">全部</view>
|
||||||
<view class="item" :id="'category-2-' + oneIndex"
|
<view class="item" :id="'category-2-' + oneIndex"
|
||||||
:class="{ selected: categoryId == oneIndex }" @click="selectCategory(oneIndex)"
|
:class="{ selected: categoryId == oneIndex }" @tap.stop="selectCategory(oneIndex)"
|
||||||
v-for="(one, oneIndex) in category.child_list" :key="oneIndex">
|
v-for="(one, oneIndex) in category.child_list" :key="oneIndex">
|
||||||
{{ one.category_name }}
|
{{ one.category_name }}
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<view class="iconfont icon-unfold" @click="$refs.screenCategoryPopup.open()"></view>
|
<view class="iconfont icon-unfold" @tap.stop="$refs.screenCategoryPopup.open()"></view>
|
||||||
</view>
|
</view>
|
||||||
<uni-popup type="top" ref="screenCategoryPopup">
|
<uni-popup type="top" ref="screenCategoryPopup">
|
||||||
<view class="screen-category-popup" @click="$refs.screenCategoryPopup.close()">
|
<view class="screen-category-popup" @tap.stop="$refs.screenCategoryPopup.close()">
|
||||||
<scroll-view scroll-y="true" class="screen-category"
|
<scroll-view scroll-y="true" class="screen-category"
|
||||||
:class="{ 'screen-category-4': value.template == 4 }">
|
:class="{ 'screen-category-4': value.template == 4 }">
|
||||||
<view class="title">全部</view>
|
<view class="title">全部</view>
|
||||||
<view class="item" :class="{ selected: categoryId == oneIndex }"
|
<view class="item" :class="{ selected: categoryId == oneIndex }"
|
||||||
@click="selectCategory(oneIndex)" v-for="(one, oneIndex) in category.child_list"
|
@tap.stop="selectCategory(oneIndex)" v-for="(one, oneIndex) in category.child_list"
|
||||||
:key="oneIndex">
|
:key="oneIndex">
|
||||||
{{ one.category_name }}
|
{{ one.category_name }}
|
||||||
</view>
|
</view>
|
||||||
@@ -81,13 +81,13 @@
|
|||||||
:data-template="value.template">
|
:data-template="value.template">
|
||||||
<block v-if="goodsList.length">
|
<block v-if="goodsList.length">
|
||||||
<view class="goods-item" v-for="(item, index) in goodsList" :key="index">
|
<view class="goods-item" v-for="(item, index) in goodsList" :key="index">
|
||||||
<view class="goods-img" @click="toDetail(item)">
|
<view class="goods-img" @tap.stop="toDetail(item)">
|
||||||
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)" />
|
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)" show-menu-by-longpress />
|
||||||
<view class="color-base-bg goods-tag" v-if="item.label_name">{{ item.label_name }}
|
<view class="color-base-bg goods-tag" v-if="item.label_name">{{ item.label_name }}
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
<view class="info-wrap">
|
<view class="info-wrap">
|
||||||
<view class="name-wrap" @click="toDetail(item)">
|
<view class="name-wrap" @tap.stop="toDetail(item)">
|
||||||
<view class="goods-name">{{ isEnEnv ? item.en_goods_name : item.goods_name }}</view>
|
<view class="goods-name">{{ isEnEnv ? item.en_goods_name : item.goods_name }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="price-wrap">
|
<view class="price-wrap">
|
||||||
@@ -99,17 +99,14 @@
|
|||||||
<text class="unit price-style small">.{{
|
<text class="unit price-style small">.{{
|
||||||
parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
|
parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
|
||||||
</block>
|
</block>
|
||||||
<block v-else>
|
|
||||||
<text class="unit price-style small">{{ $lang('Make') ? $lang('Make') : '询价' }}</text>
|
|
||||||
</block>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="member-price-tag"
|
<view class="member-price-tag"
|
||||||
v-if="item.member_price && item.member_price == showPrice(item)">
|
v-if="item.member_price && item.member_price == showPrice(item)">
|
||||||
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix" />
|
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
<view class="member-price-tag" v-else-if="item.promotion_type == 1">
|
<view class="member-price-tag" v-else-if="item.promotion_type == 1">
|
||||||
<image :src="$util.img('public/uniapp/index/discount.png')"
|
<image :src="$util.img('public/uniapp/index/discount.png')"
|
||||||
mode="widthFix" />
|
mode="widthFix" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="footer-wrap">
|
<view class="footer-wrap">
|
||||||
@@ -120,27 +117,33 @@
|
|||||||
<text>{{ showMarketPrice(item) }}</text>
|
<text>{{ showMarketPrice(item) }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="ai-chat-btn-wrap" v-if="item.isinformation == 1">
|
||||||
|
<view class="ai-chat-btn" @tap.stop="sendToAIChat(item)">
|
||||||
|
立即咨询
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- <view class="right-wrap" v-if="value.template == 2 || value.template == 4">
|
<!-- <view class="right-wrap" v-if="value.template == 2 || value.template == 4">
|
||||||
<block v-if="item.is_virtual">
|
<block v-if="item.is_virtual">
|
||||||
<view class="color-base-bg select-sku" @click="toDetail(item)">立即购买</view>
|
<view class="color-base-bg select-sku" @tap.stop="toDetail(item)">立即购买</view>
|
||||||
</block>
|
</block>
|
||||||
<block v-else>
|
<block v-else>
|
||||||
<view v-if="item.goods_spec_format" class="color-base-bg select-sku" @click="selectSku(item)">
|
<view v-if="item.goods_spec_format" class="color-base-bg select-sku" @tap.stop="selectSku(item)">
|
||||||
<text>选规格</text>
|
<text>选规格</text>
|
||||||
<text class="num-tag" v-if="item.num">{{ item.num }}</text>
|
<text class="num-tag" v-if="item.num">{{ item.num }}</text>
|
||||||
</view>
|
</view>
|
||||||
<block v-else>
|
<block v-else>
|
||||||
<block v-if="cartList['goods_' + item.goods_id]&&cartList['goods_' + item.goods_id]['sku_' + item.sku_id]">
|
<block v-if="cartList['goods_' + item.goods_id]&&cartList['goods_' + item.goods_id]['sku_' + item.sku_id]">
|
||||||
<view class="num-action reduce" @click="reduce(item)">
|
<view class="num-action reduce" @tap.stop="reduce(item)">
|
||||||
<text class="iconfont icon-jian"></text>
|
<text class="iconfont icon-jian"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="num">{{ cartList['goods_' + item.goods_id]['sku_' + item.sku_id].num }}</view>
|
<view class="num">{{ cartList['goods_' + item.goods_id]['sku_' + item.sku_id].num }}</view>
|
||||||
<view class="num-action" :id="'cart-num-' + index" @click="increase($event, item)">
|
<view class="num-action" :id="'cart-num-' + index" @tap.stop="increase($event, item)">
|
||||||
<text class="iconfont icon-jia"></text>
|
<text class="iconfont icon-jia"></text>
|
||||||
<view class="click-event"></view>
|
<view class="click-event"></view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<view class="num-action" v-else :id="'cart-num-' + index" @click="increase($event, item, 0)">
|
<view class="num-action" v-else :id="'cart-num-' + index" @tap.stop="increase($event, item, 0)">
|
||||||
<text class="iconfont icon-jia"></text>
|
<text class="iconfont icon-jia"></text>
|
||||||
<view class="click-event"></view>
|
<view class="click-event"></view>
|
||||||
</view>
|
</view>
|
||||||
@@ -148,17 +151,17 @@
|
|||||||
</block>
|
</block>
|
||||||
</view> -->
|
</view> -->
|
||||||
<!-- <view class="right-wrap" v-if="value.template == 3">
|
<!-- <view class="right-wrap" v-if="value.template == 3">
|
||||||
<view class="color-base-bg select-sku" @click="toDetail(item)">立即购买</view>
|
<view class="color-base-bg select-sku" @tap.stop="toDetail(item)">立即购买</view>
|
||||||
</view> -->
|
</view> -->
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<view class="category-empty" v-else>
|
<view class="category-empty" v-else>
|
||||||
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix" />
|
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
<!-- <view class="end-tips" ref="endTips" v-if="last && (categoryId == -1 || !category.child_list || (category.child_list && categoryId == category.child_list.length - 1))">已经到底了~</view>
|
<!-- <view class="end-tips" ref="endTips" v-if="last && (categoryId == -1 || !category.child_list || (category.child_list && categoryId == category.child_list.length - 1))">已经到底了~</view>
|
||||||
<view class="end-tips" ref="endTips" v-else @click="switchCategory('next')">
|
<view class="end-tips" ref="endTips" v-else @tap.stop="switchCategory('next')">
|
||||||
<text class="iconfont icon-xiangshangzhanhang"></text>
|
<text class="iconfont icon-xiangshangzhanhang"></text>
|
||||||
上滑查看下一分类
|
上滑查看下一分类
|
||||||
</view> -->
|
</view> -->
|
||||||
@@ -173,35 +176,31 @@
|
|||||||
<view class="goods-list" :class="{ 'double-column': !isList, 'single-column': isList }"
|
<view class="goods-list" :class="{ 'double-column': !isList, 'single-column': isList }"
|
||||||
:data-template="value.template">
|
:data-template="value.template">
|
||||||
<view class="goods-item" v-for="(item, index) in goodsList" :key="index">
|
<view class="goods-item" v-for="(item, index) in goodsList" :key="index">
|
||||||
<view class="goods-img" @click="toDetail(item)">
|
<view class="goods-img" @tap.stop="toDetail(item)">
|
||||||
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"
|
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"
|
||||||
:lazy-load="true" />
|
:lazy-load="true" show-menu-by-longpress />
|
||||||
<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>
|
</view>
|
||||||
<view class="info-wrap">
|
<view class="info-wrap">
|
||||||
<view class="name-wrap" @click="toDetail(item)">
|
<view class="name-wrap" @tap.stop="toDetail(item)">
|
||||||
<view class="goods-name">{{ isEnEnv ? item.en_goods_name : item.goods_name }}</view>
|
<view class="goods-name">{{ isEnEnv ? item.en_goods_name : item.goods_name }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="price-wrap">
|
<view class="price-wrap">
|
||||||
<view class="discount-price">
|
<view class="discount-price">
|
||||||
<block v-if="item.isinformation == 0">
|
<block v-if="item.isinformation == 0">
|
||||||
<text class="unit price-style small">¥</text>
|
<text class="unit price-style small">¥</text>
|
||||||
<text class="price price-style large">{{
|
<text class="price price-style large">{{
|
||||||
parseFloat(showPrice(item)).toFixed(2).split('.')[0] }}</text>
|
parseFloat(showPrice(item)).toFixed(2).split('.')[0] }}</text>
|
||||||
<text class="unit price-style small">.{{
|
<text class="unit price-style small">.{{
|
||||||
parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
|
parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
|
||||||
</block>
|
</block>
|
||||||
<block v-else>
|
</view>
|
||||||
<text class="unit price-style small">{{ $lang('Make') ? $lang('Make') : '询价' }}</text>
|
|
||||||
</block>
|
|
||||||
|
|
||||||
</view>
|
|
||||||
<view class="member-price-tag"
|
<view class="member-price-tag"
|
||||||
v-if="item.member_price && item.member_price == showPrice(item)">
|
v-if="item.member_price && item.member_price == showPrice(item)">
|
||||||
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix" />
|
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
<view class="member-price-tag" v-else-if="item.promotion_type == 1">
|
<view class="member-price-tag" v-else-if="item.promotion_type == 1">
|
||||||
<image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix" />
|
<image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="footer-wrap">
|
<view class="footer-wrap">
|
||||||
@@ -212,32 +211,38 @@
|
|||||||
<text>{{ showMarketPrice(item) }}</text>
|
<text>{{ showMarketPrice(item) }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="ai-chat-btn-wrap" v-if="item.isinformation == 1">
|
||||||
|
<view class="ai-chat-btn" @tap.stop="sendToAIChat(item)">
|
||||||
|
立即咨询
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<view class="right-wrap" v-if="value.template == 2">
|
<view class="right-wrap" v-if="value.template == 2">
|
||||||
<block v-if="item.is_virtual">
|
<block v-if="item.is_virtual">
|
||||||
<view class="color-base-bg select-sku" @click="toDetail(item)">立即购买</view>
|
<view class="color-base-bg select-sku" @tap.stop="toDetail(item)">立即购买</view>
|
||||||
</block>
|
</block>
|
||||||
<block v-else>
|
<block v-else>
|
||||||
<view v-if="item.goods_spec_format" class="color-base-bg select-sku"
|
<view v-if="item.goods_spec_format" class="color-base-bg select-sku"
|
||||||
@click="selectSku(item)">
|
@tap.stop="selectSku(item)">
|
||||||
<text>选规格</text>
|
<text>选规格</text>
|
||||||
<text class="num-tag" v-if="item.num">{{ item.num }}</text>
|
<text class="num-tag" v-if="item.num">{{ item.num }}</text>
|
||||||
</view>
|
</view>
|
||||||
<block v-else>
|
<block v-else>
|
||||||
<block
|
<block
|
||||||
v-if="cartList['goods_' + item.goods_id] && cartList['goods_' + item.goods_id]['sku_' + item.sku_id]">
|
v-if="cartList['goods_' + item.goods_id] && cartList['goods_' + item.goods_id]['sku_' + item.sku_id]">
|
||||||
<view class="num-action reduce" @click="reduce(item)">
|
<view class="num-action reduce" @tap.stop="reduce(item)">
|
||||||
<text class="iconfont icon-jian"></text>
|
<text class="iconfont icon-jian"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="num">{{ cartList['goods_' + item.goods_id]['sku_' +
|
<view class="num">{{ cartList['goods_' + item.goods_id]['sku_' +
|
||||||
item.sku_id].num }}</view>
|
item.sku_id].num }}</view>
|
||||||
<view class="num-action" :id="'cart-num-' + index"
|
<view class="num-action" :id="'cart-num-' + index"
|
||||||
@click="increase($event, item)">
|
@tap.stop="increase($event, item)">
|
||||||
<text class="iconfont icon-jia"></text>
|
<text class="iconfont icon-jia"></text>
|
||||||
<view class="click-event"></view>
|
<view class="click-event"></view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<view class="num-action" v-else :id="'cart-num-' + index"
|
<view class="num-action" v-else :id="'cart-num-' + index"
|
||||||
@click="increase($event, item, 0)">
|
@tap.stop="increase($event, item, 0)">
|
||||||
<text class="iconfont icon-jia"></text>
|
<text class="iconfont icon-jia"></text>
|
||||||
<view class="click-event"></view>
|
<view class="click-event"></view>
|
||||||
</view>
|
</view>
|
||||||
@@ -245,7 +250,7 @@
|
|||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
<view class="right-wrap" v-if="value.template == 3">
|
<view class="right-wrap" v-if="value.template == 3">
|
||||||
<view class="color-base-bg select-sku" @click="toDetail(item)">立即购买</view>
|
<view class="color-base-bg select-sku" @tap.stop="toDetail(item)">立即购买</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -718,6 +723,15 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 跳转到商品详情
|
||||||
|
* @param {Object} item 商品信息
|
||||||
|
*/
|
||||||
|
sendToAIChat(item) {
|
||||||
|
this.$util.redirectTo('/pages_goods/detail', {
|
||||||
|
goods_id: item.goods_id
|
||||||
|
});
|
||||||
|
},
|
||||||
diyRedirectTo(link) {
|
diyRedirectTo(link) {
|
||||||
if (!link) return;
|
if (!link) return;
|
||||||
this.$util.diyRedirectTo(JSON.parse(link));
|
this.$util.diyRedirectTo(JSON.parse(link));
|
||||||
@@ -1160,7 +1174,7 @@ export default {
|
|||||||
.right-wrap {
|
.right-wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: end;
|
justify-content: flex-end;
|
||||||
|
|
||||||
.num {
|
.num {
|
||||||
width: auto;
|
width: auto;
|
||||||
@@ -1314,7 +1328,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .uni-popup__wrapper-box {
|
::v-deep .uni-popup__wrapper-box {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1348,7 +1362,7 @@ export default {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .loading-layer {
|
::v-deep .loading-layer {
|
||||||
background: #fff !important;
|
background: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1384,4 +1398,25 @@ export default {
|
|||||||
color: var(--main-color);
|
color: var(--main-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ai-chat-btn-wrap {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: auto;
|
||||||
|
padding-top: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-chat-btn {
|
||||||
|
background-color: #ff0000;
|
||||||
|
color: #fff;
|
||||||
|
padding: 12rpx 30rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.2;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
: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" @tap.stop="$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" @click.stop="onClickSearch()" @tap.stop="onClickSearch()" disabled="true" />
|
<input type="text" class="uni-input font-size-tag" maxlength="50" :placeholder="$lang('search')" confirm-type="search" @tap.stop="onClickSearch()" disabled="true" />
|
||||||
<text class="iconfont icon-sousuo3"></text>
|
<text class="iconfont icon-sousuo3"></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -13,61 +13,61 @@
|
|||||||
</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="onClickSearch()" @tap.stop="onClickSearch()"
|
<view class="search-box" v-if="value.search" @tap.stop="onClickSearch()"
|
||||||
:style="wxSearchHeight">
|
:style="wxSearchHeight">
|
||||||
<view class="search-content">
|
<view class="search-content">
|
||||||
<input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')"
|
<input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')"
|
||||||
confirm-type="search" @click.stop="onClickSearch()" @tap.stop="onClickSearch()"
|
confirm-type="search" @tap.stop="onClickSearch()"
|
||||||
disabled="true" />
|
disabled="true" />
|
||||||
<text class="iconfont icon-sousuo3"></text>
|
<text class="iconfont icon-sousuo3"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="iconfont" :class="{ 'icon-apps': !isList, 'icon-list': isList }"
|
<view class="iconfont" :class="{ 'icon-apps': !isList, 'icon-list': isList }"
|
||||||
@click.stop.prevent="changeListStyle()"></view>
|
@tap.stop.prevent="changeListStyle()"></view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifdef H5 -->
|
<!-- #ifdef H5 -->
|
||||||
<view class="search-box" v-if="value.search" @click="onClickSearch()" @tap.stop="onClickSearch()">
|
<view class="search-box" v-if="value.search" @tap.stop="onClickSearch()">
|
||||||
<view class="search-content">
|
<view class="search-content">
|
||||||
<input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')" confirm-type="search"
|
<input type="text" class="uni-input" maxlength="50" :placeholder="$lang('search')" confirm-type="search"
|
||||||
@click.stop="onClickSearch()" @tap.stop="onClickSearch()" disabled="true" />
|
@tap.stop="onClickSearch()" disabled="true" />
|
||||||
<text class="iconfont icon-sousuo3"></text>
|
<text class="iconfont icon-sousuo3"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="iconfont" :class="{ 'icon-apps': !isList, 'icon-list': isList }"
|
<view class="iconfont" :class="{ 'icon-apps': !isList, 'icon-list': isList }"
|
||||||
@click.stop.prevent="changeListStyle()"></view>
|
@tap.stop.prevent="changeListStyle()"></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-view scroll-x="true" class="template-four-wrap" :scroll-with-animation="true"
|
||||||
:scroll-into-view="'category-one-' + oneCategorySelect" enable-flex="true">
|
:scroll-into-view="'category-one-' + oneCategorySelect" enable-flex="true">
|
||||||
<view class="category-item" :id="'category-one-' + index" v-for="(item, index) in templateFourData"
|
<view class="category-item" :id="'category-one-' + index" v-for="(item, index) in templateFourData"
|
||||||
:key="index" :class="{ select: oneCategorySelect == index }" @click="templateFourOneFn(index)">
|
:key="index" :class="{ select: oneCategorySelect == index }" @tap.stop="templateFourOneFn(index)">
|
||||||
<view class="image-warp" :class="[{ 'color-base-border': oneCategorySelect == index }]">
|
<view class="image-warp" :class="[{ 'color-base-border': oneCategorySelect == index }]">
|
||||||
<image :src="$util.img(item.image)" mode="aspectFill" />
|
<image :src="$util.img(item.image)" mode="aspectFill" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view :class="['text', { 'color-base-bg': oneCategorySelect == index }]">{{ item.category_name }}
|
<view :class="['text', { 'color-base-bg': oneCategorySelect == index }]">{{ item.category_name }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<view class="category-item-all" @click="$refs.templateFourPopup.open()">
|
<view class="category-item-all" @tap.stop="$refs.templateFourPopup.open()">
|
||||||
<view class="category-item-all-wrap">
|
<view class="category-item-all-wrap">
|
||||||
<text class="text">展开</text>
|
<text class="text">展开</text>
|
||||||
<image class="img" :src="$util.img('/public/uniapp/category/unfold.png')" mode="aspectFill"></image>
|
<image class="img" :src="$util.img('/public/uniapp/category/unfold.png')" mode="aspectFill" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<uni-popup type="top" ref="templateFourPopup" :top="uniPopupTop">
|
<uni-popup type="top" ref="templateFourPopup" :top="uniPopupTop">
|
||||||
<view class="template-four-popup">
|
<view class="template-four-popup">
|
||||||
<scroll-view scroll-y="true" class="template-four-scroll" enable-flex="true">
|
<scroll-view scroll-y="true" class="template-four-scroll" enable-flex="true">
|
||||||
<view class="item" :class="{ selected: oneCategorySelect == index }"
|
<view class="item" :class="{ selected: oneCategorySelect == index }"
|
||||||
@click="templateFourOneFn(index)" v-for="(item, index) in templateFourData" :key="index">
|
@tap.stop="templateFourOneFn(index)" v-for="(item, index) in templateFourData" :key="index">
|
||||||
<view class="image-warp" :class="[{ 'color-base-border': oneCategorySelect == index }]">
|
<view class="image-warp" :class="[{ 'color-base-border': oneCategorySelect == index }]">
|
||||||
<image :src="$util.img(item.image)" mode="aspectFill"></image>
|
<image :src="$util.img(item.image)" mode="aspectFill" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
<view :class="['text', { 'color-base-bg': oneCategorySelect == index }]">{{
|
<view :class="['text', { 'color-base-bg': oneCategorySelect == index }]">{{
|
||||||
item.category_name }}</view>
|
item.category_name }}</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<view class="pack-up" @click="$refs.templateFourPopup.close()">
|
<view class="pack-up" @tap.stop="$refs.templateFourPopup.close()">
|
||||||
<text>点击收起</text>
|
<text>点击收起</text>
|
||||||
<text class="iconfont icon-iconangledown-copy"></text>
|
<text class="iconfont icon-iconangledown-copy"></text>
|
||||||
</view>
|
</view>
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
{ select: select == index },
|
{ select: select == index },
|
||||||
{ '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)">
|
]" @tap.stop="switchOneCategory(index)">
|
||||||
<view class="">{{ item.category_name }}</view>
|
<view class="">{{ item.category_name }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -119,18 +119,18 @@
|
|||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<view class="category-empty" v-else>
|
<view class="category-empty" v-else>
|
||||||
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix"></image>
|
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix" show-menu-by-longpress></image>
|
||||||
<view class="tips">暂时没有分类哦!</view>
|
<view class="tips">暂时没有分类哦!</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="category-empty" v-else>
|
<view class="category-empty" v-else>
|
||||||
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix"></image>
|
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix" show-menu-by-longpress></image>
|
||||||
<view class="tips">暂时没有分类哦!</view>
|
<view class="tips">暂时没有分类哦!</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- <view class="cart-box" v-if="(value.template == 2 || value.template == 4) && value.quickBuy && storeToken && categoryTree && categoryTree.length">
|
<!-- <view class="cart-box" v-if="(value.template == 2 || value.template == 4) && value.quickBuy && storeToken && categoryTree && categoryTree.length">
|
||||||
<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" @tap.stop="$util.redirectTo('/pages_goods/cart')">
|
||||||
<text class="iconfont icon-ziyuan1"></text>
|
<text class="iconfont icon-ziyuan1"></text>
|
||||||
<view class="num" v-if="cartNumber">{{ cartNumber < 99 ? cartNumber : '99+' }}</view>
|
<view class="num" v-if="cartNumber">{{ cartNumber < 99 ? cartNumber : '99+' }}</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
<text class="unit font-size-tag price-font">.{{ cartTotalMoney[1] ? cartTotalMoney[1] : '00' }}</text>
|
<text class="unit font-size-tag price-font">.{{ cartTotalMoney[1] ? cartTotalMoney[1] : '00' }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="right-wrap"><button type="primary" class="settlement-btn" @click="settlement">去结算</button>
|
<view class="right-wrap"><button type="primary" class="settlement-btn" @tap.stop="settlement">去结算</button>
|
||||||
</view>
|
</view>
|
||||||
</view> -->
|
</view> -->
|
||||||
|
|
||||||
@@ -161,15 +161,11 @@ let menuButtonInfo = {};
|
|||||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
import nsGoodsSkuCategory from '@/components/ns-goods-sku/ns-goods-sku-category.vue';
|
|
||||||
import DiyMinx from './minx.js'
|
import DiyMinx from './minx.js'
|
||||||
var contentWrapHeight, query, cartPosition;
|
var contentWrapHeight, query, cartPosition;
|
||||||
|
|
||||||
// 商品分类
|
// 商品分类
|
||||||
export default {
|
export default {
|
||||||
components: {
|
|
||||||
nsGoodsSkuCategory
|
|
||||||
},
|
|
||||||
name: 'diy-category',
|
name: 'diy-category',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
@@ -552,7 +548,7 @@ export default {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.category-page-wrap {
|
.category-page-wrap {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
// height: calc(100vh - var(--tab-bar-height, 0));
|
// height: calc(100vh - var(--tab-bar-height, 0));
|
||||||
@@ -822,7 +818,7 @@ export default {
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .template-four {
|
::v-deep .template-four {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
|
|||||||
631
components-diy/diy-channel-list.vue
Normal file
631
components-diy/diy-channel-list.vue
Normal file
@@ -0,0 +1,631 @@
|
|||||||
|
<template>
|
||||||
|
<view class="channel-list-container" :style="[componentStyle, { '--row-count': value.rowCount }]">
|
||||||
|
<!-- 轮播模式 -->
|
||||||
|
<swiper v-if="value.showStyle == 'carousel' && carouselConfig.type != 'hide'" :indicator-dots="isIndicatorDots"
|
||||||
|
:autoplay="carouselConfig.autoplay || false" :interval="carouselConfig.interval || 3000"
|
||||||
|
:duration="carouselConfig.duration || 500" :circular="carouselConfig.circular || false"
|
||||||
|
:style="swiperHeight" class="channel-swiper">
|
||||||
|
<swiper-item v-for="(slide, slideIndex) in swiperSlides" :key="slideIndex">
|
||||||
|
<view :class="['swiper-slide-content', 'row1-of' + value.rowCount]">
|
||||||
|
<view v-for="(item, index) in slide" :key="index" :class="['channel-item', value.mode]">
|
||||||
|
<!-- 视频号视频卡片,轮播模式 -->
|
||||||
|
<diy-channel-video :value="item" @video-play="playVideo" :list-mode="true"
|
||||||
|
:title-line-clamp="value.titleLineClamp" :show-play-btn="value.showPlayBtn"
|
||||||
|
:show-view-count="value.showViewCount" :cover-style="computedCoverStyle"
|
||||||
|
:play-btn-style="value.playBtnStyle" :aspect-ratio="value.aspectRatio" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
|
||||||
|
<!-- 固定布局模式 -->
|
||||||
|
<view v-else-if="value.showStyle == 'fixed'" :class="['channel-list', 'row1-of' + value.rowCount]">
|
||||||
|
<view v-for="(item, index) in value.list" :key="index" class="channel-item">
|
||||||
|
<!-- 视频号视频卡片,列表模式 -->
|
||||||
|
<diy-channel-video :value="item" @video-play="playVideo" :list-mode="true"
|
||||||
|
:title-line-clamp="value.titleLineClamp" :show-play-btn="value.showPlayBtn"
|
||||||
|
:show-view-count="value.showViewCount" :cover-style="computedCoverStyle"
|
||||||
|
:play-btn-style="value.playBtnStyle" :aspect-ratio="value.aspectRatio" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 其他布局模式(如滚动布局) -->
|
||||||
|
<scroll-view v-else
|
||||||
|
:class="['channel-nav', value.showStyle == 'fixed' ? 'fixed-layout' : 'singleSlide', 'row1-of' + value.rowCount]"
|
||||||
|
:scroll-x="true"
|
||||||
|
:scroll-y="false"
|
||||||
|
:enhanced="true"
|
||||||
|
:bounces="false">
|
||||||
|
<view class="uni-scroll-view-content">
|
||||||
|
<view v-for="(item, index) in value.list" :key="index"
|
||||||
|
:class="['channel-nav-item', value.mode, 'row1-of' + value.rowCount]">
|
||||||
|
<!-- 视频号视频卡片,滚动模式 -->
|
||||||
|
<diy-channel-video :value="item" @video-play="playVideo" :list-mode="true"
|
||||||
|
:title-line-clamp="value.titleLineClamp" :show-play-btn="value.showPlayBtn"
|
||||||
|
:show-view-count="value.showViewCount" :cover-style="computedCoverStyle"
|
||||||
|
:play-btn-style="value.playBtnStyle" :aspect-ratio="value.aspectRatio" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* 微信视频号列表组件
|
||||||
|
* 支持多种布局模式,包括固定布局和滚动布局
|
||||||
|
* 可配置列数、视频高度、标题行数等属性
|
||||||
|
* 用于在页面中展示多个微信视频号视频
|
||||||
|
*/
|
||||||
|
import DiyMinx from './minx.js'
|
||||||
|
import { wechatChannelUtil, wechatChannelConfig } from './js/wechat-channel.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'diy-channel-list',
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* 组件配置数据
|
||||||
|
* @type {Object}
|
||||||
|
* @default () => ({})
|
||||||
|
* @property {string} showStyle - 显示样式,可选值:carousel, fixed, singleSlide
|
||||||
|
* @property {number} rowCount - 每行显示的视频数量
|
||||||
|
* @property {Array} list - 视频列表数据
|
||||||
|
* @property {string} componentBgColor - 组件背景色
|
||||||
|
* @property {string} componentAngle - 组件圆角类型,可选值:round
|
||||||
|
* @property {number} topAroundRadius - 顶部圆角半径
|
||||||
|
* @property {number} bottomAroundRadius - 底部圆角半径
|
||||||
|
* @property {Object} ornament - 装饰效果配置
|
||||||
|
* @property {boolean} showViewCount - 是否显示播放量,可选值:true, false
|
||||||
|
* @property {number} titleLineClamp - 标题显示行数
|
||||||
|
* @property {string} aspectRatio - 视频比例,可选值:16:9, 3:4
|
||||||
|
* @property {boolean} showPlayBtn - 是否显示播放按钮
|
||||||
|
* @property {Object} coverStyle - 视频封面图样式
|
||||||
|
* @property {Object} playBtnStyle - 播放按钮样式
|
||||||
|
* @property {string} mode - 显示模式, 可选值:video, text, image, graphic
|
||||||
|
* @property {number} imageSize - 图片尺寸(仅在特定模式下使用)
|
||||||
|
* @property {number} pageCount - 每页显示的视频数量
|
||||||
|
* @property {Object} carousel - 轮播配置
|
||||||
|
* @property {string} carousel.type - 轮播类型,可选值:default, hide
|
||||||
|
* @property {boolean} carousel.autoplay - 是否自动播放,默认false
|
||||||
|
* @property {number} carousel.interval - 自动播放间隔,默认3000ms
|
||||||
|
* @property {number} carousel.duration - 切换动画时长,默认500ms
|
||||||
|
* @property {boolean} carousel.circular - 是否循环播放,默认false
|
||||||
|
*/
|
||||||
|
value: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [DiyMinx],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
pageWidth: '', // 页面宽度
|
||||||
|
indicatorDots: false, // 是否显示轮播指示器
|
||||||
|
swiperCurrent: 0 // 当前轮播索引
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 组件创建时的逻辑
|
||||||
|
// 可以在这里进行初始化操作,如获取页面宽度等
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 组件挂载后添加鼠标拖拽滚动功能
|
||||||
|
if (!['fixed', 'carousel'].includes(this.value?.showStyle)) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.addMouseDragScroll();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
/**
|
||||||
|
* 组件刷新监听
|
||||||
|
* 当组件需要刷新时触发
|
||||||
|
* @param {*} newValue - 新值
|
||||||
|
*/
|
||||||
|
componentRefresh(newValue) {
|
||||||
|
// 监听组件刷新
|
||||||
|
// 可以在这里处理组件刷新时的逻辑
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
carouselConfig() {
|
||||||
|
return this.value?.carousel || {
|
||||||
|
type: 'default',
|
||||||
|
autoplay: false,
|
||||||
|
interval: 3000,
|
||||||
|
duration: 500,
|
||||||
|
circular: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 组件样式
|
||||||
|
* 根据配置动态生成样式字符串,包括背景色、圆角、阴影和边框
|
||||||
|
* @returns {string} 样式字符串
|
||||||
|
*/
|
||||||
|
componentStyle() {
|
||||||
|
const style = {};
|
||||||
|
// 背景色
|
||||||
|
if (this.value?.componentBgColor) {
|
||||||
|
style.backgroundColor = this.value?.componentBgColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 圆角样式
|
||||||
|
if (this.value?.componentAngle == 'round') {
|
||||||
|
style.borderTopLeftRadius = (2 * this.value?.topAroundRadius) + 'rpx';
|
||||||
|
style.borderTopRightRadius = (2 * this.value?.topAroundRadius) + 'rpx';
|
||||||
|
style.borderBottomLeftRadius = (2 * this.value?.bottomAroundRadius) + 'rpx';
|
||||||
|
style.borderBottomRightRadius = (2 * this.value?.bottomAroundRadius) + 'rpx';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 装饰效果:阴影
|
||||||
|
style.boxShadow = 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;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轮播高度
|
||||||
|
* 根据模式和配置计算轮播高度
|
||||||
|
* @returns {string} 轮播高度样式
|
||||||
|
*/
|
||||||
|
swiperHeight() {
|
||||||
|
let height = 0;
|
||||||
|
|
||||||
|
const pageCount = this.value?.pageCount || 1;
|
||||||
|
|
||||||
|
// 根据不同模式计算高度
|
||||||
|
if (this.value?.mode == 'graphic') {
|
||||||
|
height = (49 + this.value?.imageSize) * pageCount;
|
||||||
|
} else if (this.value?.mode == 'img') {
|
||||||
|
height = (22 + this.value?.imageSize) * pageCount;
|
||||||
|
} else if (this.value?.mode == 'text') {
|
||||||
|
height = 43 * pageCount;
|
||||||
|
} else { // 默认视频模式
|
||||||
|
if (this.value?.aspectRatio == '16:9') {
|
||||||
|
height = [250, 160, 140, 120][this.value.rowCount - 1];
|
||||||
|
} else {
|
||||||
|
height = [510, 280, 220, 180][this.value.rowCount - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'height:' + (2 * height) + 'rpx';
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示指示器
|
||||||
|
* 根据轮播配置和列表长度判断是否显示指示器
|
||||||
|
* @returns {boolean} 是否显示指示器
|
||||||
|
*/
|
||||||
|
isIndicatorDots() {
|
||||||
|
// 当轮播类型不是隐藏,且视频数量超过一页时显示指示器
|
||||||
|
const pageCount = this.value?.pageCount || 1;
|
||||||
|
return this.value?.carousel?.type != 'hide' && Math.ceil(this.value?.list?.length / (pageCount * this.value?.rowCount)) > 1
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轮播幻灯片数据
|
||||||
|
* 将视频列表分割成轮播所需的幻灯片数据
|
||||||
|
* @returns {Array} 轮播幻灯片数据
|
||||||
|
*/
|
||||||
|
swiperSlides() {
|
||||||
|
const slides = [];
|
||||||
|
const list = this.value?.list || [];
|
||||||
|
const pageSize = (this.value?.pageCount || 1) * (this.value?.rowCount || 1);
|
||||||
|
|
||||||
|
// 将列表数据分割成每页显示的数量
|
||||||
|
for (let i = 0; i < list.length; i += pageSize) {
|
||||||
|
slides.push(list.slice(i, i + pageSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
return slides;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 视频封面样式
|
||||||
|
* 根据aspectRatio属性动态计算封面样式
|
||||||
|
* @returns {Object} 封面样式对象
|
||||||
|
*/
|
||||||
|
computedCoverStyle() {
|
||||||
|
const aspectRatio = this.value?.aspectRatio || '16:9';
|
||||||
|
let paddingTop = '56.25%'; // 默认 16:9 比例
|
||||||
|
|
||||||
|
if (aspectRatio === '3:4') {
|
||||||
|
paddingTop = '133.33%'; // 3:4 比例
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
width: '100%',
|
||||||
|
height: '0',
|
||||||
|
paddingTop: paddingTop
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 播放视频
|
||||||
|
* 触发 video-play 事件,并在微信小程序中调用视频播放接口
|
||||||
|
* @param {Object} item - 视频数据对象
|
||||||
|
*/
|
||||||
|
async playVideo(item) {
|
||||||
|
await this.__$emitEvent({
|
||||||
|
eventName: 'video-play',
|
||||||
|
data: item,
|
||||||
|
promiseCallback: async (event, handler, awaitedResult) => {
|
||||||
|
if (!awaitedResult) return;
|
||||||
|
try {
|
||||||
|
// 发送视频被点击播放事件
|
||||||
|
this.$emit('channel-video-click-play', item);
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
// 在微信小程序环境中调用视频播放接口
|
||||||
|
await wechatChannelUtil.playVideo(item);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
if (item?.channelType === 'wechat') {
|
||||||
|
uni.showToast({
|
||||||
|
title: '视频号仅支持在微信小程序环境中播放',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 在非微信小程序环境中,直接触发事件
|
||||||
|
this.$emit('video-play', item);
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
} catch (err) {
|
||||||
|
console.error('打开视频号失败', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片加载错误处理
|
||||||
|
* 当图片加载失败时,设置默认图片
|
||||||
|
* @param {number} index - 图片索引
|
||||||
|
*/
|
||||||
|
imgError(index) {
|
||||||
|
// 图片加载失败的处理逻辑
|
||||||
|
// 为失败的图片设置默认图片
|
||||||
|
const item = this.value.list[index];
|
||||||
|
if (item) {
|
||||||
|
// 使用默认图片替代加载失败的图片
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
item.coverUrl = wechatChannelConfig.video.defaultCoverUrl;
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 添加鼠标拖拽滚动功能
|
||||||
|
* 在Web环境中实现与微信小程序相同的拖拽滚动效果
|
||||||
|
*/
|
||||||
|
addMouseDragScroll() {
|
||||||
|
// 只在Web环境中添加
|
||||||
|
// #ifndef MP
|
||||||
|
|
||||||
|
let isDragging = false;
|
||||||
|
let startX = 0;
|
||||||
|
let startScrollLeft = 0;
|
||||||
|
let currentScrollElement = null;
|
||||||
|
|
||||||
|
// 查找最近的可滚动祖先元素
|
||||||
|
const findScrollableParent = (element) => {
|
||||||
|
while (element && element !== document) {
|
||||||
|
const style = window.getComputedStyle(element);
|
||||||
|
if (style.overflowX === 'auto' || style.overflowX === 'scroll') {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
element = element.parentElement;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 鼠标按下事件
|
||||||
|
const handleMouseDown = (e) => {
|
||||||
|
// 检查是否点击在组件内
|
||||||
|
if (this.$el.contains(e.target)) {
|
||||||
|
// 查找可滚动元素
|
||||||
|
currentScrollElement = findScrollableParent(e.target);
|
||||||
|
if (currentScrollElement) {
|
||||||
|
isDragging = true;
|
||||||
|
startX = e.pageX;
|
||||||
|
startScrollLeft = currentScrollElement.scrollLeft;
|
||||||
|
currentScrollElement.style.cursor = 'grabbing';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 鼠标移动事件
|
||||||
|
const handleMouseMove = (e) => {
|
||||||
|
if (!isDragging || !currentScrollElement) return;
|
||||||
|
e.preventDefault();
|
||||||
|
const dx = e.pageX - startX;
|
||||||
|
currentScrollElement.scrollLeft = startScrollLeft - dx;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 鼠标释放事件
|
||||||
|
const handleMouseUp = () => {
|
||||||
|
if (isDragging && currentScrollElement) {
|
||||||
|
currentScrollElement.style.cursor = 'grab';
|
||||||
|
}
|
||||||
|
isDragging = false;
|
||||||
|
currentScrollElement = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加全局事件监听器
|
||||||
|
document.addEventListener('mousedown', handleMouseDown);
|
||||||
|
document.addEventListener('mousemove', handleMouseMove);
|
||||||
|
document.addEventListener('mouseup', handleMouseUp);
|
||||||
|
document.addEventListener('mouseleave', handleMouseUp);
|
||||||
|
|
||||||
|
// 组件销毁时移除事件监听器
|
||||||
|
this.$once('hook:beforeDestroy', () => {
|
||||||
|
document.removeEventListener('mousedown', handleMouseDown);
|
||||||
|
document.removeEventListener('mousemove', handleMouseMove);
|
||||||
|
document.removeEventListener('mouseup', handleMouseUp);
|
||||||
|
document.removeEventListener('mouseleave', handleMouseUp);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 为所有.channel-nav元素添加必要的样式
|
||||||
|
setTimeout(() => {
|
||||||
|
const channelNavs = document.querySelectorAll('.channel-nav');
|
||||||
|
channelNavs.forEach(element => {
|
||||||
|
element.style.overflowX = 'auto';
|
||||||
|
element.style.overflowY = 'hidden';
|
||||||
|
element.style.whiteSpace = 'nowrap';
|
||||||
|
element.style.width = '100%';
|
||||||
|
element.style.maxWidth = '100%';
|
||||||
|
element.style.cursor = 'grab';
|
||||||
|
element.style.userSelect = 'none'; // 防止文本选择
|
||||||
|
});
|
||||||
|
}, 100); // 延迟执行,确保DOM已完全渲染
|
||||||
|
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import './css/common-channel.scss';
|
||||||
|
|
||||||
|
.channel-list-container {
|
||||||
|
padding: 16px 16px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列表布局样式
|
||||||
|
*/
|
||||||
|
.channel-list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(var(--row-count, 2), 1fr);
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导航布局样式
|
||||||
|
* 支持固定布局和滚动布局
|
||||||
|
*/
|
||||||
|
.channel-nav {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 16rpx;
|
||||||
|
|
||||||
|
// 确保在H5环境中可以水平滚动
|
||||||
|
overflow-x: auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
// 隐藏滚动条但保留滚动功能
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollbar-width: none;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
|
||||||
|
// 启用触摸滚动和鼠标拖拽滚动
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
|
||||||
|
.uni-scroll-view-content {
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
gap: 16rpx;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef MP-WEIXIN */
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(var(--row-count, 2), 1fr);
|
||||||
|
gap: 16rpx;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单滑动模式
|
||||||
|
&.singleSlide {
|
||||||
|
.uni-scroll-view-content {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
gap: 16rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-nav-item {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 280rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-nav-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
&.row1-of1 {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
&.row1-of2 {
|
||||||
|
width: calc(50% - 8rpx);
|
||||||
|
}
|
||||||
|
&.row1-of3 {
|
||||||
|
width: calc(33.333% - 10.67rpx);
|
||||||
|
}
|
||||||
|
&.row1-of4 {
|
||||||
|
width: calc(25% - 12rpx);
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1 列布局
|
||||||
|
&.row1-of1 {
|
||||||
|
.uni-scroll-view-content {
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 列布局
|
||||||
|
&.row1-of2 {
|
||||||
|
.uni-scroll-view-content {
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3 列布局
|
||||||
|
&.row1-of3 {
|
||||||
|
.uni-scroll-view-content {
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4 列布局
|
||||||
|
&.row1-of4 {
|
||||||
|
.uni-scroll-view-content {
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保所有视频卡片高度一致
|
||||||
|
*/
|
||||||
|
.channel-item,
|
||||||
|
.channel-nav-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轮播样式
|
||||||
|
* 支持轮播模式的布局和样式
|
||||||
|
*/
|
||||||
|
.channel-swiper {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.swiper-slide-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(var(--row-count, 2), 1fr);
|
||||||
|
gap: 16rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.channel-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 轮播模式下的 1 列布局
|
||||||
|
&.row1-of1 {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 轮播模式下的 2 列布局
|
||||||
|
&.row1-of2 {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 轮播模式下的 3 列布局
|
||||||
|
&.row1-of3 {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 轮播模式下的 4 列布局
|
||||||
|
&.row1-of4 {
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应式调整
|
||||||
|
* 在小屏幕设备上调整布局和间距
|
||||||
|
*/
|
||||||
|
@media (max-width: 375px) {
|
||||||
|
|
||||||
|
.channel-list,
|
||||||
|
.channel-nav,
|
||||||
|
.channel-swiper .swiper-slide-content {
|
||||||
|
gap: 12rpx;
|
||||||
|
padding: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 小屏幕上的单滑动模式
|
||||||
|
.channel-nav {
|
||||||
|
&.singleSlide {
|
||||||
|
.uni-scroll-view-content {
|
||||||
|
gap: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-nav-item {
|
||||||
|
width: 240rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频比例样式调整
|
||||||
|
* 根据不同的视频比例调整布局
|
||||||
|
*/
|
||||||
|
|
||||||
|
// // 3:4 比例的视频卡片样式
|
||||||
|
// .channel-video.ratio-3-4 {
|
||||||
|
// // 调整视频卡片的整体高度
|
||||||
|
// ::v-deep .video-cover-wrap {
|
||||||
|
// padding-top: 133.33%; // 3:4 比例
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 列表模式下的3:4比例调整
|
||||||
|
// &.list-mode {
|
||||||
|
// ::v-deep .video-cover-wrap {
|
||||||
|
// padding-top: 133.33%; // 3:4 比例
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 16:9 比例的视频卡片样式(默认)
|
||||||
|
// .channel-video.ratio-16-9 {
|
||||||
|
// // 保持默认的16:9比例
|
||||||
|
// ::v-deep .video-cover-wrap {
|
||||||
|
// padding-top: 56.25%; // 16:9 比例
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 列表模式下的16:9比例保持默认
|
||||||
|
// &.list-mode {
|
||||||
|
// ::v-deep .video-cover-wrap {
|
||||||
|
// padding-top: 56.25%; // 16:9 比例
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }</style>
|
||||||
488
components-diy/diy-channel-video.vue
Normal file
488
components-diy/diy-channel-video.vue
Normal file
@@ -0,0 +1,488 @@
|
|||||||
|
<template>
|
||||||
|
<view class="channel-video" :class="{ 'list-mode': listMode }">
|
||||||
|
<!-- 嵌入式视频播放 -->
|
||||||
|
<view v-if="canUseEmbedMode" class="embed-video-container">
|
||||||
|
<view class="video-cover-wrap" :style="[coverStyle]">
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<native-component>
|
||||||
|
<!-- 嵌入式视频播放组件 -->
|
||||||
|
<channel-video :feed-id="value.feedId" :finder-user-name="value.finderUserName"
|
||||||
|
:feed-token="value.feedToken" :auto-play="autoPlay">
|
||||||
|
</channel-video>
|
||||||
|
</native-component>
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
<view class="video-info">
|
||||||
|
<!-- 视频标题,支持多行显示控制 -->
|
||||||
|
<view class="video-title" :style="[{ '--title-line-clamp': titleLineClamp }]">{{ value.videoTitle }}
|
||||||
|
</view>
|
||||||
|
<!-- 视频统计信息 -->
|
||||||
|
<view class="video-stats" v-if="showViewCount && value.showViewCount">{{ value.viewCount }}次观看</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 跳转式视频播放 -->
|
||||||
|
<view v-else @tap.stop="playVideo" class="video-container">
|
||||||
|
<view class="video-cover-wrap" :style="[coverStyle]">
|
||||||
|
<image class="video-cover" :src="$util.img(value.coverUrl)" mode="aspectFill" show-menu-by-longpress></image>
|
||||||
|
<view class="channel-play-btn" v-if="showPlayBtn" :style="[playBtnStyle]">
|
||||||
|
<view class="play-icon-css"></view>
|
||||||
|
</view>
|
||||||
|
<view class="video-stats-overlay" v-if="showViewCount && value.showViewCount">
|
||||||
|
{{ value.viewCount }}次观看
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="video-info">
|
||||||
|
<!-- 视频标题,支持多行显示控制 -->
|
||||||
|
<view class="video-title" :style="[{ '--title-line-clamp': titleLineClamp }]">{{ value.videoTitle }}
|
||||||
|
</view>
|
||||||
|
<!-- 视频统计信息,非列表模式下显示 -->
|
||||||
|
<view class="video-stats" v-if="showViewCount && value.showViewCount && !listMode">{{ value.viewCount }}次观看</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import { wechatChannelUtil, wechatChannelConfig } from './js/wechat-channel.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信视频号视频卡片组件
|
||||||
|
* 支持嵌入式播放和跳转式播放两种模式
|
||||||
|
* 可配置列表模式、视频高度、标题行数等属性
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'diy-channel-video',
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* 视频数据对象
|
||||||
|
* @type {Object}
|
||||||
|
* @required
|
||||||
|
* @property {string} feedId - 视频 feedId
|
||||||
|
* @property {string} feedToken - 视频 token
|
||||||
|
* @property {string} coverUrl - 视频封面图
|
||||||
|
* @property {string} videoTitle - 视频标题
|
||||||
|
* @property {number} viewCount - 观看次数
|
||||||
|
* @property {boolean} showViewCount - 是否显示观看次数
|
||||||
|
* @property {boolean} embedMode - 是否启用嵌入式播放
|
||||||
|
*/
|
||||||
|
value: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 是否为列表模式
|
||||||
|
* @type {boolean}
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
listMode: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
/** 是否显示观看次数,由父组件可以整体配置 */
|
||||||
|
showViewCount: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 标题显示行数
|
||||||
|
* @type {number}
|
||||||
|
* @default 1
|
||||||
|
*/
|
||||||
|
titleLineClamp: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
/** 是否显示播放按钮 */
|
||||||
|
showPlayBtn: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 视频封面图样式
|
||||||
|
* 采用 16:9 比例的响应式高度
|
||||||
|
*/
|
||||||
|
coverStyle: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
width: '100%',
|
||||||
|
height: '0',
|
||||||
|
paddingTop: '56.25%' // 16:9 比例
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 播放按钮样式
|
||||||
|
*/
|
||||||
|
playBtnStyle: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
width: '60rpx',
|
||||||
|
height: '60rpx',
|
||||||
|
borderRadius: '30rpx',
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.6)'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 是否自动播放 */
|
||||||
|
autoPlay: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
/**
|
||||||
|
* 是否支持嵌入式播放
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
canUseEmbedMode() {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
const enableEmbedMode = Boolean(this.value?.embedMode)
|
||||||
|
&& Boolean(this.value?.feedToken)
|
||||||
|
&& wechatChannelUtil.isEmbedModeSupported();
|
||||||
|
return enableEmbedMode;
|
||||||
|
// #endif
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 播放视频
|
||||||
|
* 触发 video-play 事件,由父组件处理具体播放逻辑
|
||||||
|
*/
|
||||||
|
async playVideo() {
|
||||||
|
this.$emit('video-play', this.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import './css/common-channel.scss';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频卡片容器样式
|
||||||
|
* 包含卡片基础样式、悬停效果和列表模式样式
|
||||||
|
*/
|
||||||
|
.channel-video {
|
||||||
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
// 悬停效果
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-4rpx);
|
||||||
|
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表模式样式调整
|
||||||
|
&.list-mode {
|
||||||
|
border-radius: 10rpx;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.08);
|
||||||
|
|
||||||
|
.video-info {
|
||||||
|
padding: 14rpx;
|
||||||
|
|
||||||
|
.video-title {
|
||||||
|
font-size: 24rpx;
|
||||||
|
margin-bottom: 6rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频容器样式
|
||||||
|
* 用于跳转式播放模式
|
||||||
|
*/
|
||||||
|
.video-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 嵌入式视频容器样式
|
||||||
|
* 与视频容器样式保持一致
|
||||||
|
*/
|
||||||
|
.embed-video-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频封面容器
|
||||||
|
*/
|
||||||
|
.video-cover-wrap {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 56.25%;
|
||||||
|
/* 16:9 比例 */
|
||||||
|
height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 12rpx 12rpx 0 0;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
|
||||||
|
// 悬停时缩放效果
|
||||||
|
.channel-video:hover & {
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表模式下的边框圆角调整
|
||||||
|
.channel-video.list-mode & {
|
||||||
|
border-radius: 10rpx 10rpx 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频封面图片
|
||||||
|
* 绝对定位填充整个容器
|
||||||
|
*/
|
||||||
|
.video-cover {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频统计信息遮罩
|
||||||
|
* 显示在视频封面底部
|
||||||
|
*/
|
||||||
|
.video-stats-overlay {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
|
||||||
|
padding: 12rpx 16rpx;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 20rpx;
|
||||||
|
text-align: right;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
|
||||||
|
// 悬停时的透明度变化
|
||||||
|
.channel-video:hover & {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-video:not(:hover) & {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频信息区域
|
||||||
|
* 包含标题和统计信息
|
||||||
|
*/
|
||||||
|
.video-info {
|
||||||
|
padding: 16rpx;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: #fff;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
|
||||||
|
// 悬停时的背景色变化
|
||||||
|
.channel-video:hover & {
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频标题
|
||||||
|
* 支持多行显示控制和渐变遮罩效果
|
||||||
|
*/
|
||||||
|
.video-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #222;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
line-height: 1.4;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: var(--title-line-clamp, 2);
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
word-break: break-all;
|
||||||
|
word-wrap: break-word;
|
||||||
|
white-space: normal;
|
||||||
|
|
||||||
|
// 悬停时的颜色变化
|
||||||
|
.channel-video:hover & {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表模式下的样式调整
|
||||||
|
.channel-video.list-mode & {
|
||||||
|
-webkit-line-clamp: var(--title-line-clamp, 1);
|
||||||
|
font-size: 24rpx;
|
||||||
|
margin-bottom: 6rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加渐变遮罩效果,让过长的文字有柔和的结束
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 40rpx;
|
||||||
|
height: 1.4em;
|
||||||
|
background: linear-gradient(to right, transparent, #fff 90%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表模式下的遮罩高度调整
|
||||||
|
.channel-video.list-mode &::after {
|
||||||
|
height: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据行数调整遮罩高度
|
||||||
|
&[style*="--title-line-clamp: 1"]::after {
|
||||||
|
height: 1.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[style*="--title-line-clamp: 3"]::after {
|
||||||
|
height: 4.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[style*="--title-line-clamp: 4"]::after {
|
||||||
|
height: 5.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表模式下的多行遮罩高度调整
|
||||||
|
.channel-video.list-mode &[style*="--title-line-clamp: 1"]::after {
|
||||||
|
height: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-video.list-mode &[style*="--title-line-clamp: 3"]::after {
|
||||||
|
height: 3.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-video.list-mode &[style*="--title-line-clamp: 4"]::after {
|
||||||
|
height: 5.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频统计信息
|
||||||
|
* 显示观看次数等数据
|
||||||
|
*/
|
||||||
|
.video-stats {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 6rpx;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
|
||||||
|
// 悬停时的颜色变化
|
||||||
|
.channel-video:hover & {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列表模式下的播放按钮样式
|
||||||
|
* 更小的尺寸和悬停效果
|
||||||
|
*/
|
||||||
|
.channel-video.list-mode .channel-play-btn {
|
||||||
|
width: 50rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
// 悬停效果
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 播放图标尺寸
|
||||||
|
.play-icon {
|
||||||
|
width: 25rpx;
|
||||||
|
height: 25rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用播放按钮样式优化
|
||||||
|
* 添加悬停效果
|
||||||
|
*/
|
||||||
|
.channel-play-btn {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
// 悬停效果
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 纯 CSS 播放按钮图标
|
||||||
|
*/
|
||||||
|
.play-icon-css {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-top: 12rpx solid transparent;
|
||||||
|
border-bottom: 12rpx solid transparent;
|
||||||
|
border-left: 18rpx solid #fff;
|
||||||
|
margin-left: 4rpx;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
|
||||||
|
// 悬停时的缩放效果
|
||||||
|
.channel-play-btn:hover & {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表模式下的尺寸调整
|
||||||
|
.channel-video.list-mode & {
|
||||||
|
border-top: 10rpx solid transparent;
|
||||||
|
border-bottom: 10rpx solid transparent;
|
||||||
|
border-left: 15rpx solid #fff;
|
||||||
|
margin-left: 3rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原生组件样式控制
|
||||||
|
* 确保 native-component 和 channel-video 正确填充容器
|
||||||
|
*/
|
||||||
|
native-component {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* channel-video 组件样式控制
|
||||||
|
* 避免受到 wx-channel-video 全局样式的影响
|
||||||
|
*/
|
||||||
|
channel-video {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style1-bg.png') + ')',
|
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style1-bg.png') + ')',
|
||||||
marginRight: couponItemHeight + 'px',
|
marginRight: couponItemHeight + 'px',
|
||||||
marginLeft: couponItemHeight + 'px'
|
marginLeft: couponItemHeight + 'px'
|
||||||
}" @click="couponAction(item, index)">
|
}" @tap.stop="couponAction(item, index)">
|
||||||
|
|
||||||
<view class="coupon-info">
|
<view class="coupon-info">
|
||||||
<view class="coupon-num" :style="{ color: value.moneyColor }"
|
<view class="coupon-num" :style="{ color: value.moneyColor }"
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_bg1.png') + ')',
|
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_bg1.png') + ')',
|
||||||
marginRight: couponItemHeight + 'px',
|
marginRight: couponItemHeight + 'px',
|
||||||
marginLeft: couponItemHeight + 'px'
|
marginLeft: couponItemHeight + 'px'
|
||||||
}" @click="couponAction(item, index)">
|
}" @tap.stop="couponAction(item, index)">
|
||||||
<view class="coupon-info">
|
<view class="coupon-info">
|
||||||
<view class="coupon-num" :style="{ color: value.moneyColor }"
|
<view class="coupon-num" :style="{ color: value.moneyColor }"
|
||||||
v-if="!parseInt(item.discount)">
|
v-if="!parseInt(item.discount)">
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_shu.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)">
|
}" @tap.stop="couponAction(item, index)">
|
||||||
<view class="coupon-num" :style="{ color: value.moneyColor }"
|
<view class="coupon-num" :style="{ color: value.moneyColor }"
|
||||||
v-if="!parseInt(item.discount)">
|
v-if="!parseInt(item.discount)">
|
||||||
<text class="font-size-tag coupon-sign">¥</text>
|
<text class="font-size-tag coupon-sign">¥</text>
|
||||||
@@ -124,7 +124,7 @@
|
|||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style4_bg.png') + ')',
|
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style4_bg.png') + ')',
|
||||||
marginRight: couponItemHeight + 'px',
|
marginRight: couponItemHeight + 'px',
|
||||||
marginLeft: couponItemHeight + 'px'
|
marginLeft: couponItemHeight + 'px'
|
||||||
}" @click="couponAction(item, index)">
|
}" @tap.stop="couponAction(item, index)">
|
||||||
<view class="coupon-info">
|
<view class="coupon-info">
|
||||||
<view class="coupon-num" :style="{ color: value.moneyColor }"
|
<view class="coupon-num" :style="{ color: value.moneyColor }"
|
||||||
v-if="!parseInt(item.discount)">
|
v-if="!parseInt(item.discount)">
|
||||||
@@ -153,7 +153,7 @@
|
|||||||
<view class="coupon-all">
|
<view class="coupon-all">
|
||||||
<view class="coupon-box">
|
<view class="coupon-box">
|
||||||
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index"
|
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index"
|
||||||
@click="couponAction(item, index)">
|
@tap.stop="couponAction(item, index)">
|
||||||
<image :src="$util.img('public/uniapp/coupon/style5_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">
|
||||||
@@ -199,7 +199,7 @@
|
|||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-1.png') + ')',
|
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-1.png') + ')',
|
||||||
marginRight: couponItemHeight + 'px',
|
marginRight: couponItemHeight + 'px',
|
||||||
marginLeft: couponItemHeight + 'px'
|
marginLeft: couponItemHeight + 'px'
|
||||||
}" @click="couponAction(item, index)">
|
}" @tap.stop="couponAction(item, index)">
|
||||||
<view class="coupon-content">
|
<view class="coupon-content">
|
||||||
<view class="price-wrap">
|
<view class="price-wrap">
|
||||||
<text class="price" :style="{ color: value.moneyColor }">{{ (item.discount == '0.00'
|
<text class="price" :style="{ color: value.moneyColor }">{{ (item.discount == '0.00'
|
||||||
@@ -229,7 +229,7 @@
|
|||||||
<text class="limit" :style="{ color: value.limitColor }" v-else>无门槛使用</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')"
|
<div v-if="computedCouponList.length <= 2" @tap.stop="$util.redirectTo('/pages_goods/category')"
|
||||||
class="coupon coupon-null" :style="{
|
class="coupon coupon-null" :style="{
|
||||||
color: value.moneyColor,
|
color: value.moneyColor,
|
||||||
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-2.png') + ')',
|
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-2.png') + ')',
|
||||||
@@ -250,7 +250,7 @@
|
|||||||
<scroll-view class="coupon-style-seven" scroll-x="true">
|
<scroll-view class="coupon-style-seven" scroll-x="true">
|
||||||
<view class="wrap">
|
<view class="wrap">
|
||||||
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index"
|
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index"
|
||||||
@click="couponAction(item, index)">
|
@tap.stop="couponAction(item, index)">
|
||||||
<image :src="$util.img('public/uniapp/coupon/style7_bg.png')"></image>
|
<image :src="$util.img('public/uniapp/coupon/style7_bg.png')"></image>
|
||||||
<view class="coupon">
|
<view class="coupon">
|
||||||
<view class="coupon-info">
|
<view class="coupon-info">
|
||||||
@@ -454,7 +454,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.$refs.login.open('/pages/index/index');
|
this.$refs.login.open(this.$util.INDEX_PAGE_URL);
|
||||||
this.couponBtnSwitch = false;
|
this.couponBtnSwitch = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -488,7 +488,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 风格一
|
// 风格一
|
||||||
/deep/.coupon-style-one {
|
::v-deep .coupon-style-one {
|
||||||
height: 110rpx;
|
height: 110rpx;
|
||||||
|
|
||||||
.coupon-item-box {
|
.coupon-item-box {
|
||||||
@@ -534,7 +534,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 风格二
|
// 风格二
|
||||||
/deep/.coupon-style-two {
|
::v-deep .coupon-style-two {
|
||||||
height: 96rpx;
|
height: 96rpx;
|
||||||
|
|
||||||
.coupon-item-box {
|
.coupon-item-box {
|
||||||
@@ -591,7 +591,7 @@ export default {
|
|||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/.coupon-style-three {
|
::v-deep .coupon-style-three {
|
||||||
height: 284rpx;
|
height: 284rpx;
|
||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -638,7 +638,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 风格四
|
// 风格四
|
||||||
/deep/.coupon-style-four {
|
::v-deep .coupon-style-four {
|
||||||
height: 108rpx;
|
height: 108rpx;
|
||||||
|
|
||||||
.coupon-item-box {
|
.coupon-item-box {
|
||||||
@@ -997,7 +997,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//风格七
|
//风格七
|
||||||
/deep/ .coupon-style-seven {
|
::v-deep .coupon-style-seven {
|
||||||
.wrap {
|
.wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
@@ -1075,7 +1075,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/.uni-scroll-view ::-webkit-scrollbar {
|
::v-deep .uni-scroll-view ::-webkit-scrollbar {
|
||||||
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -1084,7 +1084,7 @@ export default {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/::-webkit-scrollbar {
|
::v-deep ::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="componentStyle">
|
<view :style="componentStyle" data-component-name="diy-digit">
|
||||||
<scroll-view :class="['graphic-nav', value.showStyle == 'fixed' ? 'fixed-layout' : value.showStyle]"
|
<scroll-view :class="['graphic-nav', value.showStyle == 'fixed' ? 'fixed-layout' : value.showStyle]"
|
||||||
:scroll-x="value.showStyle == 'singleSlide'">
|
:scroll-x="value.showStyle == 'singleSlide'">
|
||||||
<view class="uni-scroll-view-content">
|
<view class="uni-scroll-view-content">
|
||||||
@@ -38,16 +38,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import uvCountTo from '@/components/uv-count-to/uv-count-to.vue'
|
|
||||||
import nsLogin from '@/components/ns-login/ns-login.vue'
|
|
||||||
import DiyMinx from './minx.js'
|
import DiyMinx from './minx.js'
|
||||||
// 自定义数字展示
|
// 自定义数字展示
|
||||||
export default {
|
export default {
|
||||||
name: 'diy-digit',
|
name: 'diy-digit',
|
||||||
components: {
|
|
||||||
uvCountTo,
|
|
||||||
nsLogin
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -96,8 +90,7 @@ export default {
|
|||||||
|
|
||||||
// 页面跳转
|
// 页面跳转
|
||||||
redirectTo(item) {
|
redirectTo(item) {
|
||||||
if (!item.wap_url || this.$util.getCurrRoute() != 'pages/member/index' || this.storeToken) {
|
if (!item.wap_url || this.$util.getCurrRoute() != this.$util.MEMBER_PAGE_URL || this.storeToken) {
|
||||||
console.log(item);
|
|
||||||
this.$util.diyRedirectTo(item);
|
this.$util.diyRedirectTo(item);
|
||||||
} else {
|
} else {
|
||||||
this.$refs.login.open(item.wap_url);
|
this.$refs.login.open(item.wap_url);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<view data-component-name="diy-fenxiao-goods-list" class="diy-fenxiao" v-if="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">
|
:class="['goods-list', value.template, value.style]" :style="goodsListWarpCss">
|
||||||
<view class="goods-item" v-for="(item, index) in list" :key="index" @click="toDetail(item)"
|
<view class="goods-item" v-for="(item, index) in list" :key="index" @tap.stop="toDetail(item)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
: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' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)" />
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-wrap"
|
<view class="info-wrap"
|
||||||
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
|
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
|
||||||
@@ -32,14 +32,14 @@
|
|||||||
background: value.btnStyle.theme == 'diy' ? 'linear-gradient(to right,' + value.btnStyle.bgColorStart + ',' + value.btnStyle.bgColorEnd + ')' : '',
|
background: value.btnStyle.theme == 'diy' ? 'linear-gradient(to right,' + value.btnStyle.bgColorStart + ',' + value.btnStyle.bgColorEnd + ')' : '',
|
||||||
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
|
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
|
||||||
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
||||||
}" @click.stop="followGoods(item, index)">
|
}" @tap.stop="followGoods(item, index)">
|
||||||
关注
|
关注
|
||||||
</view>
|
</view>
|
||||||
<view class="sale-btn" v-if="value.btnStyle.control && item.is_collect == 1" :style="{
|
<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 + ')' : '',
|
background: value.btnStyle.theme == 'diy' ? 'linear-gradient(to right,' + value.btnStyle.bgColorStart + ',' + value.btnStyle.bgColorEnd + ')' : '',
|
||||||
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
|
color: value.btnStyle.theme == 'diy' ? value.btnStyle.textColor : '',
|
||||||
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
borderRadius: value.btnStyle.aroundRadius * 2 + 'rpx'
|
||||||
}" @click.stop="delFollowTip(item, index)">
|
}" @tap.stop="delFollowTip(item, index)">
|
||||||
取消关注
|
取消关注
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -75,7 +75,7 @@ export default {
|
|||||||
this.currentRoute = '/' + currentPage.route;
|
this.currentRoute = '/' + currentPage.route;
|
||||||
if (!this.storeToken) {
|
if (!this.storeToken) {
|
||||||
this.$util.redirectTo(
|
this.$util.redirectTo(
|
||||||
'/pages_tool/login/login',
|
this.$util.LOGIN_PAGE_URL,
|
||||||
{
|
{
|
||||||
back: this.currentRoute
|
back: this.currentRoute
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
:class="{ left_top: value.bottomPosition == 1, right_top: value.bottomPosition == 2, left_bottom: value.bottomPosition == 3, right_bottom: value.bottomPosition == 4 }"
|
:class="{ left_top: value.bottomPosition == 1, right_top: value.bottomPosition == 2, left_bottom: value.bottomPosition == 3, right_bottom: value.bottomPosition == 4 }"
|
||||||
:style="style">
|
: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)"
|
<view class="button-box" @tap.stop="$util.diyRedirectTo(item.link)"
|
||||||
:style="{ width: value.imageSize + 'px', height: value.imageSize + 'px', fontSize: value.imageSize + 'px' }">
|
: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"
|
<image v-if="!item.iconType || item.iconType == 'img'" :src="$util.img(item.imageUrl)" mode="aspectFit"
|
||||||
:show-menu-by-longpress="true" />
|
show-menu-by-longpress />
|
||||||
<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>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view @click="submitform" class="fui-btn btn-danger block mtop">提交信息</view>
|
<view @tap.stop="submitform" class="fui-btn btn-danger block mtop">提交信息</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
<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"
|
<image class="brand-pic" :src="$util.img(item.image_url)" mode="aspectFit"
|
||||||
@click="handlerClick(item)" @tap="handlerClick(item)" @error="imgError(index)"
|
@tap.stop="handlerClick(item)" @error="imgError(index)"
|
||||||
:style="itemCss" />
|
:style="itemCss" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 商品品牌
|
// 商品品牌
|
||||||
import uniGrid from '@/components/uni-grid/uni-grid.vue';
|
|
||||||
import uniGridItem from '@/components/uni-grid-item/uni-grid-item.vue';
|
|
||||||
|
|
||||||
import DiyMinx from './minx.js'
|
import DiyMinx from './minx.js'
|
||||||
// 自定义商品品牌展示
|
// 自定义商品品牌展示
|
||||||
@@ -31,10 +29,6 @@ export default {
|
|||||||
type: Object
|
type: Object
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
|
||||||
uniGrid,
|
|
||||||
uniGridItem
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
list: [],
|
list: [],
|
||||||
|
|||||||
@@ -2,13 +2,14 @@
|
|||||||
<x-skeleton data-component-name="diy-goods-list" :type="skeletonType" :loading="loading" :configs="skeletonConfig">
|
<x-skeleton data-component-name="diy-goods-list" :type="skeletonType" :loading="loading" :configs="skeletonConfig">
|
||||||
<view :class="['goods-list', goodsValue.template, goodsValue.style]" :style="goodsListWarpCss">
|
<view :class="['goods-list', goodsValue.template, goodsValue.style]" :style="goodsListWarpCss">
|
||||||
<template v-if="goodsValue.template != 'horizontal-slide'">
|
<template v-if="goodsValue.template != 'horizontal-slide'">
|
||||||
<view class="goods-item" v-for="(item, index) in list" :key="index" @click="handlerClick(item)"
|
<view class="goods-item" v-for="(item, index) in list" :key="index" @tap.stop="handlerClick(item)"
|
||||||
@tap="handlerClick(item)" :class="[goodsValue.ornament.type]" :style="goodsItemCss">
|
:class="[goodsValue.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="goods-img-wrap">
|
<view class="goods-img-wrap">
|
||||||
<image class="goods-img"
|
<image class="goods-img"
|
||||||
:src="$util.img(item.goods_image, { size: goodsValue.template == 'large-mode' ? 'big' : 'mid' })"
|
:src="$util.img(item.goods_image, { size: goodsValue.template == 'large-mode' ? 'big' : 'mid' })"
|
||||||
mode="widthFix" @error="imgError(index)"
|
mode="widthFix" @error="imgError(index)"
|
||||||
:style="{ borderRadius: goodsValue.imgAroundRadius * 2 + 'rpx' }" />
|
:style="{ borderRadius: goodsValue.imgAroundRadius * 2 + 'rpx' }"
|
||||||
|
show-menu-by-longpress />
|
||||||
<view class="sell-out" v-if="item.stock <= 0">
|
<view class="sell-out" v-if="item.stock <= 0">
|
||||||
<text class="iconfont icon-shuqing"></text>
|
<text class="iconfont icon-shuqing"></text>
|
||||||
</view>
|
</view>
|
||||||
@@ -48,9 +49,9 @@
|
|||||||
<view class="member-price"
|
<view class="member-price"
|
||||||
v-if="(item.member_price && item.member_price == showPrice(item)) || item.promotion_type == 1">
|
v-if="(item.member_price && item.member_price == showPrice(item)) || item.promotion_type == 1">
|
||||||
<image v-if="item.member_price && item.member_price == showPrice(item)"
|
<image v-if="item.member_price && item.member_price == showPrice(item)"
|
||||||
:src="$util.img('public/uniapp/index/VIP.png')" />
|
:src="$util.img('public/uniapp/index/VIP.png')" show-menu-by-longpress />
|
||||||
<image v-else-if="item.promotion_type == 1"
|
<image v-else-if="item.promotion_type == 1"
|
||||||
:src="$util.img('public/uniapp/index/discount.png')" />
|
:src="$util.img('public/uniapp/index/discount.png')" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
<view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(item)"
|
<view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(item)"
|
||||||
class="delete-price price-font"
|
class="delete-price price-font"
|
||||||
@@ -70,7 +71,7 @@
|
|||||||
color: goodsValue.btnStyle.theme == 'diy' ? goodsValue.btnStyle.textColor : '',
|
color: goodsValue.btnStyle.theme == 'diy' ? goodsValue.btnStyle.textColor : '',
|
||||||
borderColor: goodsValue.btnStyle.theme == 'diy' ? goodsValue.btnStyle.textColor : ''
|
borderColor: goodsValue.btnStyle.theme == 'diy' ? goodsValue.btnStyle.textColor : ''
|
||||||
}" class="cart shopping-cart-btn iconfont icon-gouwuche click-wrap" :id="'goods-' + item.id"
|
}" class="cart shopping-cart-btn iconfont icon-gouwuche click-wrap" :id="'goods-' + item.id"
|
||||||
@click.stop="$refs.goodsSkuIndex.addCart(goodsValue.btnStyle.cartEvent, item, $event)">
|
@tap.stop="$refs.goodsSkuIndex.addCart(goodsValue.btnStyle.cartEvent, item, $event)">
|
||||||
<view class="click-event"></view>
|
<view class="click-event"></view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -79,7 +80,7 @@
|
|||||||
color: goodsValue.btnStyle.theme == 'diy' ? goodsValue.btnStyle.textColor : '',
|
color: goodsValue.btnStyle.theme == 'diy' ? goodsValue.btnStyle.textColor : '',
|
||||||
borderColor: goodsValue.btnStyle.theme == 'diy' ? goodsValue.btnStyle.textColor : ''
|
borderColor: goodsValue.btnStyle.theme == 'diy' ? goodsValue.btnStyle.textColor : ''
|
||||||
}" class="cart plus-sign-btn iconfont icon-add1 click-wrap" :id="'goods-' + item.id"
|
}" class="cart plus-sign-btn iconfont icon-add1 click-wrap" :id="'goods-' + item.id"
|
||||||
@click.stop="$refs.goodsSkuIndex.addCart(goodsValue.btnStyle.cartEvent, item, $event)">
|
@tap.stop="$refs.goodsSkuIndex.addCart(goodsValue.btnStyle.cartEvent, item, $event)">
|
||||||
<view class="click-event"></view>
|
<view class="click-event"></view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -90,7 +91,7 @@
|
|||||||
fontWeight: goodsValue.btnStyle.theme == 'diy' ? (goodsValue.btnStyle.fontWeight ? 'bold' : 'normal') : '',
|
fontWeight: goodsValue.btnStyle.theme == 'diy' ? (goodsValue.btnStyle.fontWeight ? 'bold' : 'normal') : '',
|
||||||
padding: goodsValue.btnStyle.theme == 'diy' ? '0 ' + goodsValue.btnStyle.padding * 2 + 'rpx' : ''
|
padding: goodsValue.btnStyle.theme == 'diy' ? '0 ' + goodsValue.btnStyle.padding * 2 + 'rpx' : ''
|
||||||
}" class="cart buy-btn click-wrap" :id="'goods-' + item.id"
|
}" class="cart buy-btn click-wrap" :id="'goods-' + item.id"
|
||||||
@click.stop="$refs.goodsSkuIndex.addCart(goodsValue.btnStyle.cartEvent, item, $event)">
|
@tap.stop="$refs.goodsSkuIndex.addCart(goodsValue.btnStyle.cartEvent, item, $event)">
|
||||||
{{ goodsValue.btnStyle.text }}
|
{{ goodsValue.btnStyle.text }}
|
||||||
<view class="click-event"></view>
|
<view class="click-event"></view>
|
||||||
<!-- <text class="cart-num" v-if="cartList['goods_' + item.goods_id]">{{ cartList['goods_' + item.goods_id].num }}</text> -->
|
<!-- <text class="cart-num" v-if="cartList['goods_' + item.goods_id]">{{ cartList['goods_' + item.goods_id].num }}</text> -->
|
||||||
@@ -100,7 +101,7 @@
|
|||||||
<view v-else-if="goodsValue.btnStyle.style == 'icon-diy'" :style="{
|
<view v-else-if="goodsValue.btnStyle.style == 'icon-diy'" :style="{
|
||||||
color: goodsValue.btnStyle.theme == 'diy' ? goodsValue.btnStyle.textColor : ''
|
color: goodsValue.btnStyle.theme == 'diy' ? goodsValue.btnStyle.textColor : ''
|
||||||
}" class="icon-diy click-wrap" :id="'goods-' + item.id"
|
}" class="icon-diy click-wrap" :id="'goods-' + item.id"
|
||||||
@click.stop="$refs.goodsSkuIndex.addCart(goodsValue.btnStyle.cartEvent, item, $event)">
|
@tap.stop="$refs.goodsSkuIndex.addCart(goodsValue.btnStyle.cartEvent, item, $event)">
|
||||||
<view class="click-event"></view>
|
<view class="click-event"></view>
|
||||||
<diy-icon :icon="goodsValue.btnStyle.iconDiy.icon"
|
<diy-icon :icon="goodsValue.btnStyle.iconDiy.icon"
|
||||||
:value="goodsValue.btnStyle.iconDiy.style ? goodsValue.btnStyle.iconDiy.style : null"></diy-icon>
|
:value="goodsValue.btnStyle.iconDiy.style ? goodsValue.btnStyle.iconDiy.style : null"></diy-icon>
|
||||||
@@ -112,12 +113,12 @@
|
|||||||
</template>
|
</template>
|
||||||
<scroll-view v-if="goodsValue.template == 'horizontal-slide' && goodsValue.slideMode == 'scroll'"
|
<scroll-view v-if="goodsValue.template == 'horizontal-slide' && goodsValue.slideMode == 'scroll'"
|
||||||
class="scroll" :scroll-x="true">
|
class="scroll" :scroll-x="true">
|
||||||
<view class="goods-item" v-for="(item, index) in list" :key="index" @click="handlerClick(item)"
|
<view class="goods-item" v-for="(item, index) in list" :key="index" @tap.stop="handlerClick(item)"
|
||||||
@tap="handlerClick(item)" :class="[goodsValue.ornament.type]" :style="goodsItemCss">
|
:class="[goodsValue.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="goods-img-wrap">
|
<view class="goods-img-wrap">
|
||||||
<image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)"
|
||||||
:lazy-load="true" />
|
:lazy-load="true" show-menu-by-longpress />
|
||||||
<view class="sell-out" v-if="item.stock <= 0">
|
<view class="sell-out" v-if="item.stock <= 0">
|
||||||
<text class="iconfont icon-shuqing"></text>
|
<text class="iconfont icon-shuqing"></text>
|
||||||
</view>
|
</view>
|
||||||
@@ -156,9 +157,9 @@
|
|||||||
<view class="member-price"
|
<view class="member-price"
|
||||||
v-if="(item.member_price && item.member_price == showPrice(item)) || item.promotion_type == 1">
|
v-if="(item.member_price && item.member_price == showPrice(item)) || item.promotion_type == 1">
|
||||||
<image v-if="item.member_price && item.member_price == showPrice(item)"
|
<image v-if="item.member_price && item.member_price == showPrice(item)"
|
||||||
:src="$util.img('public/uniapp/index/VIP.png')" />
|
:src="$util.img('public/uniapp/index/VIP.png')" show-menu-by-longpress />
|
||||||
<image v-else-if="item.promotion_type == 1"
|
<image v-else-if="item.promotion_type == 1"
|
||||||
:src="$util.img('public/uniapp/index/discount.png')" />
|
:src="$util.img('public/uniapp/index/discount.png')" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
<view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(item)"
|
<view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(item)"
|
||||||
class="delete-price price-font"
|
class="delete-price price-font"
|
||||||
@@ -179,12 +180,12 @@
|
|||||||
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
||||||
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
||||||
<view class="goods-item" v-for="(dataItem, dataIndex) in list[pageIndex]" :key="dataIndex"
|
<view class="goods-item" v-for="(dataItem, dataIndex) in list[pageIndex]" :key="dataIndex"
|
||||||
@click="handlerClick(dataItem)" @tap="handlerClick(dataItem)"
|
@tap.stop="handlerClick(dataItem)"
|
||||||
:class="[goodsValue.ornament.type]" :style="goodsItemCss">
|
:class="[goodsValue.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="goods-img-wrap">
|
<view class="goods-img-wrap">
|
||||||
<image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(dataItem.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(dataItem.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imgError(dataIndex)" :lazy-load="true" />
|
@error="imgError(dataIndex)" :lazy-load="true" show-menu-by-longpress />
|
||||||
<view class="sell-out" v-if="dataItem.stock <= 0">
|
<view class="sell-out" v-if="dataItem.stock <= 0">
|
||||||
<text class="iconfont icon-shuqing"></text>
|
<text class="iconfont icon-shuqing"></text>
|
||||||
</view>
|
</view>
|
||||||
@@ -226,9 +227,9 @@
|
|||||||
v-if="(dataItem.member_price && dataItem.member_price == showPrice(dataItem)) || dataItem.promotion_type == 1">
|
v-if="(dataItem.member_price && dataItem.member_price == showPrice(dataItem)) || dataItem.promotion_type == 1">
|
||||||
<image
|
<image
|
||||||
v-if="dataItem.member_price && dataItem.member_price == showPrice(dataItem)"
|
v-if="dataItem.member_price && dataItem.member_price == showPrice(dataItem)"
|
||||||
:src="$util.img('public/uniapp/index/VIP.png')" />
|
:src="$util.img('public/uniapp/index/VIP.png')" show-menu-by-longpress />
|
||||||
<image v-else-if="dataItem.promotion_type == 1"
|
<image v-else-if="dataItem.promotion_type == 1"
|
||||||
:src="$util.img('public/uniapp/index/discount.png')" />
|
:src="$util.img('public/uniapp/index/discount.png')" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
<view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(dataItem)"
|
<view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(dataItem)"
|
||||||
class="delete-price"
|
class="delete-price"
|
||||||
@@ -253,15 +254,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import nsGoodsSkuIndex from '@/components/ns-goods-sku/ns-goods-sku-index.vue';
|
|
||||||
import DiyMinx from './minx.js'
|
import DiyMinx from './minx.js'
|
||||||
|
import util from '@/common/js/util.js'
|
||||||
|
|
||||||
// 自定义商品列表展示
|
// 自定义商品列表展示
|
||||||
export default {
|
export default {
|
||||||
name: 'diy-goods-list',
|
name: 'diy-goods-list',
|
||||||
components: {
|
|
||||||
nsGoodsSkuIndex
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -331,7 +329,7 @@ export default {
|
|||||||
if (this.goodsValue.ornament.type == 'stroke') {
|
if (this.goodsValue.ornament.type == 'stroke') {
|
||||||
obj += 'border:' + '2rpx solid ' + this.goodsValue.ornament.color + ';';
|
obj += 'border:' + '2rpx solid ' + this.goodsValue.ornament.color + ';';
|
||||||
}
|
}
|
||||||
const screenWidth = uni.getSystemInfoSync().windowWidth;
|
let screenWidth = util.getWindowInfo().windowWidth;
|
||||||
if (this.value.template == 'horizontal-slide') {
|
if (this.value.template == 'horizontal-slide') {
|
||||||
var width = '';
|
var width = '';
|
||||||
if (this.value.slideMode == 'scroll' && this.value.goodsMarginType == 'diy') width = this.rpxUpPx(
|
if (this.value.slideMode == 'scroll' && this.value.goodsMarginType == 'diy') width = this.rpxUpPx(
|
||||||
@@ -411,7 +409,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
rpxUpPx(res) {
|
rpxUpPx(res) {
|
||||||
const screenWidth = uni.getSystemInfoSync().windowWidth;
|
const screenWidth = util.getWindowInfo().windowWidth;
|
||||||
var data = (screenWidth * parseInt(res)) / 750;
|
var data = (screenWidth * parseInt(res)) / 750;
|
||||||
return Math.floor(data);
|
return Math.floor(data);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,11 +13,11 @@
|
|||||||
<swiper-item v-for="(item, index) in page" :key="index"
|
<swiper-item v-for="(item, index) in page" :key="index"
|
||||||
:class="['swiper-item', [list[index].length / 3] >= 1 && 'flex-between']">
|
:class="['swiper-item', [list[index].length / 3] >= 1 && 'flex-between']">
|
||||||
<view class="goods-item" v-for="(dataItem, dataIndex) in list[index]" :key="dataIndex"
|
<view class="goods-item" v-for="(dataItem, dataIndex) in list[index]" :key="dataIndex"
|
||||||
@click="toDetail(dataItem)" :class="[goodsValue.ornament.type]" :style="goodsItemCss">
|
@tap.stop="toDetail(dataItem)" :class="[goodsValue.ornament.type]" :style="goodsItemCss">
|
||||||
<div class="goods-img-wrap">
|
<div class="goods-img-wrap">
|
||||||
<image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(dataItem.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(dataItem.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imgError(index, dataIndex)" :lazy-load="true" />
|
@error="imgError(index, dataIndex)" :lazy-load="true" show-menu-by-longpress />
|
||||||
<view class="sell-out" v-if="dataItem.stock <= 0">
|
<view class="sell-out" v-if="dataItem.stock <= 0">
|
||||||
<text class="iconfont icon-shuqing"></text>
|
<text class="iconfont icon-shuqing"></text>
|
||||||
</view>
|
</view>
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
<view class="label-wrap" v-if="goodsValue.labelStyle.support"
|
<view class="label-wrap" v-if="goodsValue.labelStyle.support"
|
||||||
:style="{ background: goodsValue.labelStyle.bgColor, color: goodsValue.labelStyle.color }">
|
:style="{ background: goodsValue.labelStyle.bgColor, color: goodsValue.labelStyle.color }">
|
||||||
<image :src="$util.img('app/component/view/goods_recommend/img/label.png')"
|
<image :src="$util.img('app/component/view/goods_recommend/img/label.png')"
|
||||||
mode="widthFix" />
|
mode="widthFix" show-menu-by-longpress />
|
||||||
<text>{{ goodsValue.labelStyle.title }}</text>
|
<text>{{ goodsValue.labelStyle.title }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="discount-price">
|
<view class="discount-price">
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
<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"
|
||||||
v-if="index >= [(numItem) * (value.pageCount * value.rowCount)] && index < [(numItem + 1) * (value.pageCount * value.rowCount)]"
|
v-if="index >= [(numItem) * (value.pageCount * value.rowCount)] && index < [(numItem + 1) * (value.pageCount * value.rowCount)]"
|
||||||
:style="{ width: 100 / value.rowCount + '%' }" @click="redirectTo(item.link)">
|
:style="{ width: 100 / value.rowCount + '%' }" @tap.stop="redirectTo(item.link)">
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifdef H5 -->
|
<!-- #ifdef H5 -->
|
||||||
<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"
|
||||||
v-if="index >= [(numItem - 1) * (value.pageCount * value.rowCount)] && index < [numItem * (value.pageCount * value.rowCount)]"
|
v-if="index >= [(numItem - 1) * (value.pageCount * value.rowCount)] && index < [numItem * (value.pageCount * value.rowCount)]"
|
||||||
:style="{ width: 100 / value.rowCount + '%' }" @click="redirectTo(item.link)">
|
:style="{ width: 100 / value.rowCount + '%' }" @tap.stop="redirectTo(item.link)">
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<view class="graphic-img" v-if="value.mode != 'text'"
|
<view class="graphic-img" v-if="value.mode != 'text'"
|
||||||
:style="{ fontSize: value.imageSize * 2 + 'rpx', width: value.imageSize * 2 + 'rpx', height: value.imageSize * 2 + 'rpx' }">
|
:style="{ fontSize: value.imageSize * 2 + 'rpx', width: value.imageSize * 2 + 'rpx', height: value.imageSize * 2 + 'rpx' }">
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
:style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', borderRadius: value.aroundRadius * 2 + 'rpx' }"
|
:style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', borderRadius: value.aroundRadius * 2 + 'rpx' }"
|
||||||
:show-menu-by-longpress="true" />
|
show-menu-by-longpress />
|
||||||
|
|
||||||
<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"
|
||||||
@@ -62,14 +62,14 @@
|
|||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
|
|
||||||
<view class="graphic-nav-item" :class="[value.mode]" v-for="(item, index) in value.list" :key="index"
|
<view class="graphic-nav-item" :class="[value.mode]" v-for="(item, index) in value.list" :key="index"
|
||||||
:style="{ width: 100 / value.rowCount + '%' }" @click="redirectTo(item.link)">
|
:style="{ width: 100 / value.rowCount + '%' }" @tap.stop="redirectTo(item.link)">
|
||||||
<view class="graphic-img" v-if="value.mode != 'text'"
|
<view class="graphic-img" v-if="value.mode != 'text'"
|
||||||
:style="{ fontSize: value.imageSize * 2 + 'rpx', width: value.imageSize * 2 + 'rpx', height: value.imageSize * 2 + 'rpx' }">
|
:style="{ fontSize: value.imageSize * 2 + 'rpx', width: value.imageSize * 2 + 'rpx', height: value.imageSize * 2 + 'rpx' }">
|
||||||
<image v-if="item.iconType == 'img'"
|
<image v-if="item.iconType == 'img'"
|
||||||
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
:style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', borderRadius: value.aroundRadius * 2 + 'rpx' }"
|
:style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', borderRadius: value.aroundRadius * 2 + 'rpx' }"
|
||||||
:show-menu-by-longpress="true" />
|
show-menu-by-longpress />
|
||||||
<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"
|
||||||
:style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', width: '100%', height: '100%' }"></diy-icon>
|
:style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', width: '100%', height: '100%' }"></diy-icon>
|
||||||
@@ -159,12 +159,11 @@ export default {
|
|||||||
redirectTo(link) {
|
redirectTo(link) {
|
||||||
|
|
||||||
if (link.wap_url) {
|
if (link.wap_url) {
|
||||||
if (this.$util.getCurrRoute() == 'pages/member/index' && !this.storeToken) {
|
if (this.$util.getCurrRoute() == this.$util.MEMBER_PAGE_URL && !this.storeToken) {
|
||||||
this.$refs.login.open(link.wap_url);
|
this.$refs.login.open(link.wap_url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(link)
|
|
||||||
this.$util.diyRedirectTo(link);
|
this.$util.diyRedirectTo(link);
|
||||||
},
|
},
|
||||||
swiperChange(e) {
|
swiperChange(e) {
|
||||||
|
|||||||
@@ -251,6 +251,16 @@
|
|||||||
<diy-icon :value="item"></diy-icon>
|
<diy-icon :value="item"></diy-icon>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template v-if="item.componentName == 'Tab'">
|
||||||
|
<!-- Tab 组件 -->
|
||||||
|
<diy-tab :value="item" :diyGlobal="diyGlobalData"></diy-tab>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="['ChannelList', 'WechatChannel'].includes(item.componentName)">
|
||||||
|
<!-- 视频号列表 -->
|
||||||
|
<diy-channel-list :value="item"></diy-channel-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- 自定义扩展组件 -->
|
<!-- 自定义扩展组件 -->
|
||||||
<diy-comp-extend :value="item"></diy-comp-extend>
|
<diy-comp-extend :value="item"></diy-comp-extend>
|
||||||
</view>
|
</view>
|
||||||
@@ -260,8 +270,9 @@
|
|||||||
<script>
|
<script>
|
||||||
// 组件组展示
|
// 组件组展示
|
||||||
import DiyMinx from './minx.js'
|
import DiyMinx from './minx.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
name: 'diy-group',
|
||||||
props: {
|
props: {
|
||||||
diyData: {
|
diyData: {
|
||||||
type: Object
|
type: Object
|
||||||
@@ -306,7 +317,12 @@ export default {
|
|||||||
this.diyGlobalData.value.forEach((item, index) => {
|
this.diyGlobalData.value.forEach((item, index) => {
|
||||||
item.pageStyle = '';
|
item.pageStyle = '';
|
||||||
// 给每个组件增加位置属性,用于定位,搜索、分类导航等定位
|
// 给每个组件增加位置属性,用于定位,搜索、分类导航等定位
|
||||||
item.moduleIndex = index + 1;
|
// 如果是Tab组件内部的子组件,添加tabIndex前缀避免moduleIndex冲突
|
||||||
|
if (this.diyData.tabIndex !== undefined) {
|
||||||
|
item.moduleIndex = `${this.diyData.tabIndex}-${index + 1}`;
|
||||||
|
} else {
|
||||||
|
item.moduleIndex = index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
// 特殊处理搜索框 当显示位置为滚动至顶部固定时,只设置背景颜色
|
// 特殊处理搜索框 当显示位置为滚动至顶部固定时,只设置背景颜色
|
||||||
if (item.componentName == 'Search' && item.positionWay == 'fixed') {
|
if (item.componentName == 'Search' && item.positionWay == 'fixed') {
|
||||||
@@ -341,6 +357,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else data = this.setPagestyle;
|
} else data = this.setPagestyle;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
<x-skeleton data-component-name="diy-groupbuy" :type="skeletonType" :loading="loading" :configs="skeletonConfig">
|
<x-skeleton data-component-name="diy-groupbuy" :type="skeletonType" :loading="loading" :configs="skeletonConfig">
|
||||||
<view class="diy-groupbuy" :class="[value.template, value.style]" :style="warpCss">
|
<view class="diy-groupbuy" :class="[value.template, value.style]" :style="warpCss">
|
||||||
<template v-if="value.template == 'row1-of1'">
|
<template v-if="value.template == 'row1-of1'">
|
||||||
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)"
|
<view class="item" v-for="(item, index) in list" :key="index" @tap.stop="toDetail(item)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)">
|
@error="imageError(index)" show-menu-by-longpress>
|
||||||
</image>
|
</image>
|
||||||
</view>
|
</view>
|
||||||
<view class="content"
|
<view class="content"
|
||||||
@@ -39,12 +39,12 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-if="value.template == 'horizontal-slide'">
|
<template v-if="value.template == 'horizontal-slide'">
|
||||||
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
|
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
|
||||||
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)"
|
<view class="item" v-for="(item, index) in list" :key="index" @tap.stop="toDetail(item)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" />
|
@error="imageError(index)" show-menu-by-longpress/>
|
||||||
<image class="bg" v-if="value.saleStyle.control"
|
<image class="bg" v-if="value.saleStyle.control"
|
||||||
:src="$util.img('public/uniapp/groupbuy/bg.png')" mode="widthFix" />
|
:src="$util.img('public/uniapp/groupbuy/bg.png')" mode="widthFix" />
|
||||||
<view class="num" v-if="value.saleStyle.control"
|
<view class="num" v-if="value.saleStyle.control"
|
||||||
@@ -81,11 +81,11 @@
|
|||||||
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
||||||
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
||||||
<view class="item" v-for="(item, dataIndex) in list[pageIndex]" :key="dataIndex"
|
<view class="item" v-for="(item, dataIndex) in list[pageIndex]" :key="dataIndex"
|
||||||
@click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
@tap.stop="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(dataIndex)" />
|
@error="imageError(dataIndex)" show-menu-by-longpress/>
|
||||||
<image class="bg" v-if="value.saleStyle.control"
|
<image class="bg" v-if="value.saleStyle.control"
|
||||||
:src="$util.img('public/uniapp/groupbuy/bg.png')" mode="widthFix" />
|
:src="$util.img('public/uniapp/groupbuy/bg.png')" mode="widthFix" />
|
||||||
<view class="num" v-if="value.saleStyle.control"
|
<view class="num" v-if="value.saleStyle.control"
|
||||||
@@ -274,7 +274,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
/deep/.uni-scroll-view ::-webkit-scrollbar {
|
::v-deep .uni-scroll-view ::-webkit-scrollbar {
|
||||||
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -283,7 +283,7 @@ export default {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/::-webkit-scrollbar {
|
::v-deep ::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
<view data-component-name="diy-hot-area" :style="hotAreaWarp" class="hot-area-box">
|
<view data-component-name="diy-hot-area" :style="hotAreaWarp" class="hot-area-box">
|
||||||
<view class="simple-graph-wrap">
|
<view class="simple-graph-wrap">
|
||||||
<image :style="{ height: value.imgHeight }" :src="$util.img(value.imageUrl)" mode="widthFix"
|
<image :style="{ height: value.imgHeight }" :src="$util.img(value.imageUrl)" mode="widthFix"
|
||||||
:show-menu-by-longpress="true" />
|
show-menu-by-longpress />
|
||||||
<!-- 热区功能 -->
|
<!-- 热区功能 -->
|
||||||
<view class="heat-map" v-for="(mapItem, mapIndex) in value.heatMapData" :key="mapIndex" :style="{
|
<view class="heat-map" v-for="(mapItem, mapIndex) in value.heatMapData" :key="mapIndex" :style="{
|
||||||
width: mapItem.width + '%',
|
width: mapItem.width + '%',
|
||||||
height: mapItem.height + '%',
|
height: mapItem.height + '%',
|
||||||
left: mapItem.left + '%',
|
left: mapItem.left + '%',
|
||||||
top: mapItem.top + '%'
|
top: mapItem.top + '%'
|
||||||
}" @click.stop="$util.diyRedirectTo(mapItem.link)"></view>
|
}" @tap.stop="$util.diyRedirectTo(mapItem.link)"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -15,12 +15,12 @@
|
|||||||
'width': (item.imgWidth / 2 + 'rpx') + ';',
|
'width': (item.imgWidth / 2 + 'rpx') + ';',
|
||||||
'height': (item.imgHeight / 2 + 'rpx') + ';'
|
'height': (item.imgHeight / 2 + 'rpx') + ';'
|
||||||
}" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
}" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
||||||
:show-menu-by-longpress="true" @tap="redirectTo(item.link)"></image>
|
show-menu-by-longpress @tap.stop="redirectTo(item.link)"></image>
|
||||||
<image v-else :style="{
|
<image v-else :style="{
|
||||||
'width': (item.imgWidth / 2 + 'rpx') + ';',
|
'width': (item.imgWidth / 2 + 'rpx') + ';',
|
||||||
'height': (item.imgHeight / 2 + 'rpx') + ';'
|
'height': (item.imgHeight / 2 + 'rpx') + ';'
|
||||||
}" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
}" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
||||||
:show-menu-by-longpress="true" @tap="previewImg(item.imageUrl)"></image>
|
show-menu-by-longpress @tap.stop="previewImg(item.imageUrl)"></image>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 文字部分 -->
|
<!-- 文字部分 -->
|
||||||
@@ -38,14 +38,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import nsLogin from '@/components/ns-login/ns-login.vue'
|
|
||||||
import DiyMinx from './minx.js'
|
import DiyMinx from './minx.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'diy-image-nav',
|
name: 'diy-image-nav',
|
||||||
components: {
|
|
||||||
nsLogin
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -106,20 +103,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 预览图片
|
|
||||||
previewImg(imageUrl) {
|
|
||||||
uni.previewImage({
|
|
||||||
current: 0,
|
|
||||||
urls: [this.$util.img(imageUrl)],
|
|
||||||
success: (res) => { },
|
|
||||||
fail: (res) => { },
|
|
||||||
complete: (res) => { }
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// 页面跳转
|
// 页面跳转
|
||||||
redirectTo(link) {
|
redirectTo(link) {
|
||||||
if (!link.wap_url || this.$util.getCurrRoute() != 'pages/member/index' || this.storeToken) {
|
if (!link.wap_url || this.$util.getCurrRoute() != this.$util.MEMBER_PAGE_URL || this.storeToken) {
|
||||||
this.$util.diyRedirectTo(link);
|
this.$util.diyRedirectTo(link);
|
||||||
} else {
|
} else {
|
||||||
this.$refs.login.open(link.wap_url);
|
this.$refs.login.open(link.wap_url);
|
||||||
|
|||||||
@@ -2,10 +2,9 @@
|
|||||||
<view data-component-name="diy-img-ads" class="single-graph">
|
<view data-component-name="diy-img-ads" class="single-graph">
|
||||||
<view :style="imgAdsMarginWarp" class="swiper-box">
|
<view :style="imgAdsMarginWarp" class="swiper-box">
|
||||||
<block v-if="imgAdsValue.list.length == 1">
|
<block v-if="imgAdsValue.list.length == 1">
|
||||||
<view class="simple-graph-wrap" :style="imgAdsSwiper" @click="handlerClick(imgAdsValue.list[0].link)"
|
<view class="simple-graph-wrap" :style="imgAdsSwiper" @tap.stop="handlerClick(imgAdsValue.list[0].link)">
|
||||||
@tap="handlerClick(imgAdsValue.list[0].link)">
|
|
||||||
<image :style="{ height: imgAdsValue.list[0].imgHeight }"
|
<image :style="{ height: imgAdsValue.list[0].imgHeight }"
|
||||||
:src="$util.img(imgAdsValue.list[0].imageUrl)" mode="widthFix" :show-menu-by-longpress="true" />
|
:src="$util.img(imgAdsValue.list[0].imageUrl)" mode="widthFix" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<swiper v-else class="swiper" :style="{ height: swiperHeight }" :class="{
|
<swiper v-else class="swiper" :style="{ height: swiperHeight }" :class="{
|
||||||
@@ -16,10 +15,10 @@
|
|||||||
indicator-color="rgba(130, 130, 130, .5)" :indicator-active-color="imgAdsValue.indicatorColor"
|
indicator-color="rgba(130, 130, 130, .5)" :indicator-active-color="imgAdsValue.indicatorColor"
|
||||||
@change="swiperChange">
|
@change="swiperChange">
|
||||||
<swiper-item class="swiper-item" :style="imgAdsSwiper" v-for="(item, index) in imgAdsValue.list"
|
<swiper-item class="swiper-item" :style="imgAdsSwiper" v-for="(item, index) in imgAdsValue.list"
|
||||||
:key="index" v-if="item.imageUrl" @click="handlerClick(item.link)" @tap="handlerClick(item.link)">
|
:key="index" v-if="item.imageUrl" @tap.stop="handlerClick(item.link)">
|
||||||
<view class="item" :style="imgAdsSwiper + 'height: ' + item.imgHeight">
|
<view class="item" :style="imgAdsSwiper + 'height: ' + item.imgHeight">
|
||||||
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
|
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
|
||||||
:show-menu-by-longpress="true" />
|
show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
</swiper-item>
|
</swiper-item>
|
||||||
</swiper>
|
</swiper>
|
||||||
@@ -280,39 +279,39 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
||||||
/deep/.uni-scroll-view::-webkit-scrollbar {
|
::v-deep .uni-scroll-view::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swiper /deep/ .uni-swiper-dots-horizontal {
|
.swiper ::v-deep .uni-swiper-dots-horizontal {
|
||||||
bottom: 25rpx;
|
bottom: 25rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swiper-left /deep/ .uni-swiper-dots-horizontal {
|
.swiper-left ::v-deep .uni-swiper-dots-horizontal {
|
||||||
left: 40rpx;
|
left: 40rpx;
|
||||||
transform: translate(0);
|
transform: translate(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.swiper-right /deep/ .uni-swiper-dots-horizontal {
|
.swiper-right ::v-deep .uni-swiper-dots-horizontal {
|
||||||
right: 40rpx;
|
right: 40rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
transform: translate(0);
|
transform: translate(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-angle /deep/ .uni-swiper-dots-horizontal .uni-swiper-dot {
|
.carousel-angle ::v-deep .uni-swiper-dots-horizontal .uni-swiper-dot {
|
||||||
width: 24rpx;
|
width: 24rpx;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
height: 8rpx;
|
height: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swiper.ns-indicator-dots /deep/ .uni-swiper-dot {
|
.swiper.ns-indicator-dots ::v-deep .uni-swiper-dot {
|
||||||
width: 18rpx;
|
width: 18rpx;
|
||||||
height: 6rpx;
|
height: 6rpx;
|
||||||
border-radius: 4rpx;
|
border-radius: 4rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swiper.ns-indicator-dots /deep/ .uni-swiper-dot-active {
|
.swiper.ns-indicator-dots ::v-deep .uni-swiper-dot-active {
|
||||||
width: 36rpx;
|
width: 36rpx;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
:style="{ background: value.backgroundColor ? value.backgroundColor : '', width: 'calc(100% - 48rpx)' }"
|
:style="{ background: value.backgroundColor ? value.backgroundColor : '', width: 'calc(100% - 48rpx)' }"
|
||||||
@touchmove.stop>
|
@touchmove.stop>
|
||||||
<view class="item" :id="'a' + index" v-for="(item, index) in cateList" :key="index"
|
<view class="item" :id="'a' + index" v-for="(item, index) in cateList" :key="index"
|
||||||
@click="changePageIndex(index)" :class="{ fill: value.styleType == 'fill' }"
|
@tap.stop="changePageIndex(index)" :class="{ fill: value.styleType == 'fill' }"
|
||||||
:style="{ background: index == pageIndex && value.styleType == 'fill' ? value.selectColor : '' }">
|
:style="{ background: index == pageIndex && value.styleType == 'fill' ? value.selectColor : '' }">
|
||||||
<view class="text-con" :class="index == pageIndex ? 'active' : ''" :style="{
|
<view class="text-con" :class="index == pageIndex ? 'active' : ''" :style="{
|
||||||
color: index == pageIndex ? '' : value.noColor
|
color: index == pageIndex ? '' : value.noColor
|
||||||
@@ -25,13 +25,13 @@
|
|||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<text class="iconfont icon-unfold unfold-arrows" :style="{ color: value.moreColor }"
|
<text class="iconfont icon-unfold unfold-arrows" :style="{ color: value.moreColor }"
|
||||||
@click="unfoldMenu"></text>
|
@tap.stop="unfoldMenu"></text>
|
||||||
</view>
|
</view>
|
||||||
<uni-popup ref="navTopCategoryPop" type="top" :top="uniPopTop">
|
<uni-popup ref="navTopCategoryPop" type="top" :top="uniPopTop">
|
||||||
<view class="nav-topcategory-pop">
|
<view class="nav-topcategory-pop">
|
||||||
<text v-for="(item, index) in cateList" :key="index"
|
<text v-for="(item, index) in cateList" :key="index"
|
||||||
:class="['category-item', { 'color-base-text color-base-border active': pageIndex == index }]"
|
:class="['category-item', { 'color-base-text color-base-border active': pageIndex == index }]"
|
||||||
@click="changePageIndex(index)">
|
@tap.stop="changePageIndex(index)">
|
||||||
{{ item.short_name ? item.short_name : item.category_name }}
|
{{ item.short_name ? item.short_name : item.category_name }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -55,12 +55,12 @@
|
|||||||
<view class="twoCategory min" v-if="twoCategorylist.length <= 5">
|
<view class="twoCategory min" v-if="twoCategorylist.length <= 5">
|
||||||
<view class="twoCategory-page">
|
<view class="twoCategory-page">
|
||||||
<view class="swiper-item" v-for="(item, index) in twoCategorylist"
|
<view class="swiper-item" v-for="(item, index) in twoCategorylist"
|
||||||
:key="index" @click="toCateGoodsList(item.category_id_2, 2)">
|
:key="index" @tap.stop="toCateGoodsList(item.category_id_2, 2)">
|
||||||
<view class="item-box">
|
<view class="item-box">
|
||||||
<image :src="$util.img(item.image)" v-if="item.image"
|
<image :src="$util.img(item.image)" v-if="item.image"
|
||||||
mode="aspectFill" />
|
mode="aspectFill" show-menu-by-longpress/>
|
||||||
<image :src="$util.getDefaultImage().goods" v-else
|
<image :src="$util.getDefaultImage().goods" v-else
|
||||||
mode="aspectFill" />
|
mode="aspectFill" show-menu-by-longpress/>
|
||||||
<view>{{ item.category_name }}</view>
|
<view>{{ item.category_name }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -70,12 +70,12 @@
|
|||||||
v-if="twoCategorylist.length > 5 && twoCategorylist.length <= 10">
|
v-if="twoCategorylist.length > 5 && twoCategorylist.length <= 10">
|
||||||
<view class="twoCategory-page">
|
<view class="twoCategory-page">
|
||||||
<view class="swiper-item" v-for="(item, index) in twoCategorylist"
|
<view class="swiper-item" v-for="(item, index) in twoCategorylist"
|
||||||
:key="index" @click="toCateGoodsList(item.category_id_2, 2)">
|
:key="index" @tap.stop="toCateGoodsList(item.category_id_2, 2)">
|
||||||
<view class="item-box">
|
<view class="item-box">
|
||||||
<image :src="$util.img(item.image)" v-if="item.image"
|
<image :src="$util.img(item.image)" v-if="item.image"
|
||||||
mode="aspectFill" />
|
mode="aspectFill" show-menu-by-longpress/>
|
||||||
<image :src="$util.getDefaultImage().goods" v-else
|
<image :src="$util.getDefaultImage().goods" v-else
|
||||||
mode="aspectFill" />
|
mode="aspectFill" show-menu-by-longpress/>
|
||||||
<view>{{ item.category_name }}</view>
|
<view>{{ item.category_name }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -86,9 +86,9 @@
|
|||||||
<swiper-item class="twoCategory-page" v-for="page in maxPage" :key="page">
|
<swiper-item class="twoCategory-page" v-for="page in maxPage" :key="page">
|
||||||
<view class="swiper-item" v-for="(item, index) in twoCategorylist"
|
<view class="swiper-item" v-for="(item, index) in twoCategorylist"
|
||||||
:key="index" v-if="index >= (page - 1) * 10 && index < page * 10"
|
:key="index" v-if="index >= (page - 1) * 10 && index < page * 10"
|
||||||
@click="toCateGoodsList(item.category_id_2, 2)">
|
@tap.stop="toCateGoodsList(item.category_id_2, 2)">
|
||||||
<view class="item-box">
|
<view class="item-box">
|
||||||
<image :src="item.image" mode="aspectFill" />
|
<image :src="item.image" mode="aspectFill" show-menu-by-longpress/>
|
||||||
<view>{{ item.category_name }}</view>
|
<view>{{ item.category_name }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -104,19 +104,19 @@
|
|||||||
|
|
||||||
<!-- 分类广告 -->
|
<!-- 分类广告 -->
|
||||||
<image class="category_adv" v-if="cateList[pageIndex].image_adv"
|
<image class="category_adv" v-if="cateList[pageIndex].image_adv"
|
||||||
:src="$util.img(cateList[pageIndex].image_adv)" mode="widthFix" />
|
:src="$util.img(cateList[pageIndex].image_adv)" mode="widthFix" show-menu-by-longpress/>
|
||||||
|
|
||||||
<view class="goods-list double-column" v-if="goodsList[pageIndex].list.length">
|
<view class="goods-list double-column" v-if="goodsList[pageIndex].list.length">
|
||||||
<view class="goods-item" v-for="(item, index) in goodsList[pageIndex].list"
|
<view class="goods-item" v-for="(item, index) in goodsList[pageIndex].list"
|
||||||
:key="index" @click="toDetail(item)">
|
:key="index" @tap.stop="toDetail(item)">
|
||||||
<view class="goods-img">
|
<view class="goods-img">
|
||||||
<image :src="goodsImg(item.goods_image)" mode="widthFix"
|
<image :src="goodsImg(item.goods_image)" mode="widthFix"
|
||||||
@error="imgError(index)" />
|
@error="imgError(index)" show-menu-by-longpress/>
|
||||||
<view class="color-base-bg goods-tag"
|
<view class="color-base-bg goods-tag"
|
||||||
v-if="value.goodsTag == 'default' && goodsTag(item) != ''">{{
|
v-if="value.goodsTag == 'default' && goodsTag(item) != ''">{{
|
||||||
goodsTag(item) }}</view>
|
goodsTag(item) }}</view>
|
||||||
<view class="goods-tag-img" v-if="value.goodsTag == 'diy'">
|
<view class="goods-tag-img" v-if="value.goodsTag == 'diy'">
|
||||||
<image :src="$util.img(value.tagImg.imageUrl)" />
|
<image :src="$util.img(value.tagImg.imageUrl)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-wrap">
|
<view class="info-wrap">
|
||||||
@@ -133,11 +133,11 @@
|
|||||||
<view class="member-price-tag"
|
<view class="member-price-tag"
|
||||||
v-if="item.member_price && item.member_price == showPrice(item)">
|
v-if="item.member_price && item.member_price == showPrice(item)">
|
||||||
<image :src="$util.img('public/uniapp/index/VIP.png')"
|
<image :src="$util.img('public/uniapp/index/VIP.png')"
|
||||||
mode="widthFix" />
|
mode="widthFix" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="member-price-tag" v-else-if="item.promotion_type == 1">
|
<view class="member-price-tag" v-else-if="item.promotion_type == 1">
|
||||||
<image :src="$util.img('public/uniapp/index/discount.png')"
|
<image :src="$util.img('public/uniapp/index/discount.png')"
|
||||||
mode="widthFix" />
|
mode="widthFix" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="pro-info">
|
<view class="pro-info">
|
||||||
@@ -169,7 +169,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import nsLoading from '@/components/ns-loading/ns-loading.vue';
|
|
||||||
import DiyMinx from './minx.js'
|
import DiyMinx from './minx.js'
|
||||||
export default {
|
export default {
|
||||||
name: 'diy-index-page',
|
name: 'diy-index-page',
|
||||||
@@ -189,9 +188,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mixins: [DiyMinx],
|
mixins: [DiyMinx],
|
||||||
components: {
|
|
||||||
nsLoading
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pageIndex: 0, //当前选中分类id
|
pageIndex: 0, //当前选中分类id
|
||||||
@@ -736,7 +732,7 @@ export default {
|
|||||||
margin-top: 100rpx;
|
margin-top: 100rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/.uni-scroll-view::-webkit-scrollbar {
|
::v-deep .uni-scroll-view::-webkit-scrollbar {
|
||||||
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view data-component-name="diy-kefu" class="diy-kefu" :style="style">
|
<view data-component-name="diy-kefu" class="diy-kefu" :style="style">
|
||||||
<view class="fui-list-group merchgroup" v-for="(item, index) in value.list">
|
<view class="fui-list-group merchgroup" v-for="(item, index) in value.list" :key="index">
|
||||||
<view class="fui-list jump" v-if="index == 0">
|
<view class="fui-list jump" v-if="index == 0">
|
||||||
<view class="fui-list-media">
|
<view class="fui-list-media">
|
||||||
<image class="round" :src="$util.img(item.imageUrl)" style="border-radius:6rpx"></image>
|
<image class="round" :src="$util.img(item.imageUrl)" style="border-radius:6rpx" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="fui-list-inner">
|
<view class="fui-list-inner">
|
||||||
<view class="title" style="height: 75rpx;">
|
<view class="title" style="height: 75rpx;">
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="fui-remark jump" style="padding-right: 20rpx; text-align: center; line-height: 140rpx;">
|
<view class="fui-remark jump" style="padding-right: 20rpx; text-align: center; line-height: 140rpx;">
|
||||||
<span style="font-size:24rpx;padding: 14rpx 18rpx;border-radius:8rpx"
|
<span style="font-size:24rpx;padding: 14rpx 18rpx;border-radius:8rpx"
|
||||||
:style="{ background: item.BtBgColor, color: item.BtColor }" @click="previewSqs()">立即添加</span>
|
:style="{ background: item.BtBgColor, color: item.BtColor }" @tap.stop="previewSqs()">立即添加</span>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view data-component-name="diy-picture" class="diy-picture" :style="style">
|
<view data-component-name="diy-listmenu" class="diy-listmenu" :style="style">
|
||||||
<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)" show-menu-by-longpress></image> -->
|
||||||
|
|
||||||
<view v-for="(item, index) in value.list" @click="redirectTo(item.link)" class="fui-cell"
|
<view v-for="(item, index) in value.list" @tap.stop="redirectTo(item.link)" class="fui-cell"
|
||||||
:class="item.iconType == 'img' ? 'img-cell' : ''">
|
:class="item.iconType == 'img' ? 'img-cell' : ''">
|
||||||
<view class="fui-cell-icon" :style="{ 'color': item.style ? item.style.iconColor : '#333' }">
|
<view class="fui-cell-icon" :style="{ 'color': item.style ? item.style.iconColor : '#333' }">
|
||||||
<diy-icon v-if="item.iconType == 'icon'" :icon="item.icon" :value="item.style ? item.style : null"
|
<diy-icon v-if="item.iconType == 'icon'" :icon="item.icon" :value="item.style ? item.style : null"
|
||||||
@@ -62,8 +62,8 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
redirectTo(link) {
|
redirectTo(link) {
|
||||||
if (link.wap_url) {
|
if (link.wap_url) {
|
||||||
if (this.$util.getCurrRoute() == 'pages/member/index' && !this.storeToken) {
|
if (this.$util.getCurrRoute() == this.$util.MEMBER_PAGE_URL && !this.storeToken) {
|
||||||
this.$refs.login.open(link.wap_url);
|
this.$refs?.login?.open(link.wap_url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<x-skeleton data-component-name="diy-live" type="banner" :loading="loading" :configs="skeletonConfig">
|
<x-skeleton data-component-name="diy-live" type="banner" :loading="loading" :configs="skeletonConfig">
|
||||||
<view class="live-wrap" @click="handlerClick(liveInfo.roomid)" @tap="handlerClick(liveInfo.roomid)"
|
<view class="live-wrap" @tap.stop="handlerClick(liveInfo.roomid)"
|
||||||
v-if="liveInfo">
|
v-if="liveInfo">
|
||||||
<view class="banner-wrap">
|
<view class="banner-wrap">
|
||||||
<image
|
<image
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<block v-if="value.isShowAnchorInfo">
|
<block v-if="value.isShowAnchorInfo">
|
||||||
<image
|
<image
|
||||||
:src="liveInfo.anchor_img != '' ? $util.img(liveInfo.anchor_img) : $util.getDefaultImage().head"
|
:src="liveInfo.anchor_img != '' ? $util.img(liveInfo.anchor_img) : $util.getDefaultImage().head"
|
||||||
class="anchor-img" @error="liveInfo.anchor_img = $util.getDefaultImage().head" />
|
class="anchor-img" @error="liveInfo.anchor_img = $util.getDefaultImage().head" show-menu-by-longpress/>
|
||||||
<text class="anchor-name">主播:{{ liveInfo.anchor_name }}</text>
|
<text class="anchor-name">主播:{{ liveInfo.anchor_name }}</text>
|
||||||
</block>
|
</block>
|
||||||
<text class="separate" v-if="value.isShowAnchorInfo && value.isShowLiveGood">|</text>
|
<text class="separate" v-if="value.isShowAnchorInfo && value.isShowLiveGood">|</text>
|
||||||
@@ -109,7 +109,6 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log('get live status', err);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 往后间隔1分钟或更慢的频率去轮询获取直播状态
|
// 往后间隔1分钟或更慢的频率去轮询获取直播状态
|
||||||
@@ -127,8 +126,7 @@ export default {
|
|||||||
clearInterval(timer);
|
clearInterval(timer);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log('get live status', err);
|
|
||||||
});
|
});
|
||||||
}, 60000);
|
}, 60000);
|
||||||
// #endif
|
// #endif
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<scroll-view scroll-x="true" class="many-goods-list-head" :scroll-into-view="'a' + cateIndex"
|
<scroll-view scroll-x="true" class="many-goods-list-head" :scroll-into-view="'a' + cateIndex"
|
||||||
:style="manyWrapCss">
|
:style="manyWrapCss">
|
||||||
<view v-for="(item, index) in value.list" class="scroll-item" :class="{ active: index == cateIndex }"
|
<view v-for="(item, index) in value.list" class="scroll-item" :class="{ active: index == cateIndex }"
|
||||||
:id="'a' + index" :key="index" @click="handlerClick({ item, index })" @tap="handlerClick({ item, index })">
|
:id="'a' + index" :key="index" @tap.stop="handlerClick({ item, index })">
|
||||||
<view class="split-line" v-if="index > 0"></view>
|
<view class="split-line" v-if="index > 0"></view>
|
||||||
<view class="cate">
|
<view class="cate">
|
||||||
<view class="name" :style="{ color: value.headStyle.titleColor }">{{ item.title }}</view>
|
<view class="name" :style="{ color: value.headStyle.titleColor }">{{ item.title }}</view>
|
||||||
|
|||||||
@@ -3,11 +3,18 @@
|
|||||||
<view class="fui-list-group merchgroup" style="margin-top:0" v-for="(item, index) in value.list">
|
<view class="fui-list-group merchgroup" style="margin-top:0" v-for="(item, index) in value.list">
|
||||||
<map id="map" style="width: 100%; height:600rpx" scale="12" :markers="markerst" bindupdated="bindupdated"
|
<map id="map" style="width: 100%; height:600rpx" scale="12" :markers="markerst" bindupdated="bindupdated"
|
||||||
:longitude="item.lng" :latitude="item.lat" show-location>
|
:longitude="item.lng" :latitude="item.lat" show-location>
|
||||||
<cover-view
|
<!-- <cover-view
|
||||||
style="position:absolute;right:10px;bottom:30rpx;z-index:99999;background:#4390FF;padding:5px 10px;wxcs_style_padding:10rpx 20rpx;border-radius:8rpx;color: #fff;"
|
style="position:absolute;right:10px;bottom:30rpx;z-index:99999;background:#4390FF;padding:5px 10px;wxcs_style_padding:10rpx 20rpx;border-radius:8rpx;color: #fff;"
|
||||||
@click="handlerClick(item)" @tap="handlerClick(item)">
|
@tap.stop="handlerClick(item)" @tap="handlerClick(item)">
|
||||||
<cover-view style="font-size:24rpx">一键导航</cover-view>
|
<cover-view style="font-size:24rpx">一键导航</cover-view>
|
||||||
</cover-view>
|
</cover-view> -->
|
||||||
|
|
||||||
|
<!-- 使用非原生cover-view, 解决原生cover-view组件渲染机制z-index失效的问题 -->
|
||||||
|
<div
|
||||||
|
style="position:absolute;right:12rpx;bottom:48rpx;z-index:1;background:#4390FF;padding:0rpx 20rpx;border-radius:8rpx;color: #fff;"
|
||||||
|
@tap.stop="handlerClick(item)">
|
||||||
|
<span style="font-size:24rpx;color: #fff;">一键导航</span>
|
||||||
|
</div>
|
||||||
</map>
|
</map>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|||||||
@@ -4,18 +4,18 @@
|
|||||||
<view class="common-wrap info-wrap" :class="[`data-style-${value.style}`]">
|
<view class="common-wrap info-wrap" :class="[`data-style-${value.style}`]">
|
||||||
<view class="member-info" :style="memberInfoStyle">
|
<view class="member-info" :style="memberInfoStyle">
|
||||||
<view class="info-wrap" :style="infoStyle" v-if="memberInfo">
|
<view class="info-wrap" :style="infoStyle" v-if="memberInfo">
|
||||||
<view class="headimg" @click="getWxAuth">
|
<view class="headimg" @tap.stop="getWxAuth">
|
||||||
<image :src="memberInfo.headimg ? $util.img(memberInfo.headimg) : $util.getDefaultImage().head"
|
<image :src="memberInfo.headimg ? $util.img(memberInfo.headimg) : $util.getDefaultImage().head"
|
||||||
mode="widthFix" @error="memberInfo.headimg = $util.getDefaultImage().head" />
|
mode="widthFix" @error="memberInfo.headimg = $util.getDefaultImage().head" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<!-- #ifdef MP -->
|
<!-- #ifdef MP -->
|
||||||
<block
|
<block
|
||||||
v-if="(memberInfo.nickname.indexOf('u_') != -1 && memberInfo.nickname == memberInfo.username) || memberInfo.nickname == memberInfo.mobile">
|
v-if="(memberInfo.nickname.indexOf('u_') != -1 && memberInfo.nickname == memberInfo.username) || memberInfo.nickname == memberInfo.mobile">
|
||||||
<view class="nickname"><text class="name" @click="getWxAuth">点击授权头像昵称</text></view>
|
<view class="nickname"><text class="name" @tap.stop="getWxAuth">点击授权头像昵称</text></view>
|
||||||
</block>
|
</block>
|
||||||
<view class="nickname" v-else>
|
<view class="nickname" v-else>
|
||||||
<text class="name" @click="getWxAuth">{{ memberInfo.nickname }}</text>
|
<text class="name" @tap.stop="getWxAuth">{{ memberInfo.nickname }}</text>
|
||||||
<view class="member-level"
|
<view class="member-level"
|
||||||
v-if="(value.style == 1 || value.style == 2) && memberInfo.member_level">
|
v-if="(value.style == 1 || value.style == 2) && memberInfo.member_level">
|
||||||
<!-- <text class="icondiy icon-system-huangguan"></text> -->
|
<!-- <text class="icondiy icon-system-huangguan"></text> -->
|
||||||
@@ -36,10 +36,10 @@
|
|||||||
<!-- #ifdef H5 -->
|
<!-- #ifdef H5 -->
|
||||||
<block
|
<block
|
||||||
v-if="$util.isWeiXin() && ((memberInfo.nickname.indexOf('u_') != -1 && memberInfo.nickname == memberInfo.username) || memberInfo.nickname == memberInfo.mobile)">
|
v-if="$util.isWeiXin() && ((memberInfo.nickname.indexOf('u_') != -1 && memberInfo.nickname == memberInfo.username) || memberInfo.nickname == memberInfo.mobile)">
|
||||||
<view class="nickname"><text class="name" @click="getWxAuth">点击获取微信头像</text></view>
|
<view class="nickname"><text class="name" @tap.stop="getWxAuth">点击获取微信头像</text></view>
|
||||||
</block>
|
</block>
|
||||||
<view class="nickname" v-else>
|
<view class="nickname" v-else>
|
||||||
<text class="name" @click="redirect('/pages_tool/member/info')">{{ memberInfo.nickname
|
<text class="name" @tap.stop="redirect('/pages_tool/member/info')">{{ memberInfo.nickname
|
||||||
}}</text>
|
}}</text>
|
||||||
<view class="member-level"
|
<view class="member-level"
|
||||||
v-if="(value.style == 1 || value.style == 2) && memberInfo.member_level">
|
v-if="(value.style == 1 || value.style == 2) && memberInfo.member_level">
|
||||||
@@ -61,12 +61,12 @@
|
|||||||
</view>
|
</view>
|
||||||
<view v-if="ischina == 1"
|
<view v-if="ischina == 1"
|
||||||
style="background: #fff;height: 60rpx;width: 60rpx;border-radius: 50rpx;line-height:65rpx;text-align: center;color:#000"
|
style="background: #fff;height: 60rpx;width: 60rpx;border-radius: 50rpx;line-height:65rpx;text-align: center;color:#000"
|
||||||
@click.stop="modifyInfo()">{{ langIndex == 0 ? 'CN' : 'EN' }}</view>
|
@tap.stop="modifyInfo()">{{ langIndex == 0 ? 'CN' : 'EN' }}</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="info-wrap" v-else :style="infoStyle" @click="redirect('/pages/member/index')">
|
<view class="info-wrap" v-else :style="infoStyle" @tap.stop="redirect($util.MEMBER_PAGE_URL)">
|
||||||
<view class="headimg">
|
<view class="headimg">
|
||||||
<image :src="$util.getDefaultImage().head" mode="widthFix"></image>
|
<image :src="$util.getDefaultImage().head" mode="widthFix" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<view class="nickname"><text class="name">{{ $lang('login') }}</text></view>
|
<view class="nickname"><text class="name">{{ $lang('login') }}</text></view>
|
||||||
@@ -75,12 +75,12 @@
|
|||||||
|
|
||||||
<view v-if="ischina == 1"
|
<view v-if="ischina == 1"
|
||||||
style="background: #fff;height: 60rpx;width: 60rpx;border-radius: 50rpx;line-height:65rpx;text-align: center;color:#000"
|
style="background: #fff;height: 60rpx;width: 60rpx;border-radius: 50rpx;line-height:65rpx;text-align: center;color:#000"
|
||||||
@click.stop="modifyInfo()">{{ langIndex == 0 ? 'CN' : 'EN' }}</view>
|
@tap.stop="modifyInfo()">{{ langIndex == 0 ? 'CN' : 'EN' }}</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="account-info" v-show="value.style == 1"
|
<view class="account-info" v-show="value.style == 1"
|
||||||
:style="{ 'margin-left': parseInt(value.infoMargin) * 2 + 'rpx', 'margin-right': parseInt(value.infoMargin) * 2 + 'rpx' }">
|
:style="{ 'margin-left': parseInt(value.infoMargin) * 2 + 'rpx', 'margin-right': parseInt(value.infoMargin) * 2 + 'rpx' }">
|
||||||
<view class="account-item" @click="redirect('/pages_tool/member/balance')">
|
<view class="account-item" @tap.stop="redirect('/pages_tool/member/balance')">
|
||||||
<view class="value price-font">
|
<view class="value price-font">
|
||||||
{{ memberInfo ? (parseFloat(memberInfo.balance) +
|
{{ memberInfo ? (parseFloat(memberInfo.balance) +
|
||||||
parseFloat(memberInfo.balance_money)).toFixed(2) : '--' }}
|
parseFloat(memberInfo.balance_money)).toFixed(2) : '--' }}
|
||||||
@@ -88,12 +88,12 @@
|
|||||||
<view class="title">{{ $lang('balance') }}</view>
|
<view class="title">{{ $lang('balance') }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="solid"></view>
|
<view class="solid"></view>
|
||||||
<view class="account-item" @click="redirect('/pages_tool/member/point_detail')">
|
<view class="account-item" @tap.stop="redirect('/pages_tool/member/point_detail')">
|
||||||
<view class="value price-font">{{ memberInfo ? parseFloat(memberInfo.point) : '--' }}</view>
|
<view class="value price-font">{{ memberInfo ? parseFloat(memberInfo.point) : '--' }}</view>
|
||||||
<view class="title">{{ $lang('point') }}</view>
|
<view class="title">{{ $lang('point') }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="solid"></view>
|
<view class="solid"></view>
|
||||||
<view class="account-item" @click="redirect('/pages_tool/member/coupon')">
|
<view class="account-item" @tap.stop="redirect('/pages_tool/member/coupon')">
|
||||||
<view class="value price-font">
|
<view class="value price-font">
|
||||||
{{ memberInfo && memberInfo.coupon_num != undefined ? memberInfo.coupon_num : '--' }}
|
{{ memberInfo && memberInfo.coupon_num != undefined ? memberInfo.coupon_num : '--' }}
|
||||||
</view>
|
</view>
|
||||||
@@ -110,19 +110,19 @@
|
|||||||
<text>超级会员</text>
|
<text>超级会员</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="super-text">
|
<view class="super-text">
|
||||||
<text class="see" v-if="memberInfo && memberInfo.member_level_type" @click="redirectBeforeAuth('/pages_tool/member/card')">查看特权</text>
|
<text class="see" v-if="memberInfo && memberInfo.member_level_type" @tap.stop="redirectBeforeAuth('/pages_tool/member/card')">查看特权</text>
|
||||||
<text class="see" v-else @click="redirectBeforeAuth('/pages_tool/member/card_buy')">会员可享更多权益</text>
|
<text class="see" v-else @tap.stop="redirectBeforeAuth('/pages_tool/member/card_buy')">会员可享更多权益</text>
|
||||||
<text class="iconfont icon-right"></text>
|
<text class="iconfont icon-right"></text>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<block v-if="value.style == 3">
|
<block v-if="value.style == 3">
|
||||||
<view class="super-info">
|
<view class="super-info">
|
||||||
<image :src="$util.img('public/uniapp/member/open_member.png')" class="title" mode="heightFix" />
|
<image :src="$util.img('public/uniapp/member/open_member.png')" class="title" mode="heightFix" show-menu-by-longpress/>
|
||||||
<view class="desc">开通可享更多权益</view>
|
<view class="desc">开通可享更多权益</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="super-text">
|
<view class="super-text">
|
||||||
<text class="see" v-if="memberInfo && memberInfo.member_level_type" @click="redirectBeforeAuth('/pages_tool/member/card')">查看特权</text>
|
<text class="see" v-if="memberInfo && memberInfo.member_level_type" @tap.stop="redirectBeforeAuth('/pages_tool/member/card')">查看特权</text>
|
||||||
<text class="see" v-else @click="redirectBeforeAuth('/pages_tool/member/card_buy')">立即开通</text>
|
<text class="see" v-else @tap.stop="redirectBeforeAuth('/pages_tool/member/card_buy')">立即开通</text>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
@@ -130,29 +130,29 @@
|
|||||||
<view class="member-info-style4" v-show="value.style == 4">
|
<view class="member-info-style4" v-show="value.style == 4">
|
||||||
<view class="super-member" v-if="superMember" :style="superMemberStyle">
|
<view class="super-member" v-if="superMember" :style="superMemberStyle">
|
||||||
<view class="super-info">
|
<view class="super-info">
|
||||||
<image :src="$util.img('app/component/view/member_info/img/style_4_vip_huangguan.png')" class="title" mode="widthFix" />
|
<image :src="$util.img('app/component/view/member_info/img/style_4_vip_huangguan.png')" class="title" mode="widthFix" show-menu-by-longpress/>
|
||||||
<view class="desc">开通可享更多权益</view>
|
<view class="desc">开通可享更多权益</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="super-text" :class="{ 'more' : memberInfo && memberInfo.member_level_type }">
|
<view class="super-text" :class="{ 'more' : memberInfo && memberInfo.member_level_type }">
|
||||||
<text class="see" v-if="memberInfo && memberInfo.member_level_type" @click="redirectBeforeAuth('/pages_tool/member/card')">查看更多权益</text>
|
<text class="see" v-if="memberInfo && memberInfo.member_level_type" @tap.stop="redirectBeforeAuth('/pages_tool/member/card')">查看更多权益</text>
|
||||||
<text class="see" v-else @click="redirectBeforeAuth('/pages_tool/member/card_buy')">立即开通</text>
|
<text class="see" v-else @tap.stop="redirectBeforeAuth('/pages_tool/member/card_buy')">立即开通</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="account-info" :style="{ 'margin-left': parseInt(value.infoMargin) * 2 + 'rpx', 'margin-right': parseInt(value.infoMargin) * 2 + 'rpx' }">
|
<view class="account-info" :style="{ 'margin-left': parseInt(value.infoMargin) * 2 + 'rpx', 'margin-right': parseInt(value.infoMargin) * 2 + 'rpx' }">
|
||||||
<view class="account-item" @click="redirect('/pages_tool/member/balance_detail')">
|
<view class="account-item" @tap.stop="redirect('/pages_tool/member/balance_detail')">
|
||||||
<view class="value price-font">
|
<view class="value price-font">
|
||||||
{{ memberInfo ? (parseFloat(memberInfo.balance) + parseFloat(memberInfo.balance_money)).toFixed(2) : '--' }}
|
{{ memberInfo ? (parseFloat(memberInfo.balance) + parseFloat(memberInfo.balance_money)).toFixed(2) : '--' }}
|
||||||
</view>
|
</view>
|
||||||
<view class="title">余额</view>
|
<view class="title">余额</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="solid"></view>
|
<view class="solid"></view>
|
||||||
<view class="account-item" @click="redirect('/pages_tool/member/point_detail')">
|
<view class="account-item" @tap.stop="redirect('/pages_tool/member/point_detail')">
|
||||||
<view class="value price-font">{{ memberInfo ? parseFloat(memberInfo.point) : '--' }}
|
<view class="value price-font">{{ memberInfo ? parseFloat(memberInfo.point) : '--' }}
|
||||||
</view>
|
</view>
|
||||||
<view class="title">积分</view>
|
<view class="title">积分</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="solid"></view>
|
<view class="solid"></view>
|
||||||
<view class="account-item" @click="redirect('/pages_tool/member/coupon')">
|
<view class="account-item" @tap.stop="redirect('/pages_tool/member/coupon')">
|
||||||
<view class="value price-font">
|
<view class="value price-font">
|
||||||
{{ memberInfo && memberInfo.coupon_num != undefined ? memberInfo.coupon_num : '--' }}
|
{{ memberInfo && memberInfo.coupon_num != undefined ? memberInfo.coupon_num : '--' }}
|
||||||
</view>
|
</view>
|
||||||
@@ -161,7 +161,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="style4-other">
|
<view class="style4-other">
|
||||||
<view class="style4-btn-wrap">
|
<view class="style4-btn-wrap">
|
||||||
<view @click="redirect('/pages_tool/recharge/list')" class="recharge-btn">余额充值</view>
|
<view @tap.stop="redirect('/pages_tool/recharge/list')" class="recharge-btn">余额充值</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view> -->
|
</view> -->
|
||||||
@@ -169,18 +169,18 @@
|
|||||||
|
|
||||||
<view class="account-info" v-show="value.style == 2"
|
<view class="account-info" v-show="value.style == 2"
|
||||||
:style="{ 'margin-left': parseInt(value.infoMargin) * 2 + 'rpx', 'margin-right': parseInt(value.infoMargin) * 2 + 'rpx' }">
|
:style="{ 'margin-left': parseInt(value.infoMargin) * 2 + 'rpx', 'margin-right': parseInt(value.infoMargin) * 2 + 'rpx' }">
|
||||||
<view class="account-item" @click="redirect('/pages_tool/member/balance')">
|
<view class="account-item" @tap.stop="redirect('/pages_tool/member/balance')">
|
||||||
<view class="value price-font">{{ memberInfo ? (parseFloat(memberInfo.balance) +
|
<view class="value price-font">{{ memberInfo ? (parseFloat(memberInfo.balance) +
|
||||||
parseFloat(memberInfo.balance_money)).toFixed(2) : '--' }}</view>
|
parseFloat(memberInfo.balance_money)).toFixed(2) : '--' }}</view>
|
||||||
<view class="title">{{ $lang('balance') }}</view>
|
<view class="title">{{ $lang('balance') }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="solid"></view>
|
<view class="solid"></view>
|
||||||
<view class="account-item" @click="redirect('/pages_tool/member/point_detail')">
|
<view class="account-item" @tap.stop="redirect('/pages_tool/member/point_detail')">
|
||||||
<view class="value price-font">{{ memberInfo ? parseFloat(memberInfo.point) : '--' }}</view>
|
<view class="value price-font">{{ memberInfo ? parseFloat(memberInfo.point) : '--' }}</view>
|
||||||
<view class="title">{{ $lang('point') }}</view>
|
<view class="title">{{ $lang('point') }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="solid"></view>
|
<view class="solid"></view>
|
||||||
<view class="account-item" @click="redirect('/pages_tool/member/coupon')">
|
<view class="account-item" @tap.stop="redirect('/pages_tool/member/coupon')">
|
||||||
<view class="value price-font">
|
<view class="value price-font">
|
||||||
{{ memberInfo && memberInfo.coupon_num != undefined ? memberInfo.coupon_num : '--' }}
|
{{ memberInfo && memberInfo.coupon_num != undefined ? memberInfo.coupon_num : '--' }}
|
||||||
</view>
|
</view>
|
||||||
@@ -196,14 +196,14 @@
|
|||||||
<view class="head">
|
<view class="head">
|
||||||
<text class="title">获取您的昵称、头像</text>
|
<text class="title">获取您的昵称、头像</text>
|
||||||
<text class="color-tip tips">获取用户头像、昵称完善个人资料,主要用于向用户提供具有辨识度的用户中心界面</text>
|
<text class="color-tip tips">获取用户头像、昵称完善个人资料,主要用于向用户提供具有辨识度的用户中心界面</text>
|
||||||
<text class="iconfont icon-close color-tip" @click="cancelCompleteInfo"></text>
|
<text class="iconfont icon-close color-tip" @tap.stop="cancelCompleteInfo"></text>
|
||||||
</view>
|
</view>
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<view class="item-wrap">
|
<view class="item-wrap">
|
||||||
<text class="label">头像</text>
|
<text class="label">头像</text>
|
||||||
<button open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
|
<button open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
|
||||||
<image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head"
|
<image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head"
|
||||||
@error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" />
|
@error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" show-menu-by-longpress/>
|
||||||
<text class="iconfont icon-right color-tip"></text>
|
<text class="iconfont icon-right color-tip"></text>
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
@@ -218,7 +218,7 @@
|
|||||||
<button open-type="getAuthorize" scope="userInfo" @getAuthorize="aliappGetUserinfo"
|
<button open-type="getAuthorize" scope="userInfo" @getAuthorize="aliappGetUserinfo"
|
||||||
:plain="true" class="border-0">
|
:plain="true" class="border-0">
|
||||||
<image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head"
|
<image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head"
|
||||||
@error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" />
|
@error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" show-menu-by-longpress/>
|
||||||
<text class="iconfont icon-right color-tip"></text>
|
<text class="iconfont icon-right color-tip"></text>
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
@@ -227,7 +227,7 @@
|
|||||||
<input type="nickname" placeholder="请输入昵称" v-model="nickName" @blur="blurNickName" />
|
<input type="nickname" placeholder="请输入昵称" v-model="nickName" @blur="blurNickName" />
|
||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<button type="default" class="save-btn" @click="saveCompleteInfo" :disabled="isDisabled">保存</button>
|
<button type="default" class="save-btn" @tap.stop="saveCompleteInfo" :disabled="isDisabled">保存</button>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</view>
|
</view>
|
||||||
@@ -243,7 +243,7 @@ let menuButtonInfo = {};
|
|||||||
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||||
// #endif
|
// #endif
|
||||||
// 自定义会员中心——会员信息展示
|
// 自定义会员中心——会员信息展示
|
||||||
import nsContact from '@/components/ns-contact/ns-contact.vue';
|
|
||||||
import DiyMinx from './minx.js'
|
import DiyMinx from './minx.js'
|
||||||
export default {
|
export default {
|
||||||
name: 'diy-member-info',
|
name: 'diy-member-info',
|
||||||
@@ -259,9 +259,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mixins: [DiyMinx],
|
mixins: [DiyMinx],
|
||||||
components: {
|
|
||||||
nsContact
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
info: null,
|
info: null,
|
||||||
@@ -548,7 +545,7 @@ export default {
|
|||||||
*/
|
*/
|
||||||
redirectBeforeAuth(url) {
|
redirectBeforeAuth(url) {
|
||||||
if (!this.storeToken) {
|
if (!this.storeToken) {
|
||||||
this.$refs.login.open('/pages/member/index');
|
this.$refs.login.open(this.$util.MEMBER_PAGE_URL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,7 +583,7 @@ export default {
|
|||||||
url: '/wechat/api/wechat/authcode',
|
url: '/wechat/api/wechat/authcode',
|
||||||
data: {
|
data: {
|
||||||
scopes: 'snsapi_userinfo',
|
scopes: 'snsapi_userinfo',
|
||||||
redirect_url: this.$config.h5Domain + '/pages/member/index'
|
redirect_url: this.$config.h5Domain + this.$util.MEMBER_PAGE_URL
|
||||||
},
|
},
|
||||||
success: res => {
|
success: res => {
|
||||||
if (res.code >= 0) {
|
if (res.code >= 0) {
|
||||||
@@ -1383,11 +1380,11 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
|
::v-deep .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .member-info-style4 .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
|
::v-deep .member-info-style4 .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
|
||||||
background: #fff !important;
|
background: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1487,8 +1484,8 @@ export default {
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.member-complete-info-popup /deep/ .uni-popup__wrapper.bottom,
|
.member-complete-info-popup ::v-deep .uni-popup__wrapper.bottom,
|
||||||
.member-complete-info-popup /deep/ .uni-popup__wrapper.bottom .uni-popup__wrapper-box {
|
.member-complete-info-popup ::v-deep .uni-popup__wrapper.bottom .uni-popup__wrapper-box {
|
||||||
border-top-left-radius: 30rpx !important;
|
border-top-left-radius: 30rpx !important;
|
||||||
border-top-right-radius: 30rpx !important;
|
border-top-right-radius: 30rpx !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
<view data-component-name="diy-member-my-order" class="common-wrap" :style="warpCss">
|
<view data-component-name="diy-member-my-order" class="common-wrap" :style="warpCss">
|
||||||
<view class="order-wrap">
|
<view class="order-wrap">
|
||||||
<view class="status-wrap">
|
<view class="status-wrap">
|
||||||
<view class="item-wrap" @click="redirect('/pages_order/list?status=waitpay')"
|
<view class="item-wrap" @tap.stop="redirect('/pages_order/list?status=waitpay')"
|
||||||
style="margin-right: 10rpx;">
|
style="margin-right: 10rpx;">
|
||||||
<view class="icon-block">
|
<view class="icon-block">
|
||||||
<template v-if="value.style == 3">
|
<template v-if="value.style == 3">
|
||||||
<image :src="$util.img('public/uniapp/member/order/wait_pay.png')" mode="widthFix" />
|
<image :src="$util.img('public/uniapp/member/order/wait_pay.png')" mode="widthFix" show-menu-by-longpress/>
|
||||||
<view class="icon-shade"
|
<view class="icon-shade"
|
||||||
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_pay_shade.png') + ')'">
|
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_pay_shade.png') + ')'">
|
||||||
</view>
|
</view>
|
||||||
@@ -21,11 +21,11 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="title">{{ $lang('waitpay') }}</view>
|
<view class="title">{{ $lang('waitpay') }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="item-wrap" @click="redirect('/pages_order/list?status=waitsend')"
|
<view class="item-wrap" @tap.stop="redirect('/pages_order/list?status=waitsend')"
|
||||||
style="margin-right: 10rpx;">
|
style="margin-right: 10rpx;">
|
||||||
<view class="icon-block">
|
<view class="icon-block">
|
||||||
<template v-if="value.style == 3">
|
<template v-if="value.style == 3">
|
||||||
<image :src="$util.img('public/uniapp/member/order/wait_send.png')" mode="widthFix"></image>
|
<image :src="$util.img('public/uniapp/member/order/wait_send.png')" mode="widthFix" show-menu-by-longpress></image>
|
||||||
<view class="icon-shade"
|
<view class="icon-shade"
|
||||||
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_send_shade.png') + ')'">
|
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_send_shade.png') + ')'">
|
||||||
</view>
|
</view>
|
||||||
@@ -40,11 +40,11 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="title">{{ $lang('waitsend') }}</view>
|
<view class="title">{{ $lang('waitsend') }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="item-wrap" @click="redirect('/pages_order/list?status=waitconfirm')"
|
<view class="item-wrap" @tap.stop="redirect('/pages_order/list?status=waitconfirm')"
|
||||||
style="margin-right: 10rpx;">
|
style="margin-right: 10rpx;">
|
||||||
<view class="icon-block">
|
<view class="icon-block">
|
||||||
<template v-if="value.style == 3">
|
<template v-if="value.style == 3">
|
||||||
<image :src="$util.img('public/uniapp/member/order/wait_confirm.png')" mode="widthFix" />
|
<image :src="$util.img('public/uniapp/member/order/wait_confirm.png')" mode="widthFix" show-menu-by-longpress/>
|
||||||
<view class="icon-shade"
|
<view class="icon-shade"
|
||||||
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_confirm_shade.png') + ')'">
|
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_confirm_shade.png') + ')'">
|
||||||
</view>
|
</view>
|
||||||
@@ -59,11 +59,11 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="title">{{ $lang('waitconfirm') }}</view>
|
<view class="title">{{ $lang('waitconfirm') }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="item-wrap" @click="redirect('/pages_order/list?status=waitrate')"
|
<view class="item-wrap" @tap.stop="redirect('/pages_order/list?status=waitrate')"
|
||||||
style="margin-right: 10rpx;">
|
style="margin-right: 10rpx;">
|
||||||
<view class="icon-block">
|
<view class="icon-block">
|
||||||
<template v-if="value.style == 3">
|
<template v-if="value.style == 3">
|
||||||
<image :src="$util.img('public/uniapp/member/order/wait_use.png')" mode="widthFix" />
|
<image :src="$util.img('public/uniapp/member/order/wait_use.png')" mode="widthFix" show-menu-by-longpress/>
|
||||||
<view class="icon-shade"
|
<view class="icon-shade"
|
||||||
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_rate_shade.png') + ')'">
|
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_rate_shade.png') + ')'">
|
||||||
</view>
|
</view>
|
||||||
@@ -76,10 +76,10 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="title">{{ $lang('completed') }}</view>
|
<view class="title">{{ $lang('completed') }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="item-wrap" @click="redirect('/pages_tool/order/activist')">
|
<view class="item-wrap" @tap.stop="redirect('/pages_tool/order/activist')">
|
||||||
<view class="icon-block">
|
<view class="icon-block">
|
||||||
<template v-if="value.style == 3">
|
<template v-if="value.style == 3">
|
||||||
<image :src="$util.img('public/uniapp/member/order/refunding.png')" mode="widthFix" />
|
<image :src="$util.img('public/uniapp/member/order/refunding.png')" mode="widthFix" show-menu-by-longpress/>
|
||||||
<view class="icon-shade"
|
<view class="icon-shade"
|
||||||
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/refunding_shade.png') + ')'">
|
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/refunding_shade.png') + ')'">
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
<view class="merch-wrap" :style="warpCss">
|
<view class="merch-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"
|
<view :class="['item', value.ornament.type]" v-for="(item, index) in list" :key="index"
|
||||||
:style="itemCss" @click="handlerClick(item)" @tap="handlerClick(item)">
|
:style="itemCss" @tap.stop="handlerClick(item)">
|
||||||
<view class="merch-img">
|
<view class="merch-img">
|
||||||
<image class="cover-img" :src="$util.img(item.merch_image)" mode="widthFix"
|
<image class="cover-img" :src="$util.img(item.merch_image)" mode="widthFix"
|
||||||
@error="imgError(index)" />
|
@error="imgError(index)" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
<view class="info-wrap">
|
<view class="info-wrap">
|
||||||
<text class="title">{{ item.merch_name }}</text>
|
<text class="title">{{ item.merch_name }}</text>
|
||||||
@@ -25,12 +25,12 @@
|
|||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
|
|
||||||
<view class="merch-nav-item graphic" v-for="(item, index) in list" :key="index"
|
<view class="merch-nav-item graphic" v-for="(item, index) in list" :key="index"
|
||||||
:style="{ width: 100 / 4 + '%' }" @click="handlerClick(item)" @tap="handlerClick(item)">
|
:style="{ width: 100 / 4 + '%' }" @tap.stop="handlerClick(item)">
|
||||||
<view class="graphic-img" v-if="value.mode != 'text'"
|
<view class="graphic-img" v-if="value.mode != 'text'"
|
||||||
:style="{ fontSize: value.imageSize * 2 + 'rpx', width: value.imageSize * 2 + 'rpx', height: value.imageSize * 2 + 'rpx' }">
|
:style="{ fontSize: value.imageSize * 2 + 'rpx', width: value.imageSize * 2 + 'rpx', height: value.imageSize * 2 + 'rpx' }">
|
||||||
<image
|
<image
|
||||||
:src="$util.img(item.merch_image) || $util.img('public/uniapp/default_img/goods.png')"
|
:src="$util.img(item.merch_image) || $util.img('public/uniapp/default_img/goods.png')"
|
||||||
mode="aspectFill" :show-menu-by-longpress="true"
|
mode="aspectFill" show-menu-by-longpress
|
||||||
style="max-width: 80rpx; max-height: 80rpx; border-radius: 50rpx;" />
|
style="max-width: 80rpx; max-height: 80rpx; border-radius: 50rpx;" />
|
||||||
</view>
|
</view>
|
||||||
<text class="graphic-text"
|
<text class="graphic-text"
|
||||||
@@ -119,7 +119,6 @@ export default {
|
|||||||
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
|
||||||
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
|
||||||
}
|
}
|
||||||
console.log(obj)
|
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
// 子项样式
|
// 子项样式
|
||||||
@@ -140,14 +139,12 @@ export default {
|
|||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getList() {
|
getList() {
|
||||||
console.log(121)
|
|
||||||
var data = {
|
var data = {
|
||||||
num: this.value.count
|
num: this.value.count
|
||||||
};
|
};
|
||||||
console.log(this.value)
|
|
||||||
if (this.value.sources == 'diy') {
|
if (this.value.sources == 'diy') {
|
||||||
data.num = 0;
|
data.num = 0;
|
||||||
data.merch_id_arr = this.value.merchIds.toString();
|
data.merch_id_arr = this.value.merchIds.toString();
|
||||||
|
|||||||
@@ -3,13 +3,12 @@
|
|||||||
<view class="diy-notes" :style="{ backgroundColor: value.componentBgColor }">
|
<view class="diy-notes" :style="{ backgroundColor: value.componentBgColor }">
|
||||||
<view class="diy-notes-top">
|
<view class="diy-notes-top">
|
||||||
<view class="notes-title" :style="{ color: value.titleTextColor }">{{ value.title }}</view>
|
<view class="notes-title" :style="{ color: value.titleTextColor }">{{ value.title }}</view>
|
||||||
<view class="notes-more" @click="toMore()" :style="{ color: value.moreTextColor }">{{ value.more }}
|
<view class="notes-more" @tap.stop="toMore()" :style="{ color: value.moreTextColor }">{{ value.more }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<scroll-view class="diy-notes-box" scroll-x="true" show-scrollbar="true">
|
<scroll-view class="diy-notes-box" scroll-x="true" show-scrollbar="true">
|
||||||
<view class="notes-box-item" v-for="(item, i) in dataList" :key="i" @click="handlerClick(item)"
|
<view class="notes-box-item" v-for="(item, i) in dataList" :key="i" @tap.stop="handlerClick(item)" :style="notesItemStyle">
|
||||||
@tap="handlerClick(item)" :style="notesItemStyle">
|
|
||||||
<view class="notes-item" v-if="item.status == 1">
|
<view class="notes-item" v-if="item.status == 1">
|
||||||
<view class="notes-item-con">
|
<view class="notes-item-con">
|
||||||
<view class="notes-title">{{ item.note_title }}</view>
|
<view class="notes-title">{{ item.note_title }}</view>
|
||||||
@@ -26,10 +25,10 @@
|
|||||||
|
|
||||||
<view class="notes-img-wrap" :class="{ 'notes-img-wrap-list': item.cover_type == 1 }">
|
<view class="notes-img-wrap" :class="{ 'notes-img-wrap-list': item.cover_type == 1 }">
|
||||||
<image v-if="item.cover_type == 0" :src="$util.img(item.img)" @error="imageError(i)"
|
<image v-if="item.cover_type == 0" :src="$util.img(item.img)" @error="imageError(i)"
|
||||||
mode="aspectFill" class="notes-item-image" />
|
mode="aspectFill" class="notes-item-image" show-menu-by-longpress/>
|
||||||
<image v-else v-for="(imgItem, imgIndex) in item.img" :key="imgIndex"
|
<image v-else v-for="(imgItem, imgIndex) in item.img" :key="imgIndex"
|
||||||
:src="$util.img(imgItem)" @error="imageError(i)" mode="aspectFit"
|
:src="$util.img(imgItem)" @error="imageError(i)" mode="aspectFit"
|
||||||
class="notes-item-image-li" />
|
class="notes-item-image-li" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="notes-item-con">
|
<view class="notes-item-con">
|
||||||
@@ -157,7 +156,7 @@ export default {
|
|||||||
/* 点赞 */
|
/* 点赞 */
|
||||||
giveLike(noteId, index) {
|
giveLike(noteId, index) {
|
||||||
if (!this.storeToken) {
|
if (!this.storeToken) {
|
||||||
this.$refs.login.open('/pages/index/index');
|
this.$refs.login.open(this.$util.INDEX_PAGE_URL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,12 +41,12 @@
|
|||||||
<view @touchmove.prevent.stop>
|
<view @touchmove.prevent.stop>
|
||||||
<uni-popup ref="noticePopup" type="center">
|
<uni-popup ref="noticePopup" type="center">
|
||||||
<view class="notice-popup">
|
<view class="notice-popup">
|
||||||
<view class="head-wrap" @click="closeNoticePopup">
|
<view class="head-wrap" @tap.stop="closeNoticePopup">
|
||||||
<text>公告</text>
|
<text>公告</text>
|
||||||
<text class="iconfont icon-close"></text>
|
<text class="iconfont icon-close"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="content-wrap">{{ notice }}</view>
|
<view class="content-wrap">{{ notice }}</view>
|
||||||
<button type="primary" @click="closeNoticePopup">我知道了</button>
|
<button type="primary" @tap.stop="closeNoticePopup">我知道了</button>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
<!-- <text class="iconfont icon-shuaxin"></text> -->
|
<!-- <text class="iconfont icon-shuaxin"></text> -->
|
||||||
</view>
|
</view>
|
||||||
<view class="qrocde-action">
|
<view class="qrocde-action">
|
||||||
<button type="primary" @click="toLink">
|
<button type="primary" @tap.stop="toLink">
|
||||||
<text class="iconfont icon-fukuanma"></text>
|
<text class="iconfont icon-fukuanma"></text>
|
||||||
<text class="action-name">付款码</text>
|
<text class="action-name">付款码</text>
|
||||||
</button>
|
</button>
|
||||||
<button type="primary" @click="openPaymentPopup">
|
<button type="primary" @tap.stop="openPaymentPopup">
|
||||||
<text class="iconfont icon-saomafu"></text>
|
<text class="iconfont icon-saomafu"></text>
|
||||||
<text class="action-name">扫码付</text>
|
<text class="action-name">扫码付</text>
|
||||||
</button>
|
</button>
|
||||||
@@ -26,12 +26,12 @@
|
|||||||
<view @touchmove.prevent.stop>
|
<view @touchmove.prevent.stop>
|
||||||
<uni-popup ref="paymentPopup" type="center">
|
<uni-popup ref="paymentPopup" type="center">
|
||||||
<view class="payment-popup">
|
<view class="payment-popup">
|
||||||
<view class="head-wrap" @click="closePaymentPopup">
|
<view class="head-wrap" @tap.stop="closePaymentPopup">
|
||||||
<text>提示</text>
|
<text>提示</text>
|
||||||
<text class="iconfont icon-close"></text>
|
<text class="iconfont icon-close"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="content-wrap">扫码付请退出程序后直接使用微信扫一扫或返回上一页使用付款码进行支付</view>
|
<view class="content-wrap">扫码付请退出程序后直接使用微信扫一扫或返回上一页使用付款码进行支付</view>
|
||||||
<button type="primary" @click="closePaymentPopup">我知道了</button>
|
<button type="primary" @tap.stop="closePaymentPopup">我知道了</button>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</view>
|
</view>
|
||||||
@@ -75,8 +75,6 @@ export default {
|
|||||||
// 允许从相机和相册扫码,h5端不起作用
|
// 允许从相机和相册扫码,h5端不起作用
|
||||||
uni.scanCode({
|
uni.scanCode({
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
console.log('条码类型:' + res.scanType);
|
|
||||||
console.log('条码内容:' + res.result);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// #endif
|
// #endif
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
<view class="fui-picture">
|
<view class="fui-picture">
|
||||||
<view v-for="(item, index) in value.list" style="line-height: 0;">
|
<view v-for="(item, index) in value.list" style="line-height: 0;">
|
||||||
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)"
|
<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>
|
v-if="item.link.wap_url" @tap.stop="handlerClick(item)" show-menu-by-longpress></image>
|
||||||
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-else
|
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-else
|
||||||
@click="handlerClick(item)" @tap="handlerClick(item)"></image>
|
@tap.stop="handlerClick(item)" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
<!-- <view wx:if="{{!childitem.linkurl}}" bindtap="previewImg" data-src="{{childitem.imgurl}}" style="padding:{{diyitem.style.paddingtop==0?0:diyitem.style.paddingtop+'rpx'}} {{diyitem.style.paddingleft==0?0:diyitem.style.paddingleft+'rpx'}}" wx:for="{{diyitem.data}}" wx:for-index="childid" wx:for-item="childitem" wx:key="{{childid}}">
|
<!-- <view wx:if="{{!childitem.linkurl}}" bindtap="previewImg" data-src="{{childitem.imgurl}}" style="padding:{{diyitem.style.paddingtop==0?0:diyitem.style.paddingtop+'rpx'}} {{diyitem.style.paddingleft==0?0:diyitem.style.paddingleft+'rpx'}}" wx:for="{{diyitem.data}}" wx:for-index="childid" wx:for-item="childitem" wx:key="{{childid}}">
|
||||||
<image mode="widthFix" src="{{childitem.imgurl}}" style="{{bannerheight?'height:'+bannerheight+'px':'height:auto'}}"></image>
|
<image mode="widthFix" src="{{childitem.imgurl}}" style="{{bannerheight?'height:'+bannerheight+'px':'height:auto'}}"></image>
|
||||||
@@ -52,20 +52,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
previewImg(img) {
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
uni.previewImage({
|
|
||||||
current: 0,
|
|
||||||
urls: [this.$util.img(img)],
|
|
||||||
success: function (res) { },
|
|
||||||
fail: function (res) { },
|
|
||||||
complete: function (res) { },
|
|
||||||
})
|
|
||||||
// #endif
|
|
||||||
},
|
|
||||||
redirectTo(link) {
|
redirectTo(link) {
|
||||||
if (link.wap_url) {
|
if (link.wap_url) {
|
||||||
if (this.$util.getCurrRoute() == 'pages/member/index' && !this.storeToken) {
|
if (this.$util.getCurrRoute() == this.$util.MEMBER_PAGE_URL && !this.storeToken) {
|
||||||
this.$refs.login.open(link.wap_url);
|
this.$refs.login.open(link.wap_url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -77,7 +66,9 @@ export default {
|
|||||||
await this.__$emitEvent({
|
await this.__$emitEvent({
|
||||||
eventName: 'picture-tap', data: item, promiseCallback: (event, handler, awaitedResult) => {
|
eventName: 'picture-tap', data: item, promiseCallback: (event, handler, awaitedResult) => {
|
||||||
if (!awaitedResult) return;
|
if (!awaitedResult) return;
|
||||||
if (item.link.wap_url) {
|
|
||||||
|
const link = item.link;
|
||||||
|
if (link?.name || link?.wap_url || link?.appid) {
|
||||||
this.redirectTo(item.link);
|
this.redirectTo(item.link);
|
||||||
} else {
|
} else {
|
||||||
this.previewImg(item.imageUrl);
|
this.previewImg(item.imageUrl);
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
<x-skeleton data-component-name="diy-pinfan" :type="skeletonType" :loading="loading" :configs="skeletonConfig">
|
<x-skeleton data-component-name="diy-pinfan" :type="skeletonType" :loading="loading" :configs="skeletonConfig">
|
||||||
<view class="diy-pinfan" :class="[value.template, value.style]" :style="warpCss">
|
<view class="diy-pinfan" :class="[value.template, value.style]" :style="warpCss">
|
||||||
<template v-if="value.template == 'row1-of1'">
|
<template v-if="value.template == 'row1-of1'">
|
||||||
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)"
|
<view class="item" v-for="(item, index) in list" :key="index" @tap.stop="toDetail(item)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" />
|
@error="imageError(index)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="content"
|
<view class="content"
|
||||||
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
|
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
|
||||||
@@ -61,12 +61,12 @@
|
|||||||
|
|
||||||
<template v-if="value.template == 'horizontal-slide'">
|
<template v-if="value.template == 'horizontal-slide'">
|
||||||
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
|
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
|
||||||
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)"
|
<view class="item" v-for="(item, index) in list" :key="index" @tap.stop="toDetail(item)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" />
|
@error="imageError(index)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
|
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
|
||||||
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
||||||
@@ -113,11 +113,11 @@
|
|||||||
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
||||||
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
||||||
<view class="item" v-for="(item, dataIndex) in list[pageIndex]" :key="dataIndex"
|
<view class="item" v-for="(item, dataIndex) in list[pageIndex]" :key="dataIndex"
|
||||||
@click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
@tap.stop="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(dataIndex)" />
|
@error="imageError(dataIndex)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
|
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
|
||||||
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
||||||
@@ -319,7 +319,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
/deep/.uni-scroll-view ::-webkit-scrollbar {
|
::v-deep .uni-scroll-view ::-webkit-scrollbar {
|
||||||
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -328,7 +328,7 @@ export default {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/::-webkit-scrollbar {
|
::v-deep ::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
|||||||
@@ -10,18 +10,18 @@
|
|||||||
:style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }">
|
:style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }">
|
||||||
{{ value.titleStyle.leftText }}
|
{{ value.titleStyle.leftText }}
|
||||||
</view>
|
</view>
|
||||||
<image v-else class="left-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix" />
|
<image v-else class="left-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix" show-menu-by-longpress/>
|
||||||
<view class="head-content">
|
<view class="head-content">
|
||||||
<view class="img-warp">
|
<view class="img-warp">
|
||||||
<block v-if="headData && headData.member_list && headData.member_list.length">
|
<block v-if="headData && headData.member_list && headData.member_list.length">
|
||||||
<image v-for="(item, index) in headData.member_list" :key="index"
|
<image v-for="(item, index) in headData.member_list" :key="index"
|
||||||
:src="$util.img(item.member_img || 'public/static/img/default_img/square.png')"
|
:src="$util.img(item.member_img || 'public/static/img/default_img/square.png')"
|
||||||
mode="aspectFill" @error="headImageError(index)" />
|
mode="aspectFill" @error="headImageError(index)" show-menu-by-longpress/>
|
||||||
</block>
|
</block>
|
||||||
<block v-else>
|
<block v-else>
|
||||||
<image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" />
|
<image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" show-menu-by-longpress/>
|
||||||
<image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" />
|
<image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" show-menu-by-longpress/>
|
||||||
<image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" />
|
<image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" show-menu-by-longpress/>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
<view :style="{ color: value.titleStyle.textColor }">
|
<view :style="{ color: value.titleStyle.textColor }">
|
||||||
@@ -31,19 +31,19 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="head-right"
|
<view class="head-right"
|
||||||
:style="{ fontSize: value.titleStyle.moreFontSize * 2 + 'rpx', color: value.titleStyle.moreColor }"
|
:style="{ fontSize: value.titleStyle.moreFontSize * 2 + 'rpx', color: value.titleStyle.moreColor }"
|
||||||
@click="$util.redirectTo('/pages_promotion/pintuan/list')">
|
@tap.stop="$util.redirectTo('/pages_promotion/pintuan/list')">
|
||||||
<text>{{ value.titleStyle.more }}</text>
|
<text>{{ value.titleStyle.more }}</text>
|
||||||
<text class="iconfont icon-right"></text>
|
<text class="iconfont icon-right"></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<template v-if="value.template == 'row1-of1'">
|
<template v-if="value.template == 'row1-of1'">
|
||||||
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)"
|
<view class="item" v-for="(item, index) in list" :key="index" @tap.stop="toDetail(item)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" />
|
@error="imageError(index)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="content"
|
<view class="content"
|
||||||
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
|
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
|
||||||
@@ -100,12 +100,12 @@
|
|||||||
|
|
||||||
<template v-if="value.template == 'horizontal-slide'">
|
<template v-if="value.template == 'horizontal-slide'">
|
||||||
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
|
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
|
||||||
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)"
|
<view class="item" v-for="(item, index) in list" :key="index" @tap.stop="toDetail(item)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" />
|
@error="imageError(index)" show-menu-by-longpress/>
|
||||||
<view v-if="value.groupStyle.control && value.style == 'style-1'" class="num" :style="{
|
<view v-if="value.groupStyle.control && value.style == 'style-1'" class="num" :style="{
|
||||||
color: value.theme == 'diy' ? value.groupStyle.color : '',
|
color: value.theme == 'diy' ? value.groupStyle.color : '',
|
||||||
background: value.theme == 'diy' ? 'linear-gradient(to right,' + value.groupStyle.bgColorStart + ',' + value.groupStyle.bgColorEnd + ')' : ''
|
background: value.theme == 'diy' ? 'linear-gradient(to right,' + value.groupStyle.bgColorStart + ',' + value.groupStyle.bgColorEnd + ')' : ''
|
||||||
@@ -161,11 +161,11 @@
|
|||||||
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
||||||
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
||||||
<view class="item" v-for="(item, dataIndex) in list[pageIndex]" :key="dataIndex"
|
<view class="item" v-for="(item, dataIndex) in list[pageIndex]" :key="dataIndex"
|
||||||
@click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
@tap.stop="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(dataIndex)" />
|
@error="imageError(dataIndex)" show-menu-by-longpress/>
|
||||||
<view v-if="value.groupStyle.control && value.style != 'style-2'" class="num" :style="{
|
<view v-if="value.groupStyle.control && value.style != 'style-2'" class="num" :style="{
|
||||||
color: value.theme == 'diy' ? value.groupStyle.color : '',
|
color: value.theme == 'diy' ? value.groupStyle.color : '',
|
||||||
background: value.theme == 'diy' ? 'linear-gradient(to right,' + value.groupStyle.bgColorStart + ',' + value.groupStyle.bgColorEnd + ')' : ''
|
background: value.theme == 'diy' ? 'linear-gradient(to right,' + value.groupStyle.bgColorStart + ',' + value.groupStyle.bgColorEnd + ')' : ''
|
||||||
@@ -391,7 +391,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
/deep/.uni-scroll-view ::-webkit-scrollbar {
|
::v-deep .uni-scroll-view ::-webkit-scrollbar {
|
||||||
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -400,7 +400,7 @@ export default {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/::-webkit-scrollbar {
|
::v-deep ::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
<x-skeleton data-component-name="diy-presale" :type="skeletonType" :loading="loading" :configs="skeletonConfig">
|
<x-skeleton data-component-name="diy-presale" :type="skeletonType" :loading="loading" :configs="skeletonConfig">
|
||||||
<view class="diy-presale" v-if="list.length" :class="[value.template, value.style]" :style="warpCss">
|
<view class="diy-presale" v-if="list.length" :class="[value.template, value.style]" :style="warpCss">
|
||||||
<template v-if="value.template == 'row1-of1'">
|
<template v-if="value.template == 'row1-of1'">
|
||||||
<view class="item" v-for="(item, index) in list" :key="index" @click="handlerClick(item)"
|
<view class="item" v-for="(item, index) in list" :key="index" @tap.stop="handlerClick(item)"
|
||||||
@tap="handlerClick(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" />
|
@error="imageError(index)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="content"
|
<view class="content"
|
||||||
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.btnStyle.control">
|
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.btnStyle.control">
|
||||||
@@ -40,12 +40,12 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-if="value.template == 'horizontal-slide'">
|
<template v-if="value.template == 'horizontal-slide'">
|
||||||
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
|
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
|
||||||
<view class="item" v-for="(item, index) in list" :key="index" @click="handlerClick(item)"
|
<view class="item" v-for="(item, index) in list" :key="index" @tap.stop="handlerClick(item)"
|
||||||
@tap="handlerClick(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" />
|
@error="imageError(index)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
|
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
|
||||||
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
||||||
@@ -75,12 +75,11 @@
|
|||||||
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
||||||
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
:class="['swiper-item', (list.length && [list[pageIndex].length / 3] >= 1) && 'flex-between']">
|
||||||
<view class="item" v-for="(item, dataIndex) in list[pageIndex]" :key="dataIndex"
|
<view class="item" v-for="(item, dataIndex) in list[pageIndex]" :key="dataIndex"
|
||||||
@click="handlerClick(item)" @tap="handlerClick(item)" :class="[value.ornament.type]"
|
@tap.stop="handlerClick(item)" :class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
:style="goodsItemCss">
|
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(dataIndex)" />
|
@error="imageError(dataIndex)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
|
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
|
||||||
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
||||||
@@ -276,7 +275,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
/deep/.uni-scroll-view ::-webkit-scrollbar {
|
::v-deep .uni-scroll-view ::-webkit-scrollbar {
|
||||||
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -285,7 +284,7 @@ export default {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/::-webkit-scrollbar {
|
::v-deep ::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
<view class="uni-scroll-view-content">
|
<view class="uni-scroll-view-content">
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<view class="quick-nav-item" v-for="(item, index) in value.list" :key="index"
|
<view class="quick-nav-item" v-for="(item, index) in value.list" :key="index"
|
||||||
@click="handlerClick(item)" @tap="handlerClick(item)"
|
@tap.stop="handlerClick(item)"
|
||||||
:style="{ background: 'linear-gradient(to right,' + item.bgColorStart ? item.bgColorStart : '' + ',' + item.bgColorEnd ? item.bgColorEnd : '' + ')' }">
|
:style="{ background: 'linear-gradient(to right,' + item.bgColorStart ? item.bgColorStart : '' + ',' + item.bgColorEnd ? item.bgColorEnd : '' + ')' }">
|
||||||
<view class="quick-img" v-if="item.imageUrl || item.icon">
|
<view class="quick-img" v-if="item.imageUrl || item.icon">
|
||||||
<image v-if="item.iconType == 'img'"
|
<image v-if="item.iconType == 'img'"
|
||||||
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
|
||||||
mode="heightFix" :show-menu-by-longpress="true"></image>
|
mode="heightFix" show-menu-by-longpress ></image>
|
||||||
<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" :style="{ fontSize: '60rpx' }"></diy-icon>
|
:value="item.style ? item.style : null" :style="{ fontSize: '60rpx' }"></diy-icon>
|
||||||
</view>
|
</view>
|
||||||
@@ -61,7 +61,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
redirectTo(link) {
|
redirectTo(link) {
|
||||||
if (link.wap_url) {
|
if (link.wap_url) {
|
||||||
if (this.$util.getCurrRoute() == 'pages/member/index' && !this.storeToken) {
|
if (this.$util.getCurrRoute() == this.$util.MEMBER_PAGE_URL && !this.storeToken) {
|
||||||
this.$refs.login.open(link.wap_url);
|
this.$refs.login.open(link.wap_url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<view data-component-name="diy-rich-text" class="rich-text-box" :style="richTextWarpCss">
|
<view data-component-name="diy-rich-text" class="rich-text-box" :style="richTextWarpCss">
|
||||||
<rich-text :nodes="html" @click="handlerClick" @tap="handlerClick"></rich-text>
|
<rich-text :nodes="html" @tap.stop="handlerClick"></rich-text>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -8,22 +8,20 @@
|
|||||||
<!-- 1左2右 -->
|
<!-- 1左2右 -->
|
||||||
<template v-if="value.mode == 'row1-lt-of2-rt'">
|
<template v-if="value.mode == 'row1-lt-of2-rt'">
|
||||||
<view class="template-left">
|
<view class="template-left">
|
||||||
<view :class="['item', value.mode]" @click="handlerClick(value.list[0].link)"
|
<view :class="['item', value.mode]" @tap.stop="handlerClick(value.list[0].link, value.list[0].imageUrl)"
|
||||||
@tap="handlerClick(value.list[0].link)"
|
:style="{ marginRight: value.imageGap * 2 + 'rpx', width: list[0].imgWidth, height: list[0].imgHeight + 'px' }">
|
||||||
:style="{ marginRight: value.imageGap * 2 + 'rpx', width: list[0].imgWidth, height: list[0].imgHeight + 'px' }">
|
|
||||||
<image :src="$util.img(value.list[0].imageUrl)" :mode="list[0].imageMode || 'scaleToFill'"
|
<image :src="$util.img(value.list[0].imageUrl)" :mode="list[0].imageMode || 'scaleToFill'"
|
||||||
:style="list[0].pageItemStyle" :show-menu-by-longpress="true" />
|
:style="list[0].pageItemStyle" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="template-right">
|
<view class="template-right">
|
||||||
<template v-for="(item, index) in list">
|
<template v-for="(item, index) in list">
|
||||||
<template v-if="index > 0">
|
<template v-if="index > 0">
|
||||||
<view :key="index" :class="['item', value.mode]" @click="handlerClick(item.link)"
|
<view :key="index" :class="['item', value.mode]" @tap.stop="handlerClick(item.link, item.imageUrl)"
|
||||||
@tap="handlerClick(item.link)"
|
:style="{ marginBottom: value.imageGap * 2 + 'rpx', width: item.imgWidth, height: item.imgHeight + 'px' }">
|
||||||
:style="{ marginBottom: value.imageGap * 2 + 'rpx', width: item.imgWidth, height: item.imgHeight + 'px' }">
|
|
||||||
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
|
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
|
||||||
:style="item.pageItemStyle" :show-menu-by-longpress="true" />
|
:style="item.pageItemStyle" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
@@ -34,31 +32,30 @@
|
|||||||
<template v-else-if="value.mode == 'row1-lt-of1-tp-of2-bm'">
|
<template v-else-if="value.mode == 'row1-lt-of1-tp-of2-bm'">
|
||||||
<view class="template-left">
|
<view class="template-left">
|
||||||
<view :class="['item', value.mode]"
|
<view :class="['item', value.mode]"
|
||||||
:style="{ marginRight: value.imageGap * 2 + 'rpx', width: list[0].imgWidth, height: list[0].imgHeight + 'px' }"
|
:style="{ marginRight: value.imageGap * 2 + 'rpx', width: list[0].imgWidth, height: list[0].imgHeight + 'px' }"
|
||||||
@click="handlerClick(value.list[0].link)" @tap="handlerClick(value.list[0].link)">
|
@tap.stop="handlerClick(value.list[0].link, value.list[0].imageUrl)">
|
||||||
<image :src="$util.img(value.list[0].imageUrl)" :mode="list[0].imageMode || 'scaleToFill'"
|
<image :src="$util.img(value.list[0].imageUrl)" :mode="list[0].imageMode || 'scaleToFill'"
|
||||||
:style="list[0].pageItemStyle" :show-menu-by-longpress="true" />
|
:style="list[0].pageItemStyle" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="template-right">
|
<view class="template-right">
|
||||||
<view :class="['item', value.mode]"
|
<view :class="['item', value.mode]"
|
||||||
:style="{ marginBottom: value.imageGap * 2 + 'rpx', width: list[1].imgWidth, height: list[1].imgHeight + 'px' }"
|
:style="{ marginBottom: value.imageGap * 2 + 'rpx', width: list[1].imgWidth, height: list[1].imgHeight + 'px' }"
|
||||||
@click="handlerClick(value.list[1].link)" @tap="handlerClick(value.list[1].link)">
|
@tap.stop="handlerClick(value.list[1].link, value.list[1].imageUrl)">
|
||||||
<image :src="$util.img(value.list[1].imageUrl)" :mode="list[1].imageMode || 'scaleToFill'"
|
<image :src="$util.img(value.list[1].imageUrl)" :mode="list[1].imageMode || 'scaleToFill'"
|
||||||
:style="list[1].pageItemStyle" :show-menu-by-longpress="true" />
|
:style="list[1].pageItemStyle" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
<view class="template-bottom">
|
<view class="template-bottom">
|
||||||
<template v-for="(item, index) in list">
|
<template v-for="(item, index) in list">
|
||||||
<template v-if="index > 1">
|
<template v-if="index > 1">
|
||||||
<view :key="index" :class="['item', value.mode]" @click="handlerClick(item.link)"
|
<view :key="index" :class="['item', value.mode]" @tap.stop="handlerClick(item.link, item.imageUrl)" :style="{
|
||||||
@tap="handlerClick(item.link)" :style="{
|
marginRight: value.imageGap * 2 + 'rpx',
|
||||||
marginRight: value.imageGap * 2 + 'rpx',
|
width: item.imgWidth,
|
||||||
width: item.imgWidth,
|
height: item.imgHeight + 'px'
|
||||||
height: item.imgHeight + 'px'
|
}">
|
||||||
}">
|
|
||||||
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
|
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
|
||||||
:style="item.pageItemStyle" :show-menu-by-longpress="true" />
|
:style="item.pageItemStyle" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
@@ -68,10 +65,10 @@
|
|||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<view :class="['item', value.mode]" v-for="(item, index) in list" :key="index"
|
<view :class="['item', value.mode]" v-for="(item, index) in list" :key="index"
|
||||||
@click="handlerClick(item.link)" @tap="handlerClick(item.link)"
|
@tap.stop="handlerClick(item.link, item.imageUrl)"
|
||||||
:style="{ marginRight: value.imageGap * 2 + 'rpx', marginBottom: value.imageGap * 2 + 'rpx', width: item.widthStyle, height: item.imgHeight + 'px' }">
|
:style="{ marginRight: value.imageGap * 2 + 'rpx', marginBottom: value.imageGap * 2 + 'rpx', width: item.widthStyle, height: item.imgHeight + 'px' }">
|
||||||
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
|
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
|
||||||
:style="item.pageItemStyle" :show-menu-by-longpress="true" />
|
:style="item.pageItemStyle" show-menu-by-longpress />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
@@ -374,11 +371,16 @@ export default {
|
|||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
|
|
||||||
async handlerClick(link) {
|
async handlerClick(link, imageUrl) {
|
||||||
await this.__$emitEvent({
|
await this.__$emitEvent({
|
||||||
eventName: 'rubik-cube-tap', data: link, promiseCallback: (event, handler, awaitedResult) => {
|
eventName: 'rubik-cube-tap', data: link, promiseCallback: (event, handler, awaitedResult) => {
|
||||||
if (!awaitedResult) return;
|
if (!awaitedResult) return;
|
||||||
this.$util.diyRedirectTo(link);
|
|
||||||
|
if (link?.name || link?.wap_url || link?.appid) {
|
||||||
|
this.$util.diyRedirectTo(link);
|
||||||
|
} else if (imageUrl){
|
||||||
|
this.previewImg(imageUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
<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"
|
<view :class="['search-box', 'search-box-' + value.searchStyle]" :style="searchWrapCss"
|
||||||
@click="handlerSearchClick" @tap="handlerSearchClick">
|
@tap.stop="handlerSearchClick">
|
||||||
<block v-if="[1, 2].includes(value.searchStyle)">
|
<block v-if="[1, 2].includes(value.searchStyle)">
|
||||||
<view class="img" v-if="value.searchStyle == 2 && value.iconType == 'img'">
|
<view class="img" v-if="value.searchStyle == 2 && value.iconType == 'img'">
|
||||||
<image :src="$util.img(value.imageUrl)" mode="heightFix" />
|
<image :src="$util.img(value.imageUrl)" mode="heightFix" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<diy-icon class="icon" v-if="value.searchStyle == 2 && value.iconType == 'icon'" :icon="value.icon"
|
<diy-icon class="icon" v-if="value.searchStyle == 2 && value.iconType == 'icon'" :icon="value.icon"
|
||||||
:value="value.style ? value.style : 'null'"
|
:value="value.style ? value.style : 'null'"
|
||||||
@@ -14,32 +14,30 @@
|
|||||||
<input type="text" class="uni-input ns-font-size-base" maxlength="50" :placeholder="value.title"
|
<input type="text" class="uni-input ns-font-size-base" maxlength="50" :placeholder="value.title"
|
||||||
v-model="searchText" @confirm="handlerSearchClick" disabled="true"
|
v-model="searchText" @confirm="handlerSearchClick" disabled="true"
|
||||||
:placeholderStyle="placeholderStyle" />
|
:placeholderStyle="placeholderStyle" />
|
||||||
<text class="iconfont icon-sousuo3" @click.stop="handlerSearchClick" @tap="handlerSearchClick"
|
<text class="iconfont icon-sousuo3" @tap.stop="handlerSearchClick"
|
||||||
:style="{ color: value.textColor ? value.textColor : 'rgba(0,0,0,0)' }"></text>
|
:style="{ color: value.textColor ? value.textColor : 'rgba(0,0,0,0)' }"></text>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<block v-if="value.searchStyle == 3">
|
<block v-if="value.searchStyle == 3">
|
||||||
<view class="search-content" :style="inputStyle" @click.stop="handlerSearchClick"
|
<view class="search-content" :style="inputStyle"
|
||||||
@tap="handlerSearchClick">
|
@tap.stop="handlerSearchClick">
|
||||||
<text class="iconfont icon-sousuo3"
|
<text class="iconfont icon-sousuo3"
|
||||||
:style="{ color: value.textColor ? value.textColor : 'rgba(0,0,0,0)' }"></text>
|
:style="{ color: value.textColor ? value.textColor : 'rgba(0,0,0,0)' }"></text>
|
||||||
<input type="text" class="uni-input ns-font-size-base" maxlength="50" :placeholder="value.title"
|
<input type="text" class="uni-input ns-font-size-base" maxlength="50" :placeholder="value.title"
|
||||||
v-model="searchText" @confirm="handlerSearchClick" disabled="true"
|
v-model="searchText" @confirm="handlerSearchClick" disabled="true"
|
||||||
@click.stop="handlerSearchClick" @tap="handlerSearchClick"
|
@tap.stop="handlerSearchClick"
|
||||||
:placeholderStyle="placeholderStyle" />
|
:placeholderStyle="placeholderStyle" />
|
||||||
<text class="search-content-btn" @click.stop="handlerSearchClick" @tap="handlerSearchClick"
|
<text class="search-content-btn" @tap.stop="handlerSearchClick"
|
||||||
:style="{ 'backgroundColor': value.pageBgColor ? value.pageBgColor : 'rgba(0,0,0,0)' }">搜索</text>
|
:style="{ 'backgroundColor': value.pageBgColor ? value.pageBgColor : 'rgba(0,0,0,0)' }">搜索</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="img" v-if="value.iconType == 'img'"
|
<view class="img" v-if="value.iconType == 'img'"
|
||||||
@click.stop="handlerRedirectToClick(value.searchLink)"
|
@tap.stop="handlerRedirectToClick(value.searchLink)">
|
||||||
@tap="handlerRedirectToClick(value.searchLink)">
|
<image :src="$util.img(value.imageUrl)" mode="heightFix" show-menu-by-longpress/>
|
||||||
<image :src="$util.img(value.imageUrl)" mode="heightFix" />
|
|
||||||
</view>
|
</view>
|
||||||
<diy-icon class="icon" v-if="value.iconType == 'icon'" :icon="value.icon"
|
<diy-icon class="icon" v-if="value.iconType == 'icon'" :icon="value.icon"
|
||||||
:value="value.style ? value.style : 'null'"
|
:value="value.style ? value.style : 'null'"
|
||||||
:style="{ maxWidth: 30 * 2 + 'rpx', maxHeight: 30 * 2 + 'rpx' }"
|
:style="{ maxWidth: 30 * 2 + 'rpx', maxHeight: 30 * 2 + 'rpx' }"
|
||||||
@click.stop="handlerRedirectToClick(value.searchLink)"
|
@tap.stop="handlerRedirectToClick(value.searchLink)"></diy-icon>
|
||||||
@tap="handlerRedirectToClick(value.searchLink)"></diy-icon>
|
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -198,7 +196,7 @@ export default {
|
|||||||
},
|
},
|
||||||
redirectTo(link) {
|
redirectTo(link) {
|
||||||
if (link.wap_url) {
|
if (link.wap_url) {
|
||||||
if (this.$util.getCurrRoute() == 'pages/member/index' && !this.storeToken) {
|
if (this.$util.getCurrRoute() == this.$util.MEMBER_PAGE_URL && !this.storeToken) {
|
||||||
this.$refs.login.open(link.wap_url);
|
this.$refs.login.open(link.wap_url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -257,7 +255,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
/deep/ .uni-input-placeholder {
|
::v-deep .uni-input-placeholder {
|
||||||
overflow: initial;
|
overflow: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
:style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }">
|
:style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }">
|
||||||
{{ value.titleStyle.leftText }}
|
{{ value.titleStyle.leftText }}
|
||||||
</view>
|
</view>
|
||||||
<image v-else class="title-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix" />
|
<image v-else class="title-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix" show-menu-by-longpress/>
|
||||||
<text v-if="value.titleStyle.style == 'style-2' && isFuture"
|
<text v-if="value.titleStyle.style == 'style-2' && isFuture"
|
||||||
:style="{ color: value.titleStyle.textColor }" class="seckill-style-name">距离开始</text>
|
:style="{ color: value.titleStyle.textColor }" class="seckill-style-name">距离开始</text>
|
||||||
<view class="time" :style="{ background: value.titleStyle.timeBgColor }">
|
<view class="time" :style="{ background: value.titleStyle.timeBgColor }">
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="marketimg-box-title-right" v-if="value.titleStyle.moreSupport"
|
<view class="marketimg-box-title-right" v-if="value.titleStyle.moreSupport"
|
||||||
:style="{ fontSize: value.titleStyle.moreFontSize * 2 + 'rpx', color: value.titleStyle.moreColor }"
|
:style="{ fontSize: value.titleStyle.moreFontSize * 2 + 'rpx', color: value.titleStyle.moreColor }"
|
||||||
@click="toMore">
|
@tap.stop="toMore">
|
||||||
<text>{{ value.titleStyle.more }}</text>
|
<text>{{ value.titleStyle.more }}</text>
|
||||||
<text class="iconfont icon-right"></text>
|
<text class="iconfont icon-right"></text>
|
||||||
</view>
|
</view>
|
||||||
@@ -35,12 +35,12 @@
|
|||||||
|
|
||||||
<view class="content-wrap">
|
<view class="content-wrap">
|
||||||
<template v-if="value.template == 'row1-of1'">
|
<template v-if="value.template == 'row1-of1'">
|
||||||
<view class="item" v-for="(item, index) in dataList" :key="index" @click="toDetail(item.id)"
|
<view class="item" v-for="(item, index) in dataList" :key="index" @tap.stop="toDetail(item.id)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" />
|
@error="imageError(index)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="goods-name" v-if="value.goodsNameStyle.control"
|
<view class="goods-name" v-if="value.goodsNameStyle.control"
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
}">
|
}">
|
||||||
<image v-if="value.style == 'style-2'" class="progress-bar"
|
<image v-if="value.style == 'style-2'" class="progress-bar"
|
||||||
:src="$util.img('public/uniapp/seckill/progress_bar_01.png')"
|
:src="$util.img('public/uniapp/seckill/progress_bar_01.png')"
|
||||||
mode="widthFix" />
|
mode="widthFix" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="num"
|
<view class="num"
|
||||||
@@ -105,12 +105,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="value.template == 'row1-of2'">
|
<template v-if="value.template == 'row1-of2'">
|
||||||
<view class="item" v-for="(item, index) in dataList" :key="index" @click="toDetail(item.id)"
|
<view class="item" v-for="(item, index) in dataList" :key="index" @tap.stop="toDetail(item.id)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" />
|
@error="imageError(index)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="content" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
<view class="content" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
||||||
<view class="goods-name" v-if="value.goodsNameStyle.control"
|
<view class="goods-name" v-if="value.goodsNameStyle.control"
|
||||||
@@ -150,12 +150,12 @@
|
|||||||
<template v-if="value.template == 'horizontal-slide'">
|
<template v-if="value.template == 'horizontal-slide'">
|
||||||
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true"
|
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true"
|
||||||
:show-scrollbar="false">
|
:show-scrollbar="false">
|
||||||
<view class="item" v-for="(item, index) in dataList" :key="index" @click="toDetail(item.id)"
|
<view class="item" v-for="(item, index) in dataList" :key="index" @tap.stop="toDetail(item.id)"
|
||||||
:class="[value.ornament.type]" :style="goodsItemCss">
|
:class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(index)" />
|
@error="imageError(index)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="content" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
<view class="content" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
||||||
<view class="goods-name" v-if="value.goodsNameStyle.control"
|
<view class="goods-name" v-if="value.goodsNameStyle.control"
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
<view class="discount-price" v-if="value.priceStyle.mainControl">
|
<view class="discount-price" v-if="value.priceStyle.mainControl">
|
||||||
<image v-if="value.style == 'style-2'" class="tag"
|
<image v-if="value.style == 'style-2'" class="tag"
|
||||||
:src="$util.img('addon/seckill/component/view/seckill/img/style_4_tag.png')"
|
:src="$util.img('addon/seckill/component/view/seckill/img/style_4_tag.png')"
|
||||||
mode="widthFix" />
|
mode="widthFix" show-menu-by-longpress/>
|
||||||
<text class="unit price-style small"
|
<text class="unit price-style small"
|
||||||
:style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">¥</text>
|
:style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">¥</text>
|
||||||
<text class="price price-style large"
|
<text class="price price-style large"
|
||||||
@@ -190,11 +190,11 @@
|
|||||||
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex"
|
||||||
:class="['swiper-item', dataList[pageIndex] && [dataList[pageIndex].length / 3].length >= 1 && 'flex-between']">
|
:class="['swiper-item', dataList[pageIndex] && [dataList[pageIndex].length / 3].length >= 1 && 'flex-between']">
|
||||||
<view class="item" v-for="(item, dataIndex) in dataList[pageIndex]" :key="dataIndex"
|
<view class="item" v-for="(item, dataIndex) in dataList[pageIndex]" :key="dataIndex"
|
||||||
@click="toDetail(item.id)" :class="[value.ornament.type]" :style="goodsItemCss">
|
@tap.stop="toDetail(item.id)" :class="[value.ornament.type]" :style="goodsItemCss">
|
||||||
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
|
||||||
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
|
||||||
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
|
||||||
@error="imageError(dataIndex, pageIndex)" />
|
@error="imageError(dataIndex, pageIndex)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="content"
|
<view class="content"
|
||||||
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
|
||||||
@@ -206,7 +206,7 @@
|
|||||||
<view class="discount-price" v-if="value.priceStyle.mainControl">
|
<view class="discount-price" v-if="value.priceStyle.mainControl">
|
||||||
<image v-if="value.style == 'style-2'" class="tag"
|
<image v-if="value.style == 'style-2'" class="tag"
|
||||||
:src="$util.img('addon/seckill/component/view/seckill/img/style_4_tag.png')"
|
:src="$util.img('addon/seckill/component/view/seckill/img/style_4_tag.png')"
|
||||||
mode="widthFix" />
|
mode="widthFix" show-menu-by-longpress/>
|
||||||
<text class="unit price-style small"
|
<text class="unit price-style small"
|
||||||
:style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">¥</text>
|
:style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">¥</text>
|
||||||
<text class="price price-style large"
|
<text class="price price-style large"
|
||||||
@@ -536,7 +536,7 @@ scroll-view ::-webkit-scrollbar {
|
|||||||
touch-action: none;
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/.uni-scroll-view ::-webkit-scrollbar {
|
::v-deep .uni-scroll-view ::-webkit-scrollbar {
|
||||||
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -545,7 +545,7 @@ scroll-view ::-webkit-scrollbar {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/::-webkit-scrollbar {
|
::v-deep ::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
|
|
||||||
/deep/ .uni-scroll-view-content {
|
::v-deep .uni-scroll-view-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ export default {
|
|||||||
&.between {
|
&.between {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
/deep/.uni-scroll-view-content {
|
::v-deep .uni-scroll-view-content {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<block v-if="value.style == 1">
|
<block v-if="value.style == 1">
|
||||||
<view class="store-box store-one">
|
<view class="store-box store-one">
|
||||||
<view class="store-info">
|
<view class="store-info">
|
||||||
<view class="info-box" :style="{ color: value.textColor }" @click="toStoreList()">
|
<view class="info-box" :style="{ color: value.textColor }" @tap.stop="toStoreList()">
|
||||||
<block v-if="globalStoreInfo && globalStoreInfo.store_id">
|
<block v-if="globalStoreInfo && globalStoreInfo.store_id">
|
||||||
<text class="title">{{ globalStoreInfo.store_name }}</text>
|
<text class="title">{{ globalStoreInfo.store_name }}</text>
|
||||||
<text>
|
<text>
|
||||||
@@ -15,26 +15,26 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="address-wrap" :style="{ color: value.textColor }">
|
<view class="address-wrap" :style="{ color: value.textColor }">
|
||||||
<text class="iconfont icon-dizhi"></text>
|
<text class="iconfont icon-dizhi"></text>
|
||||||
<text v-if="globalStoreInfo && globalStoreInfo.store_id" @click="mapRoute" class="address">{{
|
<text v-if="globalStoreInfo && globalStoreInfo.store_id" @tap.stop="mapRoute" class="address">{{
|
||||||
globalStoreInfo.show_address }}</text>
|
globalStoreInfo.show_address }}</text>
|
||||||
<text v-else>获取当前位置...</text>
|
<text v-else>获取当前位置...</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="store-image" @click="selectStore()">
|
<view class="store-image" @tap.stop="selectStore()">
|
||||||
<image :src="$util.img(globalStoreInfo.store_image)"
|
<image :src="$util.img(globalStoreInfo.store_image)"
|
||||||
v-if="globalStoreInfo && globalStoreInfo.store_image" mode="aspectFill"></image>
|
v-if="globalStoreInfo && globalStoreInfo.store_image" mode="aspectFill" show-menu-by-longpress></image>
|
||||||
<image :src="$util.getDefaultImage().store" v-else mode="aspectFill"></image>
|
<image :src="$util.getDefaultImage().store" v-else mode="aspectFill" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
|
|
||||||
<block v-if="value.style == 2">
|
<block v-if="value.style == 2">
|
||||||
<view class="store-box store-three" @click="toStoreList()">
|
<view class="store-box store-three" @tap.stop="toStoreList()">
|
||||||
<view class="store-info">
|
<view class="store-info">
|
||||||
<view class="store-image" @click="selectStore()">
|
<view class="store-image" @tap.stop="selectStore()">
|
||||||
<image :src="$util.img(globalStoreInfo.store_image)"
|
<image :src="$util.img(globalStoreInfo.store_image)"
|
||||||
v-if="globalStoreInfo && globalStoreInfo.store_image" mode="aspectFill"></image>
|
v-if="globalStoreInfo && globalStoreInfo.store_image" mode="aspectFill" show-menu-by-longpress></image>
|
||||||
<image :src="$util.getDefaultImage().store" v-else mode="aspectFill"></image>
|
<image :src="$util.getDefaultImage().store" v-else mode="aspectFill" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-box" :style="{ color: value.textColor }">
|
<view class="info-box" :style="{ color: value.textColor }">
|
||||||
<block v-if="globalStoreInfo && globalStoreInfo.store_id">
|
<block v-if="globalStoreInfo && globalStoreInfo.store_id">
|
||||||
@@ -47,13 +47,13 @@
|
|||||||
<text class="title" v-else>定位中...</text>
|
<text class="title" v-else>定位中...</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="store-icon" @click.stop="search()"><text class="iconfont icon-sousuo3"
|
<view class="store-icon" @tap.stop="search()"><text class="iconfont icon-sousuo3"
|
||||||
:style="{ color: value.textColor }"></text></view>
|
:style="{ color: value.textColor }"></text></view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
|
|
||||||
<block v-if="value.style == 3">
|
<block v-if="value.style == 3">
|
||||||
<view class="store-box store-four" @click="toStoreList()">
|
<view class="store-box store-four" @tap.stop="toStoreList()">
|
||||||
<view class="store-left-wrap">
|
<view class="store-left-wrap">
|
||||||
<block v-if="globalStoreInfo && globalStoreInfo.store_id">
|
<block v-if="globalStoreInfo && globalStoreInfo.store_id">
|
||||||
<text class="iconfont icon-weizhi" :style="{ color: value.textColor }"></text>
|
<text class="iconfont icon-weizhi" :style="{ color: value.textColor }"></text>
|
||||||
@@ -64,8 +64,8 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="store-right-search">
|
<view class="store-right-search">
|
||||||
<input type="text" class="uni-input font-size-tag" disabled placeholder="商品搜索"
|
<input type="text" class="uni-input font-size-tag" disabled placeholder="商品搜索"
|
||||||
@click.stop="search()" />
|
@tap.stop="search()" />
|
||||||
<text class="iconfont icon-sousuo3" @click.stop="search()"></text>
|
<text class="iconfont icon-sousuo3" @tap.stop="search()"></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
|
|||||||
1287
components-diy/diy-tab.vue
Normal file
1287
components-diy/diy-tab.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view data-component-name="diy-text" class="diy-text" @click="handlerClick(value.link)"
|
<view data-component-name="diy-text" class="diy-text" @tap="handlerClick(value.link)" :style="warpCss">
|
||||||
@tap="handlerClick(value.link)" :style="warpCss">
|
|
||||||
<view :class="value.style == 'style-8' ? 'title2' : 'title'"
|
<view :class="value.style == 'style-8' ? 'title2' : 'title'"
|
||||||
:style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor }">
|
: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;">
|
||||||
@@ -90,23 +89,23 @@
|
|||||||
<view class="style9-box">
|
<view class="style9-box">
|
||||||
<view class="style9-center">
|
<view class="style9-center">
|
||||||
<view class="left-img">
|
<view class="left-img">
|
||||||
<image :src="$util.img('public/uniapp/diy/style9-1.png')" />
|
<image :src="$util.img('public/uniapp/diy/style9-1.png')" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<text class="style9-title"
|
<text class="style9-title"
|
||||||
:style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor, fontWeight: value.fontWeight }">
|
:style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor, fontWeight: value.fontWeight }">
|
||||||
{{ value.text }}
|
{{ value.text }}
|
||||||
</text>
|
</text>
|
||||||
<view class="right-img">
|
<view class="right-img">
|
||||||
<image :src="$util.img('public/uniapp/diy/style9-2.png')" />
|
<image :src="$util.img('public/uniapp/diy/style9-2.png')" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
<view class="style9-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
|
<view class="style9-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
|
||||||
@click.stop="handlerClick(value.more.link)" @tap="handlerClick(value.more.link)">
|
@tap.stop="handlerClick(value.more.link)">
|
||||||
{{ value.more.text }}
|
{{ value.more.text }}
|
||||||
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view>
|
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<text class="sub-title" :style="{ color: value.subTitle.color }">{{ value.subTitle.text
|
<text class="sub-title" :style="{ color: value.subTitle.color }">{{ value.subTitle.text
|
||||||
}}</text>
|
}}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
@@ -115,7 +114,7 @@
|
|||||||
<view class="style10-box">
|
<view class="style10-box">
|
||||||
<view class="style10-center">
|
<view class="style10-center">
|
||||||
<view class="left-img">
|
<view class="left-img">
|
||||||
<image :src="$util.img('public/uniapp/diy/style10-1.png')"></image>
|
<image :src="$util.img('public/uniapp/diy/style10-1.png')" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
<text class="style10-title" v-if="$util.img('public/uniapp/diy/style10-3.png')" :style="{
|
<text class="style10-title" v-if="$util.img('public/uniapp/diy/style10-3.png')" :style="{
|
||||||
backgroundImage: 'url(' + $util.img('public/uniapp/diy/style10-3.png') + ')',
|
backgroundImage: 'url(' + $util.img('public/uniapp/diy/style10-3.png') + ')',
|
||||||
@@ -129,16 +128,16 @@
|
|||||||
{{ value.text }}
|
{{ value.text }}
|
||||||
</text>
|
</text>
|
||||||
<view class="right-img">
|
<view class="right-img">
|
||||||
<image :src="$util.img('public/uniapp/diy/style10-2.png')"></image>
|
<image :src="$util.img('public/uniapp/diy/style10-2.png')" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="style10-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
|
<view class="style10-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
|
||||||
@click.stop="handlerClick(value.more.link)" @tap="handlerClick(value.more.link)">
|
@tap.stop="handlerClick(value.more.link)">
|
||||||
{{ value.more.text }}
|
{{ value.more.text }}
|
||||||
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view>
|
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<text class="sub-title" :style="{ color: value.subTitle.color }">{{ value.subTitle.text
|
<text class="sub-title" :style="{ color: value.subTitle.color }">{{ value.subTitle.text
|
||||||
}}</text>
|
}}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
@@ -159,16 +158,16 @@
|
|||||||
value.subTitle.text }}</view>
|
value.subTitle.text }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="style11-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
|
<view class="style11-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
|
||||||
@click.stop="$util.diyRedirectTo(value.more.link)">
|
@tap.stop="$util.diyRedirectTo(value.more.link)">
|
||||||
{{ value.more.text }}
|
{{ value.more.text }}
|
||||||
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view>
|
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<image class="center-img" :src="$util.img('public/uniapp/diy/style11-1.png')"
|
<image class="center-img" :src="$util.img('public/uniapp/diy/style11-1.png')"
|
||||||
mode="widthFix"></image>
|
mode="widthFix" show-menu-by-longpress></image>
|
||||||
|
|
||||||
<image class="right-img" :src="$util.img('public/uniapp/diy/style11-2.png')"
|
<image class="right-img" :src="$util.img('public/uniapp/diy/style11-2.png')"
|
||||||
mode="widthFix"></image>
|
mode="widthFix" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -183,15 +182,15 @@
|
|||||||
{{ value.text }}
|
{{ value.text }}
|
||||||
</view>
|
</view>
|
||||||
<text class="style12-sub-title" :style="{ color: value.subTitle.color }">{{ value.subTitle.text
|
<text class="style12-sub-title" :style="{ color: value.subTitle.color }">{{ value.subTitle.text
|
||||||
}}</text>
|
}}</text>
|
||||||
<view class="style12-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
|
<view class="style12-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
|
||||||
@click.stop="$util.diyRedirectTo(value.more.link)">
|
@tap.stop="$util.diyRedirectTo(value.more.link)">
|
||||||
<text>{{ value.more.text }}</text>
|
<text>{{ value.more.text }}</text>
|
||||||
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view>
|
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="style13" v-else-if="value.style == 'style-13'">
|
<view class="style13" v-else-if="value.style == 'style-13'">
|
||||||
<image class="left-img" :src="$util.img('public/uniapp/diy/style13-1.png')" mode="widthFix"></image>
|
<image class="left-img" :src="$util.img('public/uniapp/diy/style13-1.png')" mode="widthFix" show-menu-by-longpress></image>
|
||||||
<view class="style13-title" :style="{
|
<view class="style13-title" :style="{
|
||||||
fontSize: value.fontSize * 2 + 'rpx',
|
fontSize: value.fontSize * 2 + 'rpx',
|
||||||
color: value.textColor,
|
color: value.textColor,
|
||||||
@@ -199,7 +198,7 @@
|
|||||||
}">
|
}">
|
||||||
{{ value.text }}
|
{{ value.text }}
|
||||||
</view>
|
</view>
|
||||||
<image class="right-img" :src="$util.img('public/uniapp/diy/style13-1.png')" mode="widthFix"></image>
|
<image class="right-img" :src="$util.img('public/uniapp/diy/style13-1.png')" mode="widthFix" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="style14" v-else-if="value.style == 'style-14'">
|
<view class="style14" v-else-if="value.style == 'style-14'">
|
||||||
<view class="title-wrap">
|
<view class="title-wrap">
|
||||||
@@ -278,7 +277,7 @@
|
|||||||
<text :style="{ fontWeight: value.subTitle.fontWeight }">{{ value.subTitle.text }}</text>
|
<text :style="{ fontWeight: value.subTitle.fontWeight }">{{ value.subTitle.text }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="style16-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
|
<view class="style16-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
|
||||||
@click.stop="$util.diyRedirectTo(value.more.link)">
|
@tap.stop="$util.diyRedirectTo(value.more.link)">
|
||||||
<text>{{ value.more.text }}</text>
|
<text>{{ value.more.text }}</text>
|
||||||
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view>
|
<view class="iconfont icon-right" :style="{ color: value.more.color }"></view>
|
||||||
</view>
|
</view>
|
||||||
@@ -324,7 +323,7 @@ export default {
|
|||||||
await this.__$emitEvent({
|
await this.__$emitEvent({
|
||||||
eventName: 'text-tap', data: link, promiseCallback: (event, handler, awaitedResult) => {
|
eventName: 'text-tap', data: link, promiseCallback: (event, handler, awaitedResult) => {
|
||||||
if (!awaitedResult) return;
|
if (!awaitedResult) return;
|
||||||
$util.diyRedirectTo(link);
|
this.$util.diyRedirectTo(link);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
<view v-for="(item, index) in value.list" :key="index" class="goods-item" @tap="showVideo(item)">
|
<view v-for="(item, index) in value.list" :key="index" class="goods-item" @tap="showVideo(item)">
|
||||||
<view class="goods-img-wrap">
|
<view class="goods-img-wrap">
|
||||||
<image class="goods-img" style="border-radius:10rpx 10rpx 0 0;" :src="$util.img(item.imageUrl)"
|
<image class="goods-img" style="border-radius:10rpx 10rpx 0 0;" :src="$util.img(item.imageUrl)"
|
||||||
mode="widthFix" @error="imgError(index)"></image>
|
mode="widthFix" @error="imgError(index)" show-menu-by-longpress ></image>
|
||||||
<view style="position:absolute;top:10rpx;right:10rpx;">
|
<view style="position:absolute;top:10rpx;right:10rpx;">
|
||||||
<image style="width:30rpx;" :src="$util.img('addon/personnel/shop/view/enterprise/play.png')"
|
<image style="width:30rpx;" :src="$util.img('addon/personnel/shop/view/enterprise/play.png')"
|
||||||
mode="widthFix"></image>
|
mode="widthFix" show-menu-by-longpress ></image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="info-wrap">
|
<view class="info-wrap">
|
||||||
@@ -34,10 +34,10 @@
|
|||||||
'max-height': '200rpx;',
|
'max-height': '200rpx;',
|
||||||
'border-radius': '8rpx;'
|
'border-radius': '8rpx;'
|
||||||
}" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')" mode="widthFix"
|
}" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')" mode="widthFix"
|
||||||
:show-menu-by-longpress="true"></image>
|
show-menu-by-longpress ></image>
|
||||||
<view style="position:absolute;top:10rpx;right:10rpx;">
|
<view style="position:absolute;top:10rpx;right:10rpx;">
|
||||||
<image style="width:30rpx;"
|
<image style="width:30rpx;"
|
||||||
:src="$util.img('addon/personnel/shop/view/enterprise/play.png')" mode="widthFix">
|
:src="$util.img('addon/personnel/shop/view/enterprise/play.png')" mode="widthFix" show-menu-by-longpress >
|
||||||
</image>
|
</image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -53,22 +53,29 @@
|
|||||||
|
|
||||||
<!-- 视频播放弹窗 -->
|
<!-- 视频播放弹窗 -->
|
||||||
<uni-popup ref="videoPopup" type="center" style="background:transparent;width:100%;height:100%;">
|
<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;">
|
<view class="video-container" :style="popupVideoStyle">
|
||||||
<video class="adaptive-video" :autoPauseIfNavigate="true" :autoPauseIfOpenNative="true"
|
<video
|
||||||
:autoplay="false" :enableAutoRotation="true" id="myVideo" :src="video_url" :controls="true"></video>
|
ref="popupVideoRef"
|
||||||
|
class="adaptive-video"
|
||||||
|
:autoPauseIfNavigate="true"
|
||||||
|
:autoPauseIfOpenNative="true"
|
||||||
|
:autoplay="false"
|
||||||
|
:enableAutoRotation="true"
|
||||||
|
id="myVideo"
|
||||||
|
:src="video_url"
|
||||||
|
:controls="true"
|
||||||
|
@loadedmetadata="onPopupVideoLoaded"
|
||||||
|
></video>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import uniPopup from '@/components/uni-popup/uni-popup.vue'
|
|
||||||
import DiyMinx from './minx.js'
|
import DiyMinx from './minx.js'
|
||||||
export default {
|
export default {
|
||||||
name: 'diy-video-list',
|
name: 'diy-video-list',
|
||||||
components: {
|
|
||||||
uniPopup
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -107,7 +114,6 @@ export default {
|
|||||||
style += 'box-shadow:' + (this.value.ornament.type == 'shadow' ? '0 0 10rpx ' + this.value.ornament.color : '') + ';';
|
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 : '') + ';';
|
style += 'border:' + (this.value.ornament.type == 'stroke' ? '2rpx solid ' + this.value.ornament.color : '') + ';';
|
||||||
|
|
||||||
console.log(this.value);
|
|
||||||
|
|
||||||
return style;
|
return style;
|
||||||
},
|
},
|
||||||
@@ -129,19 +135,76 @@ export default {
|
|||||||
isIndicatorDots() {
|
isIndicatorDots() {
|
||||||
return this.value.carousel.type != 'hide' &&
|
return this.value.carousel.type != 'hide' &&
|
||||||
1 != Math.ceil(this.value.list.length / (this.value.pageCount * this.value.rowCount));
|
1 != Math.ceil(this.value.list.length / (this.value.pageCount * this.value.rowCount));
|
||||||
|
},
|
||||||
|
|
||||||
|
// 弹窗视频容器样式
|
||||||
|
popupVideoStyle() {
|
||||||
|
let style = 'position:fixed;width:100%;left:0;';
|
||||||
|
|
||||||
|
if (this.popupVideoRatio) {
|
||||||
|
// 根据视频比例设置位置
|
||||||
|
if (this.popupVideoRatio === 'portrait') {
|
||||||
|
// 竖屏视频:居中显示,使用9/16比例
|
||||||
|
style += 'top:50%;transform:translateY(-50%);';
|
||||||
|
style += 'aspect-ratio: 9 / 16;';
|
||||||
|
} else {
|
||||||
|
// 横屏视频:靠近顶部显示,使用16/9比例
|
||||||
|
style += 'top:20%;';
|
||||||
|
style += 'aspect-ratio: 16 / 9;';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 默认:居中显示,使用竖屏比例
|
||||||
|
style += 'top:50%;transform:translateY(-50%);';
|
||||||
|
style += 'aspect-ratio: 9 / 16;';
|
||||||
|
}
|
||||||
|
|
||||||
|
return style;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 显示视频播放弹窗
|
// 显示视频播放弹窗
|
||||||
showVideo(item) {
|
showVideo(item) {
|
||||||
this.video_url = item.videoUrl;
|
this.video_url = item.videoUrl;
|
||||||
|
// 重置视频比例为null,等待新的检测结果
|
||||||
|
this.popupVideoRatio = null;
|
||||||
this.$refs.videoPopup.open();
|
this.$refs.videoPopup.open();
|
||||||
},
|
},
|
||||||
|
|
||||||
// 图片加载错误处理
|
// 图片加载错误处理
|
||||||
imgError(index) {
|
imgError(index) {
|
||||||
// 图片加载失败的处理逻辑
|
// 图片加载失败的处理逻辑
|
||||||
console.log('图片加载失败:', index);
|
},
|
||||||
|
|
||||||
|
// 弹窗视频加载完成事件
|
||||||
|
onPopupVideoLoaded(event) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
let width = 0;
|
||||||
|
let height = 0;
|
||||||
|
|
||||||
|
// H5 端:获取真实视频宽高
|
||||||
|
// #ifdef H5
|
||||||
|
const video = this.$refs.popupVideoRef;
|
||||||
|
if (video) {
|
||||||
|
width = video.videoWidth || 0;
|
||||||
|
height = video.videoHeight || 0;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// 微信小程序端:通过事件对象获取视频宽高
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
if (event && event.detail) {
|
||||||
|
width = event.detail.width || 0;
|
||||||
|
height = event.detail.height || 0;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
if (width && height) {
|
||||||
|
this.popupVideoRatio = width >= height ? 'landscape' : 'portrait';
|
||||||
|
} else {
|
||||||
|
// 获取失败,默认竖屏
|
||||||
|
this.popupVideoRatio = 'portrait';
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<video data-component-name="diy-video" class="diy-video" :src="$util.img(value.videoUrl)"
|
<view class="video-container" :style="containerStyle">
|
||||||
:poster="$util.img(value.imageUrl)" :style="videoWarpCss" objectFit="cover"
|
<!-- H5端使用原生video标签 -->
|
||||||
@click="handlerClick(value.videoUrl)" @tap="handlerClick(value.videoUrl)"></video>
|
<!-- #ifdef H5 -->
|
||||||
|
<video
|
||||||
|
ref="videoRef"
|
||||||
|
data-component-name="diy-video"
|
||||||
|
class="diy-video h5-video"
|
||||||
|
:src="videoUrl"
|
||||||
|
:poster="posterUrl"
|
||||||
|
:style="videoWarpCss"
|
||||||
|
controls
|
||||||
|
preload="metadata"
|
||||||
|
@loadedmetadata="onVideoLoaded"
|
||||||
|
@click="handlerClick(videoUrl)"
|
||||||
|
></video>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
<!-- 微信小程序端使用uni-app的video组件 -->
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<video
|
||||||
|
ref="videoRef"
|
||||||
|
data-component-name="diy-video"
|
||||||
|
class="diy-video mp-video"
|
||||||
|
:src="videoUrl"
|
||||||
|
:poster="posterUrl"
|
||||||
|
:style="videoWarpCss"
|
||||||
|
controls
|
||||||
|
@loadedmetadata="onVideoLoaded"
|
||||||
|
@error="onVideoError"
|
||||||
|
></video>
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -15,27 +44,149 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {
|
||||||
|
videoRatio: null, // 视频比例:'landscape'(横屏)或 'portrait'(竖屏)
|
||||||
|
videoUrl: '',
|
||||||
|
posterUrl: ''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.initVideoData();
|
||||||
},
|
},
|
||||||
created() { },
|
|
||||||
mixins: [DiyMinx],
|
mixins: [DiyMinx],
|
||||||
watch: {
|
watch: {
|
||||||
// 组件刷新监听
|
value: {
|
||||||
componentRefresh: function (nval) { }
|
immediate: true,
|
||||||
|
handler(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.initVideoData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
videoWarpCss: function () {
|
videoWarpCss: function () {
|
||||||
var obj = '';
|
var obj = '';
|
||||||
if (this.value.componentAngle == 'round') {
|
if (this.value && this.value.componentAngle == 'round') {
|
||||||
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
|
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
|
||||||
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
|
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
|
||||||
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
|
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
|
||||||
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
|
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
|
},
|
||||||
|
// 动态计算容器比例
|
||||||
|
containerStyle() {
|
||||||
|
let style = '';
|
||||||
|
|
||||||
|
if (this.videoRatio === 'landscape') {
|
||||||
|
// 横屏视频:16/9比例
|
||||||
|
style += 'aspect-ratio: 16 / 9;';
|
||||||
|
} else if (this.videoRatio === 'portrait') {
|
||||||
|
// 竖屏视频:9/16比例
|
||||||
|
style += 'aspect-ratio: 9 / 16;';
|
||||||
|
} else {
|
||||||
|
// 未加载完成 → 默认使用竖屏比例
|
||||||
|
style += 'aspect-ratio: 9 / 16;';
|
||||||
|
}
|
||||||
|
|
||||||
|
return style;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 初始化视频数据
|
||||||
|
initVideoData() {
|
||||||
|
this.videoUrl = this.getVideoUrl();
|
||||||
|
this.posterUrl = this.getPosterUrl();
|
||||||
|
// H5端:预加载视频获取宽高
|
||||||
|
// #ifdef H5
|
||||||
|
this.preloadVideoForRatio();
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取视频URL
|
||||||
|
getVideoUrl() {
|
||||||
|
if (!this.value || !this.value.videoUrl) return '';
|
||||||
|
const videoUrl = this.value.videoUrl;
|
||||||
|
// 如果是完整的http/https链接,直接使用
|
||||||
|
if (videoUrl.indexOf('http://') === 0 || videoUrl.indexOf('https://') === 0) {
|
||||||
|
return videoUrl;
|
||||||
|
}
|
||||||
|
// 否则使用$util.img()处理
|
||||||
|
return this.$util.img(videoUrl);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取封面图URL
|
||||||
|
getPosterUrl() {
|
||||||
|
if (!this.value || !this.value.imageUrl) return '';
|
||||||
|
return this.$util.img(this.value.imageUrl);
|
||||||
|
},
|
||||||
|
|
||||||
|
// H5端:预加载视频获取宽高比例
|
||||||
|
preloadVideoForRatio() {
|
||||||
|
const videoUrl = this.videoUrl;
|
||||||
|
if (!videoUrl) return;
|
||||||
|
|
||||||
|
const video = document.createElement('video');
|
||||||
|
video.preload = 'metadata';
|
||||||
|
video.src = videoUrl;
|
||||||
|
video.muted = true;
|
||||||
|
video.playsInline = true;
|
||||||
|
|
||||||
|
video.addEventListener('loadedmetadata', () => {
|
||||||
|
const width = video.videoWidth;
|
||||||
|
const height = video.videoHeight;
|
||||||
|
|
||||||
|
if (width && height) {
|
||||||
|
this.videoRatio = width >= height ? 'landscape' : 'portrait';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
video.addEventListener('error', (e) => {
|
||||||
|
console.error('H5端预加载视频失败:', e);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 触发加载
|
||||||
|
video.load();
|
||||||
|
},
|
||||||
|
|
||||||
|
// 视频加载完成事件(组件内video标签)
|
||||||
|
onVideoLoaded(event) {
|
||||||
|
let width = 0;
|
||||||
|
let height = 0;
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
if (event && event.target) {
|
||||||
|
width = event.target.videoWidth || 0;
|
||||||
|
height = event.target.videoHeight || 0;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
if (event && event.detail) {
|
||||||
|
width = event.detail.width || 0;
|
||||||
|
height = event.detail.height || 0;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
if (width && height) {
|
||||||
|
this.videoRatio = width >= height ? 'landscape' : 'portrait';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 视频播放事件
|
||||||
|
onVideoPlay() {
|
||||||
|
},
|
||||||
|
|
||||||
|
// 视频暂停事件
|
||||||
|
onVideoPause() {
|
||||||
|
},
|
||||||
|
|
||||||
|
// 视频错误事件
|
||||||
|
onVideoError(event) {
|
||||||
|
console.error('视频加载失败:', event);
|
||||||
|
},
|
||||||
|
|
||||||
async handlerClick(videoUrl) {
|
async handlerClick(videoUrl) {
|
||||||
await this.__$emitEvent({
|
await this.__$emitEvent({
|
||||||
eventName: 'video-tap', data: videoUrl, promiseCallback: (event, handler, awaitedResult) => {
|
eventName: 'video-tap', data: videoUrl, promiseCallback: (event, handler, awaitedResult) => {
|
||||||
@@ -48,11 +199,32 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
video {
|
.video-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.diy-video>>>.uni-video-container {
|
/* 基础样式 */
|
||||||
background-color: transparent;
|
.diy-video {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* H5端样式 */
|
||||||
|
/* #ifdef H5 */
|
||||||
|
.h5-video {
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* 微信小程序端样式 */
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
.mp-video {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
</style>
|
</style>
|
||||||
187
components-diy/js/wechat-channel.js
Normal file
187
components-diy/js/wechat-channel.js
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
// 微信视频号组件配置
|
||||||
|
export const wechatChannelConfig = {
|
||||||
|
// 图标相关
|
||||||
|
icon: {
|
||||||
|
defaultSize: 80, // 默认图标尺寸(rpx)
|
||||||
|
smallSize: 60, // 小图标尺寸(rpx)
|
||||||
|
channelArrowSize: 24, // 频道箭头图标尺寸(rpx)
|
||||||
|
channelArrow: 'addon/personnel/shop/view/enterprise/arrow.png', // 频道箭头图标路径
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// 视频相关配置
|
||||||
|
video: {
|
||||||
|
defaultHeight: 320, // 默认视频高度(rpx)
|
||||||
|
minHeight: 200, // 最小视频高度(rpx)
|
||||||
|
maxHeight: 500, // 最大视频高度(rpx)
|
||||||
|
defaultCoverUrl: 'addon/personnel/shop/view/enterprise/default-video-cover.png', // 默认视频封面
|
||||||
|
},
|
||||||
|
|
||||||
|
// 播放按钮配置
|
||||||
|
playButton: {
|
||||||
|
size: 80, // 标准尺寸(rpx)
|
||||||
|
smallSize: 60, // 小尺寸(rpx)
|
||||||
|
iconSize: 40, // 标准图标尺寸(rpx)
|
||||||
|
smallIconSize: 30, // 小图标尺寸(rpx)
|
||||||
|
background: 'rgba(0, 0, 0, 0.4)', // 背景颜色
|
||||||
|
},
|
||||||
|
|
||||||
|
// 布局配置
|
||||||
|
layout: {
|
||||||
|
borderRadius: 12, // 圆角(rpx)
|
||||||
|
padding: 16, // 内边距(rpx)
|
||||||
|
margin: 10, // 外边距(rpx)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 字体配置
|
||||||
|
font: {
|
||||||
|
channelNameSize: 28, // 频道名称字体大小(rpx)
|
||||||
|
videoTitleSize: 28, // 视频标题字体大小(rpx)
|
||||||
|
statsSize: 24, // 统计信息字体大小(rpx)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 颜色配置
|
||||||
|
color: {
|
||||||
|
channelName: '#333', // 频道名称颜色
|
||||||
|
videoTitle: '#333', // 视频标题颜色
|
||||||
|
stats: '#999', // 统计信息颜色
|
||||||
|
border: '#f0f0f0', // 边框颜色
|
||||||
|
},
|
||||||
|
|
||||||
|
// 微信相关配置
|
||||||
|
wechat: {
|
||||||
|
minSdkVersion: '2.19.2', // 最小微信基础库版本
|
||||||
|
embedComponent: 'channel-video', // 嵌入式视频组件名称
|
||||||
|
},
|
||||||
|
|
||||||
|
// 错误提示配置
|
||||||
|
error: {
|
||||||
|
notWechat: '当前环境不是微信小程序',
|
||||||
|
lowVersion: '当前微信基础库版本过低,需要 2.19.2 或以上版本',
|
||||||
|
notSupported: '当前环境不支持微信视频号',
|
||||||
|
missingFields: '缺少必要字段: {field}',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取配置项的辅助函数
|
||||||
|
export const getwechatChannelConfig = (key, defaultValue = null) => {
|
||||||
|
const keys = key.split('.');
|
||||||
|
let config = wechatChannelConfig;
|
||||||
|
|
||||||
|
for (const k of keys) {
|
||||||
|
if (config[k] === undefined) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
config = config[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 微信视频号工具函数
|
||||||
|
export const wechatChannelUtil = {
|
||||||
|
// 版本比较
|
||||||
|
versionCompare(v1, v2) {
|
||||||
|
const arr1 = v1.split('.');
|
||||||
|
const arr2 = v2.split('.');
|
||||||
|
for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) {
|
||||||
|
const num1 = parseInt(arr1[i] || 0);
|
||||||
|
const num2 = parseInt(arr2[i] || 0);
|
||||||
|
if (num1 > num2) return 1;
|
||||||
|
if (num1 < num2) return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 检查是否支持嵌入式播放
|
||||||
|
isEmbedModeSupported() {
|
||||||
|
return typeof wx !== 'undefined' && wx.canIUse(wechatChannelConfig.wechat.embedComponent);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取默认视频封面
|
||||||
|
getDefaultCoverUrl() {
|
||||||
|
return wechatChannelConfig.video.defaultCoverUrl;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 数据校验
|
||||||
|
validateVideoData(item) {
|
||||||
|
const requiredFields = ['feedId', 'finderUserName'];
|
||||||
|
for (const field of requiredFields) {
|
||||||
|
if (!item[field]) {
|
||||||
|
throw new Error(`缺少必要字段: ${field}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 播放视频
|
||||||
|
playVideo(item) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
// 数据校验
|
||||||
|
this.validateVideoData(item);
|
||||||
|
} catch (err) {
|
||||||
|
this.handleError(err, item);
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查微信环境
|
||||||
|
if (typeof wx === 'undefined') {
|
||||||
|
const err = new Error(wechatChannelConfig.error.notWechat);
|
||||||
|
this.handleError(err, item);
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查基础库版本
|
||||||
|
const systemInfo = wx.getSystemInfoSync();
|
||||||
|
const SDKVersion = systemInfo.SDKVersion;
|
||||||
|
if (this.versionCompare(SDKVersion, wechatChannelConfig.wechat.minSdkVersion) < 0) {
|
||||||
|
const err = new Error(wechatChannelConfig.error.lowVersion);
|
||||||
|
this.handleError(err, item);
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用微信视频号播放API
|
||||||
|
if (wx.openChannelsActivity) {
|
||||||
|
wx.openChannelsActivity({
|
||||||
|
feedId: item.feedId,
|
||||||
|
finderUserName: item.finderUserName,
|
||||||
|
success: (res) => {
|
||||||
|
resolve(res);
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
this.handleError(err, item);
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const err = new Error(wechatChannelConfig.error.notSupported);
|
||||||
|
this.handleError(err, item);
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 统一错误处理
|
||||||
|
handleError(err, item) {
|
||||||
|
console.error('微信视频号错误:', err);
|
||||||
|
const { message = '', errMsg = '微信视频播放失败!', errCode = -1 } = err;
|
||||||
|
|
||||||
|
// 错误码5: 表示用户点击了取消. openChannelsActivity:fail cancel
|
||||||
|
if ([5].includes(errCode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const showErrorToast = (otherMsgs = []) => {
|
||||||
|
uni.showToast({
|
||||||
|
title: [errMsg, message,...otherMsgs].join('\n'),
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
showErrorToast();
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -2,8 +2,20 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
// 异步触发事件
|
// 异步触发事件
|
||||||
async __$emitEvent(payload = {eventName: '__unnamedEvent', data: {}, promiseCallback: null}) {
|
async __$emitEvent(payload = {eventName: '__unnamedEvent', data: {}, promiseCallback: null}) {
|
||||||
// console.log('__$emitEvent', payload)
|
|
||||||
await this.$eventBus.emit(payload.eventName, payload.data, payload.promiseCallback)
|
await this.$eventBus.emit(payload.eventName, payload.data, payload.promiseCallback)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 预览图片
|
||||||
|
previewImg(img) {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
uni.previewImage({
|
||||||
|
current: 0,
|
||||||
|
urls: [this.$util.img(img)],
|
||||||
|
success: function (res) { },
|
||||||
|
fail: function (res) { },
|
||||||
|
complete: function (res) { },
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"component": true,
|
|
||||||
"usingComponents": {
|
|
||||||
"ns-loading": "../ns-loading/ns-loading"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,14 +13,14 @@
|
|||||||
<view class="message-item " :class="message.isItMe ? 'right' : 'left'">
|
<view class="message-item " :class="message.isItMe ? 'right' : 'left'">
|
||||||
<block v-if="message.isItMe">
|
<block v-if="message.isItMe">
|
||||||
<view class="head_img">
|
<view class="head_img">
|
||||||
<image class="img" :src="myHeadImg" v-if="myHeadImg" @error="myHeadImgError" mode="aspectFit"/>
|
<image class="img" :src="myHeadImg" v-if="myHeadImg" @error="myHeadImgError" mode="aspectFit" show-menu-by-longpress/>
|
||||||
<image class="img" :src="defaultHead" mode="aspectFit" v-else/>
|
<image class="img" :src="defaultHead" mode="aspectFit" v-else show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<block v-else>
|
<block v-else>
|
||||||
<view class="head_img">
|
<view class="head_img">
|
||||||
<image class="img" :src="avatar" mode="aspectFit" v-if="avatar"></image>
|
<image class="img" :src="avatar" mode="aspectFit" v-if="avatar" show-menu-by-longpress></image>
|
||||||
<image class="img" :src="defaultHead" mode="aspectFit" v-else></image>
|
<image class="img" :src="defaultHead" mode="aspectFit" v-else show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<view class="chat_text">
|
<view class="chat_text">
|
||||||
@@ -34,20 +34,20 @@
|
|||||||
<view class="message-item " :class="message.isItMe ? 'right' : 'left'">
|
<view class="message-item " :class="message.isItMe ? 'right' : 'left'">
|
||||||
<block v-if="message.isItMe">
|
<block v-if="message.isItMe">
|
||||||
<view class="head_img">
|
<view class="head_img">
|
||||||
<image class="img" :src="myHeadImg" v-if="myHeadImg" mode="aspectFit"></image>
|
<image class="img" :src="myHeadImg" v-if="myHeadImg" mode="aspectFit" show-menu-by-longpress></image>
|
||||||
<image class="img" :src="defaultHead" mode="aspectFit" v-else></image>
|
<image class="img" :src="defaultHead" mode="aspectFit" v-else show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<block v-else>
|
<block v-else>
|
||||||
<view class="head_img">
|
<view class="head_img">
|
||||||
<image class="img" :src="avatar" mode="aspectFit" v-if="avatar"></image>
|
<image class="img" :src="avatar" mode="aspectFit" v-if="avatar" show-menu-by-longpress></image>
|
||||||
<image class="img" :src="defaultHead" mode="aspectFit" v-else></image>
|
<image class="img" :src="defaultHead" mode="aspectFit" v-else show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<view class="chat_img">
|
<view class="chat_img">
|
||||||
<text class="iconfont icon-warn margin-right color-base-text" v-if="message.isItMe && !message.sendStatus"></text>
|
<text class="iconfont icon-warn margin-right color-base-text" v-if="message.isItMe && !message.sendStatus"></text>
|
||||||
<view class="content_img" @click="previewMedia($util.img(message.image))" :style="{ backgroundImage: 'url(' + $util.img(message.image) + ')' }">
|
<view class="content_img" @click="previewMedia($util.img(message.image))" :style="{ backgroundImage: 'url(' + $util.img(message.image) + ')' }">
|
||||||
<!-- <image class="img_img" :src="$util.img(message.image)" mode="aspectFit"></image> -->
|
<!-- <image class="img_img" :src="$util.img(message.image)" mode="aspectFit" show-menu-by-longpress></image> -->
|
||||||
</view>
|
</view>
|
||||||
<!-- <text class="iconfont icon-warn margin-left" v-if="!message.isItMe && !message.sendStatus"></text> -->
|
<!-- <text class="iconfont icon-warn margin-left" v-if="!message.isItMe && !message.sendStatus"></text> -->
|
||||||
</view>
|
</view>
|
||||||
@@ -64,18 +64,14 @@
|
|||||||
</view>
|
</view>
|
||||||
<uni-popup ref="imgPopup" type="center">
|
<uni-popup ref="imgPopup" type="center">
|
||||||
<view class="imagePop">
|
<view class="imagePop">
|
||||||
<image :src="$util.img(currImg)" mode="aspectFit"></image>
|
<image :src="$util.img(currImg)" mode="aspectFit" show-menu-by-longpress></image>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import nsChatGoods from '@/pages_tool/components/ns-chat/ns-chat-goods.vue';
|
|
||||||
import nsChatOrder from '@/pages_tool/components/ns-chat/ns-chat-order.vue';
|
|
||||||
import nsChatReceiveGoods from '@/pages_tool/components/ns-chat/ns-chat-receiveGoods.vue';
|
|
||||||
import htmlParser from '@/common/js/html-parser';
|
import htmlParser from '@/common/js/html-parser';
|
||||||
import uniPopup from '@/components/uni-popup/uni-popup.vue';
|
|
||||||
import emjoy from '@/common/js/emjoy.js';
|
import emjoy from '@/common/js/emjoy.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -98,12 +94,6 @@
|
|||||||
currImg: ''
|
currImg: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
components: {
|
|
||||||
nsChatGoods,
|
|
||||||
nsChatOrder,
|
|
||||||
uniPopup,
|
|
||||||
nsChatReceiveGoods
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.avatar = this.$util.img(this.siteInfo.logo_square);
|
this.avatar = this.$util.img(this.siteInfo.logo_square);
|
||||||
this.myHeadImg = this.$util.img(this.memberInfo.headimg);
|
this.myHeadImg = this.$util.img(this.memberInfo.headimg);
|
||||||
@@ -166,11 +156,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
/deep/.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
|
::v-deep .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
|
::v-deep .uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
@@ -189,6 +179,7 @@
|
|||||||
.chat-message {
|
.chat-message {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
background: white; /* 白色 */
|
||||||
|
|
||||||
.message {
|
.message {
|
||||||
padding: 13rpx 20rpx;
|
padding: 13rpx 20rpx;
|
||||||
@@ -280,7 +271,7 @@
|
|||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
background-color: #4cd964;
|
background-color: #c4e0ff; /* 浅蓝色 */
|
||||||
margin-right: 28rpx;
|
margin-right: 28rpx;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
line-height: 36rpx;
|
line-height: 36rpx;
|
||||||
@@ -1,465 +0,0 @@
|
|||||||
// 商品详情业务
|
|
||||||
import {
|
|
||||||
Weixin
|
|
||||||
} from '@/common/js/wx-jssdk.js';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
skuId: 0,
|
|
||||||
goodsId: 0,
|
|
||||||
isIphoneX: false, //判断手机是否是iphoneX以上
|
|
||||||
whetherCollection: 0,
|
|
||||||
|
|
||||||
//是否开启预览,0:不开启,1:开启
|
|
||||||
preview: 0,
|
|
||||||
videoContext: '',
|
|
||||||
|
|
||||||
// 媒体,图片,视频
|
|
||||||
|
|
||||||
// 解决每个商品SKU图片数量不同时,无法切换到第一个,导致轮播图显示不出来
|
|
||||||
swiperInterval: 1,
|
|
||||||
swiperAutoplay: false,
|
|
||||||
swiperCurrent: 1,
|
|
||||||
switchMedia: 'img',
|
|
||||||
|
|
||||||
//评价
|
|
||||||
goodsEvaluate: [{
|
|
||||||
member_headimg: '',
|
|
||||||
member_name: '',
|
|
||||||
content: '',
|
|
||||||
images: [],
|
|
||||||
create_time: 0,
|
|
||||||
sku_name: ''
|
|
||||||
}],
|
|
||||||
evaluateConfig: {
|
|
||||||
evaluate_audit: 1,
|
|
||||||
evaluate_show: 0,
|
|
||||||
evaluate_status: 1
|
|
||||||
},
|
|
||||||
|
|
||||||
// 是否可分享到好物圈
|
|
||||||
goodsCircle: false,
|
|
||||||
service: null,
|
|
||||||
shareUrl: '', // 分享链接
|
|
||||||
source_member: 0, //分享人的id
|
|
||||||
isCommunity: false, //社群弹窗
|
|
||||||
|
|
||||||
poster: "-1", //海报
|
|
||||||
posterMsg: "", //海报错误信息
|
|
||||||
posterHeight: 0,
|
|
||||||
posterParams: {}, //海报所需参数
|
|
||||||
goodsRoute: '',
|
|
||||||
posterApi: '',
|
|
||||||
goodsAttrShow: false, // 商品属性是否展开
|
|
||||||
|
|
||||||
//门店列表
|
|
||||||
storeList: {
|
|
||||||
data: [],
|
|
||||||
page: 1,
|
|
||||||
page_size: 10
|
|
||||||
},
|
|
||||||
isShowStore: false,
|
|
||||||
latitude: null, // 纬度
|
|
||||||
longitude: null, // 经度
|
|
||||||
evaluateCount: 0, // 商品评论数量
|
|
||||||
deliveryType: null, // 配送方式
|
|
||||||
isVirtual: 0 //是否为虚拟商品
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.isIphoneX = this.$util.uniappIsIPhoneX();
|
|
||||||
|
|
||||||
if (this.location) {
|
|
||||||
this.latitude = this.location.latitude;
|
|
||||||
this.longitude = this.location.longitude;
|
|
||||||
} else {
|
|
||||||
this.$util.getLocation();
|
|
||||||
}
|
|
||||||
this.getStoreData();
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
location: function (nVal) {
|
|
||||||
if (nVal) {
|
|
||||||
this.latitude = nVal.latitude;
|
|
||||||
this.longitude = nVal.longitude;
|
|
||||||
this.getStoreData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
init(params) {
|
|
||||||
this.skuId = params.sku_id;
|
|
||||||
this.goodsId = params.goods_id;
|
|
||||||
this.preview = params.preview;
|
|
||||||
this.source_member = params.source_member;
|
|
||||||
this.whetherCollection = params.whetherCollection;
|
|
||||||
this.posterParams = params.posterParams;
|
|
||||||
|
|
||||||
this.shareUrl = params.shareUrl;
|
|
||||||
this.goodsRoute = params.goodsRoute;
|
|
||||||
this.posterApi = params.posterApi;
|
|
||||||
this.isVirtual = params.isVirtual;
|
|
||||||
this.deliveryType = params.deliveryType;
|
|
||||||
this.evaluateConfig = params.evaluateConfig;
|
|
||||||
|
|
||||||
if (this.evaluateConfig.evaluate_show == 1) {
|
|
||||||
//商品评论
|
|
||||||
this.getGoodsEvaluate(params.evaluateList);
|
|
||||||
this.evaluateCount = params.evaluateCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let k in this.deliveryType) {
|
|
||||||
if (k == 'store') {
|
|
||||||
this.isShowStore = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getService();
|
|
||||||
|
|
||||||
this.videoContext = uni.createVideoContext('goodsVideo');
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
this.goodsSyncToGoodsCircle();
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
},
|
|
||||||
swiperChange(e) {
|
|
||||||
this.swiperCurrent = e.detail.current + 1;
|
|
||||||
},
|
|
||||||
|
|
||||||
//-------------------------------------服务-------------------------------------
|
|
||||||
|
|
||||||
openMerchantsServicePopup() {
|
|
||||||
this.$refs.merchantsServicePopup.open();
|
|
||||||
},
|
|
||||||
closeMerchantsServicePopup() {
|
|
||||||
this.$refs.merchantsServicePopup.close();
|
|
||||||
},
|
|
||||||
|
|
||||||
//-------------------------------------门店列表-------------------------------------
|
|
||||||
openStoreListPopup() {
|
|
||||||
this.$refs.storeListPopup.open();
|
|
||||||
},
|
|
||||||
closeStoreListPopup() {
|
|
||||||
this.$refs.storeListPopup.close();
|
|
||||||
},
|
|
||||||
getStoreData() {
|
|
||||||
//门店列表
|
|
||||||
let data = {
|
|
||||||
page: this.storeList.page,
|
|
||||||
page_size: this.storeList.page_size
|
|
||||||
};
|
|
||||||
if (this.latitude && this.longitude) {
|
|
||||||
data.latitude = this.latitude;
|
|
||||||
data.longitude = this.longitude;
|
|
||||||
}
|
|
||||||
this.$api.sendRequest({
|
|
||||||
url: '/api/store/page',
|
|
||||||
data: data,
|
|
||||||
success: res => {
|
|
||||||
if (this.storeList.page == 1) this.storeList.data == [];
|
|
||||||
if (res.code >= 0 && res.data) {
|
|
||||||
this.storeList.data = this.storeList.data.concat(res.data.list);
|
|
||||||
} else {
|
|
||||||
this.$util.showToast({
|
|
||||||
title: res.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
selectStore(item) {
|
|
||||||
this.$util.redirectTo('/pages_tool/store/detail', {
|
|
||||||
store_id: item.store_id
|
|
||||||
});
|
|
||||||
this.closeStoreListPopup();
|
|
||||||
},
|
|
||||||
//-------------------------------------属性-------------------------------------
|
|
||||||
|
|
||||||
switchGoodsAttr() {
|
|
||||||
this.goodsAttrShow = !this.goodsAttrShow;
|
|
||||||
},
|
|
||||||
//-------------------------------------评价-------------------------------------
|
|
||||||
//商品评论列表
|
|
||||||
getGoodsEvaluate(list) {
|
|
||||||
if (list) {
|
|
||||||
this.goodsEvaluate = list;
|
|
||||||
this.goodsEvaluate.forEach((item, index) => {
|
|
||||||
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.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), '***')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 预览评价图片
|
|
||||||
previewEvaluate(index, img_index, field) {
|
|
||||||
var paths = [];
|
|
||||||
for (let i = 0; i < this.goodsEvaluate[index][field].length; i++) {
|
|
||||||
paths.push(this.$util.img(this.goodsEvaluate[index][field][i]));
|
|
||||||
}
|
|
||||||
uni.previewImage({
|
|
||||||
current: img_index,
|
|
||||||
urls: paths
|
|
||||||
});
|
|
||||||
},
|
|
||||||
//-------------------------------------关注-------------------------------------
|
|
||||||
async collection() {
|
|
||||||
if (this.preview) return; // 开启预览,禁止任何操作和跳转
|
|
||||||
|
|
||||||
if (this.storeToken) {
|
|
||||||
|
|
||||||
//未关注添加关注
|
|
||||||
if (this.whetherCollection == 0) {
|
|
||||||
let res = await this.$api.sendRequest({
|
|
||||||
url: "/api/goodscollect/add",
|
|
||||||
data: {
|
|
||||||
sku_id: this.skuId,
|
|
||||||
goods_id: this.goodsSkuDetail.goods_id,
|
|
||||||
sku_name: this.goodsSkuDetail.sku_name,
|
|
||||||
sku_price: this.goodsSkuDetail.show_price,
|
|
||||||
sku_image: this.goodsSkuDetail.sku_image
|
|
||||||
},
|
|
||||||
async: false,
|
|
||||||
});
|
|
||||||
var data = res.data;
|
|
||||||
if (data > 0) {
|
|
||||||
this.whetherCollection = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//已关注取消关注
|
|
||||||
let res = await this.$api.sendRequest({
|
|
||||||
url: "/api/goodscollect/delete",
|
|
||||||
data: {
|
|
||||||
goods_id: this.goodsSkuDetail.goods_id
|
|
||||||
},
|
|
||||||
async: false,
|
|
||||||
});
|
|
||||||
var data = res.data;
|
|
||||||
if (data > 0) {
|
|
||||||
this.whetherCollection = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.whetherCollection;
|
|
||||||
} else {
|
|
||||||
if (this.source_member) {
|
|
||||||
this.$refs.login.open(this.shareUrl + '&source_member=' + this.source_member);
|
|
||||||
} else {
|
|
||||||
this.$refs.login.open(this.shareUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//-------------------------------------分享-------------------------------------
|
|
||||||
// 打开分享弹出层
|
|
||||||
openSharePopup() {
|
|
||||||
this.$refs.sharePopup.open();
|
|
||||||
},
|
|
||||||
// 关闭分享弹出层
|
|
||||||
closeSharePopup() {
|
|
||||||
this.$refs.sharePopup.close();
|
|
||||||
},
|
|
||||||
copyUrl() {
|
|
||||||
let text = this.$config.h5Domain + this.shareUrl;
|
|
||||||
if (this.memberInfo && this.memberInfo.member_id) text += '&source_member=' + this.memberInfo.member_id;
|
|
||||||
this.$util.copy(text, () => {
|
|
||||||
this.closeSharePopup();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
//-------------------------------------海报-------------------------------------
|
|
||||||
// 打开海报弹出层
|
|
||||||
openPosterPopup() {
|
|
||||||
this.getGoodsPoster();
|
|
||||||
this.$refs.sharePopup.close();
|
|
||||||
},
|
|
||||||
// 关闭海报弹出层
|
|
||||||
closePosterPopup() {
|
|
||||||
this.$refs.posterPopup.close();
|
|
||||||
this.poster = ''
|
|
||||||
},
|
|
||||||
//生成海报
|
|
||||||
getGoodsPoster() {
|
|
||||||
uni.showLoading({
|
|
||||||
'title': '海报生成中...'
|
|
||||||
})
|
|
||||||
//活动海报信息
|
|
||||||
if (this.memberInfo && this.memberInfo.member_id) this.posterParams.source_member = this.memberInfo.member_id;
|
|
||||||
|
|
||||||
this.$api.sendRequest({
|
|
||||||
url: this.posterApi,
|
|
||||||
data: {
|
|
||||||
page: this.goodsRoute,
|
|
||||||
qrcode_param: JSON.stringify(this.posterParams)
|
|
||||||
},
|
|
||||||
success: res => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.$refs.posterPopup.open();
|
|
||||||
this.poster = res.data.path + "?time=" + new Date().getTime();
|
|
||||||
} else {
|
|
||||||
this.posterMsg = res.message;
|
|
||||||
this.$util.showToast({
|
|
||||||
title: res.message
|
|
||||||
})
|
|
||||||
}
|
|
||||||
uni.hideLoading();
|
|
||||||
},
|
|
||||||
fail: err => {
|
|
||||||
uni.hideLoading();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// 预览图片
|
|
||||||
previewMedia(index) {
|
|
||||||
var paths = [];
|
|
||||||
for (let i = 0; i < this.goodsSkuDetail.sku_images.length; i++) {
|
|
||||||
paths.push(this.$util.img(this.goodsSkuDetail.sku_images[i], {
|
|
||||||
size: 'big'
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
uni.previewImage({
|
|
||||||
current: index,
|
|
||||||
urls: paths,
|
|
||||||
// longPressActions: {
|
|
||||||
// itemList: ['发送给朋友', '保存图片', '关注'],
|
|
||||||
// success: function(data) {
|
|
||||||
// console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
|
|
||||||
// },
|
|
||||||
// fail: function(err) {
|
|
||||||
// console.log(err.errMsg);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
},
|
|
||||||
swiperImageError(index) {
|
|
||||||
this.goodsSkuDetail.sku_images[index] = this.$util.getDefaultImage().goods;
|
|
||||||
this.$forceUpdate();
|
|
||||||
},
|
|
||||||
// #ifdef MP || APP-PLUS
|
|
||||||
//小程序中保存海报
|
|
||||||
saveGoodsPoster() {
|
|
||||||
let url = this.$util.img(this.poster);
|
|
||||||
uni.downloadFile({
|
|
||||||
url: url,
|
|
||||||
success: (res) => {
|
|
||||||
if (res.errMsg == "downloadFile:ok") {
|
|
||||||
uni.saveImageToPhotosAlbum({
|
|
||||||
filePath: res.tempFilePath,
|
|
||||||
success: () => {
|
|
||||||
this.$util.showToast({
|
|
||||||
title: "保存成功"
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
this.$util.showToast({
|
|
||||||
title: "保存失败,请稍后重试"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
this.$util.showToast({
|
|
||||||
title: "保存失败,请稍后重试"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// #endif
|
|
||||||
//售后保障查询
|
|
||||||
getService() {
|
|
||||||
this.$api.sendRequest({
|
|
||||||
url: '/api/goods/aftersale',
|
|
||||||
success: res => {
|
|
||||||
if (res.code == 0 && res.data) {
|
|
||||||
this.service = res.data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
/**
|
|
||||||
* 将商品同步到微信圈子
|
|
||||||
*/
|
|
||||||
goodsSyncToGoodsCircle() {
|
|
||||||
this.$api.sendRequest({
|
|
||||||
url: '/goodscircle/api/goods/sync',
|
|
||||||
data: {
|
|
||||||
goods_id: this.goodsSkuDetail.goods_id
|
|
||||||
},
|
|
||||||
success: res => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.goodsCircle = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 将商品推荐到微信圈子
|
|
||||||
*/
|
|
||||||
openBusinessView() {
|
|
||||||
if (wx.openBusinessView) {
|
|
||||||
wx.openBusinessView({
|
|
||||||
businessType: 'friendGoodsRecommend',
|
|
||||||
extraData: {
|
|
||||||
product: {
|
|
||||||
item_code: this.goodsSkuDetail.goods_id,
|
|
||||||
title: this.goodsSkuDetail.sku_name,
|
|
||||||
image_list: this.goodsSkuDetail.sku_images.map((ele) => {
|
|
||||||
return this.$util.img(ele);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
success: function (res) {
|
|
||||||
console.log('success', res);
|
|
||||||
},
|
|
||||||
fail: function (res) {
|
|
||||||
console.log('fail', res);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// #endif
|
|
||||||
toEvaluateDetail(id) {
|
|
||||||
this.$util.redirectTo('/pages_tool/goods/evaluate', {
|
|
||||||
goods_id: id
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showImg(e) {
|
|
||||||
//拿到图片的路径里面的内容放在我们数组中
|
|
||||||
let contentimg = e.target.dataset.nodes;
|
|
||||||
let arrImg = [];
|
|
||||||
for (var i = 0; i < contentimg.length; i++) {
|
|
||||||
var img = contentimg[i].children;
|
|
||||||
if (Array.isArray(img)) {
|
|
||||||
for (var j = 0; j < img.length; j++) {
|
|
||||||
if (img[j].attrs && img[j].name == "img") {
|
|
||||||
if (img[j].attrs.src) {
|
|
||||||
arrImg.push(img[j].attrs.src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//最后一步就是把我们的所有图片放在预览的api中就可以了
|
|
||||||
uni.previewImage({
|
|
||||||
current: arrImg,
|
|
||||||
urls: arrImg,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
//-------------------------------------社群-------------------------------------
|
|
||||||
|
|
||||||
//添加福利群
|
|
||||||
onCommunity() {
|
|
||||||
this.isCommunity = true
|
|
||||||
},
|
|
||||||
onCloseCommunity() {
|
|
||||||
this.isCommunity = false
|
|
||||||
},
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,455 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view>
|
|
||||||
<view scroll-y="true" class="goods-detail" :class="isIphoneX ? 'active' : ''">
|
|
||||||
<view class="goods-container">
|
|
||||||
<!-- 弹幕 -->
|
|
||||||
<pengpai-fadein-out v-if="goodsSkuDetail.barrage_show && goodsSkuDetail.barrageData" ref="pengpai" :duration="1600" :wait="1900" :top="200" :left="0" :radius="60" :loop="true" :info="goodsSkuDetail.barrageData"/>
|
|
||||||
|
|
||||||
<!-- 商品媒体信息 -->
|
|
||||||
<view class="goods-media" :style="{height: goodsSkuDetail.swiperHeight}">
|
|
||||||
<!-- 商品图片 -->
|
|
||||||
<view class="goods-img" :class="{ show: switchMedia == 'img' }">
|
|
||||||
<swiper class="swiper" @change="swiperChange" :interval="swiperInterval" :autoplay="swiperAutoplay" autoplay="true" interval="4000" circular="true">
|
|
||||||
<swiper-item v-for="(item, index) in goodsSkuDetail.sku_images" :key="index" :item-id="'goods_id_' + index">
|
|
||||||
<view class="item" @click="previewMedia(index)">
|
|
||||||
<image :src="$util.img(item, { size: 'big' })" @error="swiperImageError(index)" mode="aspectFit" />
|
|
||||||
</view>
|
|
||||||
</swiper-item>
|
|
||||||
</swiper>
|
|
||||||
<view class="img-indicator-dots">
|
|
||||||
<text>{{ swiperCurrent }}</text>
|
|
||||||
<text v-if="goodsSkuDetail.sku_images">/{{ goodsSkuDetail.sku_images.length }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 商品视频 -->
|
|
||||||
<view class="goods-video" :class="{ show: switchMedia == 'video' }">
|
|
||||||
<video id="goodsVideo" :src="$util.img(goodsSkuDetail.video_url)" :poster="$util.img(goodsSkuDetail.sku_image, { size: 'big' })" objectFit="cover"></video>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 切换视频、图片 -->
|
|
||||||
<view class="media-mode" v-if="goodsSkuDetail.video_url != ''">
|
|
||||||
<text :class="{ 'color-base-bg': switchMedia == 'video' }" @click="switchMedia = 'video'">{{ $lang('video') }}</text>
|
|
||||||
<text :class="{ 'color-base-bg': switchMedia == 'img' }" @click="(switchMedia = 'img'), videoContext.pause()">{{ $lang('image') }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 价格区域 -->
|
|
||||||
<view class="goods-gression">
|
|
||||||
<slot name="price"></slot>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="newdetail margin-bottom" v-if="goodsSkuDetail.isinformation == 0">
|
|
||||||
|
|
||||||
<!-- 入口区域 -->
|
|
||||||
<slot name="entrance"></slot>
|
|
||||||
|
|
||||||
<!-- 配送 -->
|
|
||||||
<!-- @click="$refs.deliveryType.open()" -->
|
|
||||||
<view class="item delivery-type" v-if="goodsSkuDetail.is_virtual == 0" >
|
|
||||||
<view class="label">{{$lang('send')}}</view>
|
|
||||||
<block v-if="deliveryType">
|
|
||||||
<view class="box">
|
|
||||||
<block v-for="(item, index) in deliveryType" :key="index">
|
|
||||||
<text v-if="goodsSkuDetail.support_trade_type.indexOf(index) != -1">{{$lang('express')}}</text>
|
|
||||||
<!-- {{ item.name }} -->
|
|
||||||
</block>
|
|
||||||
</view>
|
|
||||||
<text class="iconfont icon-right"></text>
|
|
||||||
</block>
|
|
||||||
<block v-else>
|
|
||||||
<view class="box">未配置</view>
|
|
||||||
</block>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 门店 -->
|
|
||||||
<!-- <view class="item store-wrap" @click="openStoreListPopup()" v-if="addonIsExist.store && globalStoreInfo && isShowStore">
|
|
||||||
<view class="label">门店</view>
|
|
||||||
<view class="list-wrap">
|
|
||||||
<view class="name-wrap">
|
|
||||||
<text class="icondiy icon-system-shop"></text>
|
|
||||||
<text class="name">{{globalStoreInfo.store_name}}</text>
|
|
||||||
</view>
|
|
||||||
<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="decorate" v-if="parseFloat(globalStoreInfo.distance)">.</text>
|
|
||||||
<view class="address">{{ globalStoreInfo.full_address + globalStoreInfo.address }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<text class="iconfont icon-right"></text>
|
|
||||||
</view> -->
|
|
||||||
|
|
||||||
<view class="item service" @click="openMerchantsServicePopup()" v-if="goodsSkuDetail.goods_service.length">
|
|
||||||
<view class="label">服务</view>
|
|
||||||
<view class="list-wrap">
|
|
||||||
<view class="item-wrap" v-for="(item, index) in goodsSkuDetail.goods_service" :key="index" v-if="index < 3">
|
|
||||||
<view class="item-wrap-box">
|
|
||||||
<view class="item-wrap-icon">
|
|
||||||
<text class="iconfont icon-dui" v-if="!item.icon || (!item.icon.imageUrl && !item.icon.icon)"></text>
|
|
||||||
<image class="icon-img" v-else-if="item.icon.iconType == 'img'" :src=" $util.img(item.icon.imageUrl)" />
|
|
||||||
<diy-icon class="icon-box" v-else-if="item.icon.iconType == 'icon'" :icon="item.icon.icon" :value="item.icon.style ? item.icon.style : null"></diy-icon>
|
|
||||||
</view>
|
|
||||||
<text>{{ item.service_name }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<text class="iconfont icon-right"></text>
|
|
||||||
</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 @touchmove.prevent.stop>
|
|
||||||
<uni-popup ref="deliveryType" type="bottom">
|
|
||||||
<view class="deliverytype-popup-layer popup-layer">
|
|
||||||
<view class="head-wrap" @click="$refs.deliveryType.close()">
|
|
||||||
<text>配送</text>
|
|
||||||
<text class="iconfont icon-close"></text>
|
|
||||||
</view>
|
|
||||||
<scroll-view scroll-y class="type-body">
|
|
||||||
<block v-for="(item, index) in deliveryType" :key="index">
|
|
||||||
<view class="type-item" :class="{ 'not-support': goodsSkuDetail.support_trade_type.indexOf(index) == -1 }">
|
|
||||||
<text class="iconfont" :class="item.icon"></text>
|
|
||||||
<view class="content">
|
|
||||||
<view class="title">{{ item.name }}</view>
|
|
||||||
<view class="desc">{{ item.desc }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
</scroll-view>
|
|
||||||
</view>
|
|
||||||
</uni-popup>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 商品服务 -->
|
|
||||||
<view @touchmove.prevent.stop>
|
|
||||||
<uni-popup ref="merchantsServicePopup" type="bottom">
|
|
||||||
<view class="goods-merchants-service-popup-layer popup-layer">
|
|
||||||
<view class="head-wrap" @click="closeMerchantsServicePopup()">
|
|
||||||
<text>商品服务</text>
|
|
||||||
<text class="iconfont icon-close"></text>
|
|
||||||
</view>
|
|
||||||
<scroll-view scroll-y>
|
|
||||||
<view class="item" :class="{ 'empty-desc': !item.desc }" v-for="(item, index) in goodsSkuDetail.goods_service" :key="index">
|
|
||||||
<view class="item-icon" :class="{'empty-desc':!item.desc}">
|
|
||||||
<text class="iconfont icon-dui color-base-text" v-if="!item.icon || (!item.icon.imageUrl && !item.icon.icon)"></text>
|
|
||||||
<image class="icon-img" v-else-if="item.icon.iconType == 'img'" :src=" $util.img(item.icon.imageUrl)" />
|
|
||||||
<diy-icon class="icon-box" v-else-if="item.icon.iconType == 'icon'" :icon="item.icon.icon" :value="item.icon.style ? item.icon.style : null"></diy-icon>
|
|
||||||
</view>
|
|
||||||
<view class="info-wrap">
|
|
||||||
<text class="title">{{ item.service_name }}</text>
|
|
||||||
<text class="describe" v-if="item.desc">{{ item.desc }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
<view class="button-box">
|
|
||||||
<button type="primary" @click="closeMerchantsServicePopup()">确定</button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uni-popup>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 门店列表 -->
|
|
||||||
<view @touchmove.prevent.stop>
|
|
||||||
<uni-popup ref="storeListPopup" type="bottom">
|
|
||||||
<view class="goods-merchants-service-popup-layer popup-layer store-list-wrap">
|
|
||||||
<view class="head-wrap" @click="closeStoreListPopup()">
|
|
||||||
<text>门店列表</text>
|
|
||||||
<text class="iconfont icon-close"></text>
|
|
||||||
</view>
|
|
||||||
<scroll-view scroll-y>
|
|
||||||
<view class="store-list-content">
|
|
||||||
<view class="list-item" v-for="(item, index) in storeList.data" :key="index" @click="selectStore(item)">
|
|
||||||
<view class="item-box">
|
|
||||||
<view class="item-image">
|
|
||||||
<image :src="$util.img(item.store_image)" v-if="item.store_image"/>
|
|
||||||
<image :src="$util.getDefaultImage().store" v-else/>
|
|
||||||
</view>
|
|
||||||
<view class="item-info">
|
|
||||||
<view class="item-title">
|
|
||||||
<text class="title">{{ item.store_name }}</text>
|
|
||||||
<text class="distance color-base-text" v-if="item.distance">
|
|
||||||
距离{{ item.distance > 1 ? item.distance + 'km' : item.distance * 1000 + 'm' }}
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
<view class="item-time" v-if="item.open_date">营业时间:{{ item.open_date }}
|
|
||||||
</view>
|
|
||||||
<view class="item-address">{{ item.full_address + item.address }}</view>
|
|
||||||
</view>
|
|
||||||
<view class="item-right"><text class="iconfont icon-right"></text></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
</view>
|
|
||||||
</uni-popup>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 业务区域 -->
|
|
||||||
<slot name="business"></slot>
|
|
||||||
|
|
||||||
<view class="detail-community" v-if="goodsSkuDetail.qr_data && goodsSkuDetail.qr_data.qr_state == 1">
|
|
||||||
<view class="community-box">
|
|
||||||
<image :src="$util.img('public/uniapp/goods/detail_erweiImage.png')" mode="aspectFill"></image>
|
|
||||||
<view class="community-content">
|
|
||||||
<view class="community-title">{{ goodsSkuDetail.qr_data.qr_name }}</view>
|
|
||||||
<view class="community-txt">{{ goodsSkuDetail.qr_data.community_describe }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="community-btn" @click="onCommunity()">添加</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 促销 -->
|
|
||||||
<!-- <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-radius">
|
|
||||||
<view>添加社群</view>
|
|
||||||
</view>
|
|
||||||
<view class="community-model-content-draw" v-if="goodsSkuDetail.qr_data && goodsSkuDetail.qr_data.qr_img">
|
|
||||||
<image :src="goodsSkuDetail.qr_data.qr_img != '' && goodsSkuDetail.qr_data.qr_state == 1 ? $util.img(goodsSkuDetail.qr_data.qr_img) : $util.img('public/uniapp/goods/detail_erweiImage.png') " mode="aspectFill" show-menu-by-longpress="true"/>
|
|
||||||
</view>
|
|
||||||
<view class="community-model-content-text">长按识别二维码,添加社群</view>
|
|
||||||
</view>
|
|
||||||
<view class="community-model-close" @click.stop="onCloseCommunity()">
|
|
||||||
<text class="iconfont icon-close"></text>
|
|
||||||
</view>
|
|
||||||
</view> -->
|
|
||||||
|
|
||||||
<!-- 参与流程 -->
|
|
||||||
<slot name="articipation"></slot>
|
|
||||||
|
|
||||||
<!-- 商品评价 -->
|
|
||||||
<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="tit">
|
|
||||||
<!-- <view class="tit" :class="{ active: goodsEvaluate.content }"> -->
|
|
||||||
<view>
|
|
||||||
<text class="color-title font-size-base">
|
|
||||||
评价
|
|
||||||
<text class="font-size-base">({{ evaluateCount }})</text>
|
|
||||||
</text>
|
|
||||||
<text class="evaluate-item-empty" v-if="!evaluateCount">暂无评价</text>
|
|
||||||
<view class="evaluate-item-empty" v-else>
|
|
||||||
<text class="font-size-tag">查看全部</text>
|
|
||||||
<text class="iconfont icon-right font-size-tag"></text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="evaluate-item" v-for="(item, index) in goodsEvaluate" :key="index"
|
|
||||||
v-if="item.content">
|
|
||||||
<view class="evaluator">
|
|
||||||
<view class="evaluator-info">
|
|
||||||
<view class="evaluator-face">
|
|
||||||
<image v-if="item.member_headimg" :src="$util.img(item.member_headimg)" @error="item.member_headimg = $util.getDefaultImage().head" mode="aspectFill" />
|
|
||||||
<image v-else :src="$util.getDefaultImage().head" @error="item.member_headimg = $util.getDefaultImage().head" mode="aspectFill" />
|
|
||||||
</view>
|
|
||||||
<view class="evaluator-name-wrap">
|
|
||||||
<text class="evaluator-name using-hidden" v-if="item.member_name.length > 2 && item.is_anonymous == 1">
|
|
||||||
{{ item.member_name[0] }}***{{ item.member_name[item.member_name.length - 1] }}
|
|
||||||
</text>
|
|
||||||
<text class="evaluator-name using-hidden" v-else>{{ item.member_name }}</text>
|
|
||||||
<view v-if="item.scores" class="evaluator-xing">
|
|
||||||
<xiaoStarComponent :starCount="item.scores * 2"></xiaoStarComponent>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<text class="time color-tip">{{ $util.timeStampTurnTime(item.create_time) }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="cont margin-top">{{ item.content }}</view>
|
|
||||||
<scroll-view scroll-x="true">
|
|
||||||
<view class="evaluate-img" v-if="item.images">
|
|
||||||
<view class="img-box" v-for="(img, img_index) in item.images" :key="img_index" @click="previewEvaluate(index, img_index, 'images')">
|
|
||||||
<image :src="$util.img(img)" mode="aspectFill" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</scroll-view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="goods-attr" v-if="goodsSkuDetail.goods_attr_format && goodsSkuDetail.goods_attr_format.length > 0">
|
|
||||||
<view class="title">规格属性</view>
|
|
||||||
<view class="attr-wrap">
|
|
||||||
<block v-for="(item, index) in goodsSkuDetail.goods_attr_format" :key="index">
|
|
||||||
<view class="item" v-if="goodsAttrShow || (!goodsAttrShow && index < 4)">
|
|
||||||
<text class="attr-name">{{ item.attr_name }}</text>
|
|
||||||
<text class="value-name">{{ item.attr_value_name }}</text>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
<view class="attr-action" v-if="goodsSkuDetail.goods_attr_format.length > 4" @click="switchGoodsAttr">
|
|
||||||
<block v-if="!goodsAttrShow">
|
|
||||||
展开<text class="iconfont icon-iconangledown"></text>
|
|
||||||
</block>
|
|
||||||
<block v-else>
|
|
||||||
收起<text class="iconfont icon-iconangledown-copy"></text>
|
|
||||||
</block>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 详情 -->
|
|
||||||
<view class="goods-detail-tab">
|
|
||||||
<view class="detail-tab">
|
|
||||||
<view class="tab-item">{{$lang('details')}}</view>
|
|
||||||
</view>
|
|
||||||
<view class="detail-content active">
|
|
||||||
<view class="detail-content-item">
|
|
||||||
<view class="goods-details" v-if="goodsSkuDetail.goods_content">
|
|
||||||
<!-- <rich-text :nodes="goodsSkuDetail.goods_content" @click="showImg($event)" :data-nodes="goodsSkuDetail.goods_content"></rich-text> -->
|
|
||||||
<!-- {{goodsSkuDetail.goods_content}} -->
|
|
||||||
<mp-html :content="goodsSkuDetail.goods_content" />
|
|
||||||
<!-- :loading="loading" @preview="preview" @navigate="navigate" -->
|
|
||||||
</view>
|
|
||||||
<view class="goods-details active" v-else></view>
|
|
||||||
<view class="goods-details" v-if="service && service.is_display == 1 && service.content">
|
|
||||||
<rich-text :nodes="service.content" @click="showImg($event)" :data-nodes="service.content"></rich-text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 商品推荐 -->
|
|
||||||
<ns-goods-recommend ref="goodrecommend" route="goods_detail"></ns-goods-recommend>
|
|
||||||
|
|
||||||
<ns-copyright></ns-copyright>
|
|
||||||
|
|
||||||
<!-- 海报 -->
|
|
||||||
<view @touchmove.prevent.stop class="poster-layer">
|
|
||||||
<uni-popup ref="posterPopup" type="center">
|
|
||||||
<template v-if="poster != '-1'">
|
|
||||||
<view class="poster-wrap">
|
|
||||||
<view class="image-wrap">
|
|
||||||
<image :src="$util.img(poster)" :show-menu-by-longpress="true" mode="widthFix" />
|
|
||||||
<view class="close iconfont icon-close" @click="closePosterPopup()"></view>
|
|
||||||
</view>
|
|
||||||
<!-- #ifdef MP || APP-PLUS -->
|
|
||||||
<view class="save-btn" @click="saveGoodsPoster()">保存图片</view>
|
|
||||||
<!-- #endif -->
|
|
||||||
<!-- #ifdef H5 -->
|
|
||||||
<view class="save-btn">长按图片进行保存</view>
|
|
||||||
<!-- #endif -->
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</uni-popup>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 分享弹窗 -->
|
|
||||||
<view @touchmove.prevent.stop>
|
|
||||||
<uni-popup ref="sharePopup" type="bottom" class="share-popup">
|
|
||||||
<view>
|
|
||||||
<view class="share-title">分享</view>
|
|
||||||
<view class="share-content">
|
|
||||||
<!-- #ifdef MP -->
|
|
||||||
<view class="share-box">
|
|
||||||
<button class="share-btn" :plain="true" open-type="share">
|
|
||||||
<view class="iconfont icon-share-friend"></view>
|
|
||||||
<text>分享给好友</text>
|
|
||||||
</button>
|
|
||||||
</view>
|
|
||||||
<!-- #endif -->
|
|
||||||
|
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
|
||||||
<view class="share-box" v-if="goodsCircle">
|
|
||||||
<button class="share-btn" :plain="true" @click="openBusinessView">
|
|
||||||
<view class="iconfont icon-haowuquan"></view>
|
|
||||||
<text>分享到好物圈</text>
|
|
||||||
</button>
|
|
||||||
</view>
|
|
||||||
<!-- #endif -->
|
|
||||||
|
|
||||||
<view class="share-box" @click="openPosterPopup">
|
|
||||||
<button class="share-btn" :plain="true">
|
|
||||||
<view class="iconfont icon-pengyouquan"></view>
|
|
||||||
<text>生成分享海报</text>
|
|
||||||
</button>
|
|
||||||
</view>
|
|
||||||
<!-- #ifdef H5 -->
|
|
||||||
<view class="share-box" @click="copyUrl">
|
|
||||||
<button class="share-btn" :plain="true">
|
|
||||||
<view class="iconfont icon-fuzhilianjie"></view>
|
|
||||||
<text>复制链接</text>
|
|
||||||
</button>
|
|
||||||
</view>
|
|
||||||
<!-- #endif -->
|
|
||||||
</view>
|
|
||||||
<view class="share-footer" @click="closeSharePopup"><text>取消分享</text></view>
|
|
||||||
</view>
|
|
||||||
</uni-popup>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<slot name="fixedbtn"></slot>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 操作区域 -->
|
|
||||||
<slot name="action"></slot>
|
|
||||||
<to-top v-if="showTop" @toTop="scrollToTopNative()"></to-top>
|
|
||||||
<ns-login ref="login"></ns-login>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// 商品详情视图
|
|
||||||
import uniPopup from '@/components/uni-popup/uni-popup.vue';
|
|
||||||
import nsGoodsRecommend from '@/components/ns-goods-recommend/ns-goods-recommend.vue';
|
|
||||||
import pengpaiFadeinOut from '@/components/pengpai-fadein-out/pengpai-fadein-out.vue';
|
|
||||||
import xiaoStarComponent from '@/components/xiao-star-component/xiao-star-component.vue';
|
|
||||||
import scroll from '@/common/js/scroll-view.js';
|
|
||||||
import toTop from '@/components/toTop/toTop.vue';
|
|
||||||
import detail from './detail.js';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'goods-detail-view',
|
|
||||||
props: {
|
|
||||||
goodsSkuDetail: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
uniPopup,
|
|
||||||
nsGoodsRecommend,
|
|
||||||
pengpaiFadeinOut,
|
|
||||||
toTop,
|
|
||||||
xiaoStarComponent
|
|
||||||
},
|
|
||||||
mixins: [scroll, detail]
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import '@/common/css/goods_detail.scss';
|
|
||||||
</style>
|
|
||||||
<style scoped></style>
|
|
||||||
@@ -1,246 +1,329 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 悬浮按钮 -->
|
<view v-if="pageCount === 1 || need" class="fixed-box"
|
||||||
<view v-if="pageCount == 1 || need" class="fixed-box"
|
:style="[customContainerStyle, {
|
||||||
:style="[{ height: fixBtnShow ? '400rpx' : '320rpx' }, customContainerStyle]">
|
height: containerHeight,
|
||||||
<!-- <view class="btn-item" v-if="fixBtnShow" @click="$util.redirectTo('/pages/index/index')"> -->
|
backgroundImage: bgUrl ? `url(${bgUrl})` : '',
|
||||||
<!-- 切换语言按钮 -->
|
backgroundSize: 'cover'
|
||||||
<button class="btn-item" v-if="fixBtnShow && isLanguageSwitchEnabled" @click="toggleLanguage()"
|
}]">
|
||||||
:style="[{ backgroundSize: '100% 100%' }, customButtonStyle]">
|
<!-- 中英文切换按钮 -->
|
||||||
<text :style="customTextStyle">{{ currentLangDisplayName }}</text>
|
<view
|
||||||
</button>
|
v-if="isLanguageSwitchEnabled && fixBtnShow"
|
||||||
<!-- 客服按钮 -->
|
class="btn-item common-bg"
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
@click="toggleLanguage"
|
||||||
<button class="btn-item" v-if="fixBtnShow" hoverClass="none" openType="contact" sessionFrom="weapp"
|
>
|
||||||
showMessageCard="true"
|
<text>{{ currentLangDisplayName }}</text>
|
||||||
:style="[{ backgroundImage: 'url(' + (kefuimg ? kefuimg : '') + ')', backgroundSize: '100% 100%' }, customButtonStyle]">
|
</view>
|
||||||
<text class="icox icox-kefu" v-if="!kefuimg"></text>
|
<!-- 微信官方客服按钮-->
|
||||||
<!-- <view>首页</view> -->
|
<button
|
||||||
</button>
|
v-if="fixBtnShow && hasValidKefuConfig && isWeappOfficialKefu"
|
||||||
<!-- #endif -->
|
class="btn-item common-bg"
|
||||||
<view class="btn-item" v-if="fixBtnShow" @click="call()"
|
open-type="contact"
|
||||||
:style="[{ backgroundImage: 'url(' + (phoneimg ? phoneimg : '') + ')', backgroundSize: '100% 100%' }, customButtonStyle]">
|
>
|
||||||
<text class="iconfont icon-dianhua" v-if="!phoneimg"></text>
|
<text class="icox icox-kefu" v-if="!kefuimg"></text>
|
||||||
<!-- <view>我的</view> -->
|
</button>
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- <view class="btn-item icon-xiala" v-if="fixBtnShow" @click="fixBtnShow ? (fixBtnShow = false) : (fixBtnShow = true)">
|
<!-- 其他类型客服按钮(智能客服、企业微信等)-->
|
||||||
<text class="iconfont icon-unfold"></text>
|
<view
|
||||||
</view>
|
v-if="fixBtnShow && hasValidKefuConfig && !isWeappOfficialKefu && !showWeappSystemKefu"
|
||||||
<view class="btn-item switch" v-else :class="{ show: fixBtnShow }"
|
class="btn-item common-bg"
|
||||||
@click="fixBtnShow ? (fixBtnShow = false) : (fixBtnShow = true)">
|
@click="handleUnifiedKefuClick"
|
||||||
<view class="">快捷</view>
|
>
|
||||||
<view>导航</view>
|
<image
|
||||||
</view> -->
|
v-if="currentKefuImg"
|
||||||
</view>
|
:src="currentKefuImg"
|
||||||
|
mode="aspectFill"
|
||||||
|
class="kefu-img"
|
||||||
|
show-menu-by-longpress></image>
|
||||||
|
<text class="ai-icon" v-if="isAIKefu && !currentKefuImg">🤖</text>
|
||||||
|
<text class="ai-icon" v-if="isWxworkKefu && !currentKefuImg">💬</text>
|
||||||
|
<text class="ai-icon" v-if="!isAIKefu && !isWxworkKefu && !currentKefuImg">👤</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 智能客服按钮(当同时显示小程序系统客服时)-->
|
||||||
|
<view
|
||||||
|
v-if="fixBtnShow && hasValidKefuConfig && !isWeappOfficialKefu && showWeappSystemKefu"
|
||||||
|
class="btn-item common-bg"
|
||||||
|
@click="handleUnifiedKefuClick"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
v-if="currentKefuImg"
|
||||||
|
:src="currentKefuImg"
|
||||||
|
mode="aspectFill"
|
||||||
|
class="kefu-img"
|
||||||
|
show-menu-by-longpress></image>
|
||||||
|
<text class="ai-icon" v-if="isAIKefu && !currentKefuImg">🤖</text>
|
||||||
|
<text class="ai-icon" v-if="isWxworkKefu && !currentKefuImg">💬</text>
|
||||||
|
<text class="ai-icon" v-if="!isAIKefu && !isWxworkKefu && !currentKefuImg">👤</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 小程序系统客服按钮 -->
|
||||||
|
<button
|
||||||
|
v-if="fixBtnShow && hasValidKefuConfig && showWeappSystemKefu"
|
||||||
|
class="btn-item common-bg"
|
||||||
|
open-type="contact"
|
||||||
|
>
|
||||||
|
<text class="icox icox-kefu" v-if="!kefuimg"></text>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 电话按钮 -->
|
||||||
|
<view
|
||||||
|
v-if="fixBtnShow"
|
||||||
|
class="btn-item common-bg"
|
||||||
|
@click="call"
|
||||||
|
:style="[{ backgroundImage: phoneimg ? `url(${phoneimg})` : '', backgroundSize: '100% 100%' }, customButtonStyle]"
|
||||||
|
>
|
||||||
|
<text class="iconfont icon-dianhua" v-if="!phoneimg"></text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { createCustomerService } from '@/common/js/customer-service.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'hover-nav',
|
name: 'hover-nav',
|
||||||
props: {
|
props: {
|
||||||
need: {
|
need: { type: Boolean, default: false }
|
||||||
type: Boolean,
|
},
|
||||||
default: false
|
data() {
|
||||||
}
|
return {
|
||||||
},
|
pageCount: 0,
|
||||||
data() {
|
fixBtnShow: true,
|
||||||
return {
|
shopInfo: null,
|
||||||
pageCount: 0,
|
currentLangIndex: 0,
|
||||||
fixBtnShow: true,
|
langIndexMap: {},
|
||||||
tel: '',
|
customerService: null,
|
||||||
kefuimg: '',
|
};
|
||||||
phoneimg: '',
|
},
|
||||||
shopInfo: null, // 店铺信息对象
|
computed: {
|
||||||
|
bgUrl() {
|
||||||
|
return this.shopInfo?.bgUrl || '';
|
||||||
|
},
|
||||||
|
aiAgentimg() {
|
||||||
|
return this.shopInfo?.aiAgentimg || '';
|
||||||
|
},
|
||||||
|
kefuimg() {
|
||||||
|
return this.shopInfo?.kefuimg || this.$util.getDefaultImage().kefu;
|
||||||
|
},
|
||||||
|
phoneimg() {
|
||||||
|
return this.shopInfo?.phoneimg || this.$util.getDefaultImage().phone;
|
||||||
|
},
|
||||||
|
tel() {
|
||||||
|
return this.shopInfo?.mobile || '';
|
||||||
|
},
|
||||||
|
isLanguageSwitchEnabled() {
|
||||||
|
return !!this.shopInfo?.ischina;
|
||||||
|
},
|
||||||
|
currentLangDisplayName() {
|
||||||
|
const lang = this.langIndexMap[this.currentLangIndex];
|
||||||
|
return lang === 'zh-cn' ? 'EN' : 'CN';
|
||||||
|
},
|
||||||
|
customContainerStyle() {
|
||||||
|
return this.shopInfo?.floatingButton?.container || {};
|
||||||
|
},
|
||||||
|
customButtonStyle() {
|
||||||
|
return this.shopInfo?.floatingButton?.button || {};
|
||||||
|
},
|
||||||
|
unreadCount() {
|
||||||
|
const customerService = createCustomerService(this);
|
||||||
|
return customerService.getUnreadCount();
|
||||||
|
},
|
||||||
|
currentKefuImg() {
|
||||||
|
const customerService = createCustomerService(this);
|
||||||
|
return customerService.getKefuButtonIcon();
|
||||||
|
},
|
||||||
|
isWeappOfficialKefu() {
|
||||||
|
const customerService = createCustomerService(this);
|
||||||
|
return customerService.isWeappOfficialKefu();
|
||||||
|
},
|
||||||
|
isAIKefu() {
|
||||||
|
const customerService = createCustomerService(this);
|
||||||
|
return customerService.isAIKefu();
|
||||||
|
},
|
||||||
|
isWxworkKefu() {
|
||||||
|
const customerService = createCustomerService(this);
|
||||||
|
return customerService.isWxworkKefu();
|
||||||
|
},
|
||||||
|
isThirdKefu() {
|
||||||
|
const customerService = createCustomerService(this);
|
||||||
|
return customerService.isThirdKefu();
|
||||||
|
},
|
||||||
|
showWeappSystemKefu() {
|
||||||
|
const customerService = createCustomerService(this);
|
||||||
|
return customerService.shouldShowExtraWeappSystemKefu();
|
||||||
|
},
|
||||||
|
hasValidKefuConfig() {
|
||||||
|
const customerService = createCustomerService(this);
|
||||||
|
return customerService.hasValidKefuConfig();
|
||||||
|
},
|
||||||
|
//根据显示的按钮数量动态计算容器高度
|
||||||
|
containerHeight() {
|
||||||
|
if (!this.fixBtnShow) return '320rpx';
|
||||||
|
|
||||||
// --- 语言切换相关 ---
|
let buttonCount = 1;
|
||||||
currentLangIndex: 0, // 当前选中的语言索引
|
if (this.isLanguageSwitchEnabled) buttonCount++;
|
||||||
langIndexMap: {}, // 语言索引到语言值的映射
|
if (this.showWeappSystemKefu) buttonCount++;
|
||||||
isLanguageSwitchEnabled: false, // 是否启用语言切换
|
buttonCount++;
|
||||||
|
const totalRpx = 94 * buttonCount - 14;
|
||||||
|
const pxValue = Math.round(totalRpx * 0.5);
|
||||||
|
|
||||||
// --- 其他 ---
|
return ` $ {pxValue}px`;
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
created() {
|
watch: {
|
||||||
// 初始化语言设置
|
shopInfo: {
|
||||||
this.initLanguage();
|
handler(newVal) {
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.initLanguage();
|
||||||
|
this.pageCount = getCurrentPages().length;
|
||||||
|
uni.getStorage({
|
||||||
|
key: 'shopInfo',
|
||||||
|
success: (e) => {
|
||||||
|
this.shopInfo = e.data;
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
console.warn('未获取到 shopInfo,使用默认设置');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 初始化 customerService 实例
|
||||||
|
this.customerService = createCustomerService(this);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initLanguage() {
|
||||||
|
this.langList = this.$langConfig.list();
|
||||||
|
this.langIndexMap = {};
|
||||||
|
for (let i = 0; i < this.langList.length; i++) {
|
||||||
|
this.langIndexMap[i] = this.langList[i].value;
|
||||||
|
}
|
||||||
|
const savedLang = this.$langConfig.getCurrentLocale();
|
||||||
|
if (savedLang) {
|
||||||
|
for (let i = 0; i < this.langList.length; i++) {
|
||||||
|
if (this.langList[i].value === savedLang) {
|
||||||
|
this.currentLangIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.currentLangIndex = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
this.kefuimg = this.$util.getDefaultImage().kefu
|
call() {
|
||||||
this.phoneimg = this.$util.getDefaultImage().phone
|
this.customerService.makePhoneCallByNumber(this.tel);
|
||||||
this.pageCount = getCurrentPages().length;
|
},
|
||||||
|
|
||||||
// 从店铺信息中获取相关信息
|
toggleLanguage() {
|
||||||
uni.getStorage({
|
this.currentLangIndex = this.currentLangIndex === 0 ? 1 : 0;
|
||||||
key: 'shopInfo',
|
const targetLang = this.langIndexMap[this.currentLangIndex];
|
||||||
success: (e) => {
|
|
||||||
console.log(`获取到的shopInfo:${JSON.stringify(e.data)}`)
|
|
||||||
this.shopInfo = e.data;
|
|
||||||
|
|
||||||
// 从店铺信息中获取手机号
|
uni.setStorageSync("lang", targetLang);
|
||||||
this.tel = e.data.mobile
|
|
||||||
// 从店铺信息中获取是否启用语言切换
|
|
||||||
this.isLanguageSwitchEnabled = e.data.ischina;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
},
|
const pages = getCurrentPages();
|
||||||
computed: {
|
const currentPage = pages[pages.length - 1];
|
||||||
currentLangDisplayName() {
|
const currentRoute = currentPage.route;
|
||||||
// 语言切换按钮显示名称,当前语言为中文时显示EN,否则显示CN
|
|
||||||
// 根据 langIndexMap 获取当前语言值
|
|
||||||
const lang = this.langIndexMap[this.currentLangIndex];
|
|
||||||
return lang == 'zh-cn' ? 'EN' : 'CN';
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取容器的自定义样式
|
uni.reLaunch({
|
||||||
customContainerStyle() {
|
url: '/' + currentRoute
|
||||||
// 只返回非空的样式属性,确保不覆盖原有的默认样式
|
});
|
||||||
return this.shopInfo?.floatingButton?.container || {};
|
},
|
||||||
},
|
|
||||||
|
|
||||||
// 获取按钮的自定义样式
|
handleUnifiedKefuClick() {
|
||||||
customButtonStyle() {
|
this.customerService.handleUnifiedKefuClick({
|
||||||
// 只返回非空的样式属性,确保不覆盖原有的默认样式
|
sendMessageTitle: '来自悬浮按钮的咨询',
|
||||||
return this.shopInfo?.floatingButton?.button || {};
|
sendMessagePath: '/pages/index/index'
|
||||||
},
|
});
|
||||||
|
}
|
||||||
// 获取文本的自定义样式
|
}
|
||||||
customTextStyle() {
|
}
|
||||||
// 只返回非空的样式属性,确保不覆盖原有的默认样式
|
|
||||||
return this.shopInfo?.floatingButton?.text || {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initLanguage() {
|
|
||||||
// 初始化语言列表
|
|
||||||
this.langList = this.$langConfig.list();
|
|
||||||
|
|
||||||
// 初始化语言索引映射
|
|
||||||
for (let i = 0; i < this.langList.length; i++) {
|
|
||||||
this.langIndexMap[i] = this.langList[i].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取存储的语言设置
|
|
||||||
const savedLang = uni.getStorageSync('lang');
|
|
||||||
if (savedLang) {
|
|
||||||
for (let i = 0; i < this.langList.length; i++) {
|
|
||||||
if (this.langList[i].value == savedLang) {
|
|
||||||
this.currentLangIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.currentLangIndex = 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//拨打电话
|
|
||||||
call() {
|
|
||||||
uni.makePhoneCall({
|
|
||||||
phoneNumber: this.tel + ''
|
|
||||||
})
|
|
||||||
},
|
|
||||||
toggleLanguage() {
|
|
||||||
// 切换语言索引
|
|
||||||
this.currentLangIndex = this.currentLangIndex == 0 ? 1 : 0;
|
|
||||||
const targetLang = this.langIndexMap[this.currentLangIndex];
|
|
||||||
|
|
||||||
// 获取当前页面路由
|
|
||||||
let currentRoute = this.$util.getCurrentRoute().path;
|
|
||||||
// 切换语言并重新加载当前页面
|
|
||||||
this.$langConfig.change(targetLang, currentRoute);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.container-box {
|
.fixed-box {
|
||||||
width: 100%;
|
position: fixed;
|
||||||
|
right: 0rpx;
|
||||||
.item-wrap {
|
bottom: 240rpx;
|
||||||
border-radius: 10rpx;
|
/* #ifdef H5 */
|
||||||
|
bottom: 320rpx;
|
||||||
.image-box {
|
/* #endif */
|
||||||
border-radius: 10rpx;
|
z-index: 10;
|
||||||
}
|
border-radius: 120rpx;
|
||||||
|
padding: 20rpx 0;
|
||||||
image {
|
display: flex;
|
||||||
width: 100%;
|
justify-content: center;
|
||||||
height: auto;
|
flex-direction: column;
|
||||||
border-radius: 10rpx;
|
width: 100rpx;
|
||||||
will-change: transform;
|
box-sizing: border-box;
|
||||||
}
|
transition: 0.3s;
|
||||||
}
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
//悬浮按钮
|
.btn-item {
|
||||||
.fixed-box {
|
display: flex;
|
||||||
position: fixed;
|
justify-content: center;
|
||||||
right: 0rpx;
|
text-align: center;
|
||||||
bottom: 240rpx;
|
flex-direction: column;
|
||||||
// #ifdef H5
|
line-height: 1;
|
||||||
bottom: 320rpx;
|
margin: 14rpx 0;
|
||||||
// #endif
|
transition: 0.1s;
|
||||||
z-index: 10;
|
color: var(--hover-nav-text-color);
|
||||||
// background: #fff;
|
border-radius: 50%;
|
||||||
// box-shadow: 2rpx 2rpx 22rpx rgba(0, 0, 0, 0.3);
|
width: 80rpx;
|
||||||
border-radius: 120rpx;
|
height: 80rpx;
|
||||||
padding: 20rpx 0;
|
padding: 0;
|
||||||
display: flex;
|
overflow: hidden;
|
||||||
justify-content: center;
|
}
|
||||||
flex-direction: column;
|
|
||||||
width: 100rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
transition: 0.3s;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.btn-item {
|
.common-bg {
|
||||||
display: flex;
|
background-color: var(--hover-nav-bg-color);
|
||||||
justify-content: center;
|
}
|
||||||
text-align: center;
|
|
||||||
flex-direction: column;
|
|
||||||
line-height: 1;
|
|
||||||
margin: 14rpx 0;
|
|
||||||
transition: 0.1s;
|
|
||||||
background: #c6251b;
|
|
||||||
color: #fff;
|
|
||||||
border-radius: 40rpx;
|
|
||||||
width: 80rpx;
|
|
||||||
height: 80rpx;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
text {
|
.btn-item text {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
}
|
}
|
||||||
.iconfont,
|
|
||||||
.icox {
|
|
||||||
font-size: 36rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
border-radius: 40rpx;
|
|
||||||
/* 确保图标本身也是圆形 */
|
|
||||||
}
|
|
||||||
|
|
||||||
view {
|
.iconfont,
|
||||||
font-size: 26rpx;
|
.icox {
|
||||||
font-weight: bold;
|
font-size: 36rpx;
|
||||||
}
|
font-weight: bold;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 14rpx 0;
|
||||||
|
border-radius: 50rpx;
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
&.show {
|
.iconfont text,
|
||||||
transform: rotate(180deg);
|
.icox text {
|
||||||
}
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
&.switch {}
|
.kefu-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
&.icon-xiala {
|
.ai-icon {
|
||||||
margin: 0;
|
font-size: 40rpx;
|
||||||
margin-top: 0.1rpx;
|
width: 100%;
|
||||||
}
|
height: 100%;
|
||||||
}
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
:src="mOption.src"
|
:src="mOption.src"
|
||||||
mode="widthFix"
|
mode="widthFix"
|
||||||
@click="toTopClick"
|
@click="toTopClick"
|
||||||
/>
|
show-menu-by-longpress/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -62,8 +62,6 @@
|
|||||||
// 引入回到顶部组件
|
// 引入回到顶部组件
|
||||||
import MescrollTop from './components/mescroll-top.vue';
|
import MescrollTop from './components/mescroll-top.vue';
|
||||||
|
|
||||||
import nsLoading from '@/components/ns-loading/ns-loading.vue';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'mescroll-uni',
|
name: 'mescroll-uni',
|
||||||
components: {
|
components: {
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
<swiper :indicator-dots="advList.length > 1" indicator-active-color="#ffffff" :autoplay="true" :interval="3000" :duration="1000" v-if="advList.length > 1" @change="changeSwiper" :current="currentIndex" :style="{ height: swiperHeight + 'px' }" class="item-wrap">
|
<swiper :indicator-dots="advList.length > 1" indicator-active-color="#ffffff" :autoplay="true" :interval="3000" :duration="1000" v-if="advList.length > 1" @change="changeSwiper" :current="currentIndex" :style="{ height: swiperHeight + 'px' }" class="item-wrap">
|
||||||
<swiper-item v-for="(item, index) in advList" :key="index" @click="jumppage(item.adv_url)">
|
<swiper-item v-for="(item, index) in advList" :key="index" @click="jumppage(item.adv_url)">
|
||||||
<view class="image-box">
|
<view class="image-box">
|
||||||
<image :src="$util.img(item.adv_image)" mode="widthFix" :id="'content-wrap' + index"/>
|
<image :src="$util.img(item.adv_image)" mode="widthFix" :id="'content-wrap' + index" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
</swiper-item>
|
</swiper-item>
|
||||||
</swiper>
|
</swiper>
|
||||||
<view v-else class="container-box item-wrap">
|
<view v-else class="container-box item-wrap">
|
||||||
<image :src="$util.img(advList[0]['adv_image'])" mode="widthFix" lazy-load="true" @load="imageLoad" @click="jumppage(advList[0].adv_url)"/>
|
<image :src="$util.img(advList[0]['adv_image'])" mode="widthFix" lazy-load="true" @load="imageLoad" @click="jumppage(advList[0].adv_url)" show-menu-by-longpress/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="message">
|
<view class="message">
|
||||||
<view class="goods-item" v-if="goodsInfo.goods_name || goodsInfo.en_goods_name">
|
<view class="goods-item" v-if="goodsInfo.goods_name || goodsInfo.en_goods_name">
|
||||||
<image :src="$util.img(goodsInfo.sku_image)" mode="aspectFill"></image>
|
<image :src="$util.img(goodsInfo.sku_image)" mode="aspectFill" show-menu-by-longpress></image>
|
||||||
<view class="goods-info">
|
<view class="goods-info">
|
||||||
<view class="goods-name">{{ goodsInfo.sku_name ? goodsInfo.sku_name : (isEnEnv ? goodsInfo.en_goods_name : goodsInfo.goods_name) }}</view>
|
<view class="goods-name">{{ goodsInfo.sku_name ? goodsInfo.sku_name : (isEnEnv ? goodsInfo.en_goods_name : goodsInfo.goods_name) }}</view>
|
||||||
<view class="goods-bottom">
|
<view class="goods-bottom">
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="goods-item" v-else-if="goodsDetail">
|
<view class="goods-item" v-else-if="goodsDetail">
|
||||||
<image :src="$util.img(goodsDetail.sku_image)" mode="aspectFill"></image>
|
<image :src="$util.img(goodsDetail.sku_image)" mode="aspectFill" show-menu-by-longpress></image>
|
||||||
<view class="goods-info">
|
<view class="goods-info">
|
||||||
<view class="goods-name">{{ goodsDetail.sku_name ? goodsDetail.sku_name : (isEnEnv ? goodsDetail.en_goods_name : goodsDetail.goods_name) }}</view>
|
<view class="goods-name">{{ goodsDetail.sku_name ? goodsDetail.sku_name : (isEnEnv ? goodsDetail.en_goods_name : goodsDetail.goods_name) }}</view>
|
||||||
<view class="goods-bottom">
|
<view class="goods-bottom">
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="message">
|
<view class="message">
|
||||||
<view class="goods-item" v-if="orderdetails">
|
<view class="goods-item" v-if="orderdetails">
|
||||||
<image :src="$util.img(orderdetails.order_goods ? orderdetails.order_goods[0].sku_image : '')" mode="aspectFill"></image>
|
<image :src="$util.img(orderdetails.order_goods ? orderdetails.order_goods[0].sku_image : '')" mode="aspectFill" show-menu-by-longpress></image>
|
||||||
<view class="goods-info">
|
<view class="goods-info">
|
||||||
<view class="goods-name">{{ orderdetails.order_goods ? orderdetails.order_goods[0].sku_name : '' }}</view>
|
<view class="goods-name">{{ orderdetails.order_goods ? orderdetails.order_goods[0].sku_name : '' }}</view>
|
||||||
<view class="font-size-goods-tag">订单状态:{{ orderdetails.order_status_name }}</view>
|
<view class="font-size-goods-tag">订单状态:{{ orderdetails.order_status_name }}</view>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="goods-item" v-else-if="orderInfo">
|
<view class="goods-item" v-else-if="orderInfo">
|
||||||
<image :src="$util.img(orderInfo.order_goods ? orderInfo.order_goods[0].sku_image : '')" mode="aspectFill"></image>
|
<image :src="$util.img(orderInfo.order_goods ? orderInfo.order_goods[0].sku_image : '')" mode="aspectFill" show-menu-by-longpress></image>
|
||||||
<view class="goods-info">
|
<view class="goods-info">
|
||||||
<view class="goods-name">{{ orderInfo.order_goods ? orderInfo.order_goods[0].sku_name : '' }}</view>
|
<view class="goods-name">{{ orderInfo.order_goods ? orderInfo.order_goods[0].sku_name : '' }}</view>
|
||||||
<view class="font-size-goods-tag">订单状态:{{ orderInfo.order_status_name }}</view>
|
<view class="font-size-goods-tag">订单状态:{{ orderInfo.order_status_name }}</view>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="goods">
|
<view class="goods">
|
||||||
<view class="goods-msg">
|
<view class="goods-msg">
|
||||||
<image :src="$util.img(goodsInfo.sku_image)" mode="aspectFill"></image>
|
<image :src="$util.img(goodsInfo.sku_image)" mode="aspectFill" show-menu-by-longpress></image>
|
||||||
<view class="goods-item">
|
<view class="goods-item">
|
||||||
<view class="title">{{ isEnEnv ? goodsInfo.en_goods_name : goodsInfo.goods_name }}</view>
|
<view class="title">{{ isEnEnv ? goodsInfo.en_goods_name : goodsInfo.goods_name }}</view>
|
||||||
<view class="goods-sku">
|
<view class="goods-sku">
|
||||||
@@ -3,28 +3,37 @@
|
|||||||
<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" v-if="config.type == 'aliapp'"/>
|
<contact-button :tnt-inst-id="config.instid" :scene="config.scene" size="1000rpx"
|
||||||
|
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 -->
|
||||||
|
|
||||||
|
<!-- #ifndef MP-WEIXIN && MP-ALIPAY -->
|
||||||
|
<!-- 其他平台保持原逻辑 -->
|
||||||
|
<button type="default" hover-class="none" :open-type="openType" class="contact-button" @click="contactServicer"
|
||||||
|
:send-message-title="sendMessageTitle" :send-message-path="sendMessagePath"
|
||||||
|
:send-message-img="sendMessageImg" :show-message-card="true"></button>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
<uni-popup ref="servicePopup" type="center">
|
<uni-popup ref="servicePopup" type="center">
|
||||||
<view class="service-popup-wrap">
|
<view class="service-popup-wrap">
|
||||||
<view class="head-wrap" @click="$refs.servicePopup.close()">
|
<view class="head-wrap" @click="$refs.servicePopup.close()">
|
||||||
<text>联系客服</text>
|
<text>联系客服</text>
|
||||||
<text class="iconfont icon-close"></text>
|
<text class="iconfont icon-close"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="body-wrap">{{ siteInfo.site_tel ? '请联系客服,客服电话是' + siteInfo.site_tel : '抱歉,商家暂无客服,请线下联系' }}</view>
|
<view class="body-wrap">{{ siteInfo.site_tel ? '请联系客服,客服电话是' + siteInfo.site_tel : '抱歉,商家暂无客服,请线下联系' }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</view>
|
</view>
|
||||||
@@ -32,140 +41,130 @@
|
|||||||
|
|
||||||
<!-- 客服组件 -->
|
<!-- 客服组件 -->
|
||||||
<script>
|
<script>
|
||||||
export default {
|
import { createCustomerService } from '@/common/js/customer-service.js';
|
||||||
name: 'ns-contact',
|
|
||||||
props: {
|
export default {
|
||||||
niushop: {
|
name: 'ns-contact',
|
||||||
type: Object,
|
props: {
|
||||||
default: function() {
|
niushop: {
|
||||||
return {};
|
type: Object,
|
||||||
}
|
default: function () {
|
||||||
},
|
return {};
|
||||||
sendMessageTitle: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
sendMessagePath: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
sendMessageImg: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
sendMessageTitle: {
|
||||||
return {
|
type: String,
|
||||||
config: null,
|
default: ''
|
||||||
openType: ''
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
created() {
|
sendMessagePath: {
|
||||||
if (this.servicerConfig) {
|
type: String,
|
||||||
// #ifdef H5
|
default: ''
|
||||||
this.config = this.servicerConfig.h5;
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
this.config = this.servicerConfig.weapp;
|
|
||||||
if (this.config.type == 'weapp') this.openType = 'contact';
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef MP-ALIPAY
|
|
||||||
this.config = this.servicerConfig.aliapp;
|
|
||||||
if (this.config.type == 'aliapp') this.openType = 'contact';
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
sendMessageImg: {
|
||||||
/**
|
type: String,
|
||||||
* 联系客服
|
default: ''
|
||||||
*/
|
|
||||||
contactServicer() {
|
|
||||||
if (this.config.type == 'none') {
|
|
||||||
this.$refs.servicePopup.open();
|
|
||||||
}
|
|
||||||
if (this.openType == 'contact') return;
|
|
||||||
|
|
||||||
switch (this.config.type) {
|
|
||||||
case 'wxwork':
|
|
||||||
// #ifdef H5
|
|
||||||
location.href = this.config.wxwork_url;
|
|
||||||
// #endif
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
wx.openCustomerServiceChat({
|
|
||||||
extInfo: { url: this.config.wxwork_url },
|
|
||||||
corpId: this.config.corpid,
|
|
||||||
showMessageCard: true,
|
|
||||||
sendMessageTitle: this.sendMessageTitle,
|
|
||||||
sendMessagePath: this.sendMessagePath,
|
|
||||||
sendMessageImg: this.sendMessageImg
|
|
||||||
});
|
|
||||||
// #endif
|
|
||||||
break;
|
|
||||||
case 'third':
|
|
||||||
location.href = this.config.third_url;
|
|
||||||
break;
|
|
||||||
case 'niushop':
|
|
||||||
this.$util.redirectTo('/pages_tool/chat/room', this.niushop);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.makePhoneCall();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 店铺联系方式
|
|
||||||
*/
|
|
||||||
makePhoneCall() {
|
|
||||||
this.$api.sendRequest({
|
|
||||||
url: '/api/site/shopcontact',
|
|
||||||
success: res => {
|
|
||||||
if (res.code == 0 && res.data.mobile) uni.makePhoneCall({
|
|
||||||
phoneNumber: res.data
|
|
||||||
.mobile
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
customerService: null,
|
||||||
|
buttonConfig: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
/**
|
||||||
|
* 是否使用官方客服
|
||||||
|
*/
|
||||||
|
useOfficialService() {
|
||||||
|
if (!this.buttonConfig) return true;
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
// 如果是微信小程序,检查配置
|
||||||
|
if (this.buttonConfig.type === 'weapp') {
|
||||||
|
// 默认使用官方客服,除非明确设置为false
|
||||||
|
return this.buttonConfig.useOfficial !== false;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客服配置
|
||||||
|
*/
|
||||||
|
config() {
|
||||||
|
return this.customerService?.getPlatformConfig() || {};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开类型
|
||||||
|
*/
|
||||||
|
openType() {
|
||||||
|
return this.buttonConfig?.openType || '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 初始化客服服务
|
||||||
|
this.customerService = createCustomerService(this);
|
||||||
|
this.buttonConfig = this.customerService.getButtonConfig();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 联系客服
|
||||||
|
*/
|
||||||
|
contactServicer() {
|
||||||
|
// 如果是微信/支付宝小程序客服,由系统自动处理
|
||||||
|
if (this.buttonConfig.openType === 'contact') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用统一客服处理
|
||||||
|
this.customerService.handleCustomerClick({
|
||||||
|
niushop: this.niushop,
|
||||||
|
sendMessageTitle: this.sendMessageTitle,
|
||||||
|
sendMessagePath: this.sendMessagePath,
|
||||||
|
sendMessageImg: this.sendMessageImg
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.contact-wrap {
|
.contact-wrap {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.contact-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 5;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.contact-button {
|
.service-popup-wrap {
|
||||||
width: 100%;
|
width: 600rpx;
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
.head-wrap {
|
||||||
left: 0;
|
display: flex;
|
||||||
top: 0;
|
justify-content: space-between;
|
||||||
z-index: 5;
|
align-items: center;
|
||||||
padding: 0;
|
padding: 0 30rpx;
|
||||||
margin: 0;
|
height: 90rpx;
|
||||||
opacity: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.service-popup-wrap {
|
.body-wrap {
|
||||||
width: 600rpx;
|
text-align: center;
|
||||||
|
padding: 30rpx;
|
||||||
.head-wrap {
|
height: 100rpx;
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 30rpx;
|
|
||||||
height: 90rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.body-wrap {
|
|
||||||
text-align: center;
|
|
||||||
padding: 30rpx;
|
|
||||||
height: 100rpx;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="copyright && copyright.gov_record" class="gov-wrap" @click="toHref(copyright.gov_url)" target="_blank">
|
<view v-if="copyright && copyright.gov_record" class="gov-wrap" @click="toHref(copyright.gov_url)" target="_blank">
|
||||||
<image :src="$util.img('public/uniapp/common/gov_record.png')" alt="公安备案" />
|
<image :src="$util.img('public/uniapp/common/gov_record.png')" alt="公安备案" show-menu-by-longpress/>
|
||||||
<text>{{ copyright.gov_record }}</text>
|
<text>{{ copyright.gov_record }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view> -->
|
</view> -->
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<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" show-menu-by-longpress></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>
|
||||||
@@ -45,7 +45,7 @@ export default {
|
|||||||
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(this.$util.INDEX_PAGE_URL);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
re(text) {
|
re(text) {
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="box img-boxs">
|
<view class="box img-boxs">
|
||||||
<view class="img-box" v-for="(v, k) in item.img_lists" :key="k" @click="uploadImg(index)">
|
<view class="img-box" v-for="(v, k) in item.img_lists" :key="k" @click="uploadImg(index)">
|
||||||
<image :src="$util.img(v)" mode="aspectFill"></image>
|
<image :src="$util.img(v)" mode="aspectFill" show-menu-by-longpress></image>
|
||||||
<text class="iconfont icon-guanbi" @click.stop="delImg(k, index)"></text>
|
<text class="iconfont icon-guanbi" @click.stop="delImg(k, index)"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="img-box" @click="addImg(index)"><text class="iconfont icon-add1"></text></view>
|
<view class="img-box" @click="addImg(index)"><text class="iconfont icon-add1"></text></view>
|
||||||
@@ -200,12 +200,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import pickRegions from '@/components/pick-regions/pick-regions.vue';
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ns-form',
|
name: 'ns-form',
|
||||||
components: {
|
|
||||||
pickRegions
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
data: {
|
data: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
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: {
|
||||||
@@ -72,9 +71,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components:{
|
|
||||||
nsContact
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
clickEvent() {
|
clickEvent() {
|
||||||
this.$emit('click');
|
this.$emit('click');
|
||||||
|
|||||||
@@ -3,16 +3,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import nsLoading from '@/components/ns-loading/ns-loading.vue';
|
|
||||||
import nsGoodsSkuIndex from '@/components/ns-goods-sku/ns-goods-sku-index.vue';
|
|
||||||
|
|
||||||
// 商品推荐
|
// 商品推荐
|
||||||
export default {
|
export default {
|
||||||
name: 'ns-goods-recommend',
|
name: 'ns-goods-recommend',
|
||||||
components: {
|
|
||||||
nsLoading,
|
|
||||||
nsGoodsSkuIndex
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
list: [],
|
list: [],
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user