- 新增订单创建、支付、快捷下单等功能 - 优化商品详情页展示,支持商品信息动态加载 - 调整用户中心界面,新增佣金和余额展示 - 修复地址管理模块的字段命名问题 - 更新API接口路径,适配新后端服务 - 删除冗余页面和代码,提升代码可维护性master
@ -1,331 +0,0 @@ | |||
<template> | |||
<!-- 帮助与反馈 --> | |||
<view class="help"> | |||
<navbar title="帮助与反馈" leftClick @leftClick="$utils.navigateBack" /> | |||
<view class="help-box"> | |||
<view> | |||
<view class="help-issue"> | |||
<text>问题和意见</text> | |||
<text style="color: #BD3624;">*</text> | |||
</view> | |||
<uv-textarea v-model="value" :count="true" border="none" height="400" | |||
placeholder="请把发现的问题提交给我们,感谢您的参与(必填)" | |||
:text-style="{color:'#BCB7B7',fontSize:'28rpx'}" /> | |||
</view> | |||
<view> | |||
<view class="help-issue"> | |||
<text>问题截图</text> | |||
<text style="color: #BD3624;">*</text> | |||
</view> | |||
<view class="help-screenshot"> | |||
<uv-upload :fileList="fileList" multiple :maxCount="3" width="180rpx" | |||
height="180rpx" multiple @afterRead="afterRead" @delete="deleteImage"> | |||
<image src="../static/help/uploading.png" mode="aspectFill" | |||
style="width: 180rpx;height: 180rpx;" /> | |||
</uv-upload> | |||
</view> | |||
</view> | |||
<!-- <view> | |||
<view class="help-issue"> | |||
<text>联系方式</text> | |||
<text style="color: #BD3624;">*</text> | |||
</view> | |||
<uv-input placeholder="请输入联系方式" fontSize="24rpx" border="bottom" | |||
:custom-style="{backgroundColor: '#fff'}"> | |||
<template #prefix> | |||
<uv-text text="联系姓名" size="24rpx" margin="20rpx 10rpx 20rpx 10rpx" /> | |||
</template> | |||
</uv-input> | |||
<uv-input placeholder="请输入联系姓名" border="none" fontSize="24rpx" | |||
:custom-style="{backgroundColor: '#fff'}"> | |||
<template #prefix> | |||
<uv-text text="联系方式" size="24rpx" margin="20rpx 10rpx 20rpx 10rpx" /> | |||
</template> | |||
</uv-input> | |||
</view> --> | |||
<view class="help-button"> | |||
<view>确认</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<template> | |||
<view class="page"> | |||
<navbar title="帮助与反馈" leftClick @leftClick="$utils.navigateBack"/> | |||
<view class="frame"> | |||
<!--帮助与反馈--> | |||
<view class="helpFeedback"> | |||
<view class="title"> 问题和意见 <span style="color: red;">*</span></view> | |||
<view class="desc"> | |||
<textarea placeholder="请把发现的问题提交给我们,感谢您的参与(必填)"/> | |||
</view> | |||
</view> | |||
<!--问题截图--> | |||
<view class="problemImg"> | |||
<view class="title">问题截图<span style="color: red;">*</span></view> | |||
<view class="img"> | |||
<uv-upload | |||
:fileList="fileList" | |||
:maxCount="5" | |||
multiple | |||
width="150rpx" | |||
height="150rpx" | |||
@delete="deleteImage" | |||
@afterRead="afterRead" | |||
:previewFullImage="true"> | |||
</uv-upload> | |||
</view> | |||
</view> | |||
<!--联系方式--> | |||
<view class="name_phone"> | |||
<view class="title">联系方式<span style="color: red;">*</span></view> | |||
<view class="items"> | |||
<view class="item"> | |||
<view>联系姓名</view> | |||
<view> | |||
<input placeholder="请输入联系姓名" clearable></input> | |||
</view> | |||
</view> | |||
<view class="item"> | |||
<view>联系电话</view> | |||
<view> | |||
<input placeholder="请输入联系电话" clearable></input> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<!--提交反馈--> | |||
<view class="btns"> | |||
<view @click="submitFeedback" class="btn"> | |||
提交反馈 | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
import topbar from "@/components/base/topbar.vue"; | |||
import tabber from "@/components/base/tabbar.vue"; | |||
export default { | |||
name: "helpFeedback", | |||
components: {tabber, topbar}, | |||
data() { | |||
return { | |||
fileList: [], | |||
} | |||
}, | |||
methods: { | |||
// 提交反馈 | |||
submitFeedback() { | |||
}, | |||
deleteImage(e) { | |||
this.fileList.splice(e.index, 1) | |||
}, | |||
afterRead(e) { | |||
let self = this | |||
e.file.forEach(file => { | |||
self.$Oss.ossUpload(file.url).then(url => { | |||
self.fileList.push({ | |||
url | |||
}) | |||
}) | |||
}) | |||
}, | |||
}, | |||
} | |||
</script> | |||
<style scoped lang="scss"> | |||
.page { | |||
height: 100vh; | |||
background-color: #f2f5f5; | |||
.frame { | |||
padding: 40rpx; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: center; | |||
gap: 40rpx; | |||
.helpFeedback { | |||
.title { | |||
} | |||
.desc { | |||
margin-top: 20rpx; | |||
height: 300rpx; | |||
border-radius: 40rpx; | |||
overflow: hidden; | |||
padding: 20rpx; | |||
font-size: 28rpx; | |||
background-color: #fff; | |||
} | |||
} | |||
.problemImg { | |||
.img { | |||
margin-top: 20rpx; | |||
height: 150rpx; | |||
border-radius: 40rpx; | |||
overflow: hidden; | |||
padding: 20rpx; | |||
font-size: 28rpx; | |||
background-color: #fff; | |||
} | |||
} | |||
.name_phone { | |||
.title { | |||
} | |||
.items { | |||
margin-top: 20rpx; | |||
.item { | |||
display: flex; | |||
align-items: center; | |||
background-color: #FFF; | |||
height: 80rpx; | |||
padding: 10rpx 0 0 20rpx; | |||
border-bottom: 1px solid #efefef; | |||
> view:nth-of-type(1) { | |||
width: 30%; | |||
// font-weight: 700; | |||
} | |||
> view:nth-of-type(2) { | |||
width: 70%; | |||
border-radius: 10rpx; | |||
overflow: hidden; | |||
input { | |||
background-color: #FFF; | |||
font-size: 28rpx; | |||
padding: 16rpx 8rpx 16rpx 15rpx; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
.btns { | |||
width: 100%; | |||
display: flex; | |||
flex-direction: column; | |||
align-items: center; | |||
justify-content: center; | |||
gap: 20rpx; | |||
.btn { | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
width: 500rpx; | |||
height: 70rpx; | |||
border-radius: 40rpx; | |||
color: #FFF; | |||
font-size: 28rpx; | |||
margin: 20rpx 10rpx 0 0; | |||
background: $uni-color; | |||
//margin-top: 20rpx; | |||
border-radius: 40rpx; | |||
} | |||
} | |||
} | |||
} | |||
</style> | |||
<script> | |||
export default { | |||
data() { | |||
return { | |||
value: "", | |||
fileList: [] | |||
} | |||
}, | |||
onLoad(args) { | |||
}, | |||
methods: { | |||
deleteImage(e){ | |||
this.fileList.splice(e.index, 1) | |||
}, | |||
afterRead(e){ | |||
let self = this | |||
e.file.forEach(file => { | |||
self.$Oss.ossUpload(file.url).then(url => { | |||
self.fileList.push({ | |||
url | |||
}) | |||
}) | |||
}) | |||
}, | |||
} | |||
} | |||
</script> | |||
<style scoped lang="scss"> | |||
.help { | |||
.help-box { | |||
width: 92%; | |||
margin-left: 4%; | |||
.help-issue { | |||
margin: 20rpx; | |||
font-size: 28rpx; | |||
font-weight: 600; | |||
color: #333333; | |||
} | |||
.help-screenshot { | |||
display: flex; | |||
align-items: center; | |||
background-color: #fff; | |||
padding: 20rpx; | |||
} | |||
.help-button { | |||
display: flex; | |||
justify-content: center; | |||
font-size: 24rpx; | |||
flex-shrink: 0; | |||
margin-top: 60rpx; | |||
view { | |||
padding: 14rpx 120rpx; | |||
border-radius: 38rpx; | |||
} | |||
view:nth-child(1) { | |||
background: $uni-color; | |||
color: #fff; | |||
} | |||
view:nth-child(2) { | |||
color: #FFFDF6; | |||
background-color: #C83741; | |||
} | |||
} | |||
} | |||
} | |||
</style> |
@ -0,0 +1,266 @@ | |||
<template> | |||
<view class="promotion"> | |||
<navbar title="二维码" | |||
bgColor="rgb(235, 51, 0)" | |||
color="#fff" | |||
leftClick @leftClick="$utils.navigateBack" /> | |||
<image | |||
class="image" | |||
:src="promotionUrl" mode="aspectFill"></image> | |||
<!-- <canvas id="myCanvas" type="2d" canvas-id="firstCanvas1"></canvas> --> | |||
<view class="btn" | |||
v-if="promotionUrl" | |||
@click="preservationImg(promotionUrl)"> | |||
保存到相册 | |||
</view> | |||
</view> | |||
</template> | |||
<script> | |||
import { mapState } from 'vuex' | |||
export default { | |||
name: 'Promotion', | |||
computed: { | |||
...mapState(['userInfo', 'promotionUrl']), | |||
}, | |||
data() { | |||
return { | |||
url: '', | |||
title: '', | |||
baseUrl: 'https://image.hhlm1688.com/', | |||
canvas: {}, | |||
imagePath : '', | |||
// imagePath: 'https://image.hhlm1688.com/2025-03-06/32fbb8e2-160b-4cbf-9a49-a72de231de20.png', | |||
// imagePath: 'https://image.hhlm1688.com/2025-02-27/2fe7e417-54ad-4911-b9ba-84ac7d48e66d.png', | |||
// imagePath: 'https://image.hhlm1688.com/2025-02-26/6539d2fa-558d-47db-9681-ecffec5b6c5d.png', | |||
index : 0, | |||
} | |||
}, | |||
onShow() { | |||
let that = this; | |||
// that.draw() | |||
if(!that.promotionUrl){ | |||
// that.getQrCode() | |||
this.getImageInfo() | |||
} | |||
// that.$store.commit('getUserInfo') | |||
}, | |||
methods: { | |||
getImageInfo(){ | |||
let that = this; | |||
uni.showLoading({ | |||
title: "拼命绘画中..." | |||
}) | |||
uni.getImageInfo({ | |||
src: `${this.$config.baseUrl}/info/createQrCode?token=${uni.getStorageSync('token')}`, | |||
success : res => { | |||
uni.hideLoading() | |||
that.$store.commit('setPromotionUrl', res.path) | |||
}, | |||
fail : err => { | |||
uni.showToast({ | |||
icon: 'none', | |||
title: '绘画失败', | |||
}) | |||
} | |||
}) | |||
}, | |||
getQrCode() { | |||
uni.showLoading({ | |||
title: "拼命绘画中..." | |||
}) | |||
let that = this; | |||
that.$api('getInviteCode', res => { | |||
if (res.code == 200) { | |||
that.url = res.result.url | |||
that.title = res.result.name | |||
that.imagePath = that.$config.aliOss.url + res.result.url | |||
that.$store.commit('setPromotionUrl', that.imagePath) | |||
// that.draw() | |||
uni.hideLoading() | |||
} | |||
}) | |||
}, | |||
draw() { | |||
uni.showLoading({ | |||
title: "拼命绘画中..." | |||
}) | |||
let that = this; | |||
wx.createSelectorQuery() | |||
.select('#myCanvas') // 绘制的canvas的id | |||
.fields({ | |||
node: true, | |||
size: true | |||
}) | |||
.exec((res) => { | |||
console.log("----------1") | |||
const canvas = res[0].node | |||
// 渲染上下文 | |||
const ctx = canvas.getContext('2d') | |||
// Canvas 画布的实际绘制宽高 | |||
const width = res[0].width | |||
const height = res[0].height | |||
console.log(width, height); | |||
// 初始化画布大小 | |||
const dpr = wx.getWindowInfo().pixelRatio | |||
//根据dpr调整 | |||
// dpr 2 4 | |||
// 3 6 | |||
let Ratio = dpr * 2 | |||
canvas.width = width * dpr | |||
canvas.height = height * dpr | |||
that.canvas = canvas | |||
ctx.scale(dpr, dpr) | |||
ctx.clearRect(0, 0, width, height) | |||
// ctx.fillStyle = '#fff' | |||
// ctx.fillRect(0, 0, canvas.width, canvas.height) | |||
//图片 | |||
const bgImage = canvas.createImage() | |||
bgImage.src = that.configList.qr_code | |||
//二维码图片 | |||
const coderImage = canvas.createImage() | |||
coderImage.src = '../static/logo.png' | |||
// coderImage.src = that.baseUrl + that.url | |||
let size = 0; | |||
console.log("----------2") | |||
bgImage.onload = () => { | |||
canvas.width = bgImage.width | |||
canvas.height = bgImage.height | |||
ctx.drawImage(bgImage, | |||
0, 0, bgImage.width, bgImage.height) | |||
size = Math.floor(canvas.width / 3) | |||
ctx.drawImage(coderImage, | |||
canvas.width / 2 - (size / 2), canvas.height * 0.46, size, size) | |||
that.canvasToTempFilePath() | |||
} | |||
console.log("----------3") | |||
coderImage.onload = () => { | |||
ctx.drawImage(coderImage, | |||
canvas.width / 2 - (size / 2), canvas.height * 0.46, size, size) | |||
that.canvasToTempFilePath() | |||
} | |||
}) | |||
}, | |||
canvasToTempFilePath(){ | |||
let that = this; | |||
that.index++ | |||
if(that.index < 2){ | |||
return | |||
} | |||
// 绘制完成后存储路径 | |||
setTimeout(() => { | |||
wx.canvasToTempFilePath({ | |||
x: 0, | |||
y: 0, | |||
width: that.canvas.width, | |||
height: that.canvas.height, | |||
canvas : that.canvas, | |||
success: (res) => { | |||
var tempFilePath = res.tempFilePath; | |||
that.imagePath = tempFilePath | |||
that.$store.commit('setPromotionUrl', res.tempFilePath) | |||
uni.hideLoading() | |||
that.load = false | |||
} | |||
}); | |||
}, 200); | |||
}, | |||
back() { | |||
uni.navigateBack(-1) | |||
}, | |||
async preservationImg(img) { | |||
await this.$authorize('scope.writePhotosAlbum') | |||
this.imgApi(img); | |||
}, | |||
imgApi(image) { | |||
/* 获取图片的信息 */ | |||
uni.getImageInfo({ | |||
src: image, | |||
success: function(image) { | |||
/* 保存图片到手机相册 */ | |||
uni.saveImageToPhotosAlbum({ | |||
filePath: image.path, | |||
success: function() { | |||
uni.showModal({ | |||
title: '保存成功', | |||
content: '图片已成功保存到相册', | |||
showCancel: false | |||
}); | |||
}, | |||
complete(res) { | |||
console.log(res); | |||
} | |||
}); | |||
} | |||
}); | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.promotion { | |||
width: 100%; | |||
height: 100vh; | |||
background-color: $uni-color; | |||
} | |||
.image{ | |||
width: 100%; | |||
height: calc(100vh - 320rpx); | |||
} | |||
#myCanvas { | |||
position: fixed; | |||
left: 100%; | |||
/* visibility: hidden */ | |||
/* visibility: hidden; */ | |||
/* margin-top: 100rpx; */ | |||
width: 750rpx; | |||
height: calc(100vh - 120rpx); | |||
/* line-height: 20px; */ | |||
background-color: rgba(255, 255, 255, 1); | |||
text-align: center; | |||
} | |||
.btn{ | |||
position: fixed; | |||
// top: 58vh; | |||
bottom: 0; | |||
margin: 0; | |||
width: 750rpx; | |||
height: 100rpx; | |||
padding: 0; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
background-color: #fff; | |||
color: $uni-color; | |||
} | |||
</style> |
@ -0,0 +1,805 @@ | |||
<template> | |||
<view class="page"> | |||
<!-- 导航栏 --> | |||
<navbar :title="titleMap[type]" leftClick @leftClick="$utils.navigateBack" bgColor="#E3441A" color="#fff" /> | |||
<view class="bac"></view> | |||
<view class="box"> | |||
<!-- 送礼 --> | |||
<view class="give-type" v-if="type == 'give'"> | |||
<view class="tab-box"> | |||
<view class="tab-item" :class="{'active': isGive === 1}" | |||
@click="isGive = 1"> | |||
<text>单人礼包</text> | |||
<text class="desc">送给1位好友,可同时送多件礼品</text> | |||
</view> | |||
<view class="tab-item" :class="{'active': isGive === 2}" | |||
@click="isGive = 2"> | |||
<text>多人礼包</text> | |||
<text class="desc">送给多位好友,每人1件礼品</text> | |||
</view> | |||
<view class="tab-item" :class="{'active': isGive === 3}" | |||
@click="isGive = 3"> | |||
<text>抽奖礼包</text> | |||
<text class="desc">好友抽奖,中奖者获得礼品</text> | |||
</view> | |||
</view> | |||
<!-- <view class="tips"> | |||
<text>支付后分享给好友收礼</text> | |||
<text class="guide" @click="$refs.popup.open('gift_guide')">指南</text> | |||
</view> --> | |||
</view> | |||
<!-- 多人礼包人数 --> | |||
<view class="cell-item" v-if="type == 'give' && isGive === 2"> | |||
<view class="cell-item-left"> | |||
<uv-icon name="gift" size="40" color="#E3441A"></uv-icon> | |||
<view class="user-name">礼包份数</view> | |||
</view> | |||
<view class="cell-item-right"> | |||
<view class="stepper"> | |||
<text class="minus" :class="{disabled: multiNum <= multiMinNum}" | |||
@click="multiNum > multiMinNum && multiNum--">-</text> | |||
<text class="num">{{multiNum}}</text> | |||
<text class="plus" :class="{disabled: multiNum >= multiMaxNum}" | |||
@click="multiNum < multiMaxNum && multiNum++">+</text> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 抽奖礼包说明 --> | |||
<view class="lucky-box" v-if="type == 'give' && isGive === 3"> | |||
<view class="title">抽奖规则</view> | |||
<view class="tips-list"> | |||
<view class="tip-item">• 好友参与抽奖</view> | |||
<view class="tip-item">• 系统随机抽取中奖者</view> | |||
<view class="tip-item">• 中奖者填写地址领取礼品</view> | |||
</view> | |||
</view> | |||
<!-- 商品详情 --> | |||
<view class="product-item" v-for="item in payOrderProduct" :key="item.id"> | |||
<view class="img-box"> | |||
<image :src="item.image && item.image.split(',')[0]" mode="aspectFill"></image> | |||
</view> | |||
<view class="server-info"> | |||
<view class="server-title">{{ item.name }}</view> | |||
<view class="texture"> | |||
材质:{{ item.material }} | |||
</view> | |||
<view class="stepper"> | |||
<uv-number-box button-size="60" v-model="item.selectNum" | |||
:max="item.num"></uv-number-box> | |||
</view> | |||
<view class="sales-volume"> | |||
<view class="desc">已售出 {{ item.payNum }}单</view> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 地址 --> | |||
<view @click="openAddress" class="cell-item"> | |||
<view class="cell-item-left"> | |||
<image src="@/pages_order/static/createOrder/address.png" mode="widthFix" class="cell-icon"></image> | |||
<view class="user-name">{{ address.name }}</view> | |||
<view class="user-address">{{ address.address }}</view> | |||
</view> | |||
<view class="cell-item-right"> | |||
<uv-icon name="arrow-right"></uv-icon> | |||
</view> | |||
</view> | |||
<!-- 备注 --> | |||
<!-- <view class="cell-item"> | |||
<view class="cell-item-left"> | |||
<image src="@/pages_order/static/createOrder/coupon.png" mode="widthFix" class="cell-icon"></image> | |||
<view class="user-name">备注</view> | |||
</view> | |||
<view class="cell-item-right remark-input"> | |||
<uv-textarea v-model="remark" border="none" height="40rpx" placeholder="请输入订单备注信息" :count="false" :auto-height="false" /> | |||
</view> | |||
</view> --> | |||
<view class="cell-list"> | |||
<uv-radio-group v-model="payMethod"> | |||
<view style="width: 710rpx;"> | |||
<!-- 账户余额 --> | |||
<view class="cell-item"> | |||
<view class="cell-item-left"> | |||
<image src="@/pages_order/static/createOrder/account.png" mode="widthFix" class="cell-icon"> | |||
</image> | |||
<view class="user-name">账户余额</view> | |||
<view class="descript">(余额: {{ riceInfo.balance }})</view> | |||
</view> | |||
<view class="cell-item-right"> | |||
<uv-radio activeColor="#E3441A" | |||
size="40rpx" | |||
icon-size="30rpx" | |||
:name="1"/> | |||
</view> | |||
</view> | |||
<!-- 微信支付 --> | |||
<view class="cell-item"> | |||
<view class="cell-item-left"> | |||
<image src="@/pages_order/static/createOrder/wx.png" mode="widthFix" class="cell-icon"> | |||
</image> | |||
<view class="user-name">微信支付</view> | |||
<view class="descript"></view> | |||
</view> | |||
<view class="cell-item-right"> | |||
<uv-radio | |||
activeColor="#E3441A" | |||
size="40rpx" | |||
icon-size="30rpx" | |||
:name="0"/> | |||
</view> | |||
</view> | |||
</view> | |||
</uv-radio-group> | |||
</view> | |||
<!-- 优惠券 --> | |||
<!-- <view @click="openCoupon" class="cell-item"> | |||
<view class="cell-item-left"> | |||
<image src="@/pages_order/static/createOrder/coupon.png" mode="widthFix" class="cell-icon"></image> | |||
<view class="user-name">优惠券</view> | |||
<view class="descript">(¥{{ coupon.money || 0}})</view> | |||
</view> | |||
<view class="cell-item-right"> | |||
<radio color="#E3441A" :value="2" :checked="coupon.id" /> | |||
</view> | |||
</view> --> | |||
<!-- 提示 --> | |||
<view class="hint" | |||
v-if="payOrderProduct[0] && payOrderProduct[0].orderDetails"> | |||
{{ payOrderProduct[0].orderDetails }} | |||
</view> | |||
<!-- 用户协议 --> | |||
<view class="agreement"> | |||
<radio color="#E3441A" @click="agreement = !agreement" :checked="agreement" /> | |||
本人已同意<text @click="$refs.popup.open('user_xy')">《用户使用协议》</text> | |||
</view> | |||
<!-- 下单 --> | |||
<view class="submit"> | |||
<view class="price"> | |||
<view> | |||
<text style="color: #000;">合计</text> | |||
¥<text style="font-size: 18px; | |||
font-weight: 600;">{{ totalPrice }}</text>元 | |||
</view> | |||
</view> | |||
<view class="btn" @click="submit"> | |||
立即支付 | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 地址选择 --> | |||
<uv-popup ref="addressPopup" :round="30" style="padding-bottom: 90rpx;"> | |||
<addressList ref="addressList" height="60vh" @select="selectAddress" /> | |||
<view class="add-btn"> | |||
<view @click="$utils.navigateTo('/pages_order/mine/address')" class="button-submit">新增地址</view> | |||
</view> | |||
</uv-popup> | |||
<!-- 优惠券选择--> | |||
<!-- <uv-popup ref="couponPopup" :round="30"> | |||
<couponList ref="couponList" height="60vh" @select="selectCoupon" /> | |||
</uv-popup> --> | |||
<configPopup ref="popup"></configPopup> | |||
<!-- <kefu></kefu> --> | |||
</view> | |||
</template> | |||
<script> | |||
import addressList from '../components/address/addressList.vue' | |||
// import couponList from '@/components/couponList/couponList.vue' | |||
import { | |||
mapState | |||
} from 'vuex' | |||
export default { | |||
components: { | |||
addressList, | |||
// couponList | |||
}, | |||
data() { | |||
return { | |||
address: { | |||
name: '请选择地址', | |||
address: '', | |||
}, | |||
addressTotal: 0, | |||
remark: '', | |||
num: 1, | |||
agreement: false, | |||
coupon: {}, | |||
payMethod : 0, | |||
isGive : 0, | |||
type : '', | |||
titleMap : { | |||
def : '确认订单', | |||
give : '送礼清单', | |||
}, | |||
multiNum: 2, // 多人礼包人数 | |||
multiMinNum: 2, // 最小人数 | |||
multiMaxNum: 100, // 最大人数 | |||
} | |||
}, | |||
computed: { | |||
totalPrice() { | |||
let price = 0 | |||
this.payOrderProduct.forEach(n => { | |||
price += n.price * n.num | |||
}) | |||
if (this.coupon.id) { | |||
price -= this.coupon.money | |||
} | |||
return Number(price).toFixed(2) | |||
}, | |||
...mapState(['userInfo', 'payOrderProduct']), | |||
}, | |||
onLoad(args) { | |||
this.type = args.type || 'def' | |||
if(this.type == 'give'){ | |||
this.isGive = 1 | |||
} | |||
this.$store.commit('getUserInfo') | |||
}, | |||
onShow() { | |||
this.getAddressList() | |||
// this.getCouponList() | |||
}, | |||
methods: { | |||
// 打开 | |||
getAddressList() { | |||
// 获取地址列表 | |||
this.$refs.addressList.getAddressList().then(res => { | |||
this.addressTotal = res.total | |||
if (this.addressTotal != 0) { | |||
this.address = res.records[0] | |||
} | |||
}) | |||
}, | |||
//获取优惠券列表 | |||
getCouponList() { | |||
this.$refs.couponList.getCouponList() | |||
}, | |||
// 打开选择地址 | |||
openAddress() { | |||
if (this.addressTotal == 0) { | |||
return uni.navigateTo({ | |||
url: '/pages_order/mine/address?type=back' | |||
}) | |||
} | |||
this.$refs.addressPopup.open('bottom') | |||
}, | |||
// 选择地址 | |||
selectAddress(e) { | |||
this.address = e | |||
this.$refs.addressPopup.close() | |||
}, | |||
// 打开优惠券选择 | |||
openCoupon() { | |||
if (this.addressTotal == 0) { | |||
return uni.navigateTo({ | |||
url: '/pages_order/mine/address?type=back' | |||
}) | |||
} | |||
this.$refs.couponPopup.open('bottom') | |||
}, | |||
// 选择优惠券 | |||
selectCoupon(e) { | |||
//判断优惠券限制 | |||
let { | |||
useMoney | |||
} = e | |||
let productTotalPrice = 0 | |||
this.payOrderProduct.forEach(item => { | |||
productTotalPrice += item.price | |||
}) | |||
if (productTotalPrice < useMoney) { | |||
return uni.showToast({ | |||
title: `此优惠券需要满${useMoney}使用`, | |||
icon: "none" | |||
}) | |||
} | |||
this.coupon = e | |||
this.$refs.couponPopup.close() | |||
}, | |||
submit() { | |||
let addressId = this.address.id | |||
if (!addressId) { | |||
uni.showToast({ | |||
title: '请选择地址', | |||
icon: 'none' | |||
}) | |||
return | |||
} | |||
if (!this.agreement) { | |||
uni.showToast({ | |||
title: '请先同意使用协议', | |||
icon: 'none' | |||
}) | |||
return | |||
} | |||
let data = {} | |||
let api = '' | |||
// if(this.type != 'give'){ | |||
// let list = [] | |||
// this.payOrderProduct.forEach(n => { | |||
// list.push({ | |||
// num: n.selectNum || 1, | |||
// shopId: n.shopId || n.id, | |||
// }) | |||
// }) | |||
// data = { | |||
// addressId, | |||
// payType : this.payMethod, | |||
// list: JSON.stringify(list), | |||
// remark: this.remark || '', // 添加备注字段 | |||
// } | |||
// api = 'createOrder' | |||
// this.deleteCart(this.payOrderProduct.map(n => n.id).join(',')) | |||
// } else { | |||
data = { | |||
addressId, | |||
num: this.payOrderProduct[0].selectNum || 1, | |||
productId: this.payOrderProduct[0].id, | |||
payType : this.payMethod, | |||
// isGive : this.isGive, | |||
// memberNum : 1, | |||
// remark: this.remark || '', // 添加备注字段 | |||
} | |||
api = 'createOrder' | |||
// } | |||
if(this.coupon.id){ | |||
data.couponId = this.coupon.id | |||
} | |||
// if(this.isGive == 2){ | |||
// data.memberNum = this.multiNum | |||
// } | |||
this.$api(api, data, res => { | |||
if (res.code == 200) { | |||
if(this.payMethod == 1){ | |||
// uni.showToast({ | |||
// title: '下单成功', | |||
// icon: 'none' | |||
// }) | |||
this.paySuccess(res) | |||
return | |||
} | |||
uni.requestPaymentWxPay(res) | |||
.then(e => { | |||
uni.showToast({ | |||
title: '下单成功', | |||
icon: 'none' | |||
}) | |||
this.paySuccess(res) | |||
}).catch(n => { | |||
setTimeout(uni.redirectTo, 700, { | |||
url: '/pages/index/order' | |||
}) | |||
}) | |||
} | |||
}) | |||
}, | |||
paySuccess(res){ | |||
if(this.type == 'def'){ | |||
setTimeout(uni.redirectTo, 700, { | |||
url: '/pages/index/order' | |||
}) | |||
}else{ | |||
setTimeout(uni.redirectTo, 700, { | |||
url: `/pages_order/order/instantGift?id=${res.message}` | |||
}) | |||
} | |||
}, | |||
// 删除购物车 | |||
deleteCart(ids) { | |||
this.$api('deleteCart', { | |||
ids | |||
}) | |||
}, | |||
} | |||
} | |||
</script> | |||
<style scoped lang="scss"> | |||
.page { | |||
overflow: auto; | |||
padding-bottom: 300rpx; | |||
.bac { | |||
width: 100%; | |||
height: 100px; | |||
background: $uni-color; | |||
} | |||
.give-type { | |||
background: #fff; | |||
border-radius: 20rpx; | |||
padding: 30rpx; | |||
margin-bottom: 20rpx; | |||
.tab-box { | |||
display: flex; | |||
justify-content: space-between; | |||
.tab-item { | |||
width: 30%; | |||
background: #F8F8F8; | |||
border-radius: 20rpx; | |||
padding: 20rpx; | |||
text-align: center; | |||
text { | |||
display: block; | |||
&.desc { | |||
font-size: 24rpx; | |||
color: #999; | |||
margin-top: 10rpx; | |||
} | |||
} | |||
&.active { | |||
background: rgba($uni-color, 0.1); | |||
color: $uni-color; | |||
.desc { | |||
color: $uni-color; | |||
} | |||
} | |||
} | |||
} | |||
.tips { | |||
margin-top: 20rpx; | |||
font-size: 26rpx; | |||
color: #999; | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
.guide { | |||
color: $uni-color; | |||
text-decoration: underline; | |||
} | |||
} | |||
} | |||
.box { | |||
padding: 20rpx; | |||
margin-top: -150rpx; | |||
// 商品详情 | |||
.product-item { | |||
display: flex; | |||
flex-wrap: wrap; | |||
align-items: center; | |||
justify-content: space-between; | |||
background: white; | |||
border-radius: 15rpx; | |||
box-sizing: border-box; | |||
padding: 25rpx; | |||
margin: 20rpx 0rpx; | |||
.img-box { | |||
width: 200rpx; | |||
height: 200rpx; | |||
background: #ccc; | |||
border-radius: 10rpx; | |||
overflow: hidden; | |||
image { | |||
width: 100%; | |||
height: 100%; | |||
} | |||
} | |||
.server-info { | |||
width: calc(100% - 200rpx); | |||
box-sizing: border-box; | |||
padding: 10rpx 20rpx; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: space-around; | |||
.server-title { | |||
font-size: 34rpx; | |||
} | |||
.texture { | |||
color: #B8B8B8; | |||
margin: 10rpx 0rpx; | |||
} | |||
.stepper { | |||
margin-bottom: 10rpx; | |||
&::v-deep .uv-number-box__input { | |||
color: $uni-color !important; | |||
width: 100rpx !important; | |||
} | |||
} | |||
.sales-volume { | |||
display: flex; | |||
align-items: center; | |||
color: #B8B8B8; | |||
font-size: 26rpx; | |||
image { | |||
width: 25rpx; | |||
height: 25rpx; | |||
} | |||
} | |||
} | |||
} | |||
//cell单元格(地址) | |||
.cell-item { | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
background: white; | |||
border-radius: 20rpx; | |||
padding: 20rpx; | |||
box-sizing: border-box; | |||
.cell-item-left { | |||
display: flex; | |||
align-items: center; | |||
width: 90%; | |||
.cell-icon { | |||
width: 40rpx; | |||
} | |||
.user-name, | |||
.user-address { | |||
white-space: nowrap; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
width: 150rpx; | |||
padding-left: 20rpx; | |||
box-sizing: border-box; | |||
} | |||
.descript { | |||
color: #888888; | |||
} | |||
.user-address { | |||
width: calc(100% - 230rpx); | |||
} | |||
} | |||
.cell-item-right { | |||
width: 10%; | |||
display: flex; | |||
justify-content: flex-end; | |||
&.remark-input { | |||
width: 70%; | |||
justify-content: flex-start; | |||
&::v-deep .uv-textarea { | |||
width: 100%; | |||
padding: 0; | |||
background-color: transparent; | |||
} | |||
&::v-deep .uv-textarea__field { | |||
padding: 0; | |||
font-size: 28rpx; | |||
} | |||
} | |||
.stepper { | |||
display: flex; | |||
align-items: center; | |||
text { | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
width: 44rpx; | |||
height: 44rpx; | |||
&.minus, &.plus { | |||
background: #F8F8F8; | |||
border-radius: 50%; | |||
font-size: 32rpx; | |||
&.disabled { | |||
color: #ccc; | |||
} | |||
} | |||
&.num { | |||
margin: 0 20rpx; | |||
color: $uni-color; | |||
font-size: 28rpx; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
.cell-list { | |||
margin: 20rpx 0rpx; | |||
border-radius: 20rpx; | |||
overflow: hidden; | |||
.cell-item { | |||
border-radius: 0rpx; | |||
} | |||
} | |||
// 提示 | |||
.hint { | |||
font-size: 26rpx; | |||
margin-top: 80rpx; | |||
color: #BFBFBF; | |||
} | |||
// 用户协议 | |||
.agreement { | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
padding: 10px 0; | |||
.van-checkbox { | |||
margin-right: 5rpx; | |||
} | |||
text { | |||
color: $uni-color; | |||
} | |||
} | |||
// 下单 | |||
.submit { | |||
position: fixed; | |||
bottom: 0; | |||
left: 0; | |||
width: 100%; | |||
height: 60px; | |||
background-color: #fff; | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
.price { | |||
color: #F39637; | |||
padding: 0 20px; | |||
} | |||
.btn { | |||
background: $uni-color; | |||
color: white; | |||
width: 120px; | |||
height: 45px; | |||
border-radius: 23px; | |||
font-size: 16px; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
} | |||
} | |||
} | |||
//新增地址按钮 | |||
.add-btn { | |||
width: 100%; | |||
.button-submit { | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
width: 596rpx; | |||
height: 90rpx; | |||
background: #E3441A; | |||
border-radius: 46rpx; | |||
margin: 20rpx auto; | |||
font-size: 28rpx; | |||
font-family: PingFang SC, PingFang SC-Regular; | |||
font-weight: 400; | |||
text-align: center; | |||
color: #ffffff; | |||
} | |||
} | |||
.multi-box, .lucky-box { | |||
background: #fff; | |||
border-radius: 20rpx; | |||
padding: 30rpx; | |||
margin-bottom: 20rpx; | |||
.title { | |||
font-size: 28rpx; | |||
font-weight: 500; | |||
margin-bottom: 20rpx; | |||
} | |||
} | |||
.multi-box { | |||
.stepper { | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
text { | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
width: 60rpx; | |||
height: 60rpx; | |||
&.minus, &.plus { | |||
background: #F8F8F8; | |||
border-radius: 50%; | |||
font-size: 36rpx; | |||
&.disabled { | |||
color: #ccc; | |||
} | |||
} | |||
&.num { | |||
margin: 0 40rpx; | |||
color: $uni-color; | |||
font-size: 32rpx; | |||
} | |||
} | |||
} | |||
} | |||
.lucky-box { | |||
.tips-list { | |||
.tip-item { | |||
font-size: 26rpx; | |||
color: #666; | |||
line-height: 2; | |||
} | |||
} | |||
} | |||
} | |||
</style> |
@ -1,362 +0,0 @@ | |||
<template> | |||
<view class="refundsOrExchange"> | |||
<navbar :title="title[titleIndex]" leftClick @leftClick="$utils.navigateBack"/> | |||
<view class="frame"> | |||
<!-- 商品简介 --> | |||
<view class="itme1" @click="openSpPopup"> | |||
<view class="left"> | |||
<img src="../../static/image/center/1.png" alt="" style="width: 100%;height: 100%;"> | |||
</view> | |||
<view class="center"> | |||
<view>{{ commodity.title }}</view> | |||
<view>{{ commodity.smallTitle }}</view> | |||
</view> | |||
<view class="right">×{{ commodity.total }}</view> | |||
</view> | |||
<!--<commoditySelect ></commoditySelect>--> | |||
<!-- 申请类型&申请原因 --> | |||
<view class="item2"> | |||
<view class="type"> | |||
<span>申请类型</span> | |||
<span>退货退款</span> | |||
</view> | |||
<uv-line></uv-line> | |||
<view class="reason"> | |||
<view>申请原因</view> | |||
<view> | |||
<uv-input placeholder="请输入申请原因" border="none" clearable></uv-input> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 退货数量&申请金额--> | |||
<view class="item3"> | |||
<view class="type"> | |||
<span>{{ titleIndex == 0 ? '退货数量' : '换货数量' }}</span> | |||
<span> | |||
<uv-number-box :min="1" :max="100"></uv-number-box> | |||
</span> | |||
</view> | |||
<uv-line v-if='titleIndex == 0 ? true :false'></uv-line> | |||
<view class="reason" v-if='titleIndex == 0 ? true :false'> | |||
<view>申请原因</view> | |||
<view> | |||
<uv-input disabled placeholder="$" border="none" clearable></uv-input> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 申请说明 --> | |||
<view class="item4"> | |||
<view>申请说明(选填)</view> | |||
<view> | |||
<uv-input placeholder="请您详细填写申请说明" border="none" clearable></uv-input> | |||
</view> | |||
<view> | |||
<uv-upload :fileList="fileList" :maxCount="5" multiple width="150rpx" height="150rpx" | |||
@delete="deleteImage" @afterRead="afterRead" :previewFullImage="true"></uv-upload> | |||
</view> | |||
</view> | |||
<!-- 联系电话 --> | |||
<view class="item5"> | |||
<view class="phone"> | |||
<view>联系电话</view> | |||
<view> | |||
<uv-input placeholder="请输入联系电话" border="none" clearable></uv-input> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 底部按钮 --> | |||
<!--商品选择--> | |||
<uv-popup ref="spPopup" :round="30"> | |||
<commoditySelect | |||
:commodityList="commodityList" | |||
@selectSp="selectCommodity" | |||
/> | |||
</uv-popup> | |||
</view> | |||
</template> | |||
<script> | |||
import commoditySelect from "../components/commodity/commoditySelect.vue" | |||
export default { | |||
onLoad(option) { | |||
this.titleIndex = option.index | |||
}, | |||
components: { | |||
commoditySelect | |||
}, | |||
data() { | |||
return { | |||
titleIndex: 0, | |||
title: ['申请换货', '申请退货'], | |||
fileList: [], | |||
bottomBtnStyle: { | |||
color: '#FFF', | |||
backgroundColor: '#fd5100', | |||
fontSize: '34rpx', | |||
text: '提交申请', | |||
width: '400rpx', | |||
height: '80rpx', | |||
borderRadius: '100rpx', | |||
bottom: '40rpx' | |||
}, | |||
commodityList: [ | |||
{ | |||
title: '商品名称', | |||
smallTitle: '产品规格:120*4*75【桌子尺寸】', | |||
total:1, | |||
}, | |||
{ | |||
title: '商品名称1', | |||
smallTitle: '产品规格:120*4*75【桌子尺寸】', | |||
total:1, | |||
}, | |||
{ | |||
title: '商品名称2', | |||
smallTitle: '产品规格:120*4*75【桌子尺寸】', | |||
total:1, | |||
} | |||
], | |||
commodity: { | |||
title: '商品名称', | |||
smallTitle: '产品规格:120*4*75【桌子尺寸】', | |||
total:1, | |||
}, | |||
} | |||
}, | |||
mounted() { | |||
}, | |||
methods: { | |||
openSpPopup() { | |||
this.$refs.spPopup.open('bottom'); | |||
}, | |||
// 选择退换货商品回调 | |||
selectCommodity(e) { | |||
console.log(e, "selectCommodity--e") | |||
this.commodity = e | |||
this.$refs.spPopup.close() | |||
}, | |||
confirm() { | |||
console.log("==="); | |||
}, | |||
// 删除 | |||
deleteImage(e) { | |||
this.fileList.splice(e.index, 1) | |||
}, | |||
// 文件上传 | |||
afterRead(e) { | |||
let self = this | |||
e.file.forEach(file => { | |||
self.$Oss.ossUpload(file.url).then(url => { | |||
self.fileList.push({ | |||
url | |||
}) | |||
}) | |||
}) | |||
}, | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
* { | |||
box-sizing: border-box; | |||
} | |||
.refundsOrExchange { | |||
.frame { | |||
display: flex; | |||
flex-direction: column; | |||
gap: 30rpx; | |||
width: 100%; | |||
padding-top: 40rpx; | |||
background-color: #f5f5f5; | |||
.itme1 { | |||
display: flex; | |||
height: 200rpx; | |||
background-color: #ffffff; | |||
.left { | |||
padding: 40rpx; | |||
width: 20%; | |||
border-radius: 10rpx; | |||
background-color: #ffffff; | |||
} | |||
.center { | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: center; | |||
gap: 20rpx; | |||
width: 60%; | |||
padding: 0rpx 0 0 20rpx; | |||
background-color: #ffffff; | |||
// 给第一个 view 设置样式 | |||
> view:first-of-type { | |||
font-size: 36rpx; | |||
color: #333; | |||
} | |||
// 给第二个 view 设置样式 | |||
> view:nth-of-type(2) { | |||
font-size: 28rpx; | |||
color: #666666; | |||
} | |||
} | |||
.right { | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
width: 10%; | |||
color: #666666; | |||
background-color: #ffffff; | |||
} | |||
} | |||
.item2 { | |||
width: 100vw; | |||
.type { | |||
display: flex; | |||
align-items: center; | |||
background-color: #FFF; | |||
height: 80rpx; | |||
padding: 0 0 0 20rpx; | |||
> span:nth-of-type(1) { | |||
width: 30%; | |||
} | |||
> span:nth-of-type(2) { | |||
width: 70%; | |||
} | |||
} | |||
.reason { | |||
display: flex; | |||
align-items: center; | |||
background-color: #FFF; | |||
height: 80rpx; | |||
// margin: 10rpx 0 0 0; | |||
padding: 10rpx 0 0 20rpx; | |||
> view:nth-of-type(1) { | |||
width: 30%; | |||
} | |||
> view:nth-of-type(2) { | |||
width: 70%; | |||
padding: 0 20rpx 0 0; | |||
} | |||
} | |||
} | |||
.item3 { | |||
width: 100vw; | |||
.type { | |||
display: flex; | |||
align-items: center; | |||
background-color: #FFF; | |||
height: 80rpx; | |||
padding: 0 0 0 20rpx; | |||
> span:nth-of-type(1) { | |||
width: 70%; | |||
} | |||
> span:nth-of-type(2) { | |||
width: 30%; | |||
} | |||
} | |||
.reason { | |||
display: flex; | |||
align-items: center; | |||
background-color: #FFF; | |||
height: 80rpx; | |||
// margin: 10rpx 0 0 0; | |||
padding: 10rpx 0 0 20rpx; | |||
> view:nth-of-type(1) { | |||
width: 30%; | |||
} | |||
> view:nth-of-type(2) { | |||
width: 70%; | |||
padding: 0 20rpx 0 0; | |||
} | |||
} | |||
} | |||
.item4 { | |||
display: flex; | |||
flex-direction: column; | |||
padding: 10rpx 0 0 20rpx; | |||
background-color: #FFF; | |||
> view:nth-of-type(1) { | |||
background-color: #FFF; | |||
} | |||
> view:nth-of-type(2) { | |||
margin: 10rpx 0 10rpx 0; | |||
background-color: #FFF; | |||
} | |||
} | |||
.item5 { | |||
display: flex; | |||
flex-direction: column; | |||
padding: 0 0 0 20rpx; | |||
background-color: #FFF; | |||
.phone { | |||
display: flex; | |||
align-items: center; | |||
background-color: #FFF; | |||
height: 80rpx; | |||
// margin: 10rpx 0 0 0; | |||
padding: 10rpx 0 0 20rpx; | |||
> view:nth-of-type(1) { | |||
width: 30%; | |||
} | |||
> view:nth-of-type(2) { | |||
width: 70%; | |||
padding: 0 20rpx 0 0; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
</style> |