Merge branch 'dev' into test

This commit is contained in:
lifizer
2025-03-06 21:30:11 +08:00
82 changed files with 25041 additions and 467 deletions
+58
View File
@@ -0,0 +1,58 @@
import request from "@/utils/request";
/**
* 礼品卡送礼订单确认
* @param {*} data
*/
export function getGiftCardSendOrderConfirm(data) {
return request.post("/giftCard/confirm", data);
}
/**
* 礼品卡送礼订单创建
* @param {*} data
*/
export function getGiftCardSendOrder(key, data) {
return request.post("/giftCard/create/" + key, data);
}
/**
* 礼品详情
* @param {*} data
*/
export function getGiftCardDetail(data) {
return request.get("/giftCard/info", data);
}
/**
* 领取礼品卡
* @param {*} data
*/
export function getGiftCardReceive(data) {
return request.post("/giftCard/receive", data);
}
/**
* 礼品卡赠礼须知
* @param {*} data
*/
export function getGiftCardSendNotice(data) {
return request.get("/giftCard/giftNotice", data);
}
/**
* 计算订单金额
* @param {*} data
*/
export function getGiftCardSendOrderAmount(key, data) {
return request.post("giftCard/computed/" + key, data);
}
/**
* 再送一份
* @param {*} data
*/
export function getGiftCardResend(data) {
return request.post("/giftCard/makeAgain", data);
}
+22
View File
@@ -0,0 +1,22 @@
import request from '@/utils/request'
/**
* 收到的礼品卡列表
* */
export function giftCardReceiveList(param) {
return request.get('/giftCard/receiveList', param)
}
/**
* 送出的礼品卡列表
* */
export function giftCardSendList(param) {
return request.get('/giftCard/sendList', param)
}
/**
* 赠礼须知
* */
export function giftNotice(param) {
return request.get('/giftCard/giftNotice', param)
}
+6
View File
@@ -0,0 +1,6 @@
import request from '@/utils/request'
// 文玩店铺列表
export function getSearchPageConfig() {
return request.get('/searchPage', {}, { login: false })
}
+13
View File
@@ -585,4 +585,17 @@ export function getHistory(params) {
*/
export function getUserLike(params) {
return request.get('/cart/guessYouLike',params)
}
/**
* 用户功能指引状态
* @param {*} params
* @returns
*/
export function queryUserGuide(params) {
return request.get('/user/guide/status', params)
}
export function setUserGuide(params) {
return request.post('/user/guide/status', params)
}
+4 -5
View File
@@ -17,16 +17,15 @@
}
.search-box {
width: 686rpx;
width: 90%;
height: 60rpx;
margin: 0 auto;
padding: 0 24rpx 0 32rpx;
box-sizing: border-box;
background: #F7F7F7;
border-radius: 30rpx;
input {
width: 560rpx;
width: 540rpx;
font-size: 24rpx;
}
@@ -66,8 +65,8 @@
}
.active {
border-left: 6rpx solid #FD574B;
color: #FD574B;
border-left: 6rpx solid #C52733;
color: #C52733;
font-weight: bold;
}
}
+3 -2
View File
@@ -87,7 +87,7 @@ export default {
components: {
uniPopup
},
props: ["callback", "items", "defaultValue"],
props: ["callback", "items", "defaultValue", 'disabled'],
data() {
return {
value: "请选择",
@@ -107,7 +107,7 @@ export default {
},
defaultValue(newValue) {
this.value = newValue;
// this.adjustDefaultValue();
this.adjustDefaultValue();
}
},
mounted() {
@@ -147,6 +147,7 @@ export default {
return idx;
},
open() {
if(this.disabled) return;
if (this.$refs.popup.showPopup) {
this.$refs.popup.close();
return;
+24 -1
View File
@@ -1,7 +1,11 @@
<template>
<view class="popup-coupons">
<view class="popup-box">
<view class="popup-title bold tc">优惠详情</view>
<view class="popup-title bold tc v12-justify-between">
<text></text>
<text>优惠详情</text>
<u-icon name="close" color="#666" size="14" @click.stop="close"></u-icon>
</view>
<SubSection
:current="current"
:can-use="canUse"
@@ -121,6 +125,10 @@ export default {
currentPrice: {
default: 0,
type: Number
},
id: {
type: Number,
default: 0
}
},
data() {
@@ -133,6 +141,17 @@ export default {
},
}
},
watch: {
id: {
immediate: true,
handler(value) {
console.log('couponId', value);
if(value) {
this.selectCoupon(value)
}
}
}
},
computed: {
list() {
const temp = this.current === 0 ? this.twoList['usable'] : this.twoList['unusable']
@@ -173,6 +192,9 @@ export default {
this.$emit('max', this.largOne)
},
methods: {
close() {
this.$emit('close')
},
force2Decimal(value) {
return this.$force2Decimal(value);
},
@@ -190,6 +212,7 @@ export default {
if (this.current === 1) return
uni.setStorageSync('couponId', this.couponId)
this.$emit('change', this.selectItem || {})
this.$emit('ok', this.couponId)
}
}
}
+224
View File
@@ -0,0 +1,224 @@
<template>
<view v-if="show" class="guide-remark white" @touchmove.stop.prevent="" >
<view class="guid-wrap">
<image
v-for="(img, index) in functionGuideData.imgs"
:key="index"
:style="[img.style]"
:src="img.url"
@click.stop="handleImg(img)"
mode="aspectFit|aspectFill|widthFix"
lazy-load="true" >
</image>
<view class="box" :style="[functionGuideData.position]">
<!-- <view class="tips flex" :style="{top: functionGuideData.tipsPosition || '-110rpx'}">
{{ functionGuideData.tips }}
</view> -->
</view>
<!-- <view class="btn-wrap flex_center" :style="[functionGuideData.btnGroupPosition]">
<view class="btn flex_center" @click="jump">跳过</view>
<view class="next-btn v12-primary flex_center" @click="next">{{ functionGuideData.step==maxStep ? '知道了' : '下一步' }}</view>
</view> -->
</view>
</view>
</template>
<script>
let timer = null
let flag = false
export default {
props: {
maxStep: {
type: Number,
default: 3
},
guideData: {
type: Object,
default: ()=> {
return {
step: 1,
tips: '', // 介绍
tipsPosition: '', // 介绍 显示位置
btnGroupPosition: '', // 按钮组显示位置
position: {}
}
}
}
},
data() {
return {
show: false,
functionGuideData: {}
}
},
watch: {
guideData: {
deep: true,
immediate: false,
handler(data) {
this.functionGuideData = data
}
}
},
methods: {
handleImg(img) {
if(!img.isBtn) return
if(img.isBtn === 'next') {
this.next()
return
}
if(img.isBtn === 'jump') {
this.jump()
return
}
},
init() {
if (this.show) return
setTimeout(() => {
// const show = uni.getStorageSync('showGuide')
const show = false
if (!show) {
this.show = true
this.$parent.setFunctionGuideData({ step: 1 })
}
}, 1000)
},
jump() {
this.$parent.setFunctionGuideData({ step: 'jump' })
this.setFunctionGuideState()
// 标记状态,只有首次访问小程序时显示指引
uni.setStorageSync('showGuide', 1)
},
next() {
this.throttle(() => {
if (this.functionGuideData.step == this.maxStep) {
this.jump()
return
}
let step = this.functionGuideData.step
this.$parent.setFunctionGuideData({ step: step + 1 })
}, 800)
},
setFunctionGuideState() {
this.show = false
this.$emit('hide')
},
/* 节流 */
throttle(fn) {
if (!flag) {
flag = true
typeof fn === 'function' && fn()
timer = setTimeout(() => {
flag = false
}, 800)
}
}
}
}
</script>
<style lang="scss" scoped>
.btn-wrap{
position: absolute;
z-index: 99;
}
.guid-wrap{
position: relative;
height: inherit;
width: inherit;
}
.next-btn {
color: #fff;
padding: 2rpx 10rpx;
}
.plus {
width: 140rpx;
height: 2rpx;
position: relative;
.in-border {
border: 2rpx dashed #fff;
width: 110rpx;
height: 110rpx;
border-radius: 50%;
position: absolute;
left: 10rpx;
top: -55rpx;
}
.plus-icon {
background: #fff;
border-radius: 50%;
overflow: hidden;
width: 92rpx;
height: 92rpx;
}
}
.guide-remark {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20230828;
.box {
position: absolute;
z-index: 10;
width: 686rpx;
border-radius: 24rpx;
left: 32rpx;
box-shadow: 0 0 0 120vh rgba(0, 0, 0, .6);
transition: all 0.3s ease;
.tips {
width: 100%;
background: #bee9ff;
border-radius: 24rpx;
padding: 20rpx 50rpx;
box-sizing: border-box;
position: absolute;
left: 0;
top: -110rpx;
z-index: 2;
font-size: 28rpx;
transition: top 0.3s ease;
}
.btn-group {
width: 100%;
position: absolute;
left: 50%;
transform: translateX(-50%);
font-size: 32rpx;
z-index: 2;
transition: bottom 0.3s ease;
.btn {
width: 240rpx;
height: 84rpx;
border-radius: 52rpx;
border: 2rpx solid #FFFFFF;
background: #fff;
margin: 0 30rpx;
white-space: nowrap;
}
}
}
}
.flex {
display: flex;
align-items: center;
}
.flex_center {
@extend .flex;
justify-content: center;
}
</style>
+29 -1
View File
@@ -1,6 +1,6 @@
<template>
<view>
<view class="product-window" :class="attr.cartAttr === true ? 'on' : ''">
<view class="product-window" :class="attr.cartAttr === true ? 'on' : ''" :style="{paddingBottom: paddingBottom}">
<view class="textpic acea-row row-between-wrapper">
<view class="pictrue" @click="previewImg(attrObj.productSelect.image)">
<image :src="attrObj.productSelect.image" class="image" />
@@ -59,6 +59,22 @@
>+</view>
</view>
</view>
<view class="v12-px-2 v12-mt-3" v-if="showOk">
<u-button
shape="circle"
color="#C52733"
@click="$emit('ok')"
:disabled="(attr.productSelect.stock === 0 && attr.cartAttr)"
>加入购物车</u-button>
</view>
<view class="v12-px-2 v12-mt-3" v-if="isGift">
<u-button
shape="circle"
color="#C52733"
@click="$emit('gift')"
:disabled="(attr.productSelect.stock === 0 && attr.cartAttr)"
>送给朋友</u-button>
</view>
</view>
<view class="mask" @touchmove.prevent :hidden="attr.cartAttr === false" @click="closeAttr"></view>
</view>
@@ -67,6 +83,18 @@
export default {
name: "ProductWindow",
props: {
isGift: {
type: Boolean,
default: false
},
paddingBottom: {
type: String,
default: '140rpx'
},
showOk: {
type: Boolean,
default: false
},
attr: {
type: Object,
default: () => {
+50 -1
View File
@@ -21,12 +21,31 @@
<view class="evaluate-infor v12-font-24">{{ item.comment }}</view>
<view class="imgList acea-row">
<view v-if="item.video" class="pictrue">
<view
@click="pauseOtherVideo('video' + evaluateWtapperIndex)"
v-if="activeVideo !== 'video' + evaluateWtapperIndex"
class="play-icon"
>
<u-icon name="play-right-fill" color="#fff" size="48"></u-icon>
</view>
<image
v-if="activeVideo !== 'video' + evaluateWtapperIndex"
:src="item.video + '?vframe/jpg/offset/1'"
class="image"
@click="pauseOtherVideo('video' + evaluateWtapperIndex)"
>
</image>
<video
v-else
:src="item.video"
:poster="item.video + '?vframe/jpg/offset/1'"
controls
autoplay
play-btn-position="center"
:id="'video' + evaluateWtapperIndex"
class="image"
@play="pauseOtherVideo('video' + evaluateWtapperIndex)"
/>
</view>
<view
@@ -56,7 +75,10 @@ export default {
}
},
data: function() {
return {};
return {
videoPlayers: [],
activeVideo: null,
};
},
mounted: function() {},
methods: {
@@ -66,6 +88,19 @@ export default {
current:imgs[index],
urls:imgs
})
},
// 播放视频时暂停其他视频
pauseOtherVideo(video) {
this.activeVideo = video;
if(this.videoPlayers.includes(video)) {
this.videoPlayers.forEach((item) => {
if(item !== video) {
uni.createVideoContext(item, this).pause();
}
})
} else {
this.videoPlayers.push(video);
}
}
}
};
@@ -80,4 +115,18 @@ export default {
.time{
padding: 0 !important;
}
.evaluateWtapper .evaluateItem .imgList .pictrue{
position: relative;
width: 300rpx;
.play-icon {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 80rpx;
height: 80rpx;
}
}
</style>
+87
View File
@@ -0,0 +1,87 @@
### 使用组件
```html
<time-picker-popup ref="TimePickerPopupRef" :value="value" @confirm="confirm"></time-picker-popup>
```
### 引入组件
```javascript
import TimePickerPopup from '@/components/time-picker-popup/time-picker-popup.vue';
```
### 注册组件
```javascript
export default {
components: { TimePickerPopup },
data() {
return {
value: ['00', '00', '00', '00']
}
},
onReady() {
this.open();
},
methods: {
confirm(data) {
uni.showToast({
title: `${data[0]}:${data[1]}-${data[2]}:${data[3]}`
})
},
open() {
this.$refs.TimePickerPopupRef.open();
}
}
}
```
### 参数
```javascript
// 当前选中的值
value: {
type: Array,
default: () => (['00', '00', '00', '00'])
},
// 标题
title: {
type: String,
default: '时间'
},
// 取消按钮文字
cancelText: {
type: String,
default: '取消'
},
// 取消按钮颜色
canceColor: {
type: String,
default: '#666666'
},
// 确定按钮文字
confirmText: {
type: String,
default: '确定'
},
// 确定按钮颜色
confirmColor: {
type: String,
default: '#2bb781'
},
// 分割符
segmentation: {
type: String,
default: '-'
},
// 设置选择器中间选中框的类名 注意页面或组件的style中写了scoped时,需要在类名前写/deep/
indicatorClass: {
type: String,
default: 'picker-view__indicator'
},
// 设置选择器中间选中框的样式
indicatorStyle: {
type: String,
default: ''
},
```
@@ -0,0 +1,159 @@
<template>
<!-- 时间选择器弹窗 -->
<uni-popup ref="popup" type="bottom" :safe-area="false">
<view class="custom-picker">
<view class="custom-picker__header">
<view class="cancel" :style="{ color: canceColor }" @tap="onCancel">{{ cancelText }}</view>
<view class="title">{{ title }}</view>
<view class="confirm" :style="{ color: confirmColor }" @tap="onConfirm">{{ confirmText }}</view>
</view>
<picker-view :indicator-class="indicatorClass" :indicator-style="indicatorStyle" class="picker-view"
:value="value" @change="bindChange" @pickstart="pickstart" @pickend="pickend">
<picker-view-column>
<view class="picker-view__item" v-for="(item,index) in rangeList[0]" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="picker-view__item" v-for="(item,index) in rangeList[1]" :key="index">{{item}}</view>
</picker-view-column>
<view class="picker-view__segmentation">{{ segmentation }}</view>
<picker-view-column>
<view class="picker-view__item" v-for="(item,index) in rangeList[2]" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="picker-view__item" v-for="(item,index) in rangeList[3]" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
</view>
</uni-popup>
</template>
<script>
import utils, {
props,
range
} from './utils.js';
export default {
name: 'TimePickerPopup',
props: props,
data() {
return {
rangeList: utils.range,
pickerValue: [0, 0, 0, 0],
isScoll: false, // 是否正在滚动
}
},
methods: {
/**
* 开启弹窗
*/
open() {
// 判断是否传入props -> value
if (Array.isArray(this.value) && this.value.length) {
this.pickerValue = this.value.map((item, index) => this.rangeList[index].findIndex(child =>
child == this.value[index]));
} else {
this.pickerValue = [0, 0, 0, 0];
}
this.$refs.popup.open();
},
/**
* 关闭弹窗
*/
close() {
this.$refs.popup.close();
// 重置选中数据
this.pickerValue = [0, 0, 0, 0];
},
/**
* 点击确定
*/
onConfirm() {
if (!this.isScoll) {
let data = this.value || ['00', '00', '00', '00'];
if (this.pickerValue && this.pickerValue.length) {
data = this.pickerValue.map((item, index) => String(this.rangeList[index][item]));
}
this.$emit('confirm', data);
this.close();
}
},
/**
* 点击取消
*/
onCancel() {
this.close();
},
/**
* 滚动开始
*/
pickstart() {
this.isScoll = true;
},
/**
* 滚动结束
*/
pickend() {
this.isScoll = false;
},
/**
* 选择器改变
* @param {Object} e
*/
bindChange(e) {
this.pickerValue = e.detail.value;
},
}
}
</script>
<style lang="scss" scoped>
.custom-picker {
width: 100%;
height: 620rpx;
background-color: #fff;
padding-bottom: 0;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
&__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 40rpx;
.cancel {
color: #666;
}
.title {
font-size: 32rpx;
color: #333;
}
.confirm {
color: #2bb781;
}
}
}
.picker-view {
width: 100%;
height: 100%;
margin-top: 20rpx;
&__item {
line-height: 100rpx;
text-align: center;
}
/deep/ &__indicator {
height: 100rpx;
color: #2bb781;
}
&__segmentation {
display: flex;
align-items: center;
}
}
</style>
+69
View File
@@ -0,0 +1,69 @@
// 组件props
const props = {
// 当前选中的值
value: {
type: Array,
default: () => (['00', '00', '00', '00'])
},
// 标题
title: {
type: String,
default: '时间'
},
// 取消按钮文字
cancelText: {
type: String,
default: '取消'
},
// 取消按钮颜色
canceColor: {
type: String,
default: '#666666'
},
// 确定按钮文字
confirmText: {
type: String,
default: '确定'
},
// 确定按钮颜色
confirmColor: {
type: String,
default: '#2bb781'
},
// 分割符
segmentation: {
type: String,
default: '-'
},
// 设置选择器中间选中框的类名 注意页面或组件的style中写了scoped时,需要在类名前写/deep/
indicatorClass: {
type: String,
default: 'picker-view__indicator'
},
// 设置选择器中间选中框的样式
indicatorStyle: {
type: String,
default: ''
},
}
// 滚动数据
let range = [
[],
[],
[],
[]
];
for (let i = 0; i < 24; i++) {
range[0].push(i >= 10 ? String(i) : `0${i}`);
range[2].push(i >= 10 ? String(i) : `0${i}`);
}
for (let i = 0; i < 60; i++) {
range[1].push(i >= 10 ? String(i) : `0${i}`);
range[3].push(i >= 10 ? String(i) : `0${i}`);
}
export default {
props,
range
}
@@ -0,0 +1,316 @@
<template>
<uni-popup ref="popup" type="bottom">
<view class="tpf-time-range-section">
<view class="tpf-time-range-title-section flex flex-align-center flex-pack-justify">
<text class="tpf-time-range-title-txt tpf-time-range-cancel" @tap="closePopup('cancel')">取消</text>
<text class="tpf-time-range-title-txt tpf-time-range-title">营业时间</text>
<text class="tpf-time-range-title-txt tpf-time-range-sure" @tap="closePopup('sure')">确定</text>
</view>
<view class="tpf-time-range-main flex flex-l flex-align-center flex-pack-justify">
<view class="tpf-time-range-item flex flex-v flex-align-center">
<picker-view class="flex-1 tpf-picker-view" :value="startDefaultTimeArr" indicator-style="height: 50px;" @change="startTimeChange">
<picker-view-column>
<view class="tpf-time-range-picker-item flex flex-align-center flex-pack-center" v-for="(item,index) in createTimeRange.hours" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="tpf-time-range-picker-item flex flex-align-center flex-pack-center" v-for="(item,index) in createTimeRange.startMinutes" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
</view>
<text class="tpf-time-divide"> - </text>
<view class="tpf-time-range-item flex flex-v flex-align-center">
<picker-view class="flex-1 tpf-picker-view" :value="endDefaultTimeArr" indicator-style="height: 50px;" @change="endTimeChange">
<picker-view-column>
<view class="tpf-time-range-picker-item flex flex-align-center flex-pack-center" v-for="(item,index) in createTimeRange.hours" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="tpf-time-range-picker-item flex flex-align-center flex-pack-center" v-for="(item,index) in createTimeRange.endMinutes" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
</view>
</view>
</view>
</uni-popup>
</template>
<script>
/**
* TimeRange 时间范围选择
* @description 对时间(时、分)区间进行选择,限制选择范围
* @property {string} startTime 定义开始时间
* @property {string} startDefaultTime 定义开始默认时间
* @property {string} endTime 定义结束时间
* @property {string} endDefaultTime 定义结束默认时间
* @event {Function()} name
*/
export default{
name:"TpfTimeRange",
props:{
// 开始时间
startTime:{
type:String,
default:"00:00",
validator:(value)=>{
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
}
},
// 开始默认时间
startDefaultTime:{
type:String,
// #ifdef MP-WEIXIN
default:"00:00",
// #endif
// #ifndef MP-WEIXIN
default(){
return this.startTime;
},
// #endif
validator:(value)=>{
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
}
},
// 结束时间
endTime:{
type:String,
default:"23:59",
validator:(value)=>{
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
}
},
// 结束默认时间
endDefaultTime:{
type:String,
// #ifdef MP-WEIXIN
default:"23:59",
// #endif
// #ifndef MP-WEIXIN
default(){
return this.endTime;
},
// #endif
validator:(value)=>{
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
}
}
},
data(){
return {
startDefaultTimeArr:[0,0],
endDefaultTimeArr:[0,0],
}
},
methods:{
startTimeChange(e){
this.startDefaultTimeArr = e.detail.value;
if(this.compareTwoTimeRange(e.detail.value,this.endDefaultTimeArr)) this.endDefaultTimeArr = e.detail.value;
},
endTimeChange(e){
this.endDefaultTimeArr = e.detail.value;
if(this.compareTwoTimeRange(this.startDefaultTimeArr,e.detail.value)) this.startDefaultTimeArr = e.detail.value;
},
open(){
this.$refs.popup.open();
},
closePopup(action=""){
if(this.compareTwoTimeRange(this.startDefaultTimeArr , this.endDefaultTimeArr)){
uni.showToast({
title:"开始时间不能大于结束时间",
icon:'none'
});
return false;
}
let startTime = this.createTimeRange.hours[this.startDefaultTimeArr[0]]+":"+this.createTimeRange.startMinutes[this.startDefaultTimeArr[1]];
let endTime = this.createTimeRange.hours[this.endDefaultTimeArr[0]]+":"+this.createTimeRange.endMinutes[this.endDefaultTimeArr[1]];
this.$emit('timeRange',[
startTime,endTime
]);
this.$refs.popup.close();
},
compareTwoTimeRange(arr1=[],arr2=[]){
if(arr1[0]>arr2[0] || (arr1[0] == arr2[0] && arr1[1] > arr2[1])) return true;
return false;
},
},
beforeCreate(){
// 初始化小时
let hour = [],minute=[];
for(let h=0;h<=24;h++){
hour.push(h<10?'0'+h:h+'');
}
for(let m=0;m<60;m++){
minute.push(m<10?'0'+m:m+'');
}
this.timeRange = {hour,minute};
},
created() {
},
computed:{
createTimeRange(){
let {startTime,startDefaultTime,endTime,endDefaultTime} = this.timeRangeDateChange;
let startTimeArr = startTime.split(":"),endTimeArr = endTime.split(":");
let hours = this.timeRange.hour.slice(
this.timeRange.hour.findIndex(item=>item == startTimeArr[0]),
this.timeRange.hour.findIndex(item=>item == endTimeArr[0])+1,
);
let startMinutes = null;
if(startTimeArr[0] == endTimeArr[0]){
startMinutes = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1]),
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1,
);
}else{
if(this.startDefaultTimeArr[0] == 0){
startMinutes = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1])
);
}
else if(this.startDefaultTimeArr[0] == hours.length-1){
startMinutes = this.timeRange.minute.slice(
0,
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1
);
}else{
startMinutes = this.timeRange.minute; // 完整数据
}
}
let endMinutes = null;
if(startTimeArr[0] == endTimeArr[0]){
endMinutes = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1]),
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1,
);
}
else{
if(this.endDefaultTimeArr[0] == 0){
endMinutes = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1])
);
}
else if(this.endDefaultTimeArr[0] == hours.length-1){
endMinutes = this.timeRange.minute.slice(
0,
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1
);
}else{
endMinutes = this.timeRange.minute; // 完整数据
}
}
return {
hours,
startMinutes,
endMinutes,
}
},
// 用于监听属性的变化
timeRangeDateChange(){
let {startTime,startDefaultTime,endTime,endDefaultTime} = this;
startTime = startTime<endTime?startTime:endTime;
startDefaultTime = startDefaultTime>=startTime && startDefaultTime<=endTime?startDefaultTime:startTime;
endDefaultTime = endDefaultTime>=startTime && endDefaultTime<=endTime && endDefaultTime>=startDefaultTime?endDefaultTime:startDefaultTime;
return {
startTime,
startDefaultTime,
endTime,
endDefaultTime
}
}
},
watch:{
timeRangeDateChange:{
handler(newVal,oldVal){
let {startTime,startDefaultTime,endTime,endDefaultTime} = newVal;
let startTimeArr = startTime.split(":"),endTimeArr = endTime.split(":");
let startDefaultTimeArr = startDefaultTime.split(":"),endDefaultTimeArr = endDefaultTime.split(":");
let hours = this.timeRange.hour.slice(
this.timeRange.hour.findIndex(item=>item == startTimeArr[0]),
this.timeRange.hour.findIndex(item=>item == endTimeArr[0])+1,
);
this.$set(this.startDefaultTimeArr,0, hours.includes(startDefaultTimeArr[0])?hours.findIndex(item=>item == startDefaultTimeArr[0]):0);
this.$set(this.endDefaultTimeArr,0, hours.includes(endDefaultTimeArr[0])?hours.findIndex(item=>item == endDefaultTimeArr[0]):this.startDefaultTimeArr[0]);
let startMinute = null,endMinute = null;
if(startTimeArr[0] == endTimeArr[0]){
startMinute = endMinute = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1]),
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1,
);
}
else{
if(startDefaultTime.split(":")[0] == startTimeArr[0]){
startMinute = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1]),
);
}
else if(startDefaultTime.split(":")[0] == endTimeArr[0]){
startMinute = this.timeRange.minute.slice(
0,
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1,
);
}else{
startMinute = this.timeRange.minute;
}
if(endDefaultTime.split(":")[0] == startTimeArr[0]){
endMinute = this.timeRange.minute.slice(
this.timeRange.minute.findIndex(item=>item == startTimeArr[1]),
);
}else if(endDefaultTime.split(":")[0] == endTimeArr[0]){
endMinute = this.timeRange.minute.slice(
0,
this.timeRange.minute.findIndex(item=>item == endTimeArr[1])+1,
);
}else{
endMinute = this.timeRange.minute;
}
}
this.$set(this.startDefaultTimeArr,1, startMinute.includes(startDefaultTimeArr[1])?startMinute.findIndex(item=>item == startDefaultTimeArr[1]):0);
this.$set(this.endDefaultTimeArr,1, endMinute.includes(endDefaultTimeArr[1])?endMinute.findIndex(item=>item == endDefaultTimeArr[1]):this.startDefaultTimeArr[1]);
},
deep:true, // 深度监听
immediate:true, // 初始化立即执行
}
}
}
</script>
<style lang="scss">
.flex{display:flex;}
.flex-v{flex-direction:column;}
.flex-wrap{flex-wrap:wrap;}
.flex-row-wrap{flex-flow:row wrap;}
.flex-1{flex:1;}
.flex-align-center{align-items:center;}
.flex-pack-center{justify-content:center;}
.flex-pack-justify{justify-content:space-between;}
.flex-pack-around{justify-content:space-around;}
.tpf-time-range-section{
background-color: #FFF;
}
.tpf-time-range-title-section{
padding: 20rpx;
border-bottom: 1px #f2f2f2 solid;
}
.tpf-time-range-title-txt{
font-size: 28rpx;
}
.tpf-time-range-title{
font-size:32rpx;
}
.tpf-time-range-main{
padding: 0 20rpx 20rpx;
}
.tpf-time-range-item{
height: 400rpx;
width: 300rpx;
}
.tpf-start-time{
padding: 20rpx 0;
}
.tpf-picker-view{
width:280rpx;
}
</style>
+49 -2
View File
@@ -2,9 +2,26 @@
<view class="xdd-product-item" @click="viewHandle(item)">
<view class="focus-img">
<image
v-if="!item.isFarmerShop"
:src="item[imageKey]"
class="img"
/>
<image
:src="item.farmerShopCover"
v-if="item.farmerShopCoverType === 1 && item.isFarmerShop"
class="img"
mode="heightFix|widthFix">
</image>
<image
:src="item.farmerShopCover + '?vframe/jpg/offset/1'"
mode="heightFix|widthFix"
v-if="item.farmerShopCoverType !== 1 && item.isFarmerShop"
:show-center-play-btn="false"
:show-fullscreen-btn="false"
:show-play-btn="false"
class="img"
:poster="item.farmerShopCover + '?vframe/jpg/offset/1'">
</image>
<image
v-if="item.isOldBrand"
:src="webUrl + '/home/old-mark.png'"
@@ -14,14 +31,21 @@
v-if="item.isLandmarkGoods"
:src="webUrl + '/home/mark-land.png'"
class="mark-img"
style="right: 20rpx"
/>
<image
v-if="item.isCountyFamous"
:src="webUrl + '/home/qixian-mark.png'"
class="mark-img"
/>
<image
v-if="item.isFarmerShop"
:src="webUrl + '/orderIcon/nm.png'"
class="mark-img-nm"
/>
</view>
<view class="info-wrap">
<view v-if="item.isFarmerShop" class="more-t v12-pt-2 v12-font-bold v12-font-28 v12-px-2" >{{ item.farmerShopContent }}</view>
<view class="info-wrap" v-if="!item.isFarmerShop">
<view class="name more-t">
{{ item[nameKey] }}
</view>
@@ -36,7 +60,7 @@
<view class="price">
<text class="price-txt price-red">{{ item[priceKey] }}</text>
</view>
<view class="btn">
<view class="btn" @click.stop="$emit('add', item)">
<image
:src="webUrl + '/home/icon-cart.png'"
class="img"
@@ -44,6 +68,14 @@
</view>
</view>
</view>
<view
v-if="item.isFarmerShop"
class="v12-justify-start v12-align-center v12-pt-2 v12-px-2 v12-pb-2">
<view class="btn v12-mr-2">
<image :src="item.farmerShopLogo" class="nm-img-logo v12-radius-100"></image>
</view>
<view class="one-t v12-font-24 v12-dark1-text" style="width:230rpx">{{ item.farmerShopName }}/{{ item.farmerShopCityName || '-' }}</view>
</view>
</view>
</template>
@@ -89,6 +121,21 @@ export default {
</script>
<style lang="less">
.nm-img-logo {
display: block;
width: 48rpx;
height: 48rpx;
}
.mark-img-nm{
position: absolute;
top: 0;
right: 0;
z-index: 3;
display: block;
width: 100%;
height: 100%;
border-radius: 0 25rpx 0 0;
}
.xdd-product-item {
border-radius: 20rpx;
background-color: #fff;
+22 -1
View File
@@ -5,7 +5,7 @@
}"
class="xdd-tabbar-wrap"
>
<view class="center-img" @click="switchTabFn('/pages/cloud/haveFun')">
<view class="center-img" id="quweiIcon" @click="switchTabFn('/pages/cloud/haveFun')">
<image
:src="webUrl + '/home/tabbar-center.png'"
class="img"
@@ -25,6 +25,7 @@
v-for="(item, index) in tabbarItem"
:key="index"
:class="currIndex === item.index ? 'curr' : ''"
:id="'icon' + index"
class="item"
@click="gotoPage(item.url, item.type, item.index)"
>
@@ -95,7 +96,27 @@ export default {
]]
}
},
mounted() {
this.getElementData('#quweiIcon')
this.getIconData('#icon1')
},
methods: {
getElementData(el) {
const query = uni.createSelectorQuery().in(this)
query.select(el).boundingClientRect().exec((res)=> {
if(res[0]) {
this.$emit('getElementData', res[0])
}
})
},
getIconData(el) {
const query = uni.createSelectorQuery().in(this)
query.select(el).boundingClientRect().exec((res)=> {
if(res[0]) {
this.$emit('getIcon', res[0])
}
})
},
/**
* 跳转至目标页面
* type: 1-tabbar页面,2-非tabbar页面
@@ -248,7 +248,7 @@
background: #EBEBEB;
display: flex;
justify-content: center;
z-index: 2;
z-index: 999;
flex-wrap: wrap;
transition:all 0.2s ease-in 0.2s;
}
+80
View File
@@ -0,0 +1,80 @@
import { queryUserGuide, setUserGuide } from '@/api/user'
export default {
data() {
return {
scrollView: '',
functionGuideData: {
step: 0,
tips: '',
tipsPosition: '',
btnGroupPosition: '',
position: {}
},
screenWidth: 0,
scrollLeft: 0,
totalWidth: 0,
scrollViewWidth: 0,
imgs: [],
_step: 0
}
},
onLoad() {
// this.setGuide('countyFamousIndex', 0)
// this.setGuide('landmarkGoodsIndex', 0)
// this.setGuide('findFunIndex', 0)
// this.setGuide('wellnessFoodIndex', 0)
// this.setGuide('ichIndex', 0)
// this.setGuide('wenwanIndex', 0)
// this.setGuide('goodsIndex', 0)
// this.setGuide('index', 0)
},
methods: {
setGuide(type, status = 1) {
const params = {
guideName: type,
guideStatus: status
}
setUserGuide(params).then(res => {
if(type === 'index') {
this.queryGuide(type)
}
})
},
queryGuide(type) {
const params = {
guideName: type
}
queryUserGuide(params).then(res => {
const { data, success } = res
if(success && data.guideStatus === 0) {
this.$refs.FunctionGuide.init()
}
if(type === 'index' && data.guideStatus === 1) {
this.isOldUser = true
}
if(type === 'index' && data.guideStatus === 0) {
this.isOldUser = false
}
})
},
setFunctionGuideData(data) {
this.functionGuideData = {
...this.functionGuideData,
...data
}
this.showFunctionGuide()
},
getElementData(el, cb) {
const query = uni.createSelectorQuery().in(this)
query.select(el).boundingClientRect().exec((res)=> {
console.log(res, 'getElementData');
if(res[0]) {
cb(res[0])
} else {
this.$refs.FunctionGuide.show = false
}
})
},
}
}
+381
View File
@@ -0,0 +1,381 @@
import {
getCartCount,
getProductCode,
getProductDetail,
postCartAdd,
getProductSkuBySelected
} from '@/api/store'
export default {
data() {
return {
isWenwan: 0,
qualifications: [],
source: '',
isOpen: false,
attrTxt: '',
attrValue: '',
id: null,
productValueArr: [],
attr: {
cartAttr: false,
cart_num: 1,
defaultSku: [],
defaultSkuIndex: [],
productAttr: [],
productSelect: {
cart_num: 1,
earnPoints: 0,
image: '',
otPrice: 0,
price: 0,
stock: 0,
store_name: '',
unique: ''
}
},
cart_num: 1
}
},
methods: {
getSkuActiveStatus(selectedSku) {
getProductSkuBySelected({ id: this.id, selectedSku }).then(res => {
const { success, data } = res
if (success) {
for (const key in data) {
if (data[key]) {
this.attr.productAttr.map(item => {
if (item.attrName === key) {
item.attrValue.map(subItem => {
data[key].map(dataItem => {
if (dataItem.sku === subItem.attr) {
subItem.canUsed = dataItem.canUsed
}
})
})
}
})
}
}
console.log(this.$refs);
this.$refs.attrWindow.reRender(this.attr)
}
})
},
productCon() {
getProductDetail(this.id).then(res => {
const { data } = res
this.storeInfo = {...data.storeInfo}
if(data.storeInfo.stock === 0) {
uni.showToast({
title: "产品库存不足,请选择其他商品",
icon: "none",
duration: 5000
})
return
}
this.isWenwan = data.isWenwan
this.qualifications = data.qualifications || []
// 给 attr 赋值,将请求回来的规格赋值给 attr
if (this.source !== 'pre' && this.source !== 'day' && this.source !== 'kill' && this.source !== 'spe') {
// this.$set(this.attr, 'productAttr', data.productAttr)
this.attr.productAttr = data.productAttr || []
this.productValueArr = []
for (const key in data.productValue) {
this.productValueArr.push({
attrItemkey: key,
...data.productValue[key]
})
}
// 初始化认为所有的规格都是可以选的
this.attr.productAttr.map(item => {
item.attrValue.map(subItem => {
subItem.canUsed = true
})
})
}
this.attr.defaultSku = data.defaultSku
this.attr.defaultSkuIndex = data.defaultSkuIndex
this.DefaultSelect()
// 是否单一规格
const onlyOne = Object.keys(data.productValue).length === 1
if(onlyOne) {
this.handleOk()
return
}
this.attr.cartAttr = !this.isOpen ? true : false
})
},
getAttrItemData(attr) {
let result = {}
this.productValueArr.map(item => {
if (item.attrItemkey === attr) {
result = item
}
})
return result
},
// 默认选中属性
DefaultSelect() {
const productAttr = this.attr.productAttr
const productAttrLength = productAttr.length
this.attr.productAttr.map((item, index) => {
item.attrValue.map((subItem, subIndex) => {
if (this.attr.defaultSkuIndex[index] === subIndex) {
subItem.check = true
} else {
subItem.check = false
}
})
})
const skuKey = (this.attr.defaultSku || []).join(',')
if (!skuKey) {
return
}
const productSelect = this.getAttrItemData(skuKey)
this.attrValue = skuKey
this.attrTxt = '已选择'
if (productSelect && productAttrLength) {
// this.$set(
// this.attr.productSelect,
// 'store_name',
// this.storeInfo.storeName
// )
// this.$set(this.attr.productSelect, 'image', productSelect.image)
// this.$set(this.attr.productSelect, 'price', productSelect.price)
// this.$set(this.attr.productSelect, 'otPrice', productSelect.otPrice)
// this.$set(this.attr.productSelect, 'stock', productSelect.stock)
// this.$set(this.attr.productSelect, 'unique', productSelect.unique)
// this.$set(this.attr.productSelect, 'earnPoints', productSelect.earnPoints)
// this.$set(this.attr.productSelect, 'cart_num', 1)
// this.$set(this, 'attrValue', value.sort().join(',')) // 作废
// this.$set(this, 'attrValue', skuKey)
// this.$set(this, 'attrTxt', '已选择')
this.attr.productSelect = {
image: productSelect.image,
price: productSelect.price,
otPrice: productSelect.otPrice,
stock: productSelect.stock,
earnPoints: productSelect.earnPoints,
unique: productSelect.unique,
store_name: this.storeInfo.storeName,
cart_num: 1
}
this.getSkuActiveStatus(skuKey)
} else if (!productSelect && productAttrLength) {
// this.$set(
// this.attr.productSelect,
// 'store_name',
// this.storeInfo.storeName
// )
// this.$set(this.attr.productSelect, 'image', this.storeInfo.image)
// this.$set(this.attr.productSelect, 'price', this.storeInfo.price)
// this.$set(this.attr.productSelect, 'otPrice', this.storeInfo.otPrice)
// this.$set(this.attr.productSelect, 'stock', 0)
// this.$set(this.attr.productSelect, 'earnPoints', 0)
// this.$set(this.attr.productSelect, 'unique', '')
// this.$set(this.attr.productSelect, 'cart_num', 0)
// this.$set(this, 'attrValue', '')
// this.$set(this, 'attrTxt', '请选择')
this.attr.productSelect = {
image: this.storeInfo.image,
price: this.storeInfo.price,
otPrice: this.storeInfo.otPrice,
stock: 0,
earnPoints: 0,
unique: '',
store_name: this.storeInfo.storeName,
cart_num: 1
}
} else if (!productSelect && !productAttrLength) {
// this.$set(
// this.attr.productSelect,
// 'store_name',
// this.storeInfo.storeName
// )
// this.$set(this.attr.productSelect, 'image', this.storeInfo.image)
// this.$set(this.attr.productSelect, 'price', this.storeInfo.price)
// this.$set(this.attr.productSelect, 'otPrice', this.storeInfo.otPrice)
// this.$set(this.attr.productSelect, 'stock', this.storeInfo.stock)
// this.$set(this.attr.productSelect, 'earnPoints', 0)
// this.$set(
// this.attr.productSelect,
// 'unique',
// this.storeInfo.unique || ''
// )
// this.$set(this.attr.productSelect, 'cart_num', 1)
this.attr.productSelect = {
image: this.storeInfo.image,
price: this.storeInfo.price,
otPrice: this.storeInfo.otPrice,
stock: this.storeInfo.stock,
earnPoints: 0,
unique: this.storeInfo.unique || '',
store_name: this.storeInfo.storeName,
cart_num: 1
}
// this.$set(this, 'attrValue', '')
// this.$set(this, 'attrTxt', '请选择')
}
},
// 点击加入购物车按钮
addToCart(item, id = 'id') {
console.log(item, 'addToCart --------- item');
this.id = item[id]
this.$nextTick(() => {
this.productCon()
})// if(this.attr.cartAttr && !this.isOpen){
// return this.isOpen = true
// }
console.log(this.$refs.attrWindow, '--222--');
},
handleOk() {
const productSelect = this.getAttrItemData(this.attrValue)
// 如果有属性,没有选择,提示用户选择
const hasNo = (this.attr.productAttr.length && productSelect === undefined && this.isOpen) || productSelect.stock === 0
if (hasNo) {
uni.showToast({
title: "产品库存不足,请选择其他商品",
icon: "none",
duration: 5000
})
return
}
const q = {
productId: this.id,
cartNum: this.attr.productSelect.cart_num,
new: 0,
uniqueId: this.attr.productSelect !== undefined ? this.attr.productSelect.unique : ''
}
postCartAdd(q).then(res => {
this.isOpen = false
this.attr.cartAttr = false
this.$set(this.attr.productSelect, 'cart_num', 1)
this.cart_num = 1
uni.showToast({
title: "添加购物车成功",
icon: "none",
duration: 2000
})
})
},
ChangeCartNum(changeValue) {
// changeValue:是否 加|减
// 获取当前变动属性
const productSelect = this.getAttrItemData(this.attrValue)
// 如果没有属性,赋值给商品默认库存
if (productSelect === undefined && !this.attr.productAttr.length) {
productSelect = this.attr.productSelect
}
// 无属性值即库存为0;不存在加减
if (productSelect === undefined) return
let stock = productSelect.stock || 0
let num = this.attr.productSelect
if (changeValue) {
num.cart_num++
if (num.cart_num > stock) {
if(stock < 1) {
this.$set(this.attr.productSelect, 'cart_num', 1)
this.$set(this, 'cart_num', 1)
} else {
this.$set(this.attr.productSelect, 'cart_num', stock)
this.$set(this, 'cart_num', stock)
}
} else {
if (num.cart_num < 1) {
this.$set(this.attr.productSelect, 'cart_num', 1)
this.$set(this, 'cart_num', 1)
} else {
this.$set(this.attr.productSelect, 'cart_num', num.cart_num)
this.$set(this, 'cart_num', num.cart_num)
}
}
} else {
num.cart_num--
if (num.cart_num < 1) {
this.$set(this.attr.productSelect, 'cart_num', 1)
this.$set(this, 'cart_num', 1)
} else {
this.$set(this.attr.productSelect, 'cart_num', num.cart_num)
this.$set(this, 'cart_num', num.cart_num)
}
}
},
// 关闭属性
changeattr(msg) {
// 修改了规格
this.attr.cartAttr = msg
this.$set(this.attr.productSelect, 'cart_num', 1)
this.$forceUpdate()
this.isOpen = false
},
// 打开属性插件
selecAttrTap() {
this.$set(this.attr.productSelect, 'cart_num', 1)
this.attr.cartAttr = true
this.isOpen = true
this.$forceUpdate()
},
ChangeAttr(res) {
const { index, subIndex, value } = res
// 修改了规格
const productSelect = this.getAttrItemData(value)
if (productSelect) {
this.attr.productAttr[index].attrValue.map((subItem, subIdx) => {
subItem.check= false
if (subIndex === subIdx) {
subItem.check = true
}
})
this.$set(this.attr.productSelect, 'image', productSelect.image)
this.$set(this.attr.productSelect, 'price', productSelect.price)
this.$set(this.attr.productSelect, 'otPrice', productSelect.otPrice)
this.$set(this.attr.productSelect, 'stock', productSelect.stock)
this.$set(this.attr.productSelect, 'unique', productSelect.unique)
this.$set(this.attr.productSelect, 'earnPoints', productSelect.earnPoints)
this.$set(this.attr.productSelect, 'cart_num', 1)
this.$set(this, 'attrValue', value)
this.$set(this, 'attrTxt', '已选择')
this.getSkuActiveStatus(value)
} else {
this.$set(this.attr.productSelect, 'image', this.storeInfo.image)
this.$set(this.attr.productSelect, 'price', this.storeInfo.price)
this.$set(this.attr.productSelect, 'otPrice', this.storeInfo.otPrice)
this.$set(this.attr.productSelect, 'stock', 0)
this.$set(this.attr.productSelect, 'unique', '')
this.$set(this.attr.productSelect, 'earnPoints', 0)
this.$set(this.attr.productSelect, 'cart_num', 0)
this.$set(this, 'attrValue', '')
this.$set(this, 'attrTxt', '请选择')
}
},
changeFun(opt) {
if (typeof opt !== 'object') opt = {}
let action = opt.action || ''
let value = opt.value === undefined ? '' : opt.value
this.cart_num = 1
this[action] && this[action](value)
},
// queryCartCount (isAnima) {
// const isLogin = this.isLogin
// if (isLogin) {
// getCartCount({
// numType: 0
// }).then(res => {
// this.CartCount = res.data.count
// //加入购物车后重置属性
// if (isAnima) {
// this.animated = true
// setTimeout(function () {
// this.animated = false
// }, 500)
// }
// })
// }
// },
}
}
+17700
View File
File diff suppressed because it is too large Load Diff
+145 -145
View File
@@ -1,148 +1,148 @@
{
"name": "xdd_mp",
"version": "0.1.0",
"private": true,
"name": "xdd_mp",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "npm run dev:h5",
"build": "npm run build:h5",
"build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
"build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
"build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
"build:mp-360": "cross-env NODE_ENV=production UNI_PLATFORM=mp-360 vue-cli-service uni-build",
"build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
"build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
"build:mp-jd": "cross-env NODE_ENV=production UNI_PLATFORM=mp-jd vue-cli-service uni-build",
"build:mp-kuaishou": "cross-env NODE_ENV=production UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build",
"build:mp-lark": "cross-env NODE_ENV=production UNI_PLATFORM=mp-lark vue-cli-service uni-build",
"build:mp-qq": "cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
"build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
"build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
"build:mp-xhs": "cross-env NODE_ENV=production UNI_PLATFORM=mp-xhs vue-cli-service uni-build",
"build:quickapp-native": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-native vue-cli-service uni-build",
"build:quickapp-webview": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview vue-cli-service uni-build",
"build:quickapp-webview-huawei": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build",
"build:quickapp-webview-union": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build",
"dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
"dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
"dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
"dev:mp-360": "cross-env NODE_ENV=development UNI_PLATFORM=mp-360 vue-cli-service uni-build --watch",
"dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
"dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
"dev:mp-jd": "cross-env NODE_ENV=development UNI_PLATFORM=mp-jd vue-cli-service uni-build --watch",
"dev:mp-kuaishou": "cross-env NODE_ENV=development UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build --watch",
"dev:mp-lark": "cross-env NODE_ENV=development UNI_PLATFORM=mp-lark vue-cli-service uni-build --watch",
"dev:mp-qq": "cross-env NODE_ENV=development UNI_PLATFORM=mp-qq vue-cli-service uni-build --watch",
"dev:mp-toutiao": "cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize",
"dev:mp-xhs": "cross-env NODE_ENV=development UNI_PLATFORM=mp-xhs vue-cli-service uni-build --watch",
"dev:quickapp-native": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-native vue-cli-service uni-build --watch",
"dev:quickapp-webview": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview vue-cli-service uni-build --watch",
"dev:quickapp-webview-huawei": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build --watch",
"dev:quickapp-webview-union": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build --watch",
"info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js",
"serve:quickapp-native": "node node_modules/@dcloudio/uni-quickapp-native/bin/serve.js",
"test:android": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=android jest -i",
"test:h5": "cross-env UNI_PLATFORM=h5 jest -i",
"test:ios": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=ios jest -i",
"test:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu jest -i",
"test:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin jest -i"
},
"dependencies": {
"@dcloudio/uni-app": "^2.0.2-3090920231225001",
"@dcloudio/uni-app-plus": "^2.0.1-35320220729002",
"@dcloudio/uni-h5": "^2.0.1-35320220729002",
"@dcloudio/uni-helper-json": "*",
"@dcloudio/uni-i18n": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-360": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-alipay": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-baidu": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-jd": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-kuaishou": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-lark": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-qq": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-toutiao": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-vue": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-weixin": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-xhs": "^2.0.1-35320220729002",
"@dcloudio/uni-quickapp-native": "^2.0.1-35320220729002",
"@dcloudio/uni-quickapp-webview": "^2.0.1-35320220729002",
"@dcloudio/uni-stacktracey": "^2.0.1-35320220729002",
"@dcloudio/uni-stat": "^2.0.1-35320220729002",
"@vue/composition-api": "^1.7.2",
"@vue/shared": "^3.0.0",
"animate.css": "^3.7.2",
"async-validator": "^3.2.4",
"core-js": "^3.6.5",
"dayjs": "^1.11.2",
"flyio": "^0.6.2",
"jweixin-module": "^1.6.0",
"miniapp-color-thief": "^1.0.5",
"number-precision": "^1.5.2",
"regenerator-runtime": "^0.12.1",
"uview-ui": "2.0.36",
"vconsole": "^3.14.6",
"vue": "^2.6.11",
"vue-ydui": "^1.2.6",
"vuex": "^3.2.0",
"wechat-jssdk": "^5.0.4"
},
"devDependencies": {
"@babel/runtime": "~7.17.9",
"@dcloudio/types": "^3.0.4",
"@dcloudio/uni-automator": "^2.0.1-35320220729002",
"@dcloudio/uni-cli-i18n": "^2.0.1-35320220729002",
"@dcloudio/uni-cli-shared": "^2.0.1-35320220729002",
"@dcloudio/uni-migration": "^2.0.1-35320220729002",
"@dcloudio/uni-template-compiler": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-uni": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.1-35320220729002",
"@dcloudio/webpack-uni-mp-loader": "^2.0.1-35320220729002",
"@dcloudio/webpack-uni-pages-loader": "^2.0.1-35320220729002",
"@vue/cli-plugin-babel": "~4.5.19",
"@vue/cli-service": "~4.5.19",
"babel-plugin-import": "^1.11.0",
"cross-env": "^7.0.2",
"jest": "^25.4.0",
"less": "^4.1.0",
"less-loader": "^4.1.0",
"mini-types": "*",
"miniprogram-api-typings": "*",
"postcss-comment": "^2.0.0",
"sass": "^1.5.0",
"vue-template-compiler": "^2.6.11"
},
"browserslist": [
"Android >= 4.4",
"ios >= 9"
],
"resolutions": {
"@babel/runtime": "~7.17.9"
},
"uni-app": {
"scripts": {
"serve": "npm run dev:h5",
"build": "npm run build:h5",
"build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
"build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
"build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
"build:mp-360": "cross-env NODE_ENV=production UNI_PLATFORM=mp-360 vue-cli-service uni-build",
"build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
"build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
"build:mp-jd": "cross-env NODE_ENV=production UNI_PLATFORM=mp-jd vue-cli-service uni-build",
"build:mp-kuaishou": "cross-env NODE_ENV=production UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build",
"build:mp-lark": "cross-env NODE_ENV=production UNI_PLATFORM=mp-lark vue-cli-service uni-build",
"build:mp-qq": "cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
"build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
"build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
"build:mp-xhs": "cross-env NODE_ENV=production UNI_PLATFORM=mp-xhs vue-cli-service uni-build",
"build:quickapp-native": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-native vue-cli-service uni-build",
"build:quickapp-webview": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview vue-cli-service uni-build",
"build:quickapp-webview-huawei": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build",
"build:quickapp-webview-union": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build",
"dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
"dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
"dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
"dev:mp-360": "cross-env NODE_ENV=development UNI_PLATFORM=mp-360 vue-cli-service uni-build --watch",
"dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
"dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
"dev:mp-jd": "cross-env NODE_ENV=development UNI_PLATFORM=mp-jd vue-cli-service uni-build --watch",
"dev:mp-kuaishou": "cross-env NODE_ENV=development UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build --watch",
"dev:mp-lark": "cross-env NODE_ENV=development UNI_PLATFORM=mp-lark vue-cli-service uni-build --watch",
"dev:mp-qq": "cross-env NODE_ENV=development UNI_PLATFORM=mp-qq vue-cli-service uni-build --watch",
"dev:mp-toutiao": "cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize",
"dev:mp-xhs": "cross-env NODE_ENV=development UNI_PLATFORM=mp-xhs vue-cli-service uni-build --watch",
"dev:quickapp-native": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-native vue-cli-service uni-build --watch",
"dev:quickapp-webview": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview vue-cli-service uni-build --watch",
"dev:quickapp-webview-huawei": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build --watch",
"dev:quickapp-webview-union": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build --watch",
"info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js",
"serve:quickapp-native": "node node_modules/@dcloudio/uni-quickapp-native/bin/serve.js",
"test:android": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=android jest -i",
"test:h5": "cross-env UNI_PLATFORM=h5 jest -i",
"test:ios": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=ios jest -i",
"test:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu jest -i",
"test:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin jest -i"
},
"dependencies": {
"@dcloudio/uni-app": "^2.0.2-3090920231225001",
"@dcloudio/uni-app-plus": "^2.0.1-35320220729002",
"@dcloudio/uni-h5": "^2.0.1-35320220729002",
"@dcloudio/uni-helper-json": "*",
"@dcloudio/uni-i18n": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-360": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-alipay": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-baidu": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-jd": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-kuaishou": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-lark": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-qq": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-toutiao": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-vue": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-weixin": "^2.0.1-35320220729002",
"@dcloudio/uni-mp-xhs": "^2.0.1-35320220729002",
"@dcloudio/uni-quickapp-native": "^2.0.1-35320220729002",
"@dcloudio/uni-quickapp-webview": "^2.0.1-35320220729002",
"@dcloudio/uni-stacktracey": "^2.0.1-35320220729002",
"@dcloudio/uni-stat": "^2.0.1-35320220729002",
"@vue/composition-api": "^1.7.2",
"@vue/shared": "^3.0.0",
"animate.css": "^3.7.2",
"async-validator": "^3.2.4",
"core-js": "^3.6.5",
"dayjs": "^1.11.2",
"flyio": "^0.6.2",
"jweixin-module": "^1.6.0",
"miniapp-color-thief": "^1.0.5",
"number-precision": "^1.5.2",
"regenerator-runtime": "^0.12.1",
"uview-ui": "2.0.36",
"vconsole": "^3.14.6",
"vue": "^2.6.11",
"vue-ydui": "^1.2.6",
"vuex": "^3.2.0",
"wechat-jssdk": "^5.0.4"
},
"devDependencies": {
"@babel/runtime": "~7.17.9",
"@dcloudio/types": "^3.0.4",
"@dcloudio/uni-automator": "^2.0.1-35320220729002",
"@dcloudio/uni-cli-i18n": "^2.0.1-35320220729002",
"@dcloudio/uni-cli-shared": "^2.0.1-35320220729002",
"@dcloudio/uni-migration": "^2.0.1-35320220729002",
"@dcloudio/uni-template-compiler": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-uni": "^2.0.1-35320220729002",
"@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.1-35320220729002",
"@dcloudio/webpack-uni-mp-loader": "^2.0.1-35320220729002",
"@dcloudio/webpack-uni-pages-loader": "^2.0.1-35320220729002",
"@vue/cli-plugin-babel": "~4.5.19",
"@vue/cli-service": "~4.5.19",
"babel-plugin-import": "^1.11.0",
"cross-env": "^7.0.2",
"jest": "^25.4.0",
"less": "^4.1.0",
"less-loader": "^4.1.0",
"mini-types": "*",
"miniprogram-api-typings": "*",
"postcss-comment": "^2.0.0",
"sass": "^1.5.0",
"vue-template-compiler": "^2.6.11"
},
"browserslist": [
"Android >= 4.4",
"ios >= 9"
],
"resolutions": {
"@babel/runtime": "~7.17.9"
},
"uni-app": {
"scripts": {
"mp-weixin-test": {
"title": "微信小程序(Test环境)",
"env": {
"UNI_PLATFORM": "mp-weixin",
"VUE_APP_ENV": "test",
"UNI_OUTPUT_DIR": "dist"
},
"define": {
"CUSTOM-CONST": true
}
},
"mp-weixin": {
"title": "微信小程序(生产环境)",
"env": {
"UNI_PLATFORM": "mp-weixin",
"VUE_APP_ENV": "prod",
"UNI_OUTPUT_DIR": "dist"
},
"define": {
"CUSTOM-CONST": true
}
}
}
}
"mp-weixin-test": {
"title": "微信小程序(Test环境)",
"env": {
"UNI_PLATFORM": "mp-weixin",
"VUE_APP_ENV": "test",
"UNI_OUTPUT_DIR": "dist"
},
"define": {
"CUSTOM-CONST": true
}
},
"mp-weixin": {
"title": "微信小程序(生产环境)",
"env": {
"UNI_PLATFORM": "mp-weixin",
"VUE_APP_ENV": "prod",
"UNI_OUTPUT_DIR": "dist"
},
"define": {
"CUSTOM-CONST": true
}
}
}
}
}
+20 -2
View File
@@ -744,8 +744,8 @@
"path": "views/nativeList",
"style": {
"navigationBarTitleText": "特产",
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#FF564A"
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#fff"
}
},
{
@@ -765,6 +765,24 @@
{
"root": "pkg_user",
"pages": [
{
"path": "views/giftList",
"style": {
"navigationBarTitleText": "我的礼品卡"
}
},
{
"path": "views/gift/gift",
"style": {
"navigationBarTitleText": "送礼包"
}
},
{
"path": "views/gift/receive",
"style": {
"navigationBarTitleText": "好友赠送的礼包"
}
},
{
"path": "views/myFavorite",
"style": {
@@ -18,12 +18,16 @@ export default {
pageKeyId: ''
}
},
onReady: function(res) {
onReady(res) {
this.videoContext = uni.createVideoContext('myVideo');
this.videoContext.requestFullScreen();
},
onLoad:function(e){
this.curPlayVideoUrl = e.videoUrl
onLoad(options) {
if (!options.click) {
uni.switchTab({ url: '/pages/home/index' })
return
}
this.curPlayVideoUrl = options.videoUrl
const id = options.id
this.pageKeyId = `findVideo_videoId_${id}`
},
@@ -51,7 +51,11 @@ export default {
pageKeyId: Object.freeze('findVideoList')
}
},
onLoad() {
onLoad(options) {
if (!options.click) {
uni.switchTab({ url: '/pages/home/index' })
return
}
this.getType()
this.fetchList()
},
@@ -94,7 +98,7 @@ export default {
})
},
goDetail(item) {
this.$yrouter.push("/pages/VideoPlayBackList/VideoPlayBackDetail?videoUrl=" + item.video + '&id=' + item.id)
this.$yrouter.push("/pages/VideoPlayBackList/VideoPlayBackDetail?videoUrl=" + item.video + '&id=' + item.id + '&click=1')
}
}
}
+22 -6
View File
@@ -146,20 +146,20 @@
:src="good['productInfo']['attrInfo']['image']"
class="good-cover flex-0 v12-radius-16"
mode="scaleToFill"
@click="navToGood(good)"
@click="navToGood(good, item)"
/>
<image
v-else
:src="good['productInfo']['image']"
mode="scaleToFill"
class="good-cover flex-0"
@click="navToGood(good)"
@click="navToGood(good, item)"
/>
</view>
<view style="width: 100%">
<view
class="one-t v12-font-28"
@click="navToGood(good)"
@click="navToGood(good, item)"
>{{ good['productInfo']['storeName'] }}</view>
<view
class="sku ai-center"
@@ -181,7 +181,7 @@
>
<view
class="v12-font-bold v12-primary-text"
@click="navToGood(good)"
@click="navToGood(good, item)"
>
<text class="bold v12-font-22">¥</text>
<text class="v12-font-36">{{ good['truePrice'] }}</text>
@@ -452,6 +452,7 @@ export default {
getAddressList({page: 1, limit: 9999}).then(res => {
const { data = [] } = res
this.addressList = data
this.addressInfo = data.find(e => e.isDefault == 1) || (data && data[0]) || null
if (!this.addressInfo.id) {
this.addressInfo = data.find(e => e.isDefault == 1) || (data && data[0]) || null
} else {
@@ -461,6 +462,7 @@ export default {
isExist = true
}
})
console.log(2, isExist);
if (!isExist) {
this.addressInfo = data.find(e => e.isDefault == 1) || (data && data[0]) || null
}
@@ -500,7 +502,13 @@ export default {
const res = await getCartGroup()
if (res.success) {
this.isLoad = true
this.list = res.data['valid']
const invalid = res.data['invalid'].map(e => {
return {
...e,
isInvalid: true
}
})
this.list = res.data['valid'].concat(invalid)
this.handleAll(false)
const _res = await getUserLike()
this.userLikeList = _res.data
@@ -751,7 +759,15 @@ export default {
this.currGood = {}
this.showAttr = false
},
navToGood(good) {
navToGood(good, item) {
if(item.isInvalid) {
uni.showToast({
title: '商品已下架或被删除',
icon: 'none',
duration: 3000
})
return
}
const query = {
id: good.productId
}
+94 -9
View File
@@ -10,14 +10,14 @@
@confirm="search"
>
<image
:src="webUrl + '/20220903142935869059.png'"
:src="webUrl + '/orderIcon/search.png'"
class="icon"
mode="scaleToFill"
@click="search"
/>
</view>
</view>
<view class="aside">
<view class="aside" id="aside">
<view
v-for="(item, index) in listGroup"
:key="index"
@@ -129,7 +129,7 @@
@click="select(item)"
>
<view class="has-goods" v-if="type === 0 && item.hasData === 0">暂无特产</view>
<view class="has-goods" v-if="type > 0 && type < 6 && item.hasShop === 0">暂无店铺</view>
<view class="has-goods" v-if="type > 0 && type < 6 && item.hasShop === 0 && item.hasAncientTown === 0">暂无店铺</view>
<view class="has-goods" v-if="type === 6 && item.hasData === 0">暂无景点</view>
<image :src="item.icon" mode="scaleToFill"></image>
<view class="one-t">{{ item.cityName }}</view>
@@ -137,6 +137,7 @@
</view>
</mescroll-body>
</view>
<FunctionGuide :maxStep="maxStep" @hide="setGuide(pageKeyId)" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
</view>
</template>
@@ -146,11 +147,14 @@ import {fetchCity} from '@/api/wenwan'
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
import {getCurAddress, getLocation} from '@/utils/common.js'
import { pageListenMixins } from '@/mixins/pageListenMixins'
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
name: 'ChoseCity',
components: {
MescrollBody
MescrollBody,
FunctionGuide
},
mixins: [
MescrollMixins({
@@ -158,7 +162,8 @@ export default {
mescroll.endSuccess(10)
}
}),
pageListenMixins
pageListenMixins,
GuideMixins
],
data() {
return {
@@ -188,6 +193,15 @@ export default {
pageKeyId: ''
}
},
computed: {
maxStep() {
const stepsMap = {
0: 1,
1: 2,
}
return stepsMap[this.type] || 1
}
},
onLoad(options) {
const type = Number(options.type)
this.type = type
@@ -216,8 +230,79 @@ export default {
this.getMapData()
}
this.init()
if([0,1] .includes(type)) {
this.queryGuide(this.pageKeyId)
}
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
const imgs = [
{
url: this.webUrl + '/引导页素材/全国特产/Group 1-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '357rpx',
top: '100rpx',
left: '-110rpx',
right: 0,
margin: 'auto',
height: '382rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/全国特产/Group 1-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 125*2+'rpx',
left: -120*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/全国特产/Group 1-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 125*2+'rpx',
left: 170*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.getElementData('#aside', res=>{
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top*2 + 'rpx',
left: res.left*2 + 'rpx',
width: `${res.width*2}rpx`,
height: `${res.height*2}rpx`,
}
})
})
return
} else {
if(this.type === 1) {
this.$refs.FunctionGuide.show = false
}
return
}
},
reload() {
uni.getSetting({
success(res) {
@@ -314,7 +399,7 @@ export default {
},
select(item) {
if (this.type === 0 && item.hasData === 0) return
// if ((this.type === 1 || this.type === 2) && item.hasShop === 0) return
if ((this.type === 1 || this.type === 2) && item.hasShop === 0 && item.hasAncientTown === 0) return
uni.setStorageSync("cityName", item.cityName)
switch (this.type) {
@@ -507,10 +592,10 @@ export default {
}
.item.on {
border-left: 6rpx solid #FD574B;
border-left: 6rpx solid #C52733;
.name {
color: #FD574B;
color: #C52733;
font-weight: bold;
}
}
@@ -530,7 +615,7 @@ export default {
box-sizing: border-box;
margin: 18rpx 0;
padding: 8rpx 0 0 8rpx;
border-left: 6rpx solid #FD574B;
border-left: 6rpx solid #C52733;
color: #262626;
font-size: 30rpx;
line-height: 30rpx;
+20 -9
View File
@@ -17,18 +17,22 @@
</view>
<view class="more-t">{{ item.content }}</view>
<view class="flex ai-center bottom">
<image
v-if="item.logo"
:src="item.logo"
<view
class="logo"
mode="scaleToFill"
></image>
<image
>
<image
v-if="item.logo"
:src="item.logo"
class="logo"
mode="scaleToFill"
></image>
<image
v-else
:src="webUrl + '/20230609145651814148.png'"
class="logo"
/>
<text class="one-t">{{ item.name }}</text>
</view>
<text class="one-t v12-ml-1">{{ item.name }}</text>
</view>
</view>
</template>
@@ -51,6 +55,12 @@ export default {
}
</script>
<style scoped lang="less">
.logo {
width: 46rpx;
height: 46rpx;
vertical-align: middle;
border-radius: 50%;
}
.cover-box-wrap {
margin: 20rpx 0 0 0;
.cover-box {
@@ -73,8 +83,8 @@ export default {
vertical-align: middle;
}
.logo {
width: 36rpx;
height: 36rpx;
width: 46rpx;
height: 46rpx;
vertical-align: middle;
margin: 0 8rpx;
border-radius: 50%;
@@ -105,6 +115,7 @@ export default {
}
.bottom {
margin: 0 0 20rpx 0;
align-content: center;
}
}
</style>
+189 -7
View File
@@ -3,7 +3,7 @@
<view class="top-box">
<view class="v12-justify-start v12-align-center">
<view class="flex jc-end">
<view class="city-box" @click="goCity('cloud')">
<view class="city-box" @click="goCity('cloud')" id="city-box">
<text style="white-space:nowrap; width: 90rpx" class="v12-primary-text one-t">{{ cityName }}</text>
<image :src="webUrl+'/icon/fun-city-change.png'" mode="scaleToFill"></image>
</view>
@@ -41,8 +41,7 @@
</view>
</view>
<view>
<scroll-view class="type-box flex" scroll-x enable-flex>
<view class="type-box flex" id="type-box">
<view class="first-box">
<view class="first-box__inner">
<view
@@ -57,6 +56,9 @@
</view>
</view>
</view>
<!-- <view style="padding-left: 0" class="type-box flex " >
</view> -->
<view class="scroll-box">
<view
v-for="(item, index) in typeList"
@@ -71,7 +73,7 @@
<view class="name">{{ item.name }}</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
<view class="type-banner-wrap">
@@ -104,7 +106,7 @@
</swiper>
</view>
</view>
<view class="body" v-if="typeIndex === -1">
<view class="body" v-if="typeIndex === -1" id="body1">
<view class="town-card" v-for="(town, i) in townList" :key="i" @click="toTown(town)">
<!-- <view class="town-title">{{ town.name }}</view> -->
<image :src="town.frontImage" mode="scaleToFill"/>
@@ -160,6 +162,7 @@
:show-avatar="false"
/>
</view>
<FunctionGuide @hide="setGuide('findFunIndex')" :maxStep="3" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
<xdd-tabbar :curr-index="4" />
</view>
</template>
@@ -169,12 +172,15 @@ import { getCurAddress, getLocation } from "@/utils/common"
import FunHotelItem from './components/HotelItem'
import { pageListenMixins } from '@/mixins/pageListenMixins'
import XddTabbar from '@/components/xdd-tabbar'
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
components: {
FunHotelItem,
XddTabbar
XddTabbar,
FunctionGuide
},
mixins: [pageListenMixins],
mixins: [pageListenMixins, GuideMixins],
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
@@ -220,6 +226,7 @@ export default {
this.getMapData()
})
this.getIcon()
this.queryGuide('findFunIndex')
},
onShow() {
const memCityName = uni.getStorageSync('cityName')
@@ -244,6 +251,180 @@ export default {
}
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
this.getElementData('#city-box', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/寻趣味/Group 1/Group 1-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '390rpx',
top: 0*2+'rpx',
left: res.width*2+'rpx',
height: '162rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/寻趣味/Group 1/Group 1-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 80*2+'rpx',
left: -60*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/寻趣味/Group 1/Group 1-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 80*2+'rpx',
left: 200*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
return
} else {
if(this.functionGuideData.step == 2) {
this._step = this.functionGuideData.step
this.getElementData('#type-box', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/寻趣味/Group 2/Group 2-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '504rpx',
top: 170*2+'rpx',
left: 0+'rpx',
right: 0,
margin: 'auto',
height: '191rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/寻趣味/Group 2/Group 2-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 270*2+'rpx',
left: -160*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/寻趣味/Group 2/Group 2-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 270*2+'rpx',
left: 160*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${(res.height-20)}px`,
}
})
})
return
}
if(this.functionGuideData.step == 3) {
this._step = this.functionGuideData.step
this.getElementData('#body1', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/寻趣味/Group 3/Group 3-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '290rpx',
top: 90*2+'rpx',
left: 0,
right: 0,
margin: 'auto',
height: '165rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/寻趣味/Group 3/Group 3-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '97rpx',
top: 60*2+'rpx',
left: 60*2+'rpx',
right: 0,
margin: 'auto',
height: '55rpx',
},
isBtn: 'jump'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: (res.top) + 'px',
left: res.left+10 + 'px',
width: `${res.width-20}px`,
height: `${res.height-20}px`,
}
})
})
return
}
return
}
},
handleRefresh() {
uni.showLoading()
this.page = 1
@@ -447,6 +628,7 @@ export default {
display: flex;
height: fit-content;
background: #fff;
overflow-x: scroll;
padding: 10rpx;
border-radius: 30rpx;
}
+1
View File
@@ -21,6 +21,7 @@
<view class="flex jc-between ai-center">
<text class="price">{{ item.price }}</text>
<image
@click.stop="$emit('add', item)"
:src="webUrl + '/home/icon-cart.png'"
class="btn"
/>
+924 -38
View File
File diff suppressed because it is too large Load Diff
+151 -5
View File
@@ -3,7 +3,7 @@
<view v-if="isLoad">
<view class="top-wrap">
<view class="top-box">
<view class="nav flex">
<view class="nav flex" id="nav-dibiao">
<view
v-for="(item,index) in navList"
:key="index"
@@ -45,7 +45,7 @@
<view @click="handleTab(item.value)" :class="{ 'tab-actived' : item.value === actived }" class="tab-item" v-for="(item, index) in tabs" :key="index">{{ item.name }}</view>
</view>
</view>
<view class="list-wrap">
<view class="list-wrap" id="list-wrap">
<view v-if="actived === 1">
<projects :landmarkDataId="landmarkDataId" :info="mapData.serviceInfo"></projects>
</view>
@@ -56,7 +56,7 @@
<information :landmarkDataId="landmarkDataId"></information>
</view>
<view v-if="actived === 4">
<goods :goods="goods" v-if="goods.length > 0"></goods>
<goods :goods="goods" v-if="goods.length > 0" @add='addToCart($event, "productId")'></goods>
<!-- <image
v-if="isCompleteLoadGood"
:src="webUrl + '/home/no-data-bg.png'"
@@ -76,6 +76,15 @@
:show-avatar="false"
/>
<shareImg ref="shareImg"></shareImg>
<ProductWindow
ref="attrWindow"
:attr="attr"
:cartNum="cart_num"
:showOk="true"
@changeFun="changeFun"
@ok="handleOk"
/>
<FunctionGuide @hide="setGuide('landmarkGoodsIndex')" :maxStep="2" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
</view>
</template>
@@ -87,10 +96,14 @@ import {
} from "@/api/product"
import goods from "./components/goods.vue"
import { pageListenMixins } from '@/mixins/pageListenMixins'
import goCartMixin from '@/mixins/goCartMixins'
import projects from './components/projects.vue'
import culture from "./components/culture.vue"
import information from "./components/information.vue"
import shareImg from "./components/shareImg.vue"
import ProductWindow from '@/components/ProductWindow'
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
name: 'LandMarkPage',
components: {
@@ -98,9 +111,11 @@ export default {
projects,
culture,
information,
shareImg
shareImg,
ProductWindow,
FunctionGuide
},
mixins: [pageListenMixins],
mixins: [pageListenMixins, goCartMixin, GuideMixins],
data() {
return {
actived: 1,
@@ -137,6 +152,7 @@ export default {
this.sceneId = decodeURIComponent(opts.scene).split('&')[0].split('=')[1]
}
this.getNavList()
this.queryGuide('landmarkGoodsIndex')
},
onHide() {
this.pageToHideHandle()
@@ -149,6 +165,136 @@ export default {
this.fetchGoods()
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
this.getElementData('#nav-dibiao', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/地标好物/Group1/Group 1-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '495rpx',
top: 50*2+'rpx',
left: 0,
right: 0,
margin: 'auto',
height: '194rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/地标好物/Group1/Group 1-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 160*2+'rpx',
left: -160*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/地标好物/Group1/Group 1-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 160*2+'rpx',
left: 160*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
return
} else {
if(this.functionGuideData.step == 2) {
this._step = this.functionGuideData.step
this.getElementData('#list-wrap', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/地标好物/Group2/Group 2-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '450rpx',
top: 300*2+'rpx',
left: 0,
right: 0,
margin: 'auto',
height: '174rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/地标好物/Group2/Group 2-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 280*2+'rpx',
left: -120*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/地标好物/Group2/Group 2-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 280*2+'rpx',
left: 180*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
uni.pageScrollTo({
scrollTop: res.top,
duration: 300
})
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
bottom: 0,
left: res.left + 'px',
width: `${res.width}px`,
height: `${(res.height) + 41}px`,
}
})
})
return
}
return
}
},
toShare() {
this.$refs.shareImg.savePosterPath(this.landmarkDataId)
},
+14 -9
View File
@@ -112,6 +112,7 @@ export default {
return {
webUrl:this.$VUE_APP_RESOURCES_URL,
id: "",
index: null,
cartInfo: [],
orderInfo: {},
expressList: [],
@@ -124,6 +125,9 @@ export default {
]
};
},
onLoad(opts) {
this.index = opts.index || 0;
},
watch: {
$yroute(n) {
if (n.name === NAME && this.$yroute.query.id !== this.id) {
@@ -151,16 +155,18 @@ export default {
.catch(err => {
uni.showToast({
title:
err.msg || err.response.data.msg || err.response.data.message,
err.msg ,
icon: "none",
duration: 2000
});
});
},
getExpress() {
console.log(this.id, "this.id");
if (!this.id) {
uni.showToast({
title: err.msg || err.response.data.msg || err.response.data.message,
title: '订单信息错误',
icon: "none",
duration: 2000
});
@@ -169,11 +175,11 @@ export default {
this.loaded = false;
orderDetail(this.id)
.then(res => {
this.orderInfo = {
deliveryId: res.data.deliveryId,
deliveryName: res.data.deliveryName,
deliverySn: res.data.deliverySn
};
console.log(this.index, "this.orderInfo");
const { data } = res;
const current = data.deliveryInfo[+this.index ];
console.log(current, "current");
this.orderInfo = current;
this.getExpressInfo();
// const result = res.data.express.result || {};
// this.cartInfo = res.data.order.cartInfo;
@@ -182,8 +188,7 @@ export default {
})
.catch(err => {
uni.showToast({
title:
err.msg || err.response.data.msg || err.response.data.message,
title: err.msg ,
icon: "none",
duration: 2000
});
+3 -2
View File
@@ -145,7 +145,7 @@
<view class="bnt default" v-if="order.isExtendedDelivery==0"
@click="toDelay(order.orderId)">延长收货
</view>
<view class="bnt default v12-radius-40" @click="goLogistics(order)">查看物流</view>
<!-- <view class="bnt default v12-radius-40" @click="goLogistics(order)">查看物流</view> -->
<view class="bnt bg-color-lightred v12-white v12-primary-text v12-primary-border v12-radius-40" @click="takeOrder(order)">确认收货</view>
</template>
<template v-if="order._status._type == 3">
@@ -654,6 +654,7 @@ page {
position: sticky;
top: 0;
background-color: #f5f5f5;
z-index: 54;
}
/deep/ .u-tabs {
position: fixed;
@@ -685,7 +686,7 @@ page {
.address {
margin-left: 4rpx;
color: #FD574B;
color: #C52733;
font-size: 22rpx;
line-height: 36rpx;
}
+44 -30
View File
@@ -28,28 +28,32 @@
</div>
</view>
</view>
<!-- <view class="reject-reason" v-if="orderInfo._status._type==-3 && orderInfo.refundRejectReason">驳回原因{{ orderInfo.refundRejectReason }}</view> -->
<view class="v12-radius-20 v12-white v12-pa-3 v12-mt-4" v-if="orderInfo._status._type == 3 || (orderInfo._status._type == 2 && orderInfo.isTickets!==1)">
<view>
<text class="v12-secondary-dark-text v12-font-28">{{ orderInfo.deliveryName }}{{ orderInfo.deliveryId }}</text>
<text class="v12-font-22 v12-px-2 v12-py-1 v12-ml-1 v12-primary-text v12-primary-border v12-radius-40" @click="copyClipboard(orderInfo.deliveryId)">
复制
</text>
</view>
<view class="v12-mt-2 v12-justify-between" @click="goLogistics(orderInfo)">
<view class="v12-align-center">
<view class="v12-align-center v12-mr-2">
<image class="logo" :src="webUrl+'/orderIcon/car.png'" mode="" style="margin-right:0; width: 32rpx; height:32rpx"/>
</view>
<view class="v12-font-28 v12-secondary-dark-text">{{ logistics.Traces && logistics.Traces.length > 0 ? logistics.Traces[logistics.Traces.length - 1].acceptStation : '暂无轨迹信息'}}</view>
</view>
<view v-if="orderInfo.deliveryId !== null && (orderInfo._status._type == -1 || orderInfo._status._type == -2 || orderInfo._status._type == 4 || orderInfo._status._type == 3 || (orderInfo._status._type == 2 && orderInfo.isTickets!==1))">
<view v-if="index < 2 || showMoreDeliver" v-for="(delivery, index) in orderInfo.deliveryInfo" :key="index" class="v12-radius-20 v12-white v12-pa-3 v12-mt-4">
<view>
<uni-icons type="right" size="20" color="#707070"></uni-icons>
<text class="v12-secondary-dark-text v12-font-28">{{ delivery.deliveryName }}{{ delivery.deliveryId }}</text>
<text class="v12-font-22 v12-px-2 v12-py-1 v12-ml-1 v12-primary-text v12-primary-border v12-radius-40" @click="copyClipboard(delivery.deliveryId)">
复制
</text>
</view>
<view class="v12-mt-2 v12-justify-between" @click="goLogistics(orderInfo, index)">
<view class="v12-align-center">
<view class="v12-align-center v12-mr-2">
<image class="logo" :src="webUrl+'/orderIcon/car.png'" mode="" style="margin-right:0; width: 32rpx; height:32rpx"/>
</view>
<view class="v12-font-28 v12-secondary-dark-text">{{ logistics[index] && logistics[index].Traces && logistics[index].Traces.length > 0 ? logistics[index] && logistics[index].Traces[logistics[index].Traces.length - 1].acceptStation : '暂无轨迹信息'}}</view>
</view>
<view>
<uni-icons type="right" size="20" color="#707070"></uni-icons>
</view>
</view>
<view class="v12-mt-2">
<text class="v12-dark-text v12-font-24">{{ logistics[index] && logistics[index].Traces && logistics[index].Traces.length > 0 ? logistics[index] && logistics[index].Traces[logistics[index].Traces.length - 1].acceptTime : '' }}</text>
</view>
</view>
<view class="v12-mt-2">
<text class="v12-dark-text v12-font-24">{{ logistics.Traces && logistics.Traces.length > 0 ? logistics.Traces[logistics.Traces.length - 1].acceptTime : '' }}</text>
<view class="v12-justify-center v12-mt-3" v-if="orderInfo.deliveryInfo.length > 2">
<u-icon :name="showMoreDeliver ? 'arrow-up' : 'arrow-down'" @click="handleShowMore"></u-icon>
</view>
</view>
<template v-if="!refundOrder">
@@ -353,10 +357,10 @@
<view class="btn flex jc-center ai-center v12-font-24" @click="goGoodsReturn(orderInfo)">申请退款</view>
</view>
</view>
<view class="bnt v12-dark-text v12-dark-border default"
<!-- <view class="bnt v12-dark-text v12-dark-border default"
@click="$yrouter.push({ path: '/pages/order/Logistics/index' ,query:{id:orderInfo.orderId }})"
v-if="orderInfo.isTickets!==1">查看物流
</view>
</view> -->
<view class="bnt v12-primary-text v12-primary-border" @click="takeOrder">确认收货</view>
</view>
</view>
@@ -403,12 +407,12 @@
</template>
<template v-if="status.type == 4">
<view class="bnt v12-dark-text v12-dark-border cancel" @click="delOrder">删除订单</view>
<view
<!-- <view
v-if="orderInfo.isTickets !== 1"
class="bnt v12-dark-text v12-dark-border default"
@click="$yrouter.push({ path: '/pages/order/Logistics/index' ,query:{id:orderInfo.orderId }})"
>查看物流
</view>
</view> -->
</template>
<template v-if="status.type == 6">
<view class="bnt v12-primary-text v12-primary-border" @click="goGroupRule(orderInfo)">查看拼团</view>
@@ -465,6 +469,7 @@ export default {
mixins: [pageListenMixins],
data: function () {
return {
showMoreDeliver: false,
showExtend: false,
delayId: '',
showMore: false,
@@ -541,21 +546,26 @@ export default {
},
methods: {
copyClipboard,
handleShowMore() {
this.showMoreDeliver = !this.showMoreDeliver;
},
handleBody() {
this.showMore = false
// this.$forceUpdate()
},
getExpressInfo() {
getExpressInfo(delivery, i) {
if(delivery.deliveryId === null) return
let params = {
orderCode: this.orderInfo.id,
shipperCode: this.orderInfo.deliverySn,
logisticCode: this.orderInfo.deliveryId
shipperCode: delivery.deliverySn,
logisticCode: delivery.deliveryId
};
express(params)
.then(res => {
const {success, data} = res
if(success) {
this.logistics = data || {}
this.logistics[i] = data || {}
this.$forceUpdate()
}
})
@@ -568,11 +578,12 @@ export default {
// });
});
},
goLogistics(order) {
goLogistics(order, index) {
this.$yrouter.push({
path: "/pages/order/Logistics/index",
query: {
id: order.orderId
id: order.orderId,
index: index
}
});
},
@@ -904,8 +915,11 @@ export default {
this.system_store = res.data.systemStore || {};
this.mapKey = res.data.mapKay;
this.setOfflinePayStatus(this.orderInfo.offlinePayStatus);
if(this.orderInfo._status._type == 3 || (this.orderInfo._status._type == 2 && this.orderInfo.isTickets!==1)) {
this.getExpressInfo()
const orderInfo = this.orderInfo
if(orderInfo._status._type == -1 || orderInfo._status._type == -2 || orderInfo._status._type == 4 || orderInfo._status._type == 3 || (orderInfo._status._type == 2 && orderInfo.isTickets!==1)) {
for(let i = 0; i < orderInfo.deliveryInfo.length; i++) {
this.getExpressInfo(orderInfo.deliveryInfo[i], i)
}
}
})
.catch(err => {
+19 -10
View File
@@ -109,13 +109,14 @@
</view>
</view>
<view class="v12-justify-between v12-align-center">
<view class="v12-mr-2" @click="changeCoupons" v-if="couponList.usable.length !== 0">
<!-- <view class="v12-mr-2" @click="changeCoupons" v-if="couponList.usable.length !== 0 && !hasCoupon">
<text class="v12-dark-text v12-font-24" >{{ couponList.usable.length === 0 ? '无' : '去选择' }}</text>
<text class="iconfont icon-jiantou v12-font-24 v12-dark-text"></text>
</view>
<view class="v12-secondary-dark-text">
</view> -->
<view class="v12-secondary-dark-text v12-align-center" @click="changeCoupons">
<text class="v12-font-22 ">-</text>
<text class="v12-font-28">{{ force2Decimal(orderPrice.couponPrice) }}</text>
<text class="iconfont icon-jiantou v12-font-24 v12-dark-text"></text>
</view>
</view>
</view>
@@ -251,7 +252,9 @@
v-if="couponList.usable.length > 0"
:two-list="couponList"
@change="changeCoupons"
@close="close"
:currentPrice="force2Decimal(orderPrice.totalPrice)"
:id="couponId"
@max="couponMax"
:show-tab="false"
/>
@@ -372,7 +375,8 @@ export default {
maxPoints: 0,
pageKeyId: Object.freeze('orderConfirm'),
total: 0,
couponTitle: ''
couponTitle: '',
hasCoupon: false,
};
},
computed: mapGetters(["userInfo", "storeItems"]),
@@ -383,12 +387,13 @@ export default {
shipping_type() {
this.computedPrice('shipping_type');
},
couponId() {
this.couponIndex = this.couponList['usable']?.findIndex(item => item.id === this.couponId)
this.computedPrice('couponId')
async couponId(value) {
this.couponIndex = this.couponList['usable']?.findIndex(item => item.id === value)
await this.computedPrice('couponId')
}
},
onLoad() {
onLoad(opts) {
console.log(opts);
const that = this
if (that.$yroute.query.pinkid !== undefined) {
that.pinkId = that.$yroute.query.pinkid
@@ -400,10 +405,11 @@ export default {
if (that.$yroute.query.lotteryRecordId !== undefined) {
that.lotteryRecordId = that.$yroute.query.lotteryRecordId
}
that.getCartInfo()
that.hasCoupon = opts.couponId !== ''
},
onShow() {
const _this = this
_this.getCartInfo()
//获取用户信息
_this.$store.dispatch("getUser", true)
const chooseAddress = uni.getStorageSync('chooseAddress') || {}
@@ -433,7 +439,7 @@ export default {
isNullOrEmpty,
couponMax(e) {
this.couponTitle = e.couponTitle
this.couponId = uni.getStorageSync('couponId') || 0
this.couponId = this.$yroute.query.couponId || uni.getStorageSync('couponId') || 0
},
showStoreList() {
this.$store.commit("get_to", "orders");
@@ -785,6 +791,9 @@ export default {
that.$refs.payPwdPop.close();//关闭支付密码弹窗
});
},
close() {
this.show = !this.show
},
// v9-2
changeCoupons(item) {
if(!item) return
+259 -19
View File
@@ -5,13 +5,26 @@
<input
v-model.trim="search"
type="text"
placeholder="请输入"
:placeholder="showkey ? '' : '请输入'"
placeholder-style="color:#999"
@confirm="submit"
@blur="showHistory"
@focus="hideHistory"
@input="hideHistory"
@change="hideHistory"
@compositionstart="hideHistory"
/>
<view class="btn flex-0 flex jc-center ai-center" @click="submit">
<button class="btn flex-0 flex jc-center ai-center" @click.stop="submit">
<text class="iconfont icon-sousuo2"></text>
<text>搜索</text>
</button>
<view class="swpier-bar" v-if="showkey">
<u-notice-bar duration="4000" @change="change" :text="recommendKeyword" :icon="' '" color="#999" fontSize="12" bgColor="transparent" direction="column"></u-notice-bar>
</view>
</view>
<view @click="goShoppingCart()" class="item animated bounceIn">
<view class="iconfont icon-gouwuche1">
<text class="num bg-color-lightred" v-if="CartCount > 0">{{ CartCount > 99 ? '99+' : CartCount }}</text>
</view>
</view>
</view>
@@ -31,7 +44,7 @@
<view
v-for="item of historyKey"
:key="item.id"
class="item"
class="item one-t"
@click="toSearch(item.word)"
>
{{ item.word }}
@@ -51,45 +64,168 @@
</view>
</view>
</view>
<view class="line"></view>
<view class="ranking-wrap">
<view
v-for="(rankingItem, rankingIndex) in rankingArr"
:key="rankingIndex"
:style="{
'background': `linear-gradient(180deg, ${rankingItem.color} 0%, #FFFFFF 35%, #FFFFFF 100%)`
}"
class="ranking-item"
>
<view class="ranking-header">
<image
:src="rankingItem.backgroundImage"
mode="widthFix"
class="icon"
/>
<view class="name">{{ rankingItem.rankingName }}</view>
</view>
<view class="ranking-body">
<view
v-for="(good, goodIndex) in rankingItem.products"
:key="goodIndex"
class="item"
@click="goodItemClick(good)"
>
<view class="img">
<image
:src="good.productImage"
mode="widthFix"
class="pic"
/>
</view>
<view class="info">
<view class="name more-t">
{{ good.productName }}
</view>
<view class="price-wrap " :class="{'v12-align-center' : ('' + good.price).length < 5 && ('' + good.otPrice).length < 5}">
<view class="price">
{{ good.price }}
</view>
<view class="ot-price" :class="{'v12-ml-1' : ('' + good.price).length < 5 && ('' + good.otPrice).length < 5}">
{{ good.otPrice }}
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {getSearchKeyword} from '@/api/store'
import {
getSearchPageConfig
} from '@/api/search'
import {
getCartCount,
} from '@/api/store'
import { mapGetters } from 'vuex'
import {trim} from '@/utils'
export default {
name: 'GoodSearch',
props: {},
data: function () {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
showkey: true,
currentSearch: '',
keywords: [],
search: '',
historyKey: []
historyKey: [],
rankingArr: [],
recommendKeyword: [],
CartCount: 0,
keywords1: ''
}
},
computed: mapGetters(['isLogin', 'location', 'userInfo']),
mounted: function () {
this.getData()
this.getCartCount()
},
onLoad(opts){
this.search = opts.keywords
},
onShow() {
this.getHistory()
},
watch: {
search(val) {
if(val) {
this.showkey = false
} else {
// this.showkey = true
// this.currentSearch = this.recommendKeyword[0]
}
}
},
methods: {
// 获取购物车数量
getCartCount () {
const isLogin = this.isLogin
if (isLogin) {
getCartCount({
numType: 0
}).then(res => {
this.CartCount = res.data.count
})
}
},
goShoppingCart() {
this.$yrouter.switchTab('/pages/cart')
},
showHistory() {
this.currentSearch = this.recommendKeyword[0]
if(this.showkey) return
if(this.search) {
this.showkey = false
return
}
this.showkey = true
},
hideHistory() {
// if(!this.search) {
// this.showkey = true
// return
// }
this.showkey = false
},
change(e) {
this.currentSearch = this.recommendKeyword[e]
},
submit() {
const search = trim(this.search) || ''
if (!search) return
this.setHistory(search)
this.search = ''
this.toSearch(search)
if (this.showkey) {
const search = trim(this.currentSearch) || ''
if (!search) return
this.setHistory(search)
// this.search = ''
this.toSearch(search)
} else {
const search = trim(this.search) || ''
if (!search) return
this.setHistory(search)
// this.search = ''
this.toSearch(search)
}
},
toSearch(s) {
this.setHistory(s)
this.$yrouter.push({path: '/pages/shop/GoodsList/index', query: {s}})
},
getData() {
getSearchKeyword().then(res => {
this.keywords = res.data
getSearchPageConfig().then(res => {
const { success, data } = res
if (success) {
this.keywords = data.hotKeyword
this.rankingArr.push(data.ranking1)
this.rankingArr.push(data.ranking2)
this.recommendKeyword = data.recommendKeyword.split(',')
// const index = this.recommendKeyword.indexOf(this.keywords1)
// [this.recommendKeyword[0], this.recommendKeyword[index]] = [this.recommendKeyword[index], this.recommendKeyword[0]];
}
})
},
getHistory() {
@@ -119,12 +255,36 @@ export default {
}
}
})
},
goodItemClick(good) {
const id = good.productId
if (!id) return
this.$yrouter.push({
path: '/pages/shop/GoodsCon/index',
query: { id }
})
}
}
}
</script>
<style lang="less">
.iconfont{
position: relative;
}
.item .iconfont.icon-gouwuche1 .num {
right: -15rpx !important;
top: -15rpx!important;
font-size: 20rpx;
position: absolute;
width: 30rpx;
height: 30rpx;
background: #C52733 !important;
color: #fff;
border-radius: 50%;
text-align: center;
padding: 2rpx;
}
.good-search {
min-height: 100vh;
background: #fff !important;
@@ -132,7 +292,8 @@ export default {
.header {
padding: 40rpx 32rpx 32rpx;
background: #F9F9F9;
display: flex;
align-items: center;
.search-box {
width: 686rpx;
height: 72rpx;
@@ -141,19 +302,27 @@ export default {
border-radius: 36rpx;
background: #fff;
font-size: 24rpx;
position: relative;
.swpier-bar{
position: absolute;
width: calc(100% - 128rpx);
top: 0;
}
input {
width: 100%;
position: relative;
z-index: 9;
}
.btn {
width: 128rpx;
height: 54rpx;
background: #FD574B;
background: #C52733;
border-radius: 28rpx;
color: #fff;
font-weight: bold;
padding: 0;
font-size: 26rpx;
.icon-sousuo2 {
margin-right: 4rpx;
font-size: 28rpx;
@@ -196,4 +365,75 @@ export default {
}
}
}
.ranking-wrap {
display: flex;
justify-content: space-between;
padding: 24rpx;
background-color: #F2F2F2;
.ranking-item {
width: 344rpx;
padding: 20rpx 12rpx;
box-sizing: border-box;
border-radius: 20rpx;
background-color: #fff;
.ranking-header {
display: flex;
align-items: center;
.icon {
display: block;
width: 40rpx;
height: 40rpx;
}
.name {
margin: 0 0 0 12rpx;
font-weight: bold;
font-size: 30rpx;
color: #333;
line-height: 42rpx;
}
}
.ranking-body {
padding: 24rpx 0 0 0;
.item {
display: flex;
align-items: center;
justify-content: space-around;
margin: 0 0 12rpx 0;
.img {
.pic {
display: block;
width: 100rpx;
height: 100rpx;
border-radius: 8rpx;
}
}
.info {
width: calc(100% - 112rpx);
margin: 0 0 0 12rpx;
.name {
height: 64rpx;
font-size: 26rpx;
color: #333;
line-height: 32rpx;
}
.price-wrap {
// display: flex;
margin: 6rpx 0 0 0;
line-height: 30rpx;
.price {
color: #E92727;
font-size: 24rpx;
}
.ot-price {
// margin: 0 0 0 20rpx;
color: #BFBFBF;
font-size: 20rpx;
text-decoration: line-through;
}
}
}
}
}
}
}
</style>
+82 -20
View File
@@ -29,7 +29,7 @@
<image :src="webUrl+'/20210806121714655368.png'" mode="" style="width: 36rpx;height: 36rpx;"></image>
</view>
</view>
<view v-if="couponListLimit2ToShow.length > 0 || attr.productSelect.earnPoints" class="v12-mt-1 v12-mb-3">
<view v-if="couponListLimit2ToShow.length > 0 || attr.productSelect.earnPoints" class="v12-mt-1 v12-mb-1">
<view class="cell flex jc-between ai-center">
<view v-if="couponListLimit2ToShow.length > 0" class="v12-justify-start">
<view
@@ -43,13 +43,7 @@
</view>
</view>
</view>
<view
v-if="attr.productSelect.earnPoints"
:class="couponListLimit2ToShow.length > 0 ? 'earn-points' : ''"
class="value value2 v12-font-24 v12-primary-text"
>
预计获得{{ attr.productSelect.earnPoints }}积分
</view>
<view
v-if="couponListLimit2ToShow.length > 0"
class="value value2 v12-font-24 v12-primary-text"
@@ -60,8 +54,24 @@
</view>
</view>
</view>
<view
v-if="attr.productSelect.earnPoints"
:class="couponListLimit2ToShow.length > 0 ? 'earn-points' : ''"
class="value value2 v12-font-24 v12-primary-text v12-mb-2"
>
预计获得{{ attr.productSelect.earnPoints }}积分
</view>
</view>
<view class="introduce bold">{{ storeInfo.storeName }}</view>
<view v-if="storeInfo.isGiftCard === 1" class="v12-primary v12-white-text v12-px-2 v12-py-1 v12-mt-2 v12-radius-20 v12-font-bold v12-justify-between v12-align-center">
<view class="v12-font-28 v12-align-center" style="height: 74rpx">
<image class="gift-img" :src="webUrl + '/orderIcon/gift.png'" mode="widthFix" ></image>
支持礼包赠送
</view>
<view @click="toGift" class="v12-white v12-dark-text v12-radius-20 v12-font-28 gift-btn">
送给朋友
</view>
</view>
<rich-text class="subInfo" :nodes="storeInfo.storeInfo" v-if="storeInfo.storeInfo"/>
</view>
@@ -182,7 +192,7 @@
<!-- v9 优惠券开始 -->
<u-popup :show="show" :round="10" mode="bottom" closeOnClickOverlay @close="changeCoupons()">
<CouponsPopup :two-list="couponList" @change="changeCoupons" :showTab="false" :currentPrice="storeInfo.price" />
<CouponsPopup :two-list="couponList" @ok="setCoupon" @change="changeCoupons" @close="changeCoupons()" :showTab="false" :currentPrice="storeInfo.price" />
</u-popup>
<!-- v9 优惠券结束 -->
@@ -463,6 +473,8 @@
:attr="attr"
:cartNum="cart_num"
@changeFun="changeFun"
@gift="gift"
:isGift="isGift"
/>
<ServiceWin ref="serviceWin" :info="storeInfo.guarantee" />
<StorePoster v-on:setPosterImageStatus="setPosterImageStatus" :posterImageStatus="posterImageStatus"
@@ -481,9 +493,9 @@
</view>
</view>
<view class="mask" @touchmove.prevent @click="listenerActionClose" v-show="posters"></view>
<view class="posterCanvasWarp">
<!-- <view class="posterCanvasWarp">
<canvas class="posterCanvas" canvas-id="myCanvas"></canvas>
</view>
</view> -->
</view>
</view>
</view>
@@ -544,6 +556,7 @@ export default {
mixins: [pageListenMixins],
data: function () {
return {
isGift: false,
// 商品信息是否展开
isProductInfoExpand: true,
shareInfoStatus: false,
@@ -617,7 +630,8 @@ export default {
isFavorite: false,
pageKeyId: '',
couponListLimit2ToShow: [],
qualifications: []
qualifications: [],
couponId: null
}
},
computed: mapGetters(['isLogin', 'location', 'userInfo']),
@@ -761,6 +775,24 @@ export default {
}
},
methods: {
gift() {
this.goCat(2)
},
toGift() {
if ((this.attr.productSelect.stock === 0 && this.attr.cartAttr) || this.storeInfo.stock === 0) {
uni.showToast({
title: '商品库存不足',
icon: 'none'
})
return
}
this.isGift = true
// 2=送给朋友
this.goCat(2)
// uni.navigateTo({
// url: '/pkg_user/views/gift/gift'
// })
},
showService() {
this.$refs.serviceWin.show = true
},
@@ -775,7 +807,7 @@ export default {
},
goRoom() {
const params = {
goodsId: this.productId,
goodsId: this.id,
goodsName: this.attr.productSelect.store_name,
skuStr: this.attrValue,
price: this.attr.productSelect.price,
@@ -785,7 +817,7 @@ export default {
seckillData: ''
}
uni.navigateTo({
url: `/pkg_common/views/room?id=${this.storeInfo.merId}&name=${this.storeInfo.merName}&params=${JSON.stringify(params)}`
url: `/pkg_common/views/room?id=${this.storeInfo.merId}&name=${this. systemStore.name}&params=${JSON.stringify(params)}`
})
},
goodsDetail(item) {
@@ -1009,6 +1041,7 @@ export default {
// 产品详情接口
productCon() {
const from = this.location
if (this.$deviceType == 'app') {
from.from = 'app'
}
@@ -1251,6 +1284,7 @@ export default {
changeattr(msg) {
// 修改了规格
this.attr.cartAttr = msg
this.$set(this.attr.productSelect, 'cart_num', 1)
this.isOpen = false
},
// 选择属性
@@ -1317,6 +1351,7 @@ export default {
return
}
// 0=加入购物车
this.isGift = false
this.goCat(0)
},
// 立即购买
@@ -1325,12 +1360,15 @@ export default {
return
}
// 1=直接购买
this.isGift = false
this.goCat(1)
},
// 加入购物车
goCat(news) {
const that = this
const productSelect = this.getAttrItemData(this.attrValue)
console.log(this.attr);
// 打开属性
if (that.attrValue) {
// 默认选中了属性,但是没有打开过属性弹窗还是自动打开让用户查看默认选中的属性
@@ -1359,7 +1397,7 @@ export default {
const q = {
productId: that.id,
cartNum: that.attr.productSelect.cart_num,
new: news,
new: news === 2 ? 1 : news,
uniqueId: that.attr.productSelect !== undefined ?
that.attr.productSelect.unique : ""
}
@@ -1378,14 +1416,23 @@ export default {
postCartAdd(q).then(function (res) {
that.isOpen = false
that.attr.cartAttr = false
if (news) {
if (news === 1) {
that.$yrouter.push({
path: "/pages/order/OrderSubmission/index",
query: {
id: res.data.cartId
id: res.data.cartId,
couponId: that.couponId // 优惠券ID
}
})
} else {
return
}
if(news === 2) {
const coupId = that.couponId ? that.couponId : (that.couponList.usable[0] && that.couponList.usable[0].id || '')
uni.navigateTo({
url: '/pkg_user/views/gift/gift?cartId=' + res.data.cartId + '&couponId=' + coupId
})
}
if(news === 0) {
uni.showToast({
title: "添加购物车成功",
icon: "success",
@@ -1394,6 +1441,7 @@ export default {
that.getCartCount(true)
}
})
return
}
}).catch(error => {
that.isOpen = false;
@@ -1433,9 +1481,12 @@ export default {
this.posters = false
},
// v9-2
changeCoupons() {
changeCoupons(e) {
this.show = !this.show
},
setCoupon(couponId) {
this.couponId = couponId
},
async checkFavorite() {
const res = await checkProduct(this.id, this.uniqueId)
if (res.success) this.isFavorite = res.data.hasFavorite
@@ -1878,6 +1929,8 @@ export default {
}
.store-title{
width: 400rpx;
height: 40rpx;
line-height: 40rpx;
}
.product-con .store-info .praise .iconfont {
font-size: 0.28 * 100rpx;
@@ -2069,7 +2122,16 @@ export default {
}
.earn-points {
flex: 1;
padding: 0 0 0 12rpx;
// padding: 0 0 0 12rpx;
margin-bottom: 10rpx;
box-sizing: border-box;
}
.gift-btn{
padding: 10rpx;
}
.gift-img{
width: 34rpx;
height: 34rpx;
margin-right: 10rpx;
}
</style>
+58 -5
View File
@@ -16,6 +16,11 @@
/>
<text class="iconfont icon-sousuo" @click="submitForm"></text>
</view>
<view @click="goShoppingCart()" class="item animated bounceIn">
<view class="iconfont icon-gouwuche1">
<text class="num bg-color-lightred" v-if="CartCount > 0">{{ CartCount > 99 ? '99+' : CartCount }}</text>
</view>
</view>
</view>
</form>
<view v-if="showSearchTypeLayer" class="search-type-layer">
@@ -76,7 +81,10 @@
</view>
<view class="vip-money">{{ force2Decimal(item.otPrice) }}</view>
</view>
<view class="sale">已售{{ item.sales }}</view>
<view class="" @click.stop="addToCart(item)">
<image class="logo" :src="webUrl+'/orderIcon/组 355.png'" mode="" style="margin-right:0; width: 34rpx; height:34rpx"/>
</view>
<!-- <view class="sale">已售{{ item.sales }}</view> -->
</view>
</view>
</view>
@@ -160,26 +168,40 @@
v-if="searchType === 'good' && loadend && list.length === 0"
/>
</view>
<ProductWindow
ref="attrWindow"
:attr="attr"
:cartNum="cart_num"
:showOk="true"
@changeFun="changeFun"
@ok="handleOk"
/>
</view>
</template>
<script>
import { getProducts, getHotels } from '@/api/store'
import ProductWindow from '@/components/ProductWindow'
import { mapGetters } from 'vuex'
import NP from 'number-precision'
import NoGoodData from '@/components/good/NoData'
import Recommend from '@/components/Recommend'
import goCartMixin from '@/mixins/goCartMixins'
import {
getCartCount,
} from '@/api/store'
export default {
name: 'GoodsList',
components: {
NoGoodData,
ProductWindow,
Recommend
},
data: function () {
mixins: [goCartMixin],
data () {
return {
CartCount: 0,
webUrl: this.$VUE_APP_RESOURCES_URL,
list: [],
query: {
page: 1,
@@ -198,16 +220,31 @@ export default {
showSearchTypeLayer: false
}
},
computed: mapGetters(['userInfo']),
computed: mapGetters(['isLogin', 'location', 'userInfo']),
onLoad(e) {
const { s = '' } = this.$yroute.query
this.query.keyword = s
this.getList()
this.getCartCount()
},
onReachBottom() {
!this.loading && this.getList()
},
methods: {
// 获取购物车数量
getCartCount () {
const isLogin = this.isLogin
if (isLogin) {
getCartCount({
numType: 0
}).then(res => {
this.CartCount = res.data.count
})
}
},
goShoppingCart() {
this.$yrouter.switchTab('/pages/cart')
},
toggleSearchType(value) {
this.showSearchTypeLayer = value
},
@@ -298,6 +335,22 @@ export default {
</script>
<style scoped lang="less">
.iconfont{
position: relative;
}
.iconfont.icon-gouwuche1 .num {
right: -15rpx !important;
top: -15rpx!important;
font-size: 20rpx;
position: absolute;
width: 30rpx;
height: 30rpx;
background: #C52733 !important;
color: #fff;
border-radius: 50%;
text-align: center;
padding: 2rpx;
}
.productList {
min-height: 100vh;
background-color: #f7f7f7;
+3 -2
View File
@@ -15,8 +15,8 @@
> </video>
</view>
<view class="top-intro">
<view class="intro-title v12-pa-3">
<text class="v12-font-bold v12-font-40">{{ townInfo.name }}</text>
<view class="intro-title v12-pa-3" style="width: 68%">
<text class="v12-font-bold v12-font-40" >{{ townInfo.name }}</text>
<text class="aaaa" v-if="townInfo.qualityRating">
{{ townInfo.qualityRating }}
</text>
@@ -273,6 +273,7 @@ export default {
padding: 0 10rpx;
font-size: 24rpx;
margin-left: 10rpx;
white-space: nowrap;
}
.top-intro{
width: 100%;
+2
View File
@@ -34,6 +34,7 @@
/>
<view class="good-info">
<view
v-if="historyItem.couponName"
:style="{
opacity: !historyItem.couponName ? 0 : 1
}"
@@ -42,6 +43,7 @@
<view class="v12-primary-text v12-primary-border v12-radius-6 v12-font-18 v12-px-1"></view>
<view class="v12-primary-text v12-primary-border v12-radius-6 v12-font-18 v12-px-1">{{ historyItem.couponName }}</view>
</view>
<view class="more-t v12-font-20 v12-mt-2">{{ historyItem.storeName }}</view>
<view class="v12-justify-between v12-mt-2 price">
<view class="v12-font-bold v12-primary-text" :class="{'v12-align-center': (historyItem.price).toString().length < 5 && (historyItem.otPrice).toString().length < 5 }">
<text class="v12-font-16"></text>
+43 -11
View File
@@ -39,9 +39,20 @@
class="vip"
/>
</view>
<view class="qrcode" @click="getSpreadPoster">
<image :src="webUrl + '/icon/icon-qrcode.png'" class="code" />
<text class="code-txt">会员码</text>
<view :class="{'v12-align-center': !nowrap}">
<view class="qrcode" @click="getSpreadPoster">
<image :src="webUrl + '/icon/icon-qrcode.png'" class="code" />
<text class="code-txt">会员码</text>
</view>
<view class="v12-align-center" :class="{'v12-ml-2': !nowrap, 'v12-mt-2' : nowrap}" @click="linkTo('/pkg_user/views/personalData')">
<image
:src="webUrl + '/icon/icon-setting.png'"
class="settings-img v12-mr-1"
/>
<text class="v12-font-30">
设置中心
</text>
</view>
</view>
</view>
<view class="avatar-cont" @click="goPersonalData()">
@@ -290,6 +301,12 @@ export default {
},
spreadPoster: {},
toolList: [
{
text: '我的礼包卡',
url: '/pkg_user/views/giftList',
icon: '/icon/gift.png',
allowEnter: true
},
{
text: '我的优惠券',
url: '/pkg_user/views/myCoupons',
@@ -337,17 +354,12 @@ export default {
url: '/pages/user/History/index',
icon: '/icon/icon-help.png',
allowEnter: true
},
{
text: '设置中心',
url: '/pkg_user/views/personalData',
icon: '/icon/icon-setting.png',
allowEnter: true
}
],
bannerBgUrl: '',
userCenterBannerUrl: '',
pageKeyId: Object.freeze('userIndex')
pageKeyId: Object.freeze('userIndex'),
nowrap: true
}
},
computed: mapGetters(['userInfo']),
@@ -379,6 +391,19 @@ export default {
},
methods: {
...mapMutations(['updateAuthorizationPage']),
// 新增方法:计算文本像素长度
getTextWidth() {
this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this);
query.select('.txt-cont').boundingClientRect(data => {
console.log(data, 'data');
if (data) {
this.nowrap = data.width < 200;
return data.width;
}
}).exec();
})
},
handleSwiper(e) {
const url = this.userCenterCarousel[e].url
this.linkTo(url)
@@ -454,6 +479,7 @@ export default {
const _this = this
getUserLevelInfo().then((res) => {
if (res.data) {
_this.getTextWidth()
_this.userLevelInfo = res.data
}
uni.hideLoading()
@@ -591,6 +617,11 @@ export default {
padding-top: 20rpx;
padding-bottom: 20rpx;
}
.settings-img{
width: 38rpx;
height: 38rpx;
filter: invert(100%) brightness(200%);
}
.my-wrapper {
padding: 30upx;
&.wrapper {
@@ -609,7 +640,7 @@ export default {
width: 33.3333%;
margin: 0 0 42rpx 0;
align-items: center;
justify-content: center;
justify-content: flex-start;
.img {
width: 28px;
height: 28px;
@@ -646,6 +677,7 @@ export default {
z-index: 2;
.bg {
width: 100%;
height: 335px !important;
}
}
.my-header-body {
+3
View File
@@ -411,6 +411,9 @@ export default {
if(that.choosMode === 2) {
uni.setStorageSync('cartChooseAddress', item)
}
if(that.choosMode === 3) {
uni.setStorageSync('giftChooseAddress', item)
}
}
that.$yrouter.back();
});
@@ -126,6 +126,11 @@ export default {
uni.setStorageSync('cartChooseAddress', item)
this.$yrouter.back()
}
// 来源礼物
if (this.choosMode === 3) {
uni.setStorageSync('giftChooseAddress', item)
this.$yrouter.back()
}
},
refresh() {
this.addressList = []
+35 -4
View File
@@ -225,16 +225,33 @@
</view>
<view class="info-item-body">
<view v-if="item.type === 2" class="video">
<video
:src="item.video"
<view @click="infoItemViewClick(item, index)" v-if="activeVideo !== 'video-item' + index" class="play-icon">
<u-icon name="play-right-fill" color="#fff" size="48"></u-icon>
</view>
<image
v-if="activeVideo !== 'video-item' + index"
:src="item.video + '?vframe/jpg/offset/1'"
:poster="item.video + '?vframe/jpg/offset/1'"
controls
play-btn-position="center"
:show-fullscreen-btn="false"
:id="'video-item' + index"
class="video-item"
@click="infoItemViewClick(item, index)"
/>
<video
v-else
:src="item.video"
controls
autoplay
play-btn-position="center"
:show-fullscreen-btn="false"
class="video-item"
:id="'video-item' + index"
@play="infoItemViewClick(item, index)"
/>
>
</video>
</view>
<view v-else>
<img-box
@@ -367,7 +384,8 @@ export default {
isLoadInfoListSuccess: false,
picColumnWidth: '325rpx',
infoArray: [],
videoPlayers: []
videoPlayers: [],
activeVideo: 'coverVideo',
}
},
onPageScroll(e) {
@@ -445,6 +463,7 @@ export default {
})
},
coverPlay(){
this.activeVideo = 'coverVideo'
this.videoPlayers.forEach(player => {
const playerCtx = uni.createVideoContext(player, this)
playerCtx.pause()
@@ -455,6 +474,7 @@ export default {
const coverCtx = uni.createVideoContext('coverVideo', this)
coverCtx.pause()
const playerId = 'video-item' + index
this.activeVideo = 'video-item' + index
if(this.videoPlayers.includes(playerId)) {
this.videoPlayers.forEach(player => {
if(player === playerId) return
@@ -616,6 +636,17 @@ export default {
padding: 0 20rpx 20rpx 20rpx;
.video {
padding: 20rpx 0 0 0;
position: relative;
.play-icon {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 80rpx;
height: 80rpx;
}
.video-item {
width: 100%;
height: 400rpx;
+20 -6
View File
@@ -61,7 +61,13 @@
<image :src="webUrl + '/20230609145651814148.png'" v-else/>
</view>
<view class="a3 flex jc-between ai-end" style="width: 100%">
<view class="inn-owner" style="flex-grow: 1;">{{ inn.ownerName }}/店主</view>
<view >
<view class="inn-owner" style="flex-grow: 1;">{{ inn.ownerName }}/店主</view>
<view style=" color: #8B8F99; margin-top: 2px" class="v12-font-24 v12-justify-start v12-align-center">
营业时间:
<text v-if="inn.serviceTime">{{ inn.serviceTime }}</text> - <text v-if="inn.serviceEndTime">{{ inn.serviceEndTime }}</text>
</view>
</view>
<view v-if="inn.guaranteeValue" class="guarantee flex jc-center ai-center">
保证金{{ inn.guaranteeValue }}
</view>
@@ -95,7 +101,9 @@
</view>
</view>
</view>
</view>
</view>
<view class="inn-signature-wrap">
<view class="triangle"></view>
@@ -116,11 +124,16 @@
</view>
<view class="bg"></view>
<view class="map-info">
<view class="map-info-hd">
<image :src="webUrl + '/page/hotel/icon-location.png'" class="icon" />
</view>
<view class="map-info-bd more-t">
{{ inn.address }}
<view >
<view class="v12-justify-between v12-align-start">
<view class="map-info-hd">
<image :src="webUrl + '/page/hotel/icon-location.png'" class="icon" />
</view>
<view class="map-info-bd more-t">
{{ inn.address }}
</view>
</view>
</view>
<view class="map-info-ft flex">
<view class="item" @click="showLocation">
@@ -1311,6 +1324,7 @@ export default {
padding: 40rpx 10rpx 40rpx 32rpx;
color: #333;
font-size: 14px;
justify-content: space-between;
.map-info-hd {
.icon {
display: block;
+10 -1
View File
@@ -29,8 +29,9 @@
maxlength="140"
placeholder-style="font-size:24rpx;color:#C2C5CC;"
class="content-style inp"
@input="inputIntro"
/>
<text class="v12-font-24 v12-dark1-text">{{ form.intro.length }} / 140</text>
<text class="v12-font-24 v12-dark1-text">{{ form.intro.length > 140 ? 140 : form.intro.length }} / 140</text>
</view>
<view class="form-item" v-if="showUpload">
<view v-if="uploadType === 'image'" class="title">图片(最多9张):</view>
@@ -117,6 +118,14 @@
this.hotelId = option.hotelId
},
methods: {
inputIntro() {
if(this.form.intro.length > 140) {
uni.showToast({
title: '字数超过限制',
icon: 'none'
})
}
},
changeTab(index) {
this.tabIndex = index
this.showUpload = false
+35 -3
View File
@@ -97,6 +97,24 @@
</view>
<text class="iconfont icon-jiantou"></text>
</view>
<view class="item" @click="showTimePicker">
<view class="cell acea-row row-between row-middle">
<view class="cell-title">营业时间</view>
<view class="cell-value">
<u--text :text="innApplyInfo.serviceTime + ' - ' + innApplyInfo.serviceEndTime"></u--text>
<tpf-time-range
startTime="00:00"
endTime="23:59"
:startDefaultTime="innApplyInfo.serviceTime"
:endDefaultTime="innApplyInfo.serviceEndTime"
ref="TimePickerPopupRef"
@timeRange="timeRange"
>
</tpf-time-range>
</view>
</view>
<text class="iconfont icon-jiantou"></text>
</view>
<view class="item is_required">
<view class="cell acea-row row-between row-middle">
<view class="cell-title">店主名字</view>
@@ -184,6 +202,7 @@
</template>
<script>
import TimePickerPopup from '@/components/timePickerPopup/time-picker-popup.vue';
import CitySelect from '@/components/CitySelect'
import tmUpload from '@/components/tm-upload/tm-upload.vue'
import {
@@ -195,6 +214,7 @@ import {getHotelTypeList, postHotelInfoEdit} from '@/api/inn.js'
export default {
components: {
CitySelect,
TimePickerPopup,
tmUpload
},
data() {
@@ -230,7 +250,9 @@ export default {
'tel': '',
'qrcode': '',
'tips': '',
'type': ''
'type': '',
serviceTime: '00:00',
serviceEndTime: '23:59'
},
loading: false
}
@@ -243,8 +265,10 @@ export default {
if (id) {
// 赋值
const hotel = JSON.parse(uni.getStorageSync('MY_HOTEL_INFO'))
console.log(hotel)
this.innHistory = hotel
this.innHistory = {
...hotel
}
console.log(hotel,'hotel');
this.fillData(this.innApplyInfo, this.innHistory)
if (hotel.coverType === 2) {
this.innApplyInfo.coverVideo = hotel.cover
@@ -273,6 +297,14 @@ export default {
}
},
methods: {
showTimePicker() {
this.$refs.TimePickerPopupRef.open()
},
timeRange(e) {
this.innApplyInfo.serviceTime = e[0]
this.innApplyInfo.serviceEndTime = e[1]
this.$forceUpdate()
},
typePickerChange: function (e) {
this.typeIndex = e.target.value
// 修改type
+25 -3
View File
@@ -24,7 +24,7 @@
<view class="msg" v-if="item.msg_type===1">
<image class="img" :src="item.msg_content" @click="preview(item.msg_content)"></image>
</view>
<view class="msg v12-d-flex" style="box-sizing: content-box" v-if="item.msg_type===2">
<view class="msg v12-d-flex" style="box-sizing: content-box" v-if="item.msg_type===2" @click="toGoods(item)">
<view class="goods-logo">
<image class="img v12-radius-8" :src="wsJson(item.msg_content).cover"></image>
</view>
@@ -126,14 +126,35 @@ export default {
this.token = uni.getStorageSync("login_status");
this.userInfo = uni.getStorageSync("userInfo");
this.uid = this.userInfo.uid
this.content = uni.getStorageSync(this.merName+this.uid+this.storeId)
this.connectSocketInit()
},
onUnload() {
if (this.socketOpen) {
this.socketTask.close();
}
uni.setStorageSync(this.merName+this.uid+this.storeId, this.content)
},
methods: {
toGoods(item) {
console.log(item);
const itemJson = JSON.parse(item.msg_content)
if(!itemJson.goodsId) {
// 提示数据错误
// uni.showToast({
// title: '数据错误',
// icon: 'none'
// })
return
}
this.$yrouter.push({
path: '/pages/shop/GoodsCon/index',
query: {
id: itemJson.goodsId
}
})
},
wsJson(json) {
return JSON.parse(json)
},
@@ -412,11 +433,12 @@ export default {
.input-box {
width: 472rpx;
min-height: 64rpx;
max-height: 124rpx;
box-sizing: border-box;
padding: 18rpx 30rpx;
border-radius: 32rpx;
background: #F5F5F5;
overflow: scroll;
textarea {
width: 100%;
}
@@ -427,7 +449,7 @@ export default {
width: 120rpx;
margin: 0;
border-radius: 100rpx;
background: #FD574B;
background: #C52733;
font-size: 28rpx;
color: #FFFFFF;
font-weight: bold;
+43 -5
View File
@@ -16,14 +16,21 @@
@click.stop="removeRoom(item.room_id)"
>
<view class="item v12-pa-3">
<view class="v12-justify-between flex" @click="goRoom(item)">
<view class="v12-justify-start flex" @click="goRoom(item)">
<image class="cover flex-0" :src="item.store_avatar || webUrl+'/20221114155314348118.png'"/>
<view>
<view class="flex jc-between ai-center">
<view class="name more-t">{{ item.store_name }}</view>
<view class="flex jc-between ai-center" style="position: relative">
<view class="v12-align-center">
<view class="name more-t">{{ item.store_name }}</view>
<view v-if="item.is_official" class="guanfang">官方</view>
<view v-else class="shangjia">商家</view>
</view>
<view class="datetime" v-if="item.last_msg">{{ item.last_msg.created_at }}</view>
</view>
<view class="sub one-t" v-if="item.last_msg">{{ item.last_msg.msg_type===0?item.last_msg.msg_content:'[图片]' }}</view>
<view class="sub v12-align-center v12-justify-between" v-if="item.last_msg">
<view class="one-t">{{ item.last_msg.msg_type===0?item.last_msg.msg_content:'[图片]' }}</view>
<view v-if="item.unread_num > 0" class="unread-num v12-primary"> {{ item.unread_num < 99 ? item.unread_num : '99+' }}</view>
</view>
</view>
</view>
</view>
@@ -103,6 +110,37 @@ export default {
}
</style>
<style scoped lang="less">
.unread-num{
color: #FFFFFF;
height: 38rpx;
width: 38rpx;
border-radius: 50%;
line-height: 38rpx;
text-align: center;
font-size: 20rpx;
}
.guanfang{
color: #ee6f6e;
background: #fad7d7;
width: fit-content;
font-size: 16rpx;
padding: 0 4rpx;
border-radius: 4rpx;
z-index: 9;
top: 0;
white-space: nowrap;
}
.shangjia{
color: #5791fe;
background: #dce9ff;
width: fit-content;
font-size: 16rpx;
padding: 0 4rpx;
border-radius: 4rpx;
z-index: 9;
top: 0;
white-space: nowrap;
}
.common-roomLogs {
min-height: 100vh;
box-sizing: border-box;
@@ -117,7 +155,7 @@ export default {
width: 80rpx;
height: 80rpx;
margin-right: 18rpx;
border-radius: 50%;
border-radius: 16rpx;
}
.name {
+80 -6
View File
@@ -265,7 +265,7 @@
<text class="required">*</text>
</template>
<template #value>
<view class="u-text__value" :class="{'area-item':form.area.length===0}">
<view class="u-text__value" :class="{'area-item':form.area && form.area.length===0}">
<CitySelect
ref="cityselect"
:defaultValue="form.area"
@@ -308,6 +308,25 @@
</template>
</u-cell>
</u-form-item>
<u-form-item prop="serviceTime">
<u-cell title="营业时间" :border="false" isLink @click="showTimePicker">
<template #icon>
<text class="required">*</text>
</template>
<template #value>
<u--text :text="form.serviceTime + ' - ' + form.serviceEndTime"></u--text>
<tpf-time-range
startTime="00:00"
endTime="23:59"
:startDefaultTime="form.serviceTime"
:endDefaultTime="form.serviceEndTime"
ref="TimePickerPopupRef"
@timeRange="timeRange"
>
</tpf-time-range>
</template>
</u-cell>
</u-form-item>
<u-form-item prop="content">
<u-cell title="一句话介绍" :border="false">
<template #icon>
@@ -376,7 +395,7 @@
type="error"
text="确定"
:disabled="!isAgree"
@click="save"
@click="handleAgree"
/>
</view>
</u-popup>
@@ -384,6 +403,7 @@
</template>
<script>
import TimePickerPopup from '@/components/timePickerPopup/time-picker-popup.vue';
import CitySelect from '@/components/CitySelect'
import { pageListenMixins } from '@/mixins/pageListenMixins'
import {
@@ -406,7 +426,8 @@ import {
export default {
name: 'PkgJoinShop',
components: {
CitySelect
CitySelect,
TimePickerPopup
},
mixins: [pageListenMixins],
data() {
@@ -429,7 +450,9 @@ export default {
area: '',
address: '',
position: '',
content: ''
content: '',
serviceTime: '00:00',
serviceEndTime: '23:59'
},
rules: {
'name': {
@@ -498,6 +521,12 @@ export default {
message: '请选择定位信息',
trigger: ['blur', 'change']
},
'serviceTime': {
type: 'string',
required: true,
message: '请选择营业时间',
trigger: ['blur', 'change']
},
'content': {
type: 'string',
required: true,
@@ -524,12 +553,53 @@ export default {
},
onLoad(options) {
this.partnerId = options.partnerId
const local_form = uni.getStorageSync('merchantApplyHotel' + '_form') || {}
this.quaPics = uni.getStorageSync('merchantApplyHotel' + '_quaPics') || []
if(!local_form.serviceTime) {
local_form.serviceTime = '00:00'
}
if(!local_form.serviceEndTime) {
local_form.serviceEndTime = '23:59'
}
this.form = !this.reviewing ? local_form : {
name: '',
cover: '',
coverVideo: '',
coverType: 1, // coverType: 1-图片,2-视频
logo: '',
qualification: '',
type: 0,
typeText: '',
phone: '',
captcha: '',
area: '',
address: '',
position: '',
content: '',
serviceTime: '00:00',
serviceEndTime: '23:59'
}
this.init()
},
onUnload() {
uni.setStorageSync('merchantApplyHotel'+'_quaPics', this.quaPics)
uni.setStorageSync('merchantApplyHotel' + '_form', this.form)
},
onReady() {
this.$refs.shopForm.setRules(this.rules)
},
methods: {
handleAgree(){
this.show = false
},
timeRange(e) {
this.form.serviceTime = e[0]
this.form.serviceEndTime = e[1]
this.$forceUpdate()
},
showTimePicker() {
this.$refs.TimePickerPopupRef.open()
},
changeRemove(state){
this.showRemove = state
},
@@ -585,6 +655,9 @@ export default {
}
this.isDraft = data.isDraft
this.reviewStatus = data.reviewStatus
if(data.isDraft === null || data.isDraft === 1) {
this.show = true
}
if (data.isDraft !== 1) {
switch (data.reviewStatus) {
case 0:
@@ -616,7 +689,7 @@ export default {
}
// 商家资质
this.quaPics = []
const quaPicsTemp = this.form.qualification.split(',')
const quaPicsTemp = this.form.qualification && this.form.qualification.split(',') || []
if (quaPicsTemp.length > 0) {
quaPicsTemp.map(item => {
if (item) {
@@ -735,7 +808,8 @@ export default {
}
this.$refs.shopForm.validate().then(res => {
// 校验通过
this.show = true
// this.show = true
this.save()
}).catch(errors => {
// 校验失败
console.log(errors)
+112 -15
View File
@@ -149,7 +149,7 @@
<text class="required">*</text>
</template>
<template #value>
<view class="u-text__value" :class="{'area-item':formSupplier.area.length===0}">
<view class="u-text__value" :class="{'area-item':formSupplier.area && formSupplier.area.length===0}">
<CitySelect
ref="cityselect"
:defaultValue="formSupplier.area"
@@ -187,6 +187,7 @@
</template>
</u-cell>
</u-form-item>
</u-cell-group>
</u--form>
<u--form
@@ -387,7 +388,7 @@
<text class="required">*</text>
</template>
<template #value>
<view class="u-text__value" :class="{'area-item':form.area.length===0}">
<view class="u-text__value" :class="{'area-item':form.area && form.area.length===0}">
<CitySelect
ref="cityselect2"
:defaultValue="form.area"
@@ -425,6 +426,25 @@
</template>
</u-cell>
</u-form-item>
<u-form-item prop="serviceTime">
<u-cell title="营业时间" :border="false" isLink @click="showTimePicker">
<template #icon>
<text class="required">*</text>
</template>
<template #value>
<u--text :text="form.serviceTime + ' - ' + form.serviceEndTime"></u--text>
<tpf-time-range
startTime="00:00"
endTime="23:59"
:startDefaultTime="form.serviceTime"
:endDefaultTime="form.serviceEndTime"
ref="TimePickerPopupRef"
@timeRange="timeRange"
>
</tpf-time-range>
</template>
</u-cell>
</u-form-item>
<u-form-item prop="content">
<u-cell title="一句话介绍" :border="false">
<template #icon>
@@ -488,7 +508,7 @@
type="error"
text="确定"
:disabled="!isAgree"
@click="save"
@click="handlAgree"
/>
</view>
</u-popup>
@@ -497,6 +517,7 @@
<script>
import CitySelect from '@/components/CitySelect'
import TimePickerPopup from '@/components/timePickerPopup/time-picker-popup.vue';
import {
getShopData,
getShopInfo,
@@ -516,7 +537,8 @@ import { pageListenMixins } from '@/mixins/pageListenMixins'
export default {
name: 'PkgJoinSupplier',
components: {
CitySelect
CitySelect,
TimePickerPopup
},
mixins: [pageListenMixins],
data() {
@@ -536,7 +558,8 @@ export default {
subType: '',
area: '',
address: '',
position: ''
position: '',
},
form: {
name: '',
@@ -551,7 +574,9 @@ export default {
area: '',
address: '',
position: '',
content: ''
content: '',
serviceTime: '00:00',
serviceEndTime: '23:59'
},
rulesSupplier: {
'name': {
@@ -675,7 +700,13 @@ export default {
required: true,
message: '请填写介绍内容',
trigger: ['blur', 'change']
}
},
'serviceTime': {
type:'string',
required: true,
message: '请选择营业时间',
trigger: ['blur', 'change']
},
},
columnsType: [],
indexType: 0,
@@ -698,7 +729,46 @@ export default {
onLoad(options) {
this.partnerId = options.partnerId || ''
const type = options.type
const local = uni.getStorageSync(type) || {}
const local_form = uni.getStorageSync(type + '_form') || {}
this.quaPics = uni.getStorageSync(type + '_quaPics') || []
if(!local_form.serviceTime) {
local_form.serviceTime = '00:00'
}
if(!local_form.serviceEndTime) {
local_form.serviceEndTime = '23:59'
}
this.form = !this.reviewing && local_form || {
name: '',
cover: '',
coverVideo: '',
// coverType: 1-图片,2-视频
coverType: 1,
logo: '',
type: 0,
typeText: '',
phone: '',
area: '',
address: '',
position: '',
content: '',
serviceTime: '00:00',
serviceEndTime: '23:59'
}
this.formSupplier = !this.reviewing && local || {
name: '',
avatar: '',
contact: '',
phone: '',
captcha: '',
qualification: '',
subType: '',
area: '',
address: '',
position: ''
}
this.formSupplier.subType = type
if (type === 'goods_supplier') {
this.infoTitle = '特产'
this.pageKeyId = 'merchantApplyGoodsSupplier'
@@ -711,11 +781,27 @@ export default {
})
this.init()
},
onUnload() {
uni.setStorageSync(this.formSupplier.subType, this.formSupplier)
uni.setStorageSync(this.formSupplier.subType+'_quaPics', this.quaPics)
uni.setStorageSync(this.formSupplier.subType + '_form', this.form)
},
onReady() {
this.$refs.shopForm.setRules(this.rules)
this.$refs.supplierForm.setRules(this.rulesSupplier)
},
methods: {
handlAgree() {
this.show = false
},
timeRange(e) {
this.form.serviceTime = e[0]
this.form.serviceEndTime = e[1]
this.$forceUpdate()
},
showTimePicker() {
this.$refs.TimePickerPopupRef.open()
},
changeRemove(state){
this.showRemove = state
},
@@ -765,12 +851,19 @@ export default {
})
},
initInfo() {
getShopInfo().then(({data}) => {
// 是否缺少参数区分文玩和特产?
getShopInfo().then((res) => {
const {data} = res
// console.log(res, 'initInfo--------');
// console.log(data, 'data--------');
if (data.partnerId != null) {
this.partnerId = data.partnerId
}
this.isDraft = data.isDraft
this.reviewStatus = data.reviewStatus
if(data.isDraft === null || data.isDraft === 1) {
this.show = true
}
if (data.isDraft !== 1) {
switch (data.reviewStatus) {
case 0:
@@ -802,7 +895,7 @@ export default {
}
// 商家资质
this.quaPics = []
const quaPicsTemp = this.form.qualification.split(',')
const quaPicsTemp = this.form.qualification && this.form.qualification.split(',') || []
if (quaPicsTemp.length > 0) {
quaPicsTemp.map(item => {
if (item) {
@@ -813,20 +906,23 @@ export default {
this.indexType = this.columnsType.findIndex(item => item.id === this.form.type)
this.form.typeText = this.columnsType[this.indexType].name
this.form.position = this.$forceToDecimal(this.form.longitude, 6) + ',' + this.$forceToDecimal(this.form.latitude, 6)
this.form.area = `${this.form.provinceName} ${this.form.cityName} ${this.form.areaName}`
this.form.area = `${this.form.provinceName || ''} ${this.form.cityName || ''} ${this.form.areaName || ''}`
console.log(this.form, 'form--------');
if (data.hotelInfo.coverType === 2) {
this.form.coverVideo = data.hotelInfo.cover
this.form.cover = ''
}
}
// console.log(data.supplierInfo, 'supplierInfo--------');
if (data.supplierInfo) {
if (this.infoTitle === "特产" && data.applyType !== 1) return
if (this.infoTitle === "文玩" && data.applyType !== 3) return
this.formSupplier = data.supplierInfo
this.indexSupplierType = this.columnsSupplierType.findIndex(item => item.key === this.formSupplier.subType)
this.formSupplier.typeText = this.columnsSupplierType[this.indexSupplierType].value
this.formSupplier.position = this.$forceToDecimal(this.formSupplier.longitude, 6) + ',' + this.$forceToDecimal(this.formSupplier.latitude, 6)
this.formSupplier.area = `${this.formSupplier.provinceName} ${this.formSupplier.cityName} ${this.formSupplier.areaName}`
this.formSupplier.area = `${this.formSupplier.provinceName || ''} ${this.formSupplier.cityName || ''} ${this.formSupplier.areaName || ''}`
this.indexSupplierType = this.columnsSupplierType.findIndex(item => item.key === this.formSupplier.subType)
// console.log(this.formSupplier);
}
})
},
@@ -927,7 +1023,7 @@ export default {
cityId: values.city.id,
areaId: values.district.id
}
this.formSupplier.area = `${address.province} ${address.city} ${address.district}`
this.formSupplier.area = `${address.province || ''} ${address.city || ''} ${address.district || ''}`
this.formSupplier.provinceId = values.province.id
this.formSupplier.cityId = values.city.id
this.formSupplier.areaId = values.district.id
@@ -942,7 +1038,7 @@ export default {
cityId: values.city.id,
areaId: values.district.id
}
this.form.area = `${address.province} ${address.city} ${address.district}`
this.form.area = `${address.province || ''} ${address.city || ''} ${address.district || ''}`
this.form.provinceId = values.province.id
this.form.cityId = values.city.id
this.form.areaId = values.district.id
@@ -971,7 +1067,8 @@ export default {
_this.$refs.shopForm.validate().then(res => {
// 校验通过
_this.$refs.supplierForm.validate().then(() => {
_this.show = true
// _this.show = true
_this.save()
}).catch(errors => {
// 校验失败
console.log(errors)
+25 -21
View File
@@ -379,6 +379,9 @@ export default {
this.isDraft = data.isDraft
this.reviewStatus = data.reviewStatus
}
if(data.isDraft === null || data.isDraft === 1) {
this.show = true
}
if (data.isDraft !== 1) {
switch (data.reviewStatus) {
case 0:
@@ -436,9 +439,29 @@ export default {
this.form.areaId = values.district.id
},
onSubmit() {
this.$refs.wholesalerForm.validate().then(res => {
// 校验通过
this.show = true
saveWholesaler(this.form).then(res => {
if (res.status === 200) {
uni.showToast({
title: '您的入驻申请已提交成功,请耐心等待审核',
icon: 'none',
success: () => {
this.initInfo()
this.show = false
}
})
}
}).catch(err => {
uni.showToast({
title: err.msg,
icon: 'none',
success: () => {
this.show = false
}
})
})
}).catch(errors => {
// 校验失败
console.log(errors)
@@ -464,26 +487,7 @@ export default {
this.isAgree = event.detail.value.length > 0
},
save() {
saveWholesaler(this.form).then(res => {
if (res.status === 200) {
uni.showToast({
title: '您的入驻申请已提交成功,请耐心等待审核',
icon: 'none',
success: () => {
this.initInfo()
this.show = false
}
})
}
}).catch(err => {
uni.showToast({
title: err.msg,
icon: 'none',
success: () => {
this.show = false
}
})
})
this.show = false
}
}
}
+137 -5
View File
@@ -25,7 +25,7 @@
class="img"
mode="widthFix"
/>
<view v-if="list.length > 0" class="province-wrap">
<view v-if="list.length > 0" class="province-wrap" id="province-wrap">
<view
:class="toggleStatus ? 'isopen' : ''"
class="list"
@@ -85,7 +85,7 @@
{{ item.intro }}
</view>
<view class="pic-wrap">
<view v-if="item.countyTotal < 7" class="one-list">
<view v-if="item.countyTotal < 7" class="one-list" :id="'more-list-wrap' + index">
<view
v-for="(county) in item.county"
:key="county.id"
@@ -107,7 +107,7 @@
</view>
</view>
</view>
<view v-else class="more-list-wrap">
<view v-else class="more-list-wrap" :id="'more-list-wrap' + index">
<view class="more-list">
<view
v-for="(county) in item.oddList"
@@ -174,6 +174,7 @@
:show-avatar="false"
/>
</view>
<FunctionGuide :maxStep="4" @hide="setGuide('countyFamousIndex')" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
</view>
</template>
@@ -188,10 +189,14 @@ import cookie from '@/utils/store/cookie'
import { userBindParent } from '@/api/user'
import { getUrlParam } from '@/utils/common.js'
import { pageListenMixins } from '@/mixins/pageListenMixins'
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
name: 'FamousList',
mixins: [pageListenMixins],
components: {
FunctionGuide
},
mixins: [pageListenMixins, GuideMixins],
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
@@ -229,8 +234,135 @@ export default {
userBindParent({spread: parseInt(this.partnerId)})
}
this.init()
this.queryGuide('countyFamousIndex')
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
this.getElementData('#province-wrap', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/千县名品/Group 1/Group 1-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '406rpx',
top: 280*2+'rpx',
left: 75*2+'rpx',
height: '218rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/千县名品/Group 1/Group 1-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 390*2+'rpx',
left: -140*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/千县名品/Group 1/Group 1-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 390*2+'rpx',
left: 180*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
return
} else {
// more-list-wrap
if(this.functionGuideData.step == 2) {
this._step = this.functionGuideData.step
this.getElementData('#more-list-wrap0', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/千县名品/Group 2/Group 2-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '406rpx',
top: 280*2+'rpx',
left: 75*2+'rpx',
height: '218rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/千县名品/Group 2/Group 2-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 250*2+'rpx',
left: -40*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/千县名品/Group 2/Group 2-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 250*2+'rpx',
left: 210*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
return
} else {
this.$refs.FunctionGuide.show = false
}
return
}
},
handlerSearch() {
if(this.keyword) {
this.searchEvent = true
+155 -8
View File
@@ -328,7 +328,7 @@
class="bg"
/>
<view class="card-cont">
<view class="tab-wrap">
<view class="tab-wrap" id="tab-wrap">
<view
v-for="(tab, tabIndex) in industryTab"
:key="tabIndex"
@@ -571,7 +571,7 @@
<text class="v12-font-bold v12-primary-text v12-font-24"></text>
<text class="v12-font-bold v12-primary-text v12-font-28">{{ item.productPrice }}</text>
</view>
<view class="btn">
<view class="btn" @click.stop="addToCart(item, 'productId')">
<image
:src="webUrl + '/home/icon-cart.png'"
class="img"
@@ -579,11 +579,11 @@
</view>
</view>
</view>
<view v-if="!item.productId" class="v12-white v12-radius-20 f-wrap" @click="goStore(item)" style="height: 516rpx">
<view v-if="!item.productId" :id="'farmer' + index" class="v12-white v12-radius-20 f-wrap" @click="goStore(item)" style="height: 516rpx">
<view>
<view class="focus-img">
<image :src="item.cover" v-if="item.coverType === 1" class="img" mode="heightFix|widthFix"></image>
<video :src="item.cover" v-else :show-center-play-btn="false" :show-fullscreen-btn="false" :show-play-btn="false" class="img" :poster="item.cover + '?vframe/jpg/offset/1'"></video>
<image mode="heightFix|widthFix" class="img" v-else :show-center-play-btn="false" :show-fullscreen-btn="false" :show-play-btn="false" :src="item.cover + '?vframe/jpg/offset/1'"></image>
<image
:src="webUrl + '/orderIcon/nm.png'"
class="mark-img"
@@ -632,6 +632,15 @@
/>
</view>
</u-popup>
<ProductWindow
ref="attrWindow"
:attr="attr"
:cartNum="cart_num"
:showOk="true"
@changeFun="changeFun"
@ok="handleOk"
/>
<FunctionGuide @hide="setGuide('countyFamousIndex')" :maxStep="2" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
</view>
</template>
@@ -653,19 +662,24 @@ import {
getShareImg,
getSaleList
} from '@/api/qianxian'
import ProductWindow from '@/components/ProductWindow'
import goCartMixin from '@/mixins/goCartMixins'
import {formatDateTime} from '@/utils'
import {getUrlParam} from '@/utils/common.js'
import imgBox from '@/components/imageTypeSet/imagebox.vue'
import XddProductItem from '@/components/xdd-product-item'
import cookie from '@/utils/store/cookie'
import { pageListenMixins } from '@/mixins/pageListenMixins'
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
components: {
imgBox,
XddProductItem
XddProductItem,
ProductWindow,
FunctionGuide
},
mixins: [pageListenMixins],
mixins: [pageListenMixins, goCartMixin, GuideMixins],
data() {
return {
saleActived: null,
@@ -754,8 +768,141 @@ export default {
// this.initPoster()
this.getListReq()
this.getsaleList()
this.queryGuide('countyFamousIndex')
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
this.$nextTick(() => {
this.getElementData('#tab-wrap', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/千县名品/Group 3/Group 3-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '500rpx',
top: res.top-100+'px',
left: 80*2+'rpx',
height: '200rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/千县名品/Group 3/Group 3-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: res.top-123+'px',
left: 60*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/千县名品/Group 3/Group 3-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: res.top-123+'px',
left: 260*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
})
return
} else {
if(this.functionGuideData.step == 2) {
this._step = this.functionGuideData.step
this.activeIndex = 4
this.$nextTick(() => {
this.getElementData('#farmer1', res=>{
uni.pageScrollTo({
scrollTop: 100,
duration: 300
})
const imgs = [
{
url: this.webUrl + '/引导页素材/千县名品/Group 4/Group 4-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '366rpx',
top: 460*2+'rpx',
left: 80*2+'rpx',
height: '167rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/千县名品/Group 4/Group 4-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 440*2+'rpx',
left: -60*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/千县名品/Group 4/Group 4-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 440*2+'rpx',
left: 200*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top - 100 + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
})
return
}
return
}
},
handleSale(e) {
if(this.saleActived === e.id) {
this.saleActived = null
@@ -780,7 +927,7 @@ export default {
countyFamousDataId: this.id
}
getSaleList(params).then(res => {
this.saleList = res.data || []
this.saleList = [{name: '全部', id: ''}].concat(res.data || [])
})
},
goStore(item) {
+2 -2
View File
@@ -206,8 +206,8 @@ export default {
}
.active {
border-left: 6rpx solid #FD574B;
color: #FD574B;
border-left: 6rpx solid #C52733;
color: #C52733;
font-weight: bold;
}
}
+15 -1
View File
@@ -159,7 +159,7 @@
<text class="v12-font-32"></text>
<text class="v12-font-36">{{ item.price }}</text>
</view>
<view class="cart-img">
<view class="cart-img" @click.stop="addToCart(item, 'productId')">
<image
class="cart-img"
:src="webUrl + '/orderIcon/组 355.png'"
@@ -177,11 +177,25 @@
</view>
</view>
</view>
<ProductWindow
ref="attrWindow"
:attr="attr"
:cartNum="cart_num"
:showOk="true"
@changeFun="changeFun"
@ok="handleOk"
/>
</view>
</template>
<script>
import { getRank, getFoods, getRecipe } from "@/api/health";
import ProductWindow from '@/components/ProductWindow'
import goCartMixin from '@/mixins/goCartMixins'
export default {
components: {
ProductWindow
},
mixins: [goCartMixin],
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
+72 -2
View File
@@ -72,7 +72,7 @@
@click="changeTab(1)"
/>
</view> -->
<view class="v12-justify-start v12-align-center news-wrap v12-radius-100">
<view class="v12-justify-start v12-align-center news-wrap v12-radius-100" id="news-wrap">
<view class="v12-font-bold v12-primary v12-white-text v12-mr-2 v12-pa-2 v12-radius-100 news-title">最新展会</view>
<swiper vertical class="text-swpier " autoplay circular duration="500" interval="3000" >
<swiper-item v-for="(item, index) in sanctum" :key="index" class="v12-align-center" @click="toExpo(item.id)">
@@ -161,6 +161,7 @@
</view>
</view>
</view>
<FunctionGuide :maxStep="1" @hide="setGuide('wellnessFoodIndex')" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
</view>
</template>
@@ -171,9 +172,14 @@ import { wellnessFood, wellnessPlaceList } from '@/api/product'
import { getWellnessPlace, getWellnessExhibition, getBanner } from '@/api/health'
import { getProducts } from '@/api/store'
import { pageListenMixins } from '@/mixins/pageListenMixins'
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
name: 'HealthList',
mixins: [pageListenMixins],
components: {
FunctionGuide
},
mixins: [pageListenMixins, GuideMixins],
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
@@ -192,8 +198,72 @@ export default {
},
onLoad() {
this.init()
this.queryGuide('wellnessFoodIndex')
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
const imgs = [
{
url: this.webUrl + '/引导页素材/康养旅居/Group 1-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '356rpx',
top: 140*2+'rpx',
left: 50*2+'rpx',
right: 0,
margin: 'auto',
height: '207rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/康养旅居/Group 1-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 110*2+'rpx',
left: 0*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/康养旅居/Group 1-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 110*2+'rpx',
left: 240*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.getElementData('#news-wrap', res=>{
this.setFunctionGuideData({
imgs: imgs,
position: {
top: res.top + 'px',
left: res.left + 'rpx',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
return
} else {
return
}
},
init() {
getBanner().then(({data}) => {
this.bannerList = data
+82 -13
View File
@@ -1,8 +1,8 @@
<template>
<view class="pkg-product-heritage">
<image style="width: 100%" :src="topImage" mode="widthFix" />
<view class="main-box">
<image style="width: 100%" :src="backgroundImage" mode="widthFix" />
<view class="main-box" id="main-box">
<image style="width: 100%" :src="backgroundImage" mode="widthFix" @load="loadImg" />
<view
class="item"
:style="{ left: item.gx + 'rpx', top: item.gy + 'rpx' }"
@@ -15,29 +15,27 @@
:src="item.image"
:class="{ unlink: !item.isLink }"
/>
<!-- <view
class="v12-text-center v12-white-text v12-radius-80 v12-px-1 title"
:class="{
'v12-primary': item.isLink,
'un-actived': !item.isLink,
}"
>
{{ item.title }}</view
> -->
</view>
</view>
<FunctionGuide :maxStep="3" @hide='setGuide("ichIndex")' :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
</view>
</template>
<script>
import { getICH } from "@/api/product";
import { pageListenMixins } from "@/mixins/pageListenMixins";
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
name: "HeritagePage",
mixins: [pageListenMixins],
components: {
FunctionGuide
},
mixins: [pageListenMixins, GuideMixins],
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
contents: [],
topImage: "",
backgroundImage: "",
@@ -52,8 +50,79 @@ export default {
},
onLoad() {
this.init();
this.queryGuide('ichIndex')
},
methods: {
loadImg(e) {
this.queryGuide('ichIndex')
},
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
this.$nextTick(() => {
this.getElementData('#main-box', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/非遗技艺/Group 1/Group 1-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '468rpx',
top: 80*2+'rpx',
left: res.left*2+'rpx',
height: '670rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/非遗技艺/Group 1/Group 1-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 60*2+'rpx',
left: -160*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/非遗技艺/Group 1/Group 1-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 60*2+'rpx',
left: 160*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
})
return
} else {
this.$refs.FunctionGuide.show = false
return
}
},
init() {
getICH().then(({ data }) => {
this.contents = data.contents;
+130 -2
View File
@@ -17,8 +17,8 @@
<view class="v12-font-26 v12-font-bold v12-dark-text intro-text">{{ details.intro }}</view>
</view>
<view class="tabs v12-my-3 v12-font-32 v12-font-bold">
<view class="tab-btn" :class="{ 'v12-primary': actived === 1, 'v12-white-text': actived === 1 }" @click="handleTab(1)">{{details.pageA.title}}</view>
<view class="tab-btn v12-ml-3" :class="{ 'v12-primary': actived === 2, 'v12-white-text': actived === 2 }" @click="handleTab(2)">{{details.pageB.title}}</view>
<view id="tab-btn1" class="tab-btn" :class="{ 'v12-primary': actived === 1, 'v12-white-text': actived === 1 }" @click="handleTab(1)">{{details.pageA.title}}</view>
<view id="tab-btn2" class="tab-btn v12-ml-3" :class="{ 'v12-primary': actived === 2, 'v12-white-text': actived === 2 }" @click="handleTab(2)">{{details.pageB.title}}</view>
</view>
<view class="pageA" v-show="actived === 1">
<view class="intro" style="white-space: break-spaces;">
@@ -68,12 +68,18 @@
/>
</view>
</view>
<FunctionGuide :maxStep="2" @hide="setGuide('ichIndex')" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
</view>
</template>
<script>
import { getIchContent } from '@/api/heritage'
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
components: {
FunctionGuide
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
@@ -82,11 +88,133 @@ export default {
details: {}
}
},
mixins: [GuideMixins],
onLoad(opts) {
this.id = opts.id
this.getDetails()
this.queryGuide('ichIndex')
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
this.getElementData('#tab-btn1', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/非遗技艺/Group 2/Group 2-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '405rpx',
top: 350*2+'rpx',
left: res.left*2+'rpx',
height: '218rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/非遗技艺/Group 2/Group 2-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 470*2+'rpx',
left: 0*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/非遗技艺/Group 2/Group 2-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 470*2+'rpx',
left: 240*2+'rpx',
height: '47rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`
}
})
})
return
} else {
this._step = this.functionGuideData.step
this.actived = 2
this.getElementData('#tab-btn2', res=>{
const imgs = [
{
url: this.webUrl + '/引导页素材/非遗技艺/Group 3/Group 3-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '496rpx',
top: 350*2+'rpx',
left: 60+'rpx',
height: '183rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/非遗技艺/Group 3/Group 3-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 450*2+'rpx',
left: -150*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/非遗技艺/Group 3/Group 3-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 450*2+'rpx',
left: 160*2+'rpx',
height: '47rpx',
},
isBtn: 'next'
},
]
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
return
}
},
viewImg(item) {
uni.previewImage({
current: item.image, // 当前显示图片的http链接
+103 -5
View File
@@ -15,6 +15,11 @@
mode="scaleToFill"
@click="searchHandle"></image>
</view>
<view @click="goShoppingCart()" class="item animated bounceIn">
<view class="iconfont icon-gouwuche1">
<text class="num bg-color-lightred" v-if="CartCount > 0">{{ CartCount > 99 ? '99+' : CartCount }}</text>
</view>
</view>
</view>
<view class="line-location flex ai-center">
<image :src="webUrl+'/20220903142929759087.png'" mode="scaleToFill"></image>
@@ -44,7 +49,18 @@
mode="scaleToFill"
/>
<view class="name more-t">{{ item.storeName }}</view>
<view class="price bold">{{ item.price }}</view>
<!-- <view class="price bold">{{ item.price }}</view> -->
<view class="price-wrap">
<view >
<view class="v12-primary-text v12-font-bold">{{ item.price }}</view>
</view>
<view class="btn" @click.stop="addToCart(item)">
<image
:src="webUrl + '/home/icon-cart.png'"
class="img"
/>
</view>
</view>
</view>
</scroll-view>
<image
@@ -55,6 +71,15 @@
/>
</view>
</view>
<ProductWindow
ref="attrWindow"
:attr="attr"
:cartNum="cart_num"
:showOk="true"
@changeFun="changeFun"
@ok="handleOk"
paddingBottom="200rpx"
/>
</view>
</template>
@@ -62,11 +87,21 @@
// 特产-城市商品列表
import { fetchNormal, getCategory } from "@/api/store"
import { pageListenMixins } from '@/mixins/pageListenMixins'
import ProductWindow from '@/components/ProductWindow'
import goCartMixin from '@/mixins/goCartMixins'
import { mapGetters } from 'vuex'
import {
getCartCount,
} from '@/api/store'
export default {
name: 'NativeListPage',
mixins: [pageListenMixins],
components: {
ProductWindow
},
mixins: [pageListenMixins, goCartMixin],
data() {
return {
CartCount: 0,
webUrl: this.$VUE_APP_RESOURCES_URL,
keyword: '',
dataList: [],
@@ -78,13 +113,29 @@ export default {
pageKeyId: ''
}
},
computed: mapGetters(['isLogin', 'location', 'userInfo']),
onLoad(option) {
const cityId = option.cityId
this.cityId = cityId
this.pageKeyId = `goodsProductList_cityId_${cityId}`
this.init()
this.getCartCount()
},
methods: {
// 获取购物车数量
getCartCount () {
const isLogin = this.isLogin
if (isLogin) {
getCartCount({
numType: 0
}).then(res => {
this.CartCount = res.data.count
})
}
},
goShoppingCart() {
this.$yrouter.switchTab('/pages/cart')
},
init() {
const memCityName = uni.getStorageSync('cityName')
if (memCityName.length) {
@@ -156,14 +207,33 @@ export default {
<style scoped lang="less">
@import "@/assets/css/product.less";
.iconfont{
position: relative;
}
.item .iconfont.icon-gouwuche1 .num {
right: -15rpx !important;
top: -15rpx!important;
font-size: 20rpx;
position: absolute;
width: 30rpx;
height: 30rpx;
background: #C52733 !important;
color: #fff;
border-radius: 50%;
text-align: center;
padding: 2rpx;
}
.pkg-product-list {
height: 100vh;
overflow-y: hidden;
.top-box {
height: 82rpx;
background: #FF564A;
background: #fff;
display: flex;
align-items: center;
background-color: #fff;
box-sizing: border-box;
}
.line-location {
@@ -191,7 +261,7 @@ export default {
}
.item {
width: 345rpx;
height: 465rpx;
height: auto;
.cover {
width: 345rpx;
height: 345rpx;
@@ -209,4 +279,32 @@ export default {
height: 338rpx;
}
}
.price-wrap {
display: flex;
justify-content: space-between;
align-items: flex-end;
padding: 10rpx 0 0 0;
.price {
font-size: 24rpx;
line-height: 40rpx;
.price-txt {
font-size: 40rpx;
font-weight: bold;
}
}
.price-red {
margin: 0 10rpx 0 0;
color: #C52733;
}
.price-grey {
color: #C4C4C4;
}
.btn {
.img {
display: block;
width: 48rpx;
height: 48rpx;
}
}
}
</style>
+1 -1
View File
@@ -203,7 +203,7 @@ export default {
height: 80rpx;
margin-top: 56rpx;
border-radius: 8rpx;
background: #FD574B;
background: #C52733;
color: #FFFFFF;
font-size: 28rpx;
}
+1 -1
View File
@@ -97,7 +97,7 @@ export default {
},
isSelectMode: false,
webUrl: this.$VUE_APP_RESOURCES_URL,
bgColor: ["#FD574B", "#0DC5C5", "#3F57DA", "#FF4F48"],
bgColor: ["#C52733", "#0DC5C5", "#3F57DA", "#FF4F48"],
pageKeyId: Object.freeze('userBankCardIndex')
}
},
+1 -1
View File
@@ -216,7 +216,7 @@ export default {
.btn-save {
height: 80rpx;
margin-top: 80rpx;
background: #FD574B;
background: #C52733;
line-height: 80rpx;
}
}
@@ -0,0 +1,428 @@
<template>
<u-popup :show="show" @close="close" mode="center" round="16" closeable>
<view class="dialog-container">
<view class="dialog-title">填写收货地址</view>
<u-form :model="form" ref="uForm" labelPosition="left" labelWidth="100">
<u-form-item label="姓名:">
<u-input v-model="userAddress.realName" placeholder="请输入姓名" required border="none"/>
</u-form-item>
<u-form-item label="联系电话:" >
<u-input maxlength="11" v-model="userAddress.phone" placeholder="请输入联系电话" required border="none"/>
</u-form-item>
<u-form-item label="所在地区:" >
<CitySelect
ref="cityselect"
:defaultValue="addressText"
@callback="result"
:items="district"
></CitySelect>
</u-form-item>
<u-form-item label="详细地址:">
<u-input v-model="userAddress.detail" placeholder="请输入详细地址" required border="none" />
</u-form-item>
</u-form>
<view class="address-analysis-wrap">
<view class="inp">
<textarea
v-model.trim="addressInput"
placeholder="请粘贴收件人手机号、姓名、收货地址并用空格区分,系统将自动识别地址信息"
placeholder-style="font-size:24rpx;color:#C2C5CC;"
class="inp-textarea"
/>
</view>
<view class="btn-wrap">
<view
class="txt"
@click="clearHandle"
>
清空
</view>
<view
:class="addressInput ? '' : 'disable'"
class="btn"
@click="distinguishHandle"
>
识别
</view>
</view>
</view>
<view class="dialog-footer">
<u-button type="primary" :disabled="loading" :loading="loading" color="#C52733" shape="circle" @click="handleSave">立即保存</u-button>
</view>
</view>
</u-popup>
</template>
<script>
import CitySelect from '@/components/CitySelect'
import config from '@/utils/mapConfig'
import attrs, { chs_extphone, required } from '@/utils/validate'
import { validatorDefaultCatch } from '@/utils/dialog'
import { getAddress, getCity, postAddress, analysisAddress } from '@/api/user'
import { isWeixin } from '@/utils'
export default {
components: {
CitySelect
},
data() {
return {
district: [],
id: null,
// 是否选择地址模式:0-不是,1-来源订单创建页面,2-来源购物车
choosMode: 0,
userAddress: {
realName: '',
phone: '',
detail: '',
isDefault: 0
},
loading: false,
address: {},
isWechat: isWeixin(),
addressText: "",
pageKeyId: Object.freeze('userAddressEdit'),
addressInput: '',
show: false,
showRegionPicker: false,
form: {
name: '',
phone: '',
region: '',
address: ''
},
rules: {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' }
],
phone: [
{ required: true, message: '请输入联系电话', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
],
region: [
{ required: true, message: '请选择所在地区', trigger: 'change' }
],
address: [
{ required: true, message: '请输入详细地址', trigger: 'blur' }
]
}
}
},
onReady() {
this.$refs.uForm.setRules(this.rules);
},
methods: {
clearHandle() {
if (!this.addressInput) return
this.addressInput = ''
},
// 识别
distinguishHandle() {
if (!this.addressInput) return
uni.showLoading()
analysisAddress({
content: this.addressInput
}).then((res) => {
uni.hideLoading()
const { success, data } = res
if (success) {
this.address = {
province: data.province || '',
city: data.city || '',
district: data.district || '',
city_id: data.cityId
}
this.userAddress.realName = data.realName || ''
this.userAddress.phone = data.phone || ''
this.userAddress.detail = data.detail || ''
this.addressText = `${this.address.province} ${this.address.city} ${this.address.district}`
}
}).catch((err) => {
uni.hideLoading()
uni.showToast({
title: err.msg + '',
icon: 'none',
mask: false,
duration: 1500
})
})
},
open() {
this.show = true
this.getCityList()
},
close() {
this.show = false
},
result(values) {
this.address = {
province: values.province.name || "",
city: values.city.name || "",
district: values.district.name || "",
city_id: values.city.id
};
this.addressText = `${this.address.province} ${this.address.city} ${this.address.district}`;
// this.addressText =
// this.address.province + this.address.city + this.address.district;
},
handleRegionConfirm(e) {
this.form.region = e.province.label + ' ' + e.city.label + ' ' + e.area.label
},
async handleSave() {
if (this.loading) return
const name = this.userAddress.realName || ''
const phone = this.userAddress.phone || ''
const addressText = this.addressText || ''
const detail = this.userAddress.detail || ''
const isDefault = this.userAddress.isDefault
if (phone.length !== 11) {
uni.showToast({
title: "请输入11位手机号码",
icon: "none"
})
return;
}
try {
await this.$validator({
name: [
required(required.message("姓名")),
attrs.range([2, 16], attrs.range.message("姓名"))
],
phone: [
required(required.message("联系电话")),
chs_extphone(chs_extphone.message())
//chs_phone(chs_phone.message())
],
addressText: [required("请选择地址")],
detail: [required(required.message("具体地址"))]
}).validate({name, phone, addressText, detail});
} catch (e) {
return validatorDefaultCatch(e);
}
try {
let that = this,
data = {
id: that.id,
real_name: name,
phone: phone,
address: this.address,
detail: detail,
is_default: isDefault ? true : false,
post_code: ""
};
uni.showLoading();
this.loading = true
postAddress(data).then((res) => {
uni.showToast({
title: res.msg,
icon: "none",
duration: 2000
});
this.$emit('save', res.data.id)
}).finally(() => {
this.loading = false
uni.hideLoading();
});
} catch (err) {
uni.showToast({
title: err.msg || err.response.data.msg || err.response.data.message,
icon: "none",
duration: 2000
});
}
},
//获取当前定位地址
getCurAddress() {
var that = this;
//定位
uni.showLoading({
title: '定位中...'
});
//this.getLocation();
uni.getLocation({
type: 'wgs84',
success: function (res) {
let latitude = res.latitude;
let longitude = res.longitude;
console.log('latitude:' + latitude + 'longitude:' + longitude)
// #ifdef H5
Vue.jsonp(
'https://apis.map.qq.com/ws/geocoder/v1/?location=' + latitude + ',' + longitude + '&key=' + config.key,
{
//callbackName: 'QQmap',
output: 'jsonp',
}).then(json => {
// Success.
uni.hideLoading();
that.addressText =
json.result.ad_info.province + " " + json.result.ad_info.city + " " + json.result.ad_info.district;
that.address.province = json.result.ad_info.province;
that.address.city = json.result.ad_info.city;
that.address.district = json.result.ad_info.district;
that.$set(that.userAddress, 'detail', json.result.formatted_addresses.recommend);
//that.userAddress.detail = json.result.formatted_addresses.recommend;
// that.$refs.cityselect.adjustDefaultValue();
//设置city_id
var pIdx = that.getIndex(that.address.province, that.district);
if (pIdx > -1) {
var citys = that.district[pIdx].c;
var cIdx = that.getIndex(that.address.city, citys);
if (cIdx > -1) {
var city = citys[cIdx];
that.address.city_id = city.v;
console.log('city_id:' + city.v);
}
}
}).catch(err => {
// Failed.
console.log('地址解析失败:' + JSON.stringify(err));
uni.hideLoading();
})
// #endif
// #ifndef H5
uni.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1/?location=' + latitude + ',' + longitude + '&key=' + config.key,
success: function (res) {
// console.log('res:'+JSON.stringify(res.data));
uni.hideLoading();
that.addressText =
res.data.result.ad_info.province + " " + res.data.result.ad_info.city + " " + res.data.result.ad_info.district;
that.address.province = res.data.result.ad_info.province;
that.address.city = res.data.result.ad_info.city;
that.address.district = res.data.result.ad_info.district;
//that.userAddress.detail = res.data.result.formatted_addresses.recommend;
that.$set(that.userAddress, 'detail', res.data.result.formatted_addresses.recommend);
// that.$refs.cityselect.adjustDefaultValue();
//设置city_id
var pIdx = that.getIndex(that.address.province, that.district);
if (pIdx > -1) {
var citys = that.district[pIdx].c;
var cIdx = that.getIndex(that.address.city, citys);
if (cIdx > -1) {
var city = citys[cIdx];
that.address.city_id = city.v;
console.log('city_id:' + city.v);
}
}
},
fail: function (res) {
console.log('地址解析失败');
uni.hideLoading();
},
complete: function () {
}
});
// #endif
},
fail: function (res) {
uni.hideLoading();
// uni.showToast({
// title:'城市定位失败:'+JSON.stringify(res),
// icon:'none',
// duration:2000
// })
}
});
},
getCityList: function () {
let that = this;
getCity()
.then(res => {
that.district = res.data;
that.ready = true;
if (this.id) {
//设置city_id
var pIdx = that.getIndex(that.address.province, that.district);
if (pIdx > -1) {
var citys = that.district[pIdx].c;
var cIdx = that.getIndex(that.address.city, citys);
if (cIdx > -1) {
var city = citys[cIdx];
that.address.city_id = city.v;
console.log('city_id:' + city.v);
}
}
}
})
.catch(err => {
that.$dialog.error(err.msg);
});
},
}
}
</script>
<style lang="less" scoped>
.address {
text {
width: 100%;
display: block;
}
}
.address-analysis-wrap {
padding: 20rpx;
margin: 20rpx;
border-radius: 15rpx;
background-color: #fff;
font-size: 24rpx;
.inp-textarea {
width: 100%;
height: 120rpx;
}
.btn-wrap {
display: flex;
justify-content: flex-end;
align-items: center;
margin: 20rpx 0 0 0;
.txt {
color: #999;
}
.btn {
padding: 12rpx 25rpx;
margin: 0 0 0 20rpx;
border-radius: 8rpx;
color: #fff;
background-color: #FE5261;
&.disable {
opacity: 0.75;
}
}
}
}
.dialog-container {
width: 600rpx;
padding: 40rpx;
background-color: #fff;
border-radius: 16rpx;
}
.dialog-title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 40rpx;
}
.dialog-footer {
margin-top: 40rpx;
}
</style>
@@ -0,0 +1,168 @@
<template>
<!-- 使用u-popup包裹整个地址列表 -->
<u-popup
:show="showPopup"
:safeAreaInsetBottom="false"
mode="center"
round="16"
closeable
@close="close"
@open="open"
>
<view class="v12-text-center v12-font-bold v12-mt-3">收货地址</view>
<view class="address-list"
>
<!-- 地址列表 -->
<view
v-for="(item, index) in addressList"
:key="index"
class="address-item"
>
<view class="address-wrap" @click="handleSelect(item)">
<view class="v12-font-28 v12-font-bold text">
收货地址
</view>
<view>
<view class="info">
<text class="v12-font-28 v12-font-bold v12-dark-text">{{ item.realName }}</text>
<text class="v12-font-28 v12-font-bold v12-dark-text v12-ml-1">{{ item.phone }}</text>
</view>
<view class="address v12-font-bold v12-font-28 v12-dark-text v12-mt-3 v12-mb-4">
{{ item.province + item.city + item.district + item.detail }}
<view @click.stop="editAddress(item)">
<u-icon :name="webUrl+'/orderIcon/edit02.png'" color="#C52733"></u-icon>
</view>
</view>
</view>
</view>
</view>
<!-- 添加新地址按钮 -->
<view class="v12-white btn-wrap">
<view class="add-btn v12-primary v12-white-text" @click="addNewAddress">
<text>添加新地址</text>
</view>
</view>
</view>
</u-popup>
</template>
<script>
export default {
props: {
addressList: {
type: Array,
default: () => []
}
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
showPopup: false, // 新增控制弹窗显示的状态
}
},
methods: {
editAddress(item) {
// this.$yrouter.push({
// path: "/pages/user/address/AddressManagement/index",
// query: {
// choosMode: 3
// }
// });
this.$yrouter.push({
path: "/pages/user/address/AddAddress/index",
query: {
choosMode: 3,
id: item.id
}
})
},
// 选择地址
handleSelect(item) {
uni.showModal({
title: '提示',
content: '确认选择这个收货地址吗?',
success: (res) => {
if (res.confirm) {
this.$emit('save', item.id)
}
}
})
},
// 添加新地址
addNewAddress() {
this.$yrouter.push({
path: "/pages/user/address/AddAddress/index",
query: {
choosMode: 3
}
});
},
// 新增打开弹窗方法
open() {
this.showPopup = true
},
// 新增关闭弹窗方法
close() {
this.showPopup = false
},
}
}
</script>
<style scoped>
.text{
white-space: nowrap;
}
.address-wrap{
display: flex;
justify-content: flex-start;
margin-bottom: 20rpx;
}
.address-list {
padding: 20rpx 20rpx 0rpx;
width: 640rpx;
max-height: 800rpx;
overflow: auto;
}
.address-item {
padding: 20rpx;
}
.info {
display: flex;
justify-content: flex-start;
margin-bottom: 10rpx;
}
.name {
font-size: 28rpx;
font-weight: bold;
}
.phone {
font-size: 28rpx;
color: #666;
}
.address {
font-size: 26rpx;
color: #888;
display: flex;
align-items: flex-end;
}
.add-btn {
padding: 20rpx;
text-align: center;
background-color: #fff;
border: 1rpx solid #ddd;
border-radius: 100rpx;
}
.btn-wrap{
position: sticky;
bottom: 0;
width: 100%;
padding: 20rpx 0;
}
</style>
@@ -0,0 +1,170 @@
<template>
<u-popup
:show="show"
mode="bottom"
round="40rpx"
@close="close"
:customStyle="{height: '600rpx'}"
closeable>
<view class="cover-picker">
<view class="cover-title">选择封面</view>
<swiper
:current="currentIndex"
:autoplay="false"
:circular="true"
:indicator-dots="false"
@change="onChange"
previous-margin="160rpx"
next-margin="180rpx"
class="cover-swiper"
>
<swiper-item v-for="(item, index) in list" :key="index">
<view class="cover-item" >
<view class="img-wrap" :class="currentIndex === index ? 'v12-mt-10' : 'v12-mt-18'">
<view class="pro-img-wrap ">
<image :src="product.image" class="pro-cover-image" mode="widthFix|heightFix" />
</view>
<image :src="item.cover" class="cover-image" mode="widthFix|heightFix" />
<view class="message-text" :style="{top: currentIndex !== index ? '260rpx' : '220rpx'}">{{ message || '礼笺轻启,礼藏心意' }}</view>
</view>
<view class="cover-name">{{ item.name }} </view>
</view>
</swiper-item>
</swiper>
<view class="v12-justify-center">
<view class="cover-confirm" @click="confirm">
确定
</view>
</view>
<view class="tips">红包封面在对方领取时展示</view>
</view>
</u-popup>
</template>
<script>
export default {
props: {
index: {
type: Number,
default: 0
},
show: {
type: Boolean,
default: true
},
list: {
type: Array,
default: () => []
},
product: {
type: Object,
default: () => {}
},
message: {
type: String,
default: ''
}
},
data() {
return {
currentIndex: this.index
}
},
watch: {
index(val) {
this.currentIndex = val
}
},
methods: {
close() {
this.$emit('update:show', false)
},
onChange(e) {
this.currentIndex = e.detail.current
},
confirm() {
this.$emit('confirm', this.list[this.currentIndex])
this.$emit('update:show', false)
}
}
}
</script>
<style lang="less" scoped>
.message-text{
position: absolute;
text-align: center;
top: 200rpx;
font-size: 24rpx;
color: #fff;
left: 0;
right: 0;
margin: auto;
}
.pro-cover-image{
width: 160rpx;
height: 160rpx;
}
.pro-img-wrap{
position: absolute;
width: 160rpx;
height: 160rpx;
left: 0;
right: 0;
margin: auto;
border: 10rpx solid #FDF0D3;
top: -40px;
border-radius: 16rpx;
overflow: hidden;
}
.img-wrap{
position: relative;
transition: all .2s ease-in-out;
}
.tips{
font-size: 24rpx;
color: #999;
text-align: center;
margin-top: 20rpx;
}
.cover-swiper{
height: 620rpx;
}
.cover-picker {
.cover-title {
padding: 30rpx;
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.cover-item {
display: flex;
flex-direction: column;
align-items: center;
.cover-image {
width: 320rpx;
height: 400rpx;
border-radius: 16rpx;
transition: all .2s ease-in-out;
}
.cover-name {
margin-top: 20rpx;
font-size: 28rpx;
color: #333;
}
}
.cover-confirm {
margin-top: 40rpx;
width: 240rpx;
height: 80rpx;
border-radius: 16rpx;
font-size: 32rpx;
background-color: #C52733 !important;
color: #fff !important;
text-align: center;
line-height: 80rpx;
}
}
</style>
+295
View File
@@ -0,0 +1,295 @@
<template>
<view class="dialog-conent" v-show="isLogin">
<view class="gift-card-modal" >
<image class="bg-image" :src="card.cover" mode="aspectFit|aspectFill|widthFix" lazy-load="false"></image>
<view class="image-wrap">
<image class="pro-image" :src="card.giftProducts[0].productImage" mode="aspectFit|aspectFill|widthFix" lazy-load="false" @error="" @load="">
</image>
</view>
<view class="wrap-box">
</view>
<view class="auto-text-color">
{{ card.message || '礼笺轻启,礼藏心意' }}
</view>
</view>
<view class="btn-wrap">
<button v-if="!isReceive && myGift.isCurrentUser !== 1" class="share-btn v12-white-text v12-primary" @click="setAddress(0)">
填写地址并收下
</button>
<button v-if="card.canTransfer !== 0 && !isReceive && myGift.isCurrentUser !== 1" open-type="share" class="share-btn v12-white v12-primary-text v12-d-flex" >
点击转赠给好友
<u-icon :name="webUrl + '/icon/share.png'" ></u-icon>
</button>
</view>
<view v-if="myGift.isCurrentUser === 1" @click="toOrder" style="z-index: 10">
<view class="address-btn v12-white-text v12-primary">
您已领取礼包
</view>
<view class="v12-text-center v12-font-26 v12-primary-text v12-mt-3">查看礼包详情>></view>
</view>
<view v-if="isReceive && myGift.isCurrentUser !== 1" @click="toHome" style="z-index: 10">
<view class="address-btn v12-white-text v12-primary">
礼包已被领取
</view>
<view class="v12-text-center v12-font-26 v12-primary-text v12-mt-3" style="z-index: 10">去商城看看>></view>
</view>
<view class="tips">
<view class="tip-text v12-mr-1" @click="showTips">
未领取礼包将于24小时后自动退回
<u-icon name="error-circle" color="#666" size="24rpx"></u-icon>
</view>
</view>
<giftTips ref="giftTips" :richText="giftNotice"></giftTips>
<AddressDialog ref="addressDialog" @save="getReceive"></AddressDialog>
<AddressList ref="AddressList" :addressList="address" @save="getReceive"></AddressList>
</view>
</template>
<script>
import { getGiftCardSendNotice, getGiftCardReceive } from '@/api/gift'
import cookie from "@/utils/store/cookie";
import { getAddressList } from '@/api/user'
import giftTips from './giftTips.vue'
import AddressDialog from './AddressDialog.vue'
import AddressList from './AddressList.vue'
export default {
name: 'GiftCard',
components: {
giftTips,
AddressDialog,
AddressList
},
props: {
// 组件属性
card: {
type: Object,
default: () => {}
},
addr: {
type: Object,
default: () => {}
}
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
// 组件数据
giftNotice: '',
address: [],
order: ''
}
},
computed: {
isReceive() {
const gitfNum = this.card.giftProducts && this.card.giftProducts.length
const isReceiveNum = this.card.giftProducts && this.card.giftProducts.filter(e => e.isReceive === 1).length
return gitfNum === isReceiveNum
},
isLogin() {
return !!cookie.get('login_status');
},
myGift() {
return this.card.giftProducts && this.card.giftProducts.filter(item => item.isCurrentUser === 1).length > 0 && this.card.giftProducts.filter(item => item.isCurrentUser === 1)[0] || this.card.giftProduct && this.card.giftProducts[0]
}
},
watch: {
addr: {
handler(newVal, oldVal) {
if (newVal && newVal.id) {
// this.address = newVal
this.setAddress(1)
}
},
deep: true
},
// 修改后的监听器
myGift: {
handler(newVal) {
this.order = newVal && newVal.orderId
},
deep: true,
immediate: true
}
},
methods: {
// 分享到微信好友
toShare() {
// 分享到微信好友
},
toOrder() {
this.$yrouter.push({
path: "/pages/order/OrderDetails/index",
query: {
id: this.order
}
});
},
toHome() {
uni.switchTab({
url: '/pages/home/index'
})
},
getReceive(e) {
uni.showLoading({
title: '领取中...',
mask: true
})
// 领取礼包
getGiftCardReceive({
code: this.card.code,
recipientsNum : 1,
addressId: e
}).then(res => {
this.$refs.addressDialog.close()
this.$refs.AddressList.close()
this.order = res.data.orderId
this.$emit('receive', this.card.code)
uni.hideLoading()
}).finally(() => {
})
},
setAddress(flag) {
getAddressList().then(res => {
if (res.data.length === 0) {
this.$refs.addressDialog.open()
} else {
this.address = res.data
if(flag) return
this.$refs.AddressList.open()
}
})
},
async showTips() {
// 获取发礼提示
getGiftCardSendNotice().then(res => {
this.$refs.giftTips.showTips = true
this.giftNotice = res.data
})
},
}
}
</script>
<style scoped>
.dialog-conent{
height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center
}
.btn-wrap{
position: relative;
display: flex;
justify-content: center;
align-content: center;
}
.bg-image{
width: 586rpx;
height: 704rpx;
position: absolute;
top: 0;
}
.tips{
display: flex;
align-items: center;
margin-top: 40rpx;
position: absolute;
bottom: 50rpx;
width: 100%;
}
.tip-text{
font-family: Source Han Sans SC;
font-weight: 500;
font-size: 24rpx;
color: #666;
opacity: 0.6;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
line-height: 36rpx;
}
.wrap-box{
width: 296rpx;
height: 296rpx;
}
.image-wrap{
width: 296rpx;
height: 296rpx;
border: 10rpx solid #FDF0D3;
border-radius: 30rpx;
position: absolute;
overflow: hidden;
top: -140rpx;
}
.pro-image{
width: 296rpx;
height: 296rpx;
/* border-radius: 30rpx; */
}
.auto-text-color {
color: #fff;
font-size: 32rpx;
opacity: 0.8;
margin-top: 150rpx;
width: 400rpx;
text-align: center;
}
.share-btn{
width: fit-content;
border-radius: 100rpx;
font-size: 32rpx;
margin-top: 40rpx;
z-index: 999;
align-items: center;
border: 1rpx solid #C52733 ;
margin-left: 10rpx;
font-weight: bold;
height: 80rpx;
line-height: 80rpx;
}
.share-btn::before{
border: none;
}
.share-btn::after{
border: none ;
}
.address-btn{
width: fit-content;
padding: 10rpx 40rpx;
border-radius: 100rpx;
font-size: 32rpx;
font-weight: bold;
height: 80rpx;
line-height: 80rpx;
/* margin-top: 40rpx; */
z-index: 999;
}
.gift-card-modal {
height: 704rpx;
justify-content: center;
z-index: 999;
margin-top: 100rpx;
border-radius: 16rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: start;
position: relative;
}
.gift-card-content {
background-color: #fff;
padding: 20px;
border-radius: 10px;
width: 80%;
max-width: 300px;
}
</style>
@@ -0,0 +1,106 @@
<template>
<u-popup
:show="show"
mode="bottom"
round="20rpx"
@close="close"
:customStyle="{height: '400rpx', padding: '30rpx'}"
closeable
safeAreaInsetBottom
>
<view class="pay-picker">
<view class="title">选择支付方式</view>
<view class="pay-item" :class="{ active: activeType === 'weixin' }" @click="handleSelect('weixin')">
<text class="label">微信支付</text>
<radio :checked="activeType === 'weixin'" color="#09BB07"></radio>
</view>
<view class="pay-item" :class="{ active: activeType === 'yue' }" @click="handleSelect('yue')">
<text class="label">余额支付</text>
<radio :checked="activeType === 'yue'" color="#09BB07"></radio>
</view>
<view class="confirm-btn" @click="confirm">确定</view>
</view>
</u-popup>
</template>
<script>
export default {
props: {
show: {
type: Boolean,
default: false
}
},
data() {
return {
activeType: 'weixin' // 默认选中微信支付
}
},
methods: {
close() {
this.$emit('update:show', false)
},
handleSelect(type) {
this.activeType = type
},
confirm() {
this.$emit('confirm', this.activeType)
this.close()
}
}
}
</script>
<style lang="less" scoped>
.pay-picker {
.title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 40rpx;
}
.pay-item {
display: flex;
align-items: center;
padding: 20rpx;
margin-bottom: 20rpx;
border-radius: 10rpx;
background-color: #f5f5f5;
&.active {
background-color: #e8f5e9;
}
.icon {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
.label {
flex: 1;
font-size: 28rpx;
color: #333;
}
radio {
transform: scale(0.8);
}
}
.confirm-btn {
margin-top: 40rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
background-color: #C52733;
color: #fff;
border-radius: 40rpx;
font-size: 32rpx;
}
}
</style>
@@ -0,0 +1,70 @@
<template>
<view>
<!-- 弹窗组件 -->
<u-popup
:show="showTips"
mode="center"
closeable
round="16rpx"
@close="showTips = false"
>
<view class="popup-content">
<!-- 标题 -->
<view class="title">赠礼须知</view>
<!-- 富文本内容 -->
<view class="text-wrap">
<u-parse :content="richText" />
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
props: {
// 接收传递的参数
richText: {
type: String,
default: ''
}
},
data() {
return {
showTips: false,
}
}
}
</script>
<style lang="scss" scoped>
.text-wrap{
height: 800rpx;
overflow: auto;
}
.popup-content {
width: 600rpx;
padding:0 40rpx 40rpx 40rpx;
box-sizing: border-box;
.title {
padding-top: 40rpx;
padding-bottom: 20rpx;
font-size: 36rpx;
font-weight: bold;
text-align: center;
top: 0;
background: #fff;
background-color: #fff;
z-index: 11;
}
.close-btn {
margin-top: 40rpx;
}
/deep/ .u-parse {
max-height: 800rpx;
overflow-y: auto;
}
}
</style>
+538
View File
@@ -0,0 +1,538 @@
<template>
<view class="gift-page">
<view class="top-card" v-if="!isPayOk">
<view class="v12-justify-between v12-pa-2">
<view>
<view></view>
<view class="v12-font-28 v12-secondary-dark-text v12-d-flex">
<u-icon :name="webUrl + '/icon/gift-primary.png'"></u-icon>
送礼寄语
</view>
</view>
<view class="v12-primary-text v12-font-26 v12-d-flex v12-align-center">
<image class="custom-cover" :src="webUrl + '/icon/custom.png'" mode="heightFix" lazy-load="false">
</image>
<view @click="showCoverPicker = true">{{ cover }}封面</view>
<view>
<u-icon name="arrow-right" color="#c52733"></u-icon>
</view>
</view>
</view>
<view class="v12-px-2">
<view class="line"></view>
</view>
<view class="v12-pa-2 ">
<u-textarea
v-model="message"
placeholderClass="v12-font-28"
placeholder="礼笺轻启,礼藏心意"
maxlength="30"
border="none"
count
ref="textarea"
cols="30"
@input="messageChange"
rows="10"></u-textarea>
</view>
</view>
<view class="gift-good-card">
<view class="v12-align-center v12-justify-start">
<view>
<image :src="goodsInfo.productInfo.image" mode="scaleToFill" class="cover-image"></image>
</view>
<view class="v12-ml-2 info-wrap">
<view class="v12-dark-text v12-font-bold v12-font-28 t-more">
{{ goodsInfo.productInfo.storeName }}
</view>
<view class="gift-sku">
{{ goodsInfo.productInfo.attrInfo.sku }}
</view>
<view class="v12-justify-between">
<view>
<text class="v12-primary-text v12-font-bold v12-font-22"></text>
<text class="v12-primary-text v12-font-bold v12-font-30">{{ payPrice }}</text>
</view>
<view>
<u-number-box
v-if="!isPayOk"
v-model="goodsInfo.cartNum"
:max="goodsInfo['productInfo']['attrInfo']['stock']"
integer
disabledInput
iconStyle="color: #fff"
class="num-step"
@change="numberChange"
>
<template v-slot:minus>
<view class="v12-minus-btn v12-font-bold flex jc-center ai-center">
<u-icon name="minus" size="12" color="#FFFFFF"/>
</view>
</template>
<template v-slot:input>
<view class="num-input tc v12-num-input">{{ goodsInfo['cartNum'] }}</view>
</template>
<template v-slot:plus>
<view class="v12-plus-btn v12-font-bold flex jc-center ai-center v12-primary">
<u-icon name="plus" size="12" color="#FFFFFF"/>
</view>
</template>
</u-number-box>
<view v-else> x{{ goodsInfo['cartNum'] }} </view>
</view>
</view>
</view>
</view>
<u-divider v-if="isPayOk"></u-divider>
<view class="v12-font-26 v12-secondary-dark-text" v-if="isPayOk">
赠言{{ message || '礼笺轻启礼藏心意'}}
</view>
</view>
<view class="swich-btn" v-if="!isPayOk">
<view class="v12-font-28 v12-dark-text">是否支持好友转赠</view>
<view>
<u-switch v-model="canTransfer" ></u-switch>
</view>
</view>
<button v-if="isPayOk" open-type="share" class="share-btn" >
<view class="v12-font-28 v12-primary-text v12-align-center">
<u-icon :name="webUrl + '/icon/gift-primary.png'" size="18"></u-icon>
点击送给朋友</view>
<view class="share-icon" >
<u-icon :name="webUrl + '/icon/share.png'" ></u-icon>
</view>
</button>
<view class="btn-wrap v12-mt-16 v12-justify-center" v-if="!isPayOk">
<view class="gift-submit" @click="showPayPicker = true">付款并赠送</view>
</view>
<view class="btn-wrap v12-mt-16 v12-justify-center" v-if="isPayOk">
<view class="gift-submit" @click="makeAgain">再送一份</view>
</view>
<view class="tip-wrap v12-justify-center">
<view class="tip-text v12-mr-1">好友未收下礼包将于24小时后自动退款</view>
<u-icon @click="showTips" name="error-circle" color="#666" size="28rpx"></u-icon>
</view>
<giftTips ref="giftTips" :richText="giftNotice"></giftTips>
<CoverPicker
:show.sync="showCoverPicker"
:list="coverList"
:product="goodsInfo.productInfo"
@confirm="onCoverConfirm"
:index="defaultIndex"
:message="message"
/>
<passkeyborad
ref='payPwdPop'
showMoney
:money="payPrice"
:show="isShowPayPwdPop"
@close="isShowPayPwdPop = false"
@finish="pwdPopFinish"
/>
<PayPicker
ref="payPicker"
:show.sync="showPayPicker"
@confirm="onPayConfirm"
/>
</view>
</template>
<script>
import passkeyborad from '@/components/yzc-paykeyboard/yzc-paykeyboard'
import { getGiftCardSendOrderConfirm, getGiftCardSendOrder, getGiftCardSendOrderAmount, getGiftCardResend } from '@/api/gift'
import { weappPay } from "@/libs/wechat";
import {mapGetters} from "vuex";
import giftTips from './components/giftTips.vue'
import CoverPicker from './components/CoverPicker.vue'
import PayPicker from './components/PayPicker.vue';
export default {
components: {
giftTips,
CoverPicker,
PayPicker,
passkeyborad
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
canTransfer: false,
message: '',
cartId: '',
couponId: '',
coverList: [],
giftNotice: '',
showCoverPicker: false,
showPayPicker: false,
selectedCover: '',
giftImage: '',
orderKey: '',
goodsInfo: {},
cover: '默认',
orderGroupInfo: {
priceGroup: {}
},
templateId: '',
isShowPayPwdPop: false,
payPassword: '',
payType: '',
isPayOk: false,
giftKey: '',
payPrice: 0,
orderId: '',
defaultIndex:0
}
},
onLoad(opts) {
this.cartId = opts.cartId
this.couponId = opts.couponId
this.getGift()
},
computed: mapGetters(["userInfo"]),
onShareAppMessage() {
return {
title: this.message || '礼笺轻启,礼藏心意',
path: `/pkg_user/views/gift/receive?code=${this.giftKey}`,
imageUrl: this.giftImage
}
},
onReady() {
this.$nextTick(() => {
this.$refs.textarea.setFormatter(val => {
return val.length > 30 ? val.substring(0, 30) : val
})
})
},
methods: {
makeAgain() {
const params = {
orderId: this.orderId,
}
getGiftCardResend(params).then(res => {
this.isPayOk = false
this.coverList = [...res.data.giftCardTemplates, res.data.specialGiftCardTemplate]
this.cartId = res.data.cartInfo[0].id
this.giftNotice = res.data.giftCardGiftNotice
this.orderKey = res.data.orderKey
this.goodsInfo = res.data.cartInfo[0]
this.templateId = res.data.specialGiftCardTemplate.id
this.defaultIndex = this.coverList.findIndex(item => item.id === this.templateId)
console.log(this.defaultIndex, 'defaultIndex');
this.selectedCover = res.data.specialGiftCardTemplate.cover
this.giftImage = res.data.specialGiftCardTemplate.image
this.couponId = ''
this.computedPrice(this.goodsInfo.cartNum)
})
},
messageChange(e) {
this.message = e.substring(0, 30)
},
numberChange(e) {
this.computedPrice(e.value)
},
computedPrice(num) {
const params = {
cartId: this.cartId,
couponId: this.couponId,
cartNum : num,
}
getGiftCardSendOrderAmount(this.orderKey, params).then(res => {
this.payPrice = res.data.result.payPrice
this.$forceUpdate()
})
},
pwdPopFinish(payPwd) {
this.payPassword = payPwd;
this.confirmGift(true);
},
onPayConfirm(e) {
this.payType = e
this.confirmGift(false)
},
onCoverConfirm(cover) {
this.cover = cover.name
this.templateId = cover.id
this.selectedCover = cover.cover
this.giftImage = cover.image
},
showTips() {
this.$refs.giftTips.showTips = true
},
getGift() {
const params = {
cartId: this.cartId,
}
getGiftCardSendOrderConfirm(params).then(res => {
this.coverList = res.data.giftCardTemplates.map(e => e.id).includes(res.data.specialGiftCardTemplate.id) ? [...res.data.giftCardTemplates] : [...res.data.giftCardTemplates, res.data.specialGiftCardTemplate]
this.giftNotice = res.data.giftCardGiftNotice
this.orderKey = res.data.orderKey
this.goodsInfo = res.data.cartInfo[0]
this.templateId = res.data.specialGiftCardTemplate.id
this.selectedCover = res.data.specialGiftCardTemplate.cover
this.giftImage = res.data.specialGiftCardTemplate.image
this.defaultIndex = this.coverList.findIndex(item => item.id === this.templateId)
console.log(this.defaultIndex, 'defaultIndex');
if(!this.couponId) {
this.couponId = res.data.couponList.usable[0] && res.data.couponList.usable[0].id || ''
}
this.computedPrice(this.goodsInfo.cartNum)
})
},
/**
* 确认赠送
* @param {*}
*/
confirmGift(isPay) {
if(!isPay && this.payType === 'yue') {
//先判断用户是否绑定过手机
if (this.userInfo.phone) {
//再判断用户是否设置过支付密码
if (this.userInfo.hasPwdPay) {
//显示输入支付密码
this.isShowPayPwdPop = true;
} else {
//设置支付密码
this.$yrouter.push("/pkg_user/views/payPassword?isSetMode=true");
}
} else {
//跳转到绑定手机
this.$yrouter.push("/pkg_user/views/bindPhone");
}
return
}
uni.showLoading({
title: "生成订单中"
});
const params = {
orderKey: this.orderKey,
from: 'routine',
cartId: this.cartId,
couponId: this.couponId,
recipientsNum: this.goodsInfo.cartNum,
templateId: this.templateId,
message : this.message || '礼笺轻启,礼藏心意',
cover: this.selectedCover,
canTransfer: this.canTransfer ? 1 : 0,
payType: this.payType,
seckillId: this.orderGroupInfo.seckill_id,
combinationId: this.orderGroupInfo.combination_id,
bargainId: this.orderGroupInfo.bargain_id,
}
if (this.payType == 'yue') {
params.passwordPay = this.payPassword;
}
getGiftCardSendOrder(this.orderKey, params).then(res => {
uni.hideLoading();
const data = res.data;
this.giftKey = data.giftCard.code;
this.orderId = data.result.orderId || ''
switch (data.status) {
case "ORDER_EXIST":
case "EXTEND_ORDER":
uni.showToast({
title: res.msg,
icon: "none",
duration: 2000
});
break;
case "PAY_DEFICIENCY":
break;
case "PAY_ERROR":
uni.showToast({
title: res.msg,
icon: "none",
duration: 2000
});
break;
case "SUCCESS":
uni.showToast({
title: res.msg,
icon: "none",
duration: 2000
});
this.isPayOk = true;
break;
case "WECHAT_H5_PAY":
// H5支付
setTimeout(() => {
// location.href = data.result.jsConfig.mweb_url;
}, 100);
break;
case "WECHAT_PAY":
// 小程序支付
weappPay(data.result.jsConfig).then((e) => {
uni.showToast({
title: res.msg,
icon: "none",
duration: 2000
});
this.isPayOk = true;
}).catch(err => {
this.makeAgain()
uni.showToast({
title: '支付取消,请在我的礼品卡中完成支付',
icon: "none",
duration: 3000
});
}).finally(() => {
})
break;
case "WECHAT_APP_PAY":
// APP支付
weappPay(data.result.jsConfig).finally(() => {
});
break;
}
}) .catch(err => {
console.log(err);
uni.hideLoading();
uni.showToast({
title:"创建订单失败",
icon: "none",
duration: 2000
});
}).finally(() => {
this.isShowPayPwdPop = false;
this.$refs.payPwdPop.clear();//清空支付密码
this.$refs.payPwdPop.close();//关闭支付密码弹窗
});
}
}
}
</script>
<style lang="less" scoped>
.custom-cover{
height: 58rpx;
}
.info-wrap{
width: 100%;
height: 200rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.v12-num-input{
height: 40rpx;
width: 40rpx;
border: 1px solid #E6E6E6;
line-height: 40rpx;
font-weight: bold;
font-size: 28rpx;
color: #333;
display: flex;
align-items: center;
justify-content: center;
}
.v12-minus-btn{
border-radius: 28rpx 0rpx 0rpx 28rpx;
border: 1px solid #E6E6E6;
background-color: rgba(208,208,208,0.39);
height: 40rpx;
width: 40rpx;
font-weight: bold;
}
.v12-plus-btn{
border-radius: 0rpx 28rpx 28rpx 0rpx;
border: 1px solid #C52733;
background-color: #C52733;
height: 40rpx;
width: 40rpx;
font-weight: bold;
}
.gift-sku{
font-size: 24rpx;
color: #333333;
border-radius: 124rpx;
border: 1px solid #999999;
padding: 5rpx 10rpx;
text-align: center;
margin-top: 20rpx;
width: fit-content;
}
.cover-image{
width: 200rpx;
height: 200rpx;
background: rgba(139,33,33,0.39);
border-radius: 16rpx;
}
.tip-wrap{
position: absolute;
bottom: 100rpx;
left: 0;
margin: auto;
right: 0;
align-items: center;
}
.tip-text{
font-family: Source Han Sans SC;
font-weight: 500;
font-size: 28rpx;
color: #666666;
line-height: 36rpx;
}
.gift-submit{
width: 240rpx;
height: 80rpx;
background: rgba(197,39,51,1);
border-radius: 16rpx;
color: #fff;
line-height: 80rpx;
text-align: center;
font-size: 32rpx;
font-weight: 500;
}
.gift-page{
padding: 10rpx 20rpx;
}
.top-card{
height: 280rpx;
background: #fff;
border-radius: 16rpx;
}
.line{
width: 100%;
height: 2rpx;
background: #d2d2d2;
}
.gift-good-card{
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-top: 30rpx;
}
.swich-btn{
display: flex;
justify-content: space-between;
align-items: center;
height: 60rpx;
background: #fff;
border-radius: 30rpx;
padding: 5rpx 20rpx;
margin-top: 30rpx;
}
.share-btn{
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
border-radius: 30rpx;
padding: 5rpx 20rpx;
margin-top: 30rpx;
border: none;
}
.share-btn::after {
border: none;
}
</style>
+108
View File
@@ -0,0 +1,108 @@
<template>
<view v-if="!loading">
<GiftCard v-if="!giftCard.isExpire" :card="giftCard" :addr="giftChooseAddress" @receive="getGiftCard($event)" />
<view v-else>
<view class="no-img-wrap">
<view class="wrap-box" >
<image :src="webUrl + '/icon/no-gift.png'" mode="widthFix"></image>
<view class="v12-font-28 v12-dark1-text v12-mt-8">礼包超过24小时未领取订单已取消</view>
<view @click="toHome" class="v12-font-28 v12-primary-text v12-primary-border go-btn">去商城看看</view>
</view>
</view>
</view>
</view>
</template>
<script>
import GiftCard from './components/GiftCard.vue'
import { getGiftCardDetail } from '@/api/gift'
export default {
components: {
GiftCard
},
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
giftCard: {},
giftChooseAddress: {},
loading: false
}
},
onLoad(opts) {
this.getGiftCard(opts.code)
},
onShow() {
this.giftChooseAddress = uni.getStorageSync('giftChooseAddress') || {}
},
onShareAppMessage() {
return {
title: this.giftCard.message || '礼笺轻启,礼藏心意',
path: `/pkg_user/views/gift/receive?code=${this.giftCard.code}`,
imageUrl: this.giftCard.image
}
},
methods: {
toHome() {
uni.switchTab({
url: '/pages/home/index'
})
},
getGiftCard(code) {
this.loading = true
uni.showLoading({
title: '加载中...',
mask: true
})
getGiftCardDetail({
code: code
}).then(res => {
this.giftCard = res.data || {}
this.loading = false
}).catch(err => {
this.giftCard = {
canTransfer: 0,
isReceive: true
}
}).finally(() => {
uni.hideLoading()
})
},
}
}
</script>
<style lang="less" scoped>
.wrap-box{
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 400rpx;
}
.go-btn{
border-radius: 200rpx;
padding: 8rpx 20rpx;
font-weight: bold;
margin-top: 60rpx;
width: fit-content;
}
.no-img-wrap{
height: 100vh;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
}
.no-img-wrap image{
width: 280rpx;
height: 280rpx;
}
.top-card{
width: 710rpx;
height: 280rpx;
background: #fff;
border-radius: 16rpx;
}
</style>
+553
View File
@@ -0,0 +1,553 @@
<template>
<view class="gift-page">
<view class="cate-wrap">
<view class="cate-list">
<view
v-for="(item, index) in cateList"
:key="index"
:class="cateIndex === index ? 'curr' : ''"
class="cate-item"
@click="cateItemClickHanlde(item, index)"
>
{{ item.name }}
</view>
</view>
</view>
<view class="list-wrap">
<block v-if="isLoad">
<view v-if="cateIndex === 0" class="list-body">
<block v-if="sendList.length > 0">
<view
v-for="(item, index) in sendList"
:key="index"
class="gift-item"
>
<view
v-for="(cart, cartIndex) in item.giftInfo"
:key="cartIndex"
class="gift-body"
@click="giftItemClickHanlde(item)"
>
<view class="gift-img">
<image
:src="cart.productInfo.image"
class="img"
mode="widthFix"
/>
</view>
<view class="gift-good-info">
<view class="name more-t">
{{ cart.productInfo.storeName }}
</view>
<view v-if="cart.productInfo.attrInfo" class="attr-txt">
<view class="txt">{{ cart.productInfo.attrInfo.sku }}</view>
</view>
<view class="price-wrap">
<view class="price">
<text class="prefix"></text>{{ item.payPrice }}
</view>
<view class="num">数量&nbsp;X&nbsp;{{ cart.cartNum }}</view>
</view>
</view>
</view>
<view class="gift-bottom">
<view class="gift-txt">
赠言{{ item.message || '' }}
</view>
<!-- 状态 0-待领取 1-已全部领取 2-已失效 -->
<button
v-if="item.status === -1"
class="btn"
@click="goBuy(item)"
>
待付款
<image
:src="webUrl + '/icon/icon-gift-share.png'"
class="icon"
mode="widthFix"
/>
</button>
<button
v-if="item.status === 0"
open-type="share"
class="btn"
@click="shareGift(item)"
>
送给朋友
<image
:src="webUrl + '/icon/icon-gift-share.png'"
class="icon"
mode="widthFix"
/>
</button>
<view
v-if="item.status === 1"
class="btn"
>
已全部领取
</view>
<view
v-if="item.status === 2"
class="btn btn-grey"
>
已过期
</view>
</view>
</view>
</block>
<view v-if="sendList.length === 0" class="noCart">
<view class="pictrue">
<image :src="webUrl + '/20240102232734472795.png'"/>
</view>
</view>
</view>
<view v-if="cateIndex === 1" class="list-body">
<block v-if="receiveList.length > 0">
<view
v-for="(item, index) in receiveList"
:key="index"
class="gift-item"
>
<view
v-for="(cart, cartIndex) in item.giftInfos"
:key="cartIndex"
class="gift-body"
@click="giftItemClickHanlde(item)"
>
<view class="gift-img">
<image
:src="cart.productInfo.image"
class="img"
mode="widthFix"
/>
</view>
<view class="gift-good-info">
<view class="name more-t">
{{ cart.productInfo.storeName }}
</view>
<view v-if="cart.productInfo.attrInfo" class="attr-txt">
<view class="txt">{{ cart.productInfo.attrInfo.sku }}</view>
</view>
<view class="price-wrap">
<view class="price">
<text class="prefix"></text>{{ cart.productInfo.attrInfo.price }}
</view>
</view>
</view>
</view>
<view class="gift-bottom">
<view class="gift-txt">
赠言{{ item.message || '' }}
</view>
<view
:class="{
'btn-grey': [-2, 3].includes(+item._status._type)
}"
class="btn"
>
{{ getStatus(item) }}
</view>
</view>
</view>
</block>
<view v-if="receiveList.length === 0" class="noCart">
<view class="pictrue">
<image :src="webUrl + '/20240102232734472795.png'"/>
</view>
</view>
</view>
</block>
<goo-skeleton
v-else
:show-avatar="false"
/>
</view>
<view class="page-bottom">
<image
:src="webUrl + '/icon/icon-send-gift-notice-btn.png'"
class="icon"
mode="widthFix"
@click="showTips"
/>
</view>
<gift-tips
ref="giftTips"
:richText="giftNotice"
/>
<Payment v-model="pay" :types="payType" @checked="toPay" :balance="userInfo.nowMoney"></Payment>
<passkeyborad
:money="orderInfo.payPrice"
showMoney
:show="isShowPayPwdPop"
ref='payPwdPop'
@close="pwdPopClose"
@finish="pwdPopFinish"
></passkeyborad>
</view>
</template>
<script>
import passkeyborad from '@/components/yzc-paykeyboard/yzc-paykeyboard'
import {cancelOrderHandle, payOrderHandle, takeOrderHandle, yuePayOrderHandle, delOrderHandle} from "@/libs/order";
import Payment from "@/components/Payment";
import {
giftCardReceiveList,
giftCardSendList,
giftNotice
} from '@/api/giftList'
import {mapGetters} from "vuex";
import giftTips from '@/pkg_user/views/gift/components/giftTips.vue'
export default {
name: 'GiftLisPage',
components: {
giftTips,
passkeyborad,
Payment
},
data() {
return {
pay: false,
payType: ["yue", "weixin"],
webUrl: this.$VUE_APP_RESOURCES_URL,
giftNotice: '',
cateIndex: 0,
cateList: [
{
name: '送出的',
status: 1
},
{
name: '收到的',
status: 2
}
],
isLoad: false,
from: this.$deviceType,
sendList: [],
receiveList: [],
giftItem: {},
orderInfo: {},
isShowPayPwdPop: false,
}
},
computed: mapGetters(["userInfo"]),
created() {
giftNotice().then(res => {
this.giftNotice = res.data
})
this.getGiftCardSendList()
},
onShareAppMessage() {
return {
title: this.giftItem.message || '礼笺轻启,礼藏心意',
path: `/pkg_user/views/gift/receive?code=${this.giftItem.code}`,
imageUrl: this.giftItem.templateInfo.image
}
},
methods: {
pwdPopFinish(payPwd) {
this.payPassword = payPwd;
this.toYuePay(payPwd);
this.isShowPayPwdPop = false;
},
toYuePay(payPwd) {
//网络请求
yuePayOrderHandle(this.orderInfo.orderId, "yue", this.from, payPwd).then(res => {
console.log(res);
this.getGiftCardSendList()
this.payPassword = "";
})
},
pwdPopClose() {
this.isShowPayPwdPop = false;
},
wechatPay(type) {
payOrderHandle(this.orderInfo.orderId, type, this.from).then(res => {
console.log(res);
this.getGiftCardSendList()
})
},
goBuy(order) {
this.pay = true
this.orderInfo = order
},
toPay(type) {
//余额支付需要输入支付密码
if (type == "yue") {
this.isShowPayPwdPop = true;
return;
} else {
this.wechatPay(type);
}
},
shareGift(item) {
this.giftItem = item
},
cateItemClickHanlde(item, index) {
if (this.cateIndex === index || !this.isLoad) return
this.cateIndex = index
if (this.cateIndex === 0) {
this.getGiftCardSendList()
}
if (this.cateIndex === 1) {
this.getGiftCardReceiveList()
}
},
getGiftCardReceiveList() {
this.isLoad = false
giftCardReceiveList({
page: 1,
limit: 999
}).then(res => {
const { success, data } = res
if (success) {
this.receiveList = data || []
}
}).catch(err => {
console.log(err)
}).finally(() => {
this.isLoad = true
})
},
getGiftCardSendList() {
this.isLoad = false
giftCardSendList({
page: 1,
limit: 999
}).then(res => {
const { success, data } = res
if (success) {
this.sendList = data || []
}
}).catch(err => {
console.log(err)
}).finally(() => {
this.isLoad = true
})
},
getStatus(order) {
const type = Number(order._status._type)
let status = ''
switch (type) {
case 0:
status = '待付款'
break
case 1:
status = '礼包待发货'
break
case 2:
status = '礼包待收货'
break
case 3:
status = '礼包已收货'
break
case 4:
status = '已完成'
break
case -1:
status = '退款中'
break
case -2:
status = '已退回'
break
case -3:
status = '退款失败'
break
case 9:
status = '已取消'
break
default:
break
}
return status
},
showTips() {
this.$refs.giftTips.showTips = true
},
giftItemClickHanlde(item) {
if (this.cateIndex === 0) return
this.$yrouter.push({
path: '/pages/order/OrderDetails/index',
query: {
id: item.orderId
}
})
}
}
}
</script>
<style lang="less" scoped>
.gift-page {
position: relative;
min-height: 100vh;
padding: 20rpx 20rpx 0 20rpx;
box-sizing: border-box;
background-color: #F6F6F6;
.cate-wrap {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 9;
padding: 20rpx 32rpx;
background-color: #F6F6F6;
.cate-list {
display: flex;
align-items: center;
height: 64rpx;
border-radius: 32rpx;
background-color: #fff;
.cate-item {
flex: 1;
height: 64rpx;
border-radius: 32rpx;
line-height: 64rpx;
text-align: center;
font-size: 30rpx;
color: #333;
background-color: #fff;
&.curr {
font-weight: bold;
color: #fff;
background-color: #C41617;
}
}
}
}
.list-wrap {
position: relative;
z-index: 2;
padding: 84rpx 0 80rpx 0;
.gift-item {
padding: 16rpx;
margin: 0 0 24rpx;
border-radius: 16rpx;
background-color: #ffff;
.gift-body {
display: flex;
align-items: center;
justify-content: space-between;
.gift-img {
.img {
display: block;
width: 200rpx;
height: 200rpx;
border-radius: 16rpx;
}
}
.gift-good-info {
display: flex;
flex-direction: column;
justify-content: space-between;
width: calc(100% - 212rpx);
height: 200rpx;
.name {
font-weight: bold;
font-size: 28rpx;
color: #333;
line-height: 44rpx;
}
.attr-txt {
display: flex;
.txt {
height: 42rpx;
padding: 0 12rpx;
border-radius: 24rpx;
border: 1px solid #999;
line-height: 42rpx;
color: #333;
font-size: 24rpx;
}
}
.price-wrap {
display: flex;
align-items: center;
justify-content: space-between;
.price {
color: #C52733;
font-size: 30rpx;
font-weight: bold;
.prefix {
font-weight: normal;
font-size: 22rpx;
}
}
.num {
font-size: 24rpx;
color: #666;
}
}
}
}
.gift-bottom {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 0 0 0;
margin: 24rpx 0 0 0;
border-top: 1rpx solid #D2D2D2;
.gift-txt {
flex: 1;
font-size: 26rpx;
color: #666;
}
.btn {
display: flex;
align-items: center;
height: 46rpx;
padding: 0 12rpx;
margin: 0 0 0 24rpx;
border-radius: 8rpx;
color: #fff;
line-height: 46rpx;
font-size: 26rpx;
background-color: #C52733;
.icon {
display: block;
width: 20rpx;
height: 20rpx;
}
&.btn-grey {
color: #fff;
background-color: #C7C7C7;
}
}
}
}
}
.page-bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 9;
display: flex;
align-items: center;
justify-content: center;
height: 80rpx;
background-color: #F6F6F6;
.icon {
display: block;
width: 140rpx;
}
}
}
.noCart {
margin-top: 0.17 * 100rpx;
padding-top: 0.1 * 100rpx;
.pictrue {
width: 408rpx;
height: 414rpx;
overflow: hidden;
margin: 0.7 * 100rpx auto 0.5 * 100rpx auto;
image {
display: block;
width: 408rpx;
height: 414rpx;
}
}
}
</style>
+13 -6
View File
@@ -77,16 +77,16 @@
:src="item['image']"
mode="scaleToFill"
class="cover flex-0"
@click="navToGoods(item['productId'])"
@click="navToGoods(item)"
/>
<view style="width: 100%">
<view
class="more-t bold"
@click="navToGoods(item['productId'])"
@click="navToGoods(item)"
>{{ item['storeName'] }}</view>
<view class="sub" @click="navToGoods(item['productId'])">规格:{{ item['sku'] }}</view>
<view class="sub" @click="navToGoods(item)">规格:{{ item['sku'] }}</view>
<view class="flex jc-between ai-end">
<view class="price flex ai-end" @click="navToGoods(item['productId'])">
<view class="price flex ai-end" @click="navToGoods(item)">
<text style="color:#E92727">¥</text>
<text style="color:#E92727;font-size: 32rpx;line-height: 48rpx">{{ item['price'] }}</text>
<text style="margin-left: 10rpx;text-decoration:line-through">¥{{ item['otPrice'] }}</text>
@@ -347,9 +347,16 @@ export default {
this.fetchProduct()
},
methods: {
navToGoods(id) {
navToGoods(item) {
if(item.isInvalid) {
uni.showToast({
title: '商品已下架',
icon: 'none'
})
return
}
uni.navigateTo({
url: "/pages/shop/GoodsCon/index?id=" + id
url: "/pages/shop/GoodsCon/index?id=" + item.productId
})
},
changeTabs(index) {
+1 -1
View File
@@ -223,7 +223,7 @@ export default {
.btn-save {
height: 80rpx;
margin-top: 80rpx;
background: #FD574B;
background: #C52733;
line-height: 80rpx;
}
}
+1 -1
View File
@@ -464,7 +464,7 @@ export default {
height: 80rpx;
margin: 54rpx 0 40rpx;
border-radius: 8rpx;
background: #FD574B;
background: #C52733;
color: #FFFFFF;
font-size: 28rpx;
font-weight: bold;
@@ -108,6 +108,7 @@
methods: {
noticeChange(e){
this.index = e.detail.current
this.$emit('change', this.index)
},
// 点击通告栏
clickHandler() {
@@ -19,6 +19,7 @@
:duration="duration"
@close="close"
@click="click"
@change="change"
></u-column-notice>
</template>
<template v-else>
@@ -73,6 +74,9 @@
}
},
methods: {
change(index) {
this.$emit('change', index)
},
// 点击通告栏
click(index) {
this.$emit('click', index)
+1 -1
View File
@@ -8,7 +8,7 @@ const http = new Request();
/* 设置全局配置 */
http.setConfig((config) => {
config.baseURL = VUE_APP_API_URL;
config.timeout = 2 * 60 * 1000;
config.timeout = 4 * 60 * 1000;
config.method = "POST";
config.responseType = "text";
config.header = {
+10 -1
View File
@@ -89,6 +89,15 @@ export default {
onLoad: function () {
this.init()
this.getCityList()
const localData = uni.getStorageSync('investmentIndex')
if (localData) {
this.businessApply = localData
this.addressText = localData.addressText
this.address = localData.address
}
},
onUnload() {
uni.setStorageSync('investmentIndex', {...this.businessApply, addressText: this.addressText, address: this.address})
},
methods: {
init() {
@@ -119,7 +128,7 @@ export default {
this.total = data.total
this.businessApplyList = data.businessApplyList
if (data.businessApply) {
this.businessApply = data.businessApply
// this.businessApply = data.businessApply
this.address = {
province: data.businessApply.provinceName || "",
city: data.businessApply.cityName || "",
+2 -2
View File
@@ -97,11 +97,11 @@ export default {
width: 68rpx;
height: 48rpx;
padding-bottom: 8rpx;
border-bottom: 6rpx solid #FD574B;
border-bottom: 6rpx solid #C52733;
font-size: 32rpx;
font-weight: bold;
line-height: 48rpx;
color: #FD574B;
color: #C52733;
}
.item {
+1 -1
View File
@@ -130,7 +130,7 @@ export default {
.btn {
width: 128rpx;
height: 54rpx;
background: #FD574B;
background: #C52733;
border-radius: 28rpx;
color: #fff;
}
+76 -1
View File
@@ -18,7 +18,7 @@
</view>
</view>
<view class="list flex flex-wrap" v-if="list.length">
<view class="list flex flex-wrap" v-if="list.length" id="goods-box">
<view class="item" v-for="item in list" :key="item.id" @click="goStore(item)">
<image class="image" :src="item.cover + (item.coverType === 2 ? '?vframe/jpg/offset/1' : '')" mode="scaleToFill"></image>
@@ -36,13 +36,20 @@
<image src="@/static/images/img_nodata.png" mode="scaleToFill"/>
<view class="text">暂无数据</view>
</view>
<FunctionGuide :maxStep="1" @hide="setGuide('wenwanIndex')" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
</view>
</template>
<script>
import {fetchStore} from "@/api/wenwan";
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
components: {
FunctionGuide
},
mixins: [GuideMixins],
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
@@ -55,6 +62,7 @@ export default {
},
onLoad(option) {
this.cityId = option.cityId;
this.queryGuide('wenwanIndex')
},
onShow() {
let memCityName = uni.getStorageSync("cityName")
@@ -71,6 +79,73 @@ export default {
this.fetchList(this.cityName);
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
const imgs = [
{
url: this.webUrl + '/引导页素材/文玩艺术/Group 2/Group 2-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '425rpx',
top: 0*2+'rpx',
left: 50*2+'rpx',
right: 0,
margin: 'auto',
height: '213rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/文玩艺术/Group 2/Group 2-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 75*2+'rpx',
left: 0*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/文玩艺术/Group 2/Group 2-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 75*2+'rpx',
left: 240*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.getElementData('#goods-box', res=>{
console.log(res, 'res---------');
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top + 'px',
left: res.left + 'px',
width: `${res.width}px`,
height: `${res.height}px`,
}
})
})
return
} else {
return
}
},
goClass() {
uni.navigateTo({
url: "/wenwan/views/goodsClass?cityId=" + this.cityId